From d58e3e0324e2c65ccbbcd6ed02c356b5e4f1c8ca Mon Sep 17 00:00:00 2001 From: Vivek Deshpande Date: Fri, 26 Aug 2016 12:17:50 -0700 Subject: [PATCH 001/207] 8154122: Intrinsify fused mac operations Added FMA intrinsics on x86 Reviewed-by: kvn, aph, darcy --- .../aarch64/vm/c1_LIRGenerator_aarch64.cpp | 4 ++ .../src/cpu/aarch64/vm/vm_version_aarch64.cpp | 5 +++ .../src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp | 4 ++ hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp | 5 +++ .../cpu/sparc/vm/c1_LIRGenerator_sparc.cpp | 4 ++ hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp | 5 +++ .../cpu/x86/vm/abstractInterpreter_x86.cpp | 4 +- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 16 +++++++ hotspot/src/cpu/x86/vm/assembler_x86.hpp | 2 + .../src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 12 +++++ .../src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 26 +++++++++++ hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 18 ++++++++ hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp | 4 ++ .../templateInterpreterGenerator_x86_32.cpp | 21 +++++++++ .../templateInterpreterGenerator_x86_64.cpp | 13 +++++- hotspot/src/cpu/x86/vm/vmStructs_x86.hpp | 3 +- hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 15 +++++-- hotspot/src/cpu/x86/vm/vm_version_x86.hpp | 7 ++- hotspot/src/cpu/x86/vm/x86.ad | 24 ++++++++++ .../src/jdk/vm/ci/amd64/AMD64.java | 3 +- .../AMD64HotSpotJVMCIBackendFactory.java | 3 ++ .../hotspot/amd64/AMD64HotSpotVMConfig.java | 1 + hotspot/src/share/vm/adlc/formssel.cpp | 2 + hotspot/src/share/vm/c1/c1_Compiler.cpp | 2 + hotspot/src/share/vm/c1/c1_LIR.cpp | 6 ++- hotspot/src/share/vm/c1/c1_LIR.hpp | 4 ++ hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 3 ++ hotspot/src/share/vm/c1/c1_LIRGenerator.hpp | 1 + hotspot/src/share/vm/classfile/vmSymbols.cpp | 8 ++++ hotspot/src/share/vm/classfile/vmSymbols.hpp | 7 ++- .../vm/interpreter/abstractInterpreter.cpp | 9 ++++ .../vm/interpreter/abstractInterpreter.hpp | 2 + .../templateInterpreterGenerator.cpp | 8 +++- .../src/share/vm/jvmci/vmStructs_jvmci.cpp | 3 +- hotspot/src/share/vm/opto/c2compiler.cpp | 6 +++ hotspot/src/share/vm/opto/classes.hpp | 2 + hotspot/src/share/vm/opto/library_call.cpp | 34 ++++++++++++++ hotspot/src/share/vm/opto/matcher.cpp | 11 +++++ hotspot/src/share/vm/opto/mulnode.cpp | 44 +++++++++++++++++++ hotspot/src/share/vm/opto/mulnode.hpp | 22 ++++++++++ hotspot/src/share/vm/runtime/globals.hpp | 3 ++ hotspot/src/share/vm/runtime/vmStructs.cpp | 2 + 42 files changed, 365 insertions(+), 13 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp index e66f6ff5fe5..3a968ccb87d 100644 --- a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp @@ -1032,6 +1032,10 @@ void LIRGenerator::do_update_CRC32C(Intrinsic* x) { Unimplemented(); } +void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) { + fatal("FMA intrinsic is not implemented on this platform"); +} + void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) { fatal("vectorizedMismatch intrinsic is not implemented on this platform"); } diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp index f1470162e61..53a294b8601 100644 --- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp @@ -262,6 +262,11 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); } + if (UseFMA) { + warning("FMA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseFMA, false); + } + if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) { if (FLAG_IS_DEFAULT(UseSHA)) { FLAG_SET_DEFAULT(UseSHA, true); diff --git a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp index c8ebff099f9..04056ba2d4e 100644 --- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp @@ -1433,6 +1433,10 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) { } } +void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) { + fatal("FMA intrinsic is not implemented on this platform"); +} + void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) { fatal("vectorizedMismatch intrinsic is not implemented on this platform"); } diff --git a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp index e919469f626..6162bafd1ab 100644 --- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -230,6 +230,11 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); } + if (UseFMA) { + warning("FMA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseFMA, false); + } + if (UseSHA) { warning("SHA instructions are not available on this CPU"); FLAG_SET_DEFAULT(UseSHA, false); diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index f4d84c8dd5d..b299d5f1f0f 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -953,6 +953,10 @@ void LIRGenerator::do_update_CRC32C(Intrinsic* x) { } } +void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) { + fatal("FMA intrinsic is not implemented on this platform"); +} + void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) { fatal("vectorizedMismatch intrinsic is not implemented on this platform"); } diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp index 88ac31e096d..8f68d1112f2 100644 --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp @@ -266,6 +266,11 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); } + if (UseFMA) { + warning("FMA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseFMA, false); + } + // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times if (has_sha1() || has_sha256() || has_sha512()) { if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions diff --git a/hotspot/src/cpu/x86/vm/abstractInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/abstractInterpreter_x86.cpp index 5a1f37f26a7..0865b99a0d6 100644 --- a/hotspot/src/cpu/x86/vm/abstractInterpreter_x86.cpp +++ b/hotspot/src/cpu/x86/vm/abstractInterpreter_x86.cpp @@ -172,7 +172,9 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) { case Interpreter::java_lang_math_log10 : // fall thru case Interpreter::java_lang_math_sqrt : // fall thru case Interpreter::java_lang_math_pow : // fall thru - case Interpreter::java_lang_math_exp : + case Interpreter::java_lang_math_exp : // fall thru + case Interpreter::java_lang_math_fmaD : // fall thru + case Interpreter::java_lang_math_fmaF : return false; default: return true; diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index 94f37e4d4b4..d00802e2708 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -4769,6 +4769,22 @@ void Assembler::vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) { emit_int8((unsigned char)(0xC0 | encode)); } +void Assembler::vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { + assert(VM_Version::supports_fma(), ""); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8((unsigned char)0xB9); + emit_int8((unsigned char)(0xC0 | encode)); +} + +void Assembler::vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { + assert(VM_Version::supports_fma(), ""); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8((unsigned char)0xB9); + emit_int8((unsigned char)(0xC0 | encode)); +} + void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) { assert(VM_Version::supports_avx(), ""); InstructionMark im(this); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp index 5911b8368c2..f787ec5533a 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -1860,6 +1860,8 @@ private: void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src); void vdivss(XMMRegister dst, XMMRegister nds, Address src); void vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vfmadd231sd(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vfmadd231ss(XMMRegister dst, XMMRegister nds, XMMRegister src); void vmulsd(XMMRegister dst, XMMRegister nds, Address src); void vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src); void vmulss(XMMRegister dst, XMMRegister nds, Address src); diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 3a9bf0a6d2f..3adff833033 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -1345,6 +1345,18 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) { op->result_opr(), op->info()); break; + case lir_fmad: + __ fmad(op->result_opr()->as_xmm_double_reg(), + op->in_opr1()->as_xmm_double_reg(), + op->in_opr2()->as_xmm_double_reg(), + op->in_opr3()->as_xmm_double_reg()); + break; + case lir_fmaf: + __ fmaf(op->result_opr()->as_xmm_float_reg(), + op->in_opr1()->as_xmm_float_reg(), + op->in_opr2()->as_xmm_float_reg(), + op->in_opr3()->as_xmm_float_reg()); + break; default: ShouldNotReachHere(); break; } } diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index 43e98a7d43f..2bbe4b58cab 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -806,6 +806,32 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { } } +void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) { + assert(x->number_of_arguments() == 3, "wrong type"); + assert(UseFMA, "Needs FMA instructions support."); + LIRItem value(x->argument_at(0), this); + LIRItem value1(x->argument_at(1), this); + LIRItem value2(x->argument_at(2), this); + + value2.set_destroys_register(); + + value.load_item(); + value1.load_item(); + value2.load_item(); + + LIR_Opr calc_input = value.result(); + LIR_Opr calc_input1 = value1.result(); + LIR_Opr calc_input2 = value2.result(); + LIR_Opr calc_result = rlock_result(x); + + switch (x->id()) { + case vmIntrinsics::_fmaD: __ fmad(calc_input, calc_input1, calc_input2, calc_result); break; + case vmIntrinsics::_fmaF: __ fmaf(calc_input, calc_input1, calc_input2, calc_result); break; + default: ShouldNotReachHere(); + } + +} + void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index 8ec00bd9fce..150cf6d8301 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -3147,6 +3147,24 @@ void MacroAssembler::fremr(Register tmp) { fpop(); } +// dst = c = a * b + c +void MacroAssembler::fmad(XMMRegister dst, XMMRegister a, XMMRegister b, XMMRegister c) { + Assembler::vfmadd231sd(c, a, b); + if (dst != c) { + movdbl(dst, c); + } +} + +// dst = c = a * b + c +void MacroAssembler::fmaf(XMMRegister dst, XMMRegister a, XMMRegister b, XMMRegister c) { + Assembler::vfmadd231ss(c, a, b); + if (dst != c) { + movflt(dst, c); + } +} + + + void MacroAssembler::incrementl(AddressLiteral dst) { if (reachable(dst)) { diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp index cd3c67c4ab2..382b0011882 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -449,6 +449,10 @@ class MacroAssembler: public Assembler { // tmp is a temporary register, if none is available use noreg void fremr(Register tmp); + // dst = c = a * b + c + void fmad(XMMRegister dst, XMMRegister a, XMMRegister b, XMMRegister c); + void fmaf(XMMRegister dst, XMMRegister a, XMMRegister b, XMMRegister c); + // same as fcmp2int, but using SSE2 void cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less); diff --git a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp index 77cd5249d84..98b52c7cf1b 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp @@ -341,6 +341,27 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M // [ lo(arg) ] // [ hi(arg) ] // + if (kind == Interpreter::java_lang_math_fmaD) { + __ movdbl(xmm2, Address(rsp, 5 * wordSize)); + __ movdbl(xmm1, Address(rsp, 3 * wordSize)); + __ movdbl(xmm0, Address(rsp, 1 * wordSize)); + __ fmad(xmm0, xmm1, xmm2, xmm0); + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp + __ jmp(rdi); + + return entry_point; + } else if (kind == Interpreter::java_lang_math_fmaF) { + __ movflt(xmm2, Address(rsp, 3 * wordSize)); + __ movflt(xmm1, Address(rsp, 2 * wordSize)); + __ movflt(xmm0, Address(rsp, 1 * wordSize)); + __ fmaf(xmm0, xmm1, xmm2, xmm0); + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp + __ jmp(rdi); + + return entry_point; + } __ fld_d(Address(rsp, 1*wordSize)); switch (kind) { diff --git a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp index ed412203a4a..6cdf3c64cfd 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp @@ -369,8 +369,17 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M // [ hi(arg) ] // - - if (kind == Interpreter::java_lang_math_sqrt) { + if (kind == Interpreter::java_lang_math_fmaD) { + __ movdbl(xmm0, Address(rsp, wordSize)); + __ movdbl(xmm1, Address(rsp, 3 * wordSize)); + __ movdbl(xmm2, Address(rsp, 5 * wordSize)); + __ fmad(xmm0, xmm1, xmm2, xmm0); + } else if (kind == Interpreter::java_lang_math_fmaF) { + __ movflt(xmm0, Address(rsp, wordSize)); + __ movflt(xmm1, Address(rsp, 2 * wordSize)); + __ movflt(xmm2, Address(rsp, 3 * wordSize)); + __ fmaf(xmm0, xmm1, xmm2, xmm0); + } else if (kind == Interpreter::java_lang_math_sqrt) { __ sqrtsd(xmm0, Address(rsp, wordSize)); } else if (kind == Interpreter::java_lang_math_exp) { __ movdbl(xmm0, Address(rsp, wordSize)); diff --git a/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp b/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp index 713ee14472d..0307107ad9b 100644 --- a/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp +++ b/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp @@ -73,6 +73,7 @@ #define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \ declare_preprocessor_constant("VM_Version::CPU_AVX512BW", CPU_AVX512BW) \ declare_preprocessor_constant("VM_Version::CPU_AVX512VL", CPU_AVX512VL) \ - declare_preprocessor_constant("VM_Version::CPU_SHA", CPU_SHA) + declare_preprocessor_constant("VM_Version::CPU_SHA", CPU_SHA) \ + declare_preprocessor_constant("VM_Version::CPU_FMA", CPU_FMA) #endif // CPU_X86_VM_VMSTRUCTS_X86_HPP diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index ef78e640fd8..aa10ef276f2 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -578,7 +578,7 @@ void VM_Version::get_processor_features() { } char buf[256]; - jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", cores_per_cpu(), threads_per_core(), cpu_family(), _model, _stepping, (supports_cmov() ? ", cmov" : ""), @@ -610,7 +610,8 @@ void VM_Version::get_processor_features() { (supports_bmi2() ? ", bmi2" : ""), (supports_adx() ? ", adx" : ""), (supports_evex() ? ", evex" : ""), - (supports_sha() ? ", sha" : "")); + (supports_sha() ? ", sha" : ""), + (supports_fma() ? ", fma" : "")); _features_string = os::strdup(buf); // UseSSE is set to the smaller of what hardware supports and what @@ -732,6 +733,15 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); } + if (supports_fma() && UseSSE >= 2) { + if (FLAG_IS_DEFAULT(UseFMA)) { + UseFMA = true; + } + } else if (UseFMA) { + warning("FMA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseFMA, false); + } + if (supports_sha() LP64_ONLY(|| supports_avx2() && supports_bmi2())) { if (FLAG_IS_DEFAULT(UseSHA)) { UseSHA = true; @@ -773,7 +783,6 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(UseAdler32Intrinsics, false); } - // Adjust RTM (Restricted Transactional Memory) flags if (!supports_rtm() && UseRTMLocking) { // Can't continue because UseRTMLocking affects UseBiasedLocking flag // setting during arguments processing. See use_biased_locking(). diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp index a4c02654cad..5a51889e06b 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp @@ -74,7 +74,8 @@ class VM_Version : public Abstract_VM_Version { : 1, ssse3 : 1, cid : 1, - : 2, + : 1, + fma : 1, cmpxchg16: 1, : 4, dca : 1, @@ -289,6 +290,7 @@ protected: #define CPU_AVX512BW ((uint64_t)UCONST64(0x100000000)) // enums are limited to 31 bit #define CPU_AVX512VL ((uint64_t)UCONST64(0x200000000)) // EVEX instructions with smaller vector length #define CPU_SHA ((uint64_t)UCONST64(0x400000000)) // SHA instructions +#define CPU_FMA ((uint64_t)UCONST64(0x800000000)) // FMA instructions enum Extended_Family { // AMD @@ -522,6 +524,8 @@ protected: result |= CPU_SHA; if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) result |= CPU_LZCNT; + if (_cpuid_info.std_cpuid1_ecx.bits.fma != 0) + result |= CPU_FMA; // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { result |= CPU_3DNOW_PREFETCH; @@ -726,6 +730,7 @@ public: static bool supports_avx256only() { return (supports_avx2() && !supports_evex()); } static bool supports_avxonly() { return ((supports_avx2() || supports_avx()) && !supports_evex()); } static bool supports_sha() { return (_features & CPU_SHA) != 0; } + static bool supports_fma() { return (_features & CPU_FMA) != 0; } // Intel features static bool is_intel_family_core() { return is_intel() && extended_cpu_family() == CPU_FAMILY_INTEL_CORE; } diff --git a/hotspot/src/cpu/x86/vm/x86.ad b/hotspot/src/cpu/x86/vm/x86.ad index b12c979996b..a9d727e4cd5 100644 --- a/hotspot/src/cpu/x86/vm/x86.ad +++ b/hotspot/src/cpu/x86/vm/x86.ad @@ -3113,6 +3113,30 @@ instruct onspinwait() %{ ins_pipe(pipe_slow); %} +// a * b + c +instruct fmaD_reg(regD a, regD b, regD c) %{ + predicate(UseFMA); + match(Set c (FmaD c (Binary a b))); + format %{ "fmasd $a,$b,$c\t# $c = $a * $b + $c" %} + ins_cost(150); + ins_encode %{ + __ fmad($c$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $c$$XMMRegister); + %} + ins_pipe( pipe_slow ); +%} + +// a * b + c +instruct fmaF_reg(regF a, regF b, regF c) %{ + predicate(UseFMA); + match(Set c (FmaF c (Binary a b))); + format %{ "fmass $a,$b,$c\t# $c = $a * $b + $c" %} + ins_cost(150); + ins_encode %{ + __ fmaf($c$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $c$$XMMRegister); + %} + ins_pipe( pipe_slow ); +%} + // ====================VECTOR INSTRUCTIONS===================================== // Load vectors (4 bytes long) diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java index 2e68bb8b8c9..fa67e972c06 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java @@ -205,7 +205,8 @@ public class AMD64 extends Architecture { AVX512CD, AVX512BW, AVX512VL, - SHA + SHA, + FMA } private final EnumSet features; diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java index fa749bf2735..6dd1b8bd47f 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java @@ -124,6 +124,9 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto if ((config.vmVersionFeatures & config.amd64SHA) != 0) { features.add(AMD64.CPUFeature.SHA); } + if ((config.vmVersionFeatures & config.amd64FMA) != 0) { + features.add(AMD64.CPUFeature.FMA); + } return features; } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java index 4506916fbdd..2881990384f 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java @@ -78,4 +78,5 @@ class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess { final long amd64AVX512BW = getConstant("VM_Version::CPU_AVX512BW", Long.class); final long amd64AVX512VL = getConstant("VM_Version::CPU_AVX512VL", Long.class); final long amd64SHA = getConstant("VM_Version::CPU_SHA", Long.class); + final long amd64FMA = getConstant("VM_Version::CPU_FMA", Long.class); } diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp index e18b67e22dc..5f748379655 100644 --- a/hotspot/src/share/vm/adlc/formssel.cpp +++ b/hotspot/src/share/vm/adlc/formssel.cpp @@ -4038,6 +4038,8 @@ int MatchRule::is_expensive() const { strcmp(opType,"EncodeP")==0 || strcmp(opType,"EncodePKlass")==0 || strcmp(opType,"DecodeNKlass")==0 || + strcmp(opType,"FmaD") == 0 || + strcmp(opType,"FmaF") == 0 || strcmp(opType,"RoundDouble")==0 || strcmp(opType,"RoundFloat")==0 || strcmp(opType,"ReverseBytesI")==0 || diff --git a/hotspot/src/share/vm/c1/c1_Compiler.cpp b/hotspot/src/share/vm/c1/c1_Compiler.cpp index e292574e80c..0efb4d9818d 100644 --- a/hotspot/src/share/vm/c1/c1_Compiler.cpp +++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp @@ -162,6 +162,8 @@ bool Compiler::is_intrinsic_supported(const methodHandle& method) { case vmIntrinsics::_dlog10: case vmIntrinsics::_dexp: case vmIntrinsics::_dpow: + case vmIntrinsics::_fmaD: + case vmIntrinsics::_fmaF: case vmIntrinsics::_getObject: case vmIntrinsics::_getBoolean: case vmIntrinsics::_getByte: diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index ced682b5c0b..8c577be0918 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -666,7 +666,9 @@ void LIR_OpVisitState::visit(LIR_Op* op) { // LIR_Op3 case lir_idiv: - case lir_irem: { + case lir_irem: + case lir_fmad: + case lir_fmaf: { assert(op->as_Op3() != NULL, "must be"); LIR_Op3* op3= (LIR_Op3*)op; @@ -1663,6 +1665,8 @@ const char * LIR_Op::name() const { // LIR_Op3 case lir_idiv: s = "idiv"; break; case lir_irem: s = "irem"; break; + case lir_fmad: s = "fmad"; break; + case lir_fmaf: s = "fmaf"; break; // LIR_OpJavaCall case lir_static_call: s = "static"; break; case lir_optvirtual_call: s = "optvirtual"; break; diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index 7ca75ff3ebe..79d298d4cdf 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -956,6 +956,8 @@ enum LIR_Code { , begin_op3 , lir_idiv , lir_irem + , lir_fmad + , lir_fmaf , end_op3 , begin_opJavaCall , lir_static_call @@ -2149,6 +2151,8 @@ class LIR_List: public CompilationResourceObj { void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_abs , from, tmp, to)); } void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_sqrt, from, tmp, to)); } + void fmad(LIR_Opr from, LIR_Opr from1, LIR_Opr from2, LIR_Opr to) { append(new LIR_Op3(lir_fmad, from, from1, from2, to)); } + void fmaf(LIR_Opr from, LIR_Opr from1, LIR_Opr from2, LIR_Opr to) { append(new LIR_Op3(lir_fmaf, from, from1, from2, to)); } void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log10, from, LIR_OprFact::illegalOpr, to, tmp)); } void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); } diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index 92578575840..d616629ff2b 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -3147,6 +3147,9 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { case vmIntrinsics::_dpow : do_MathIntrinsic(x); break; case vmIntrinsics::_arraycopy: do_ArrayCopy(x); break; + case vmIntrinsics::_fmaD: do_FmaIntrinsic(x); break; + case vmIntrinsics::_fmaF: do_FmaIntrinsic(x); break; + // java.nio.Buffer.checkIndex case vmIntrinsics::_checkIndex: do_NIOCheckIndex(x); break; diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp index 91536455821..6b69a4fad88 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp @@ -245,6 +245,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { void do_isPrimitive(Intrinsic* x); void do_getClass(Intrinsic* x); void do_currentThread(Intrinsic* x); + void do_FmaIntrinsic(Intrinsic* x); void do_MathIntrinsic(Intrinsic* x); void do_LibmIntrinsic(Intrinsic* x); void do_ArrayCopy(Intrinsic* x); diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp index a52570c17c5..aa7c7a0261f 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.cpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp @@ -355,6 +355,8 @@ bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) { case vmIntrinsics::_updateBytesCRC32: case vmIntrinsics::_updateByteBufferCRC32: case vmIntrinsics::_vectorizedMismatch: + case vmIntrinsics::_fmaD: + case vmIntrinsics::_fmaF: return true; default: return false; @@ -387,6 +389,8 @@ bool vmIntrinsics::can_trap(vmIntrinsics::ID id) { case vmIntrinsics::_updateBytesCRC32: case vmIntrinsics::_updateByteBufferCRC32: case vmIntrinsics::_vectorizedMismatch: + case vmIntrinsics::_fmaD: + case vmIntrinsics::_fmaF: return false; default: return true; @@ -535,6 +539,10 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) { case vmIntrinsics::_doubleToLongBits: if (!InlineMathNatives) return true; break; + case vmIntrinsics::_fmaD: + case vmIntrinsics::_fmaF: + if (!InlineMathNatives || !UseFMA) return true; + break; case vmIntrinsics::_arraycopy: if (!InlineArrayCopy) return true; break; diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index aedc036a7ed..fd3b3fe4173 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -755,8 +755,10 @@ do_class(java_lang_Math, "java/lang/Math") \ do_class(java_lang_StrictMath, "java/lang/StrictMath") \ do_signature(double2_double_signature, "(DD)D") \ + do_signature(double3_double_signature, "(DDD)D") \ + do_signature(float3_float_signature, "(FFF)F") \ do_signature(int2_int_signature, "(II)I") \ - do_signature(long2_long_signature, "(JJ)J") \ + do_signature(long2_long_signature, "(JJ)J") \ \ /* here are the math names, all together: */ \ do_name(abs_name,"abs") do_name(sin_name,"sin") do_name(cos_name,"cos") \ @@ -770,6 +772,7 @@ do_name(multiplyExact_name,"multiplyExact") \ do_name(negateExact_name,"negateExact") \ do_name(subtractExact_name,"subtractExact") \ + do_name(fma_name, "fma") \ \ 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) \ @@ -795,6 +798,8 @@ do_intrinsic(_negateExactL, java_lang_Math, negateExact_name, long_long_signature, F_S) \ do_intrinsic(_subtractExactI, java_lang_Math, subtractExact_name, int2_int_signature, F_S) \ do_intrinsic(_subtractExactL, java_lang_Math, subtractExact_name, long2_long_signature, F_S) \ + do_intrinsic(_fmaD, java_lang_Math, fma_name, double3_double_signature, F_S) \ + do_intrinsic(_fmaF, java_lang_Math, fma_name, float3_float_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/interpreter/abstractInterpreter.cpp b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp index 3717ae061d9..1b054792532 100644 --- a/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp @@ -194,6 +194,13 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m) return java_lang_ref_reference_get; } + if (UseFMA) { + switch (m->intrinsic_id()) { + case vmIntrinsics::_fmaD: return java_lang_math_fmaD; + case vmIntrinsics::_fmaF: return java_lang_math_fmaF; + } + } + // Accessor method? if (m->is_getter()) { // TODO: We should have used ::is_accessor above, but fast accessors in Zero expect only getters. @@ -281,6 +288,8 @@ void AbstractInterpreter::print_method_kind(MethodKind kind) { case java_lang_math_sqrt : tty->print("java_lang_math_sqrt" ); break; case java_lang_math_log : tty->print("java_lang_math_log" ); break; case java_lang_math_log10 : tty->print("java_lang_math_log10" ); break; + case java_lang_math_fmaD : tty->print("java_lang_math_fmaD" ); break; + case java_lang_math_fmaF : tty->print("java_lang_math_fmaF" ); break; case java_util_zip_CRC32_update : tty->print("java_util_zip_CRC32_update"); break; case java_util_zip_CRC32_updateBytes : tty->print("java_util_zip_CRC32_updateBytes"); break; case java_util_zip_CRC32_updateByteBuffer : tty->print("java_util_zip_CRC32_updateByteBuffer"); break; diff --git a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp index 8ec0db7e0de..f1b8f79050b 100644 --- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp @@ -76,6 +76,8 @@ class AbstractInterpreter: AllStatic { java_lang_math_log10, // implementation of java.lang.Math.log10 (x) java_lang_math_pow, // implementation of java.lang.Math.pow (x,y) java_lang_math_exp, // implementation of java.lang.Math.exp (x) + java_lang_math_fmaF, // implementation of java.lang.Math.fma (x, y, z) + java_lang_math_fmaD, // implementation of java.lang.Math.fma (x, y, z) java_lang_ref_reference_get, // implementation of java.lang.ref.Reference.get() java_util_zip_CRC32_update, // implementation of java.util.zip.CRC32.update() java_util_zip_CRC32_updateBytes, // implementation of java.util.zip.CRC32.updateBytes() diff --git a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp index d57eb46cbf1..73de575a731 100644 --- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp +++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp @@ -239,6 +239,10 @@ void TemplateInterpreterGenerator::generate_all() { method_entry(java_lang_math_log10) method_entry(java_lang_math_exp ) method_entry(java_lang_math_pow ) + if (UseFMA) { + method_entry(java_lang_math_fmaF) + method_entry(java_lang_math_fmaD) + } method_entry(java_lang_ref_reference_get) AbstractInterpreter::initialize_method_handle_entries(); @@ -445,7 +449,9 @@ address TemplateInterpreterGenerator::generate_method_entry( case Interpreter::java_lang_math_log10 : // fall thru case Interpreter::java_lang_math_sqrt : // fall thru case Interpreter::java_lang_math_pow : // fall thru - case Interpreter::java_lang_math_exp : entry_point = generate_math_entry(kind); break; + case Interpreter::java_lang_math_exp : // fall thru + case Interpreter::java_lang_math_fmaD : // fall thru + case Interpreter::java_lang_math_fmaF : entry_point = generate_math_entry(kind); break; case Interpreter::java_lang_ref_reference_get : entry_point = generate_Reference_get_entry(); break; case Interpreter::java_util_zip_CRC32_update diff --git a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp index 3d48df55477..543fce0e8dd 100644 --- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp +++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp @@ -660,7 +660,8 @@ #define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \ declare_preprocessor_constant("VM_Version::CPU_AVX512BW", CPU_AVX512BW) \ declare_preprocessor_constant("VM_Version::CPU_AVX512VL", CPU_AVX512VL) \ - declare_preprocessor_constant("VM_Version::CPU_SHA", CPU_SHA) + declare_preprocessor_constant("VM_Version::CPU_SHA", CPU_SHA) \ + declare_preprocessor_constant("VM_Version::CPU_FMA", CPU_FMA) #endif diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp index c80ca6eaa8c..848d1d504a5 100644 --- a/hotspot/src/share/vm/opto/c2compiler.cpp +++ b/hotspot/src/share/vm/opto/c2compiler.cpp @@ -416,6 +416,12 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt case vmIntrinsics::_onSpinWait: if (!Matcher::match_rule_supported(Op_OnSpinWait)) return false; break; + case vmIntrinsics::_fmaD: + if (!UseFMA || !Matcher::match_rule_supported(Op_FmaD)) return false; + break; + case vmIntrinsics::_fmaF: + if (!UseFMA || !Matcher::match_rule_supported(Op_FmaF)) return false; + break; case vmIntrinsics::_hashCode: case vmIntrinsics::_identityHashCode: case vmIntrinsics::_getClass: diff --git a/hotspot/src/share/vm/opto/classes.hpp b/hotspot/src/share/vm/opto/classes.hpp index eab270ee399..06d754ffd78 100644 --- a/hotspot/src/share/vm/opto/classes.hpp +++ b/hotspot/src/share/vm/opto/classes.hpp @@ -151,6 +151,8 @@ macro(EncodeP) macro(EncodePKlass) macro(FastLock) macro(FastUnlock) +macro(FmaD) +macro(FmaF) macro(Goto) macro(Halt) macro(HasNegatives) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index e57f00ef26e..0dc8e49f611 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -317,6 +317,7 @@ class LibraryCallKit : public GraphKit { bool inline_montgomeryMultiply(); bool inline_montgomerySquare(); bool inline_vectorizedMismatch(); + bool inline_fma(vmIntrinsics::ID id); bool inline_profileBoolean(); bool inline_isCompileConstant(); @@ -825,6 +826,10 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_hasNegatives: return inline_hasNegatives(); + case vmIntrinsics::_fmaD: + case vmIntrinsics::_fmaF: + return inline_fma(intrinsic_id()); + default: // If you get here, it may be that someone has added a new intrinsic // to the list in vmSymbols.hpp without implementing it here. @@ -6657,6 +6662,35 @@ Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) return instof_false; // even if it is NULL } +//-------------inline_fma----------------------------------- +bool LibraryCallKit::inline_fma(vmIntrinsics::ID id) { + Node *a = NULL; + Node *b = NULL; + Node *c = NULL; + Node* result = NULL; + switch (id) { + case vmIntrinsics::_fmaD: + assert(callee()->signature()->size() == 6, "fma has 3 parameters of size 2 each."); + // no receiver since it is static method + a = round_double_node(argument(0)); + b = round_double_node(argument(2)); + c = round_double_node(argument(4)); + result = _gvn.transform(new FmaDNode(control(), a, b, c)); + break; + case vmIntrinsics::_fmaF: + assert(callee()->signature()->size() == 3, "fma has 3 parameters of size 1 each."); + a = argument(0); + b = argument(1); + c = argument(2); + result = _gvn.transform(new FmaFNode(control(), a, b, c)); + break; + default: + fatal_unexpected_iid(id); break; + } + set_result(result); + return true; +} + bool LibraryCallKit::inline_profileBoolean() { Node* counts = argument(1); const TypeAryPtr* ary = NULL; diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index 963c56fc833..7c7ed8dd493 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -2117,6 +2117,8 @@ void Matcher::find_shared( Node *n ) { case Op_StrInflatedCopy: case Op_StrCompressedCopy: case Op_EncodeISOArray: + case Op_FmaD: + case Op_FmaF: set_shared(n); // Force result into register (it will be anyways) break; case Op_ConP: { // Convert pointers above the centerline to NUL @@ -2305,6 +2307,15 @@ void Matcher::find_shared( Node *n ) { n->del_req(4); break; } + case Op_FmaD: + case Op_FmaF: { + // Restructure into a binary tree for Matching. + Node* pair = new BinaryNode(n->in(1), n->in(2)); + n->set_req(2, pair); + n->set_req(1, n->in(3)); + n->del_req(3); + break; + } default: break; } diff --git a/hotspot/src/share/vm/opto/mulnode.cpp b/hotspot/src/share/vm/opto/mulnode.cpp index fde86a85bfd..0bdde2614f3 100644 --- a/hotspot/src/share/vm/opto/mulnode.cpp +++ b/hotspot/src/share/vm/opto/mulnode.cpp @@ -1343,3 +1343,47 @@ const Type* URShiftLNode::Value(PhaseGVN* phase) const { return TypeLong::LONG; // Give up } + +//============================================================================= +//------------------------------Value------------------------------------------ +const Type* FmaDNode::Value(PhaseGVN* phase) const { + const Type *t1 = phase->type(in(1)); + if (t1 == Type::TOP) return Type::TOP; + if (t1->base() != Type::DoubleCon) return Type::DOUBLE; + const Type *t2 = phase->type(in(2)); + if (t2 == Type::TOP) return Type::TOP; + if (t2->base() != Type::DoubleCon) return Type::DOUBLE; + const Type *t3 = phase->type(in(3)); + if (t3 == Type::TOP) return Type::TOP; + if (t3->base() != Type::DoubleCon) return Type::DOUBLE; +#ifndef __STDC_IEC_559__ + return Type::DOUBLE; +#else + double d1 = t1->getd(); + double d2 = t2->getd(); + double d3 = t3->getd(); + return TypeD::make(fma(d1, d2, d3)); +#endif +} + +//============================================================================= +//------------------------------Value------------------------------------------ +const Type* FmaFNode::Value(PhaseGVN* phase) const { + const Type *t1 = phase->type(in(1)); + if (t1 == Type::TOP) return Type::TOP; + if (t1->base() != Type::FloatCon) return Type::FLOAT; + const Type *t2 = phase->type(in(2)); + if (t2 == Type::TOP) return Type::TOP; + if (t2->base() != Type::FloatCon) return Type::FLOAT; + const Type *t3 = phase->type(in(3)); + if (t3 == Type::TOP) return Type::TOP; + if (t3->base() != Type::FloatCon) return Type::FLOAT; +#ifndef __STDC_IEC_559__ + return Type::FLOAT; +#else + float f1 = t1->getf(); + float f2 = t2->getf(); + float f3 = t3->getf(); + return TypeF::make(fma(f1, f2, f3)); +#endif +} diff --git a/hotspot/src/share/vm/opto/mulnode.hpp b/hotspot/src/share/vm/opto/mulnode.hpp index 987f2e9e695..4d693970ca3 100644 --- a/hotspot/src/share/vm/opto/mulnode.hpp +++ b/hotspot/src/share/vm/opto/mulnode.hpp @@ -263,4 +263,26 @@ public: virtual uint ideal_reg() const { return Op_RegL; } }; +//------------------------------FmaDNode-------------------------------------- +// fused-multiply-add double +class FmaDNode : public Node { +public: + FmaDNode(Node *c, Node *in1, Node *in2, Node *in3) : Node(c, in1, in2, in3) {} + virtual int Opcode() const; + const Type *bottom_type() const { return Type::DOUBLE; } + virtual uint ideal_reg() const { return Op_RegD; } + virtual const Type* Value(PhaseGVN* phase) const; +}; + +//------------------------------FmaFNode-------------------------------------- +// fused-multiply-add float +class FmaFNode : public Node { +public: + FmaFNode(Node *c, Node *in1, Node *in2, Node *in3) : Node(c, in1, in2, in3) {} + virtual int Opcode() const; + const Type *bottom_type() const { return Type::FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } + virtual const Type* Value(PhaseGVN* phase) const; +}; + #endif // SHARE_VM_OPTO_MULNODE_HPP diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 1978313e48e..a6c7a5370c5 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -659,6 +659,9 @@ public: product(bool, UseAES, false, \ "Control whether AES instructions can be used on x86/x64") \ \ + product(bool, UseFMA, false, \ + "Control whether FMA instructions can be used") \ + \ product(bool, UseSHA, false, \ "Control whether SHA instructions can be used " \ "on SPARC, on ARM and on x86") \ diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 34b48c3cf80..6ea83ce0d3f 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -2105,6 +2105,8 @@ typedef CompactHashtable SymbolCompactHashTable; declare_c2_type(OverflowAddLNode, OverflowLNode) \ declare_c2_type(OverflowSubLNode, OverflowLNode) \ declare_c2_type(OverflowMulLNode, OverflowLNode) \ + declare_c2_type(FmaDNode, Node) \ + declare_c2_type(FmaFNode, Node) \ \ /*********************/ \ /* Adapter Blob Entries */ \ From 6384a5d55d6fb3f6d226a6788e9c41f56124cd61 Mon Sep 17 00:00:00 2001 From: Michael Berg Date: Wed, 7 Sep 2016 12:23:25 -0700 Subject: [PATCH 002/207] 8165565: Shorten branches causes incorrect code for SKX Don't replace restoreMask CountedLoopEnd with short branches. Reviewed-by: kvn --- hotspot/src/share/vm/adlc/formssel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp index 7f720b1b708..e18b67e22dc 100644 --- a/hotspot/src/share/vm/adlc/formssel.cpp +++ b/hotspot/src/share/vm/adlc/formssel.cpp @@ -1245,6 +1245,7 @@ bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch this != short_branch && // Don't match myself !is_short_branch() && // Don't match another short branch variant reduce_result() != NULL && + strstr(_ident, "restoreMask") == NULL && // Don't match side effects strcmp(reduce_result(), short_branch->reduce_result()) == 0 && _matrule->equivalent(AD.globalNames(), short_branch->_matrule)) { // The instructions are equivalent. From 4ae6ce2b442cdb3ca27bab1c092da873b8b974b9 Mon Sep 17 00:00:00 2001 From: Jamsheed Mohammed C M Date: Fri, 9 Sep 2016 06:11:54 -0700 Subject: [PATCH 003/207] 8164508: unexpected profiling mismatch in c1 generated code Made 8027631 first arg skip applicable to not inlined virtual callsite too. Reviewed-by: kvn --- hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 4 ++-- hotspot/test/compiler/jsr292/NullConstantReceiver.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index c1079e0f571..92578575840 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -3210,14 +3210,14 @@ void LIRGenerator::profile_arguments(ProfileCall* x) { Bytecodes::Code bc = x->method()->java_code_at_bci(bci); int start = 0; int stop = data->is_CallTypeData() ? ((ciCallTypeData*)data)->number_of_arguments() : ((ciVirtualCallTypeData*)data)->number_of_arguments(); - if (x->inlined() && x->callee()->is_static() && Bytecodes::has_receiver(bc)) { + if (x->callee()->is_loaded() && x->callee()->is_static() && Bytecodes::has_receiver(bc)) { // first argument is not profiled at call (method handle invoke) assert(x->method()->raw_code_at_bci(bci) == Bytecodes::_invokehandle, "invokehandle expected"); start = 1; } ciSignature* callee_signature = x->callee()->signature(); // method handle call to virtual method - bool has_receiver = x->inlined() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc); + bool has_receiver = x->callee()->is_loaded() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc); ciSignatureStream callee_signature_stream(callee_signature, has_receiver ? x->callee()->holder() : NULL); bool ignored_will_link; diff --git a/hotspot/test/compiler/jsr292/NullConstantReceiver.java b/hotspot/test/compiler/jsr292/NullConstantReceiver.java index 47da7d54414..369c7245034 100644 --- a/hotspot/test/compiler/jsr292/NullConstantReceiver.java +++ b/hotspot/test/compiler/jsr292/NullConstantReceiver.java @@ -23,10 +23,11 @@ /** * @test - * @bug 8059556 8158639 + * @bug 8059556 8158639 8164508 * * @run main/othervm -Xbatch compiler.jsr292.NullConstantReceiver * @run main/othervm -Xbatch -XX:CompileCommand=exclude,*::run compiler.jsr292.NullConstantReceiver + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,*::run compiler.jsr292.NullConstantReceiver */ package compiler.jsr292; From c6be265b461d96db15a754b573e2901035a64708 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Thu, 8 Sep 2016 18:17:50 -0400 Subject: [PATCH 004/207] 8164987: RTM jtreg tests failing due to unnamed module unable to access class jdk.internal.misc.Unsafe Reviewed-by: kvn --- hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java index 5fde3f21753..643f3bebcad 100644 --- a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java +++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java @@ -241,7 +241,8 @@ public class RTMTestBase { "-XX:-TieredCompilation", "-XX:+UseRTMLocking", CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, - "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI"); + "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI", + "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED"); if (test != null) { for (String method : test.getMethodsToCompileNames()) { From 474c035379734dc4efb6b17f606307a6cd92be76 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 1 Sep 2016 16:47:53 +0200 Subject: [PATCH 005/207] 8165235: [TESTBUG] RTM tests must check OS version Also change enabling RTM on Aix to OS version 7.2. Reviewed-by: simonis, fzhinkin --- hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp | 9 +++- .../compiler/rtm/cli/RTMLockingAwareTest.java | 3 +- ...kingStatisticsOptionOnSupportedConfig.java | 3 +- ...ngStatisticsOptionOnUnsupportedConfig.java | 5 +- ...TMAbortRatioOptionOnUnsupportedConfig.java | 5 +- ...ountIncrRateOptionOnUnsupportedConfig.java | 5 +- ...estUseRTMDeoptOptionOnSupportedConfig.java | 3 +- ...tUseRTMDeoptOptionOnUnsupportedConfig.java | 5 +- ...MForStackLocksOptionOnSupportedConfig.java | 3 +- ...orStackLocksOptionOnUnsupportedConfig.java | 5 +- ...tUseRTMLockingOptionOnSupportedConfig.java | 3 +- ...tUseRTMLockingOptionWithBiasedLocking.java | 3 +- .../rtm/locking/TestRTMAbortRatio.java | 3 +- .../rtm/locking/TestRTMAbortThreshold.java | 3 +- .../rtm/locking/TestRTMAfterNonRTMDeopt.java | 3 +- .../locking/TestRTMDeoptOnHighAbortRatio.java | 3 +- .../locking/TestRTMDeoptOnLowAbortRatio.java | 3 +- .../TestRTMLockingCalculationDelay.java | 3 +- .../rtm/locking/TestRTMLockingThreshold.java | 3 +- .../rtm/locking/TestRTMRetryCount.java | 3 +- .../rtm/locking/TestRTMSpinLoopCount.java | 3 +- .../locking/TestRTMTotalCountIncrRate.java | 3 +- .../locking/TestUseRTMAfterLockInflation.java | 3 +- .../compiler/rtm/locking/TestUseRTMDeopt.java | 3 +- .../locking/TestUseRTMForInflatedLocks.java | 3 +- .../rtm/locking/TestUseRTMForStackLocks.java | 3 +- .../locking/TestUseRTMXendForLockBusy.java | 3 +- .../TestNoRTMLockElidingOption.java | 3 +- .../TestUseRTMLockElidingOption.java | 3 +- .../TestPrintPreciseRTMLockingStatistics.java | 3 +- .../rtm/predicate/SupportedOS.java | 48 +++++++++++++++++++ 31 files changed, 119 insertions(+), 35 deletions(-) create mode 100644 hotspot/test/compiler/testlibrary/rtm/predicate/SupportedOS.java diff --git a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp index d83c3cd3b73..e919469f626 100644 --- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -274,7 +274,14 @@ void VM_Version::initialize() { } bool os_too_old = true; #ifdef AIX - if (os::Aix::os_version() >= 0x0701031e) { // at least AIX 7.1.3.30 + // Actually, this is supported since AIX 7.1.. Unfortunately, this first + // contained bugs, so that it can only be enabled after AIX 7.1.3.30. + // The Java property os.version, which is used in RTM tests to decide + // whether the feature is available, only knows major and minor versions. + // We don't want to change this property, as user code might depend on it. + // So the tests can not check on subversion 3.30, and we only enable RTM + // with AIX 7.2. + if (os::Aix::os_version() >= 0x07020000) { // At least AIX 7.2. os_too_old = false; } #endif diff --git a/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java index 6fcc2799aa9..f435c7dbb49 100644 --- a/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java +++ b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java @@ -25,6 +25,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.process.ExitCode; import jdk.test.lib.cli.CommandLineOptionTest; @@ -66,7 +67,7 @@ public abstract class RTMLockingAwareTest boolean isExperimental, String defaultValue, String[] correctValues, String[] incorrectValues, String warningMessage) { - super(new AndPredicate(new SupportedCPU(), new SupportedVM()), + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM()), optionName, isBoolean, isExperimental, defaultValue); this.correctValues = correctValues; this.incorrectValues = incorrectValues; diff --git a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java index 02f8acdc356..21773e4737f 100644 --- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -49,7 +50,7 @@ import jdk.test.lib.cli.predicate.AndPredicate; public class TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig extends TestPrintPreciseRTMLockingStatisticsBase { private TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java index 3efcbf54eaa..27cea60ae3d 100644 --- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.cli.predicate.AndPredicate; import jdk.test.lib.cli.predicate.NotPredicate; @@ -49,8 +50,8 @@ import jdk.test.lib.cli.predicate.NotPredicate; public class TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig extends TestPrintPreciseRTMLockingStatisticsBase { private TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig() { - super(new NotPredicate(new AndPredicate(new SupportedCPU(), - new SupportedVM()))); + super(new NotPredicate( + new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM()))); } public static void main(String args[]) throws Throwable { diff --git a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java index 1fec34e405f..f3a7a94e912 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.cli.predicate.AndPredicate; import jdk.test.lib.cli.predicate.NotPredicate; @@ -51,8 +52,8 @@ public class TestRTMAbortRatioOptionOnUnsupportedConfig private static final String DEFAULT_VALUE = "50"; private TestRTMAbortRatioOptionOnUnsupportedConfig() { - super(new NotPredicate(new AndPredicate(new SupportedVM(), - new SupportedCPU())), + super(new NotPredicate( + new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())), "RTMAbortRatio", false, true, TestRTMAbortRatioOptionOnUnsupportedConfig.DEFAULT_VALUE, "0", "10", "100", "200"); diff --git a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java index fcbbfe7882e..2a26f2531cd 100644 --- a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.cli.predicate.AndPredicate; import jdk.test.lib.cli.predicate.NotPredicate; @@ -51,8 +52,8 @@ public class TestRTMTotalCountIncrRateOptionOnUnsupportedConfig private static final String DEFAULT_VALUE = "64"; private TestRTMTotalCountIncrRateOptionOnUnsupportedConfig() { - super(new NotPredicate(new AndPredicate(new SupportedCPU(), - new SupportedVM())), + super(new NotPredicate( + new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())), "RTMTotalCountIncrRate", false, true, TestRTMTotalCountIncrRateOptionOnUnsupportedConfig .DEFAULT_VALUE, diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java index e674b46ebd6..80268cdb25e 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.process.ExitCode; import jdk.test.lib.cli.CommandLineOptionTest; @@ -52,7 +53,7 @@ public class TestUseRTMDeoptOptionOnSupportedConfig private static final String DEFAULT_VALUE = "false"; private TestUseRTMDeoptOptionOnSupportedConfig() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java index e6397317e8f..91d55ffee90 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -52,8 +53,8 @@ public class TestUseRTMDeoptOptionOnUnsupportedConfig private static final String DEFAULT_VALUE = "false"; private TestUseRTMDeoptOptionOnUnsupportedConfig() { - super(new NotPredicate(new AndPredicate(new SupportedCPU(), - new SupportedVM())), + super(new NotPredicate( + new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())), "UseRTMDeopt", true, false, TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE, "true"); diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java index 9e2163bb26f..eae736f70aa 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.process.ExitCode; import jdk.test.lib.cli.CommandLineOptionTest; @@ -52,7 +53,7 @@ public class TestUseRTMForStackLocksOptionOnSupportedConfig private static final String DEFAULT_VALUE = "false"; private TestUseRTMForStackLocksOptionOnSupportedConfig() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java index 84251d57807..2bf21de4fb5 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.process.ExitCode; import jdk.test.lib.cli.CommandLineOptionTest; @@ -53,8 +54,8 @@ public class TestUseRTMForStackLocksOptionOnUnsupportedConfig private static final String DEFAULT_VALUE = "false"; private TestUseRTMForStackLocksOptionOnUnsupportedConfig() { - super(new NotPredicate(new AndPredicate(new SupportedCPU(), - new SupportedVM())), + super(new NotPredicate( + new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())), "UseRTMForStackLocks", true, true, TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE, "true"); diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java index b0694e7508d..dac760c2e05 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.process.ExitCode; import jdk.test.lib.cli.CommandLineOptionTest; @@ -52,7 +53,7 @@ public class TestUseRTMLockingOptionOnSupportedConfig private static final String DEFAULT_VALUE = "false"; private TestUseRTMLockingOptionOnSupportedConfig() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java index 3aeab02004d..992f58210b9 100644 --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java @@ -42,6 +42,7 @@ package compiler.rtm.cli; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.process.ExitCode; import jdk.test.lib.cli.CommandLineOptionTest; @@ -50,7 +51,7 @@ import jdk.test.lib.cli.predicate.AndPredicate; public class TestUseRTMLockingOptionWithBiasedLocking extends CommandLineOptionTest { private TestUseRTMLockingOptionWithBiasedLocking() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java index e45212e268d..163e0020f59 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; @@ -61,7 +62,7 @@ import java.util.List; */ public class TestRTMAbortRatio extends CommandLineOptionTest { private TestRTMAbortRatio() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java index 6090fa19592..0f3c855c3fc 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -59,7 +60,7 @@ import java.util.List; */ public class TestRTMAbortThreshold extends CommandLineOptionTest { private TestRTMAbortThreshold() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java index 21c1a612b6f..0a0f4ec32d5 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java @@ -47,6 +47,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; @@ -87,7 +88,7 @@ public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest { private static final String RANGE_CHECK = "range_check"; private TestRTMAfterNonRTMDeopt() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java index 0633d8ab016..a8dd7c86d0e 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -66,7 +67,7 @@ public class TestRTMDeoptOnHighAbortRatio extends CommandLineOptionTest { = AbortProvoker.DEFAULT_ITERATIONS / 2L; private TestRTMDeoptOnHighAbortRatio() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java index 6807d82463a..afe07c656be 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java @@ -44,6 +44,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; @@ -67,7 +68,7 @@ public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest { private static final long ABORT_THRESHOLD = LOCKING_THRESHOLD / 2L; private TestRTMDeoptOnLowAbortRatio() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java index 33e263cb940..06a7ec66f85 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java @@ -44,6 +44,7 @@ import compiler.testlibrary.rtm.AbortProvoker; import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -58,7 +59,7 @@ public class TestRTMLockingCalculationDelay extends CommandLineOptionTest { private static final boolean INFLATE_MONITOR = true; private TestRTMLockingCalculationDelay() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java index 0dfea49a526..b6a1b664721 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; @@ -61,7 +62,7 @@ import java.util.List; */ public class TestRTMLockingThreshold extends CommandLineOptionTest { private TestRTMLockingThreshold() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } /** diff --git a/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java index 5526e096c91..4c9ae84275b 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java @@ -44,6 +44,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -64,7 +65,7 @@ public class TestRTMRetryCount extends CommandLineOptionTest { private static final boolean INFLATE_MONITOR = true; private TestRTMRetryCount() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java index 61dc2bcccb7..73753b2ac82 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -66,7 +67,7 @@ public class TestRTMSpinLoopCount extends CommandLineOptionTest { = new int[] { 0, 100, 1_000, 1_000_000, 10_000_000 }; private TestRTMSpinLoopCount() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java index e7158d4f670..7a4a4aef091 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; @@ -65,7 +66,7 @@ import java.util.List; */ public class TestRTMTotalCountIncrRate extends CommandLineOptionTest { private TestRTMTotalCountIncrRate() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java index f7a752f87fa..911793fefd3 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -73,7 +74,7 @@ public class TestUseRTMAfterLockInflation extends CommandLineOptionTest { = 2L * AbortProvoker.DEFAULT_ITERATIONS; private TestUseRTMAfterLockInflation() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java index d9cf61552e4..4e6bfbf7bef 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java @@ -44,6 +44,7 @@ import compiler.testlibrary.rtm.AbortProvoker; import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -56,7 +57,7 @@ import jdk.test.lib.cli.predicate.AndPredicate; */ public class TestUseRTMDeopt extends CommandLineOptionTest { private TestUseRTMDeopt() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java index 038496e310a..43fdeee0832 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java @@ -43,6 +43,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -63,7 +64,7 @@ import java.util.List; */ public class TestUseRTMForInflatedLocks extends CommandLineOptionTest { private TestUseRTMForInflatedLocks() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java index cdb854a8dcc..50fd873af60 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java @@ -44,6 +44,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -66,7 +67,7 @@ public class TestUseRTMForStackLocks extends CommandLineOptionTest { private static final boolean INFLATE_MONITOR = false; private TestUseRTMForStackLocks() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java index 936e7c970b3..12c52263800 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java @@ -46,6 +46,7 @@ import compiler.testlibrary.rtm.CompilableTest; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -62,7 +63,7 @@ public class TestUseRTMXendForLockBusy extends CommandLineOptionTest { private final static int LOCKING_TIME = 5000; private TestUseRTMXendForLockBusy() { - super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java index d92cb70bff8..bb4e6cad5b1 100644 --- a/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java +++ b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java @@ -45,6 +45,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -62,7 +63,7 @@ import java.util.List; */ public class TestNoRTMLockElidingOption extends CommandLineOptionTest { private TestNoRTMLockElidingOption() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java index b649715510f..31ef8ab09ab 100644 --- a/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java +++ b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java @@ -46,6 +46,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -68,7 +69,7 @@ import java.util.List; */ public class TestUseRTMLockElidingOption extends CommandLineOptionTest { private TestUseRTMLockElidingOption() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java index e9ec090799b..29ec33fd7b2 100644 --- a/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java +++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java @@ -48,6 +48,7 @@ import compiler.testlibrary.rtm.AbortType; import compiler.testlibrary.rtm.RTMLockingStatistics; import compiler.testlibrary.rtm.RTMTestBase; import compiler.testlibrary.rtm.predicate.SupportedCPU; +import compiler.testlibrary.rtm.predicate.SupportedOS; import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; @@ -67,7 +68,7 @@ import java.util.List; public class TestPrintPreciseRTMLockingStatistics extends CommandLineOptionTest { private TestPrintPreciseRTMLockingStatistics() { - super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + super(new AndPredicate(new SupportedCPU(), new SupportedOS(), new SupportedVM())); } @Override diff --git a/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedOS.java b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedOS.java new file mode 100644 index 00000000000..6eee0046853 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedOS.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package compiler.testlibrary.rtm.predicate; + +import jdk.test.lib.Platform; + +import java.util.function.BooleanSupplier; + +public class SupportedOS implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + if (Platform.isAix()) { + // Actually, this works since AIX 7.1.3.30, but os.version property + // is set to 7.1. + return (Platform.getOsVersionMajor() > 7) || + (Platform.getOsVersionMajor() == 7 && Platform.getOsVersionMinor() > 1); + + } else if (Platform.isLinux()) { + if (Platform.isPPC()) { + return (Platform.getOsVersionMajor() > 4) || + (Platform.getOsVersionMajor() == 4 && Platform.getOsVersionMinor() > 1); + } + } + return true; + } +} From a83ab529f9e41ee32dea748b5ecd4873fcb9a6e8 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 14 Sep 2016 05:48:18 -0700 Subject: [PATCH 006/207] 8165755: [JVMCI] replace use of vm_abort with vm_exit Reviewed-by: dholmes --- hotspot/src/share/vm/jvmci/jvmciCompiler.cpp | 35 ++++++++++---------- hotspot/src/share/vm/jvmci/jvmciCompiler.hpp | 5 ++- hotspot/src/share/vm/jvmci/jvmciRuntime.cpp | 10 ------ 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp index 3fcf7bc5f71..c66df6611d8 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp +++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp @@ -114,11 +114,11 @@ void JVMCICompiler::bootstrap(TRAPS) { JVMCIRuntime::bootstrap_finished(CHECK); } -#define CHECK_ABORT THREAD); \ +#define CHECK_EXIT THREAD); \ if (HAS_PENDING_EXCEPTION) { \ char buf[256]; \ jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ - JVMCICompiler::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ + JVMCICompiler::exit_on_pending_exception(PENDING_EXCEPTION, buf); \ return; \ } \ (void)(0 @@ -133,10 +133,10 @@ void JVMCICompiler::compile_method(const methodHandle& method, int entry_bci, JV return; } - JVMCIRuntime::initialize_well_known_classes(CHECK_ABORT); + JVMCIRuntime::initialize_well_known_classes(CHECK_EXIT); HandleMark hm; - Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_ABORT); + Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_EXIT); JavaValue method_result(T_OBJECT); JavaCallArguments args; @@ -202,23 +202,22 @@ CompLevel JVMCIRuntime::adjust_comp_level(methodHandle method, bool is_osr, Comp return level; } -/** - * Aborts the VM due to an unexpected exception. - */ -void JVMCICompiler::abort_on_pending_exception(Handle exception, const char* message, bool dump_core) { - Thread* THREAD = Thread::current(); +void JVMCICompiler::exit_on_pending_exception(Handle exception, const char* message) { + JavaThread* THREAD = JavaThread::current(); CLEAR_PENDING_EXCEPTION; - java_lang_Throwable::java_printStackTrace(exception, THREAD); + static volatile int report_error = 0; + if (!report_error && Atomic::cmpxchg(1, &report_error, 0) == 0) { + // Only report an error once + tty->print_raw_cr(message); + java_lang_Throwable::java_printStackTrace(exception, THREAD); + } else { + // Allow error reporting thread to print the stack trace. + os::sleep(THREAD, 200, false); + } - // Give other aborting threads to also print their stack traces. - // This can be very useful when debugging class initialization - // failures. - assert(THREAD->is_Java_thread(), "compiler threads should be Java threads"); - const bool interruptible = true; - os::sleep(THREAD, 200, interruptible); - - vm_abort(dump_core); + before_exit(THREAD); + vm_exit(-1); } // Compilation entry point for methods diff --git a/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp b/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp index d051086fb44..15e4724d482 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp +++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp @@ -47,7 +47,10 @@ private: static elapsedTimer _codeInstallTimer; - static void abort_on_pending_exception(Handle exception, const char* message, bool dump_core = false); + /** + * Exits the VM due to an unexpected exception. + */ + static void exit_on_pending_exception(Handle exception, const char* message); public: JVMCICompiler(); diff --git a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp index e9305c25aab..0c504a858dc 100644 --- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp +++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp @@ -817,16 +817,6 @@ JVM_ENTRY(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass)) } JVM_END -#define CHECK_WARN_ABORT_(message) THREAD); \ - if (HAS_PENDING_EXCEPTION) { \ - warning(message); \ - char buf[512]; \ - jio_snprintf(buf, 512, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ - JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ - return; \ - } \ - (void)(0 - void JVMCIRuntime::shutdown(TRAPS) { if (_HotSpotJVMCIRuntime_instance != NULL) { _shutdown_called = true; From d5ca7a299c0c19ceaa7589ac8ecb169b45b81040 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 14 Sep 2016 12:34:37 -0700 Subject: [PATCH 007/207] 8165434: [JVMCI] remove uses of setAccessible Reviewed-by: twisti, never --- .../src/jdk/vm/ci/hotspot/CompilerToVM.java | 13 ++- .../ci/hotspot/HotSpotCodeCacheProvider.java | 35 +++---- .../ci/hotspot/HotSpotMetaAccessProvider.java | 32 +------ .../HotSpotMethodHandleAccessProvider.java | 91 +++++-------------- .../jdk/vm/ci/hotspot/HotSpotModifiers.java | 66 ++++++++++++++ .../hotspot/HotSpotResolvedJavaFieldImpl.java | 4 +- .../HotSpotResolvedJavaMethodImpl.java | 44 ++++----- .../HotSpotResolvedObjectTypeImpl.java | 6 +- .../jdk/vm/ci/hotspot/HotSpotVMConfig.java | 6 +- .../src/jdk/vm/ci/hotspot/UnsafeAccess.java | 20 +--- .../src/jdk/vm/ci/meta/MetaUtil.java | 16 ---- .../src/jdk/vm/ci/meta/ModifiersProvider.java | 32 +------ .../jdk/vm/ci/meta/ResolvedJavaMethod.java | 33 +------ .../src/jdk/vm/ci/meta/ResolvedJavaType.java | 9 -- .../src/share/vm/jvmci/jvmciCompilerToVM.cpp | 32 ++++++- .../src/share/vm/jvmci/vmStructs_jvmci.cpp | 5 +- .../compiler/jvmci/common/CTVMUtilities.java | 13 +-- .../jdk/vm/ci/hotspot/CompilerToVMHelper.java | 7 +- ...est.java => AsResolvedJavaMethodTest.java} | 54 +++++------ .../FindUniqueConcreteMethodTest.java | 48 ++++------ .../GetResolvedJavaMethodTest.java | 26 +++--- .../test/MemoryAccessProviderData.java | 19 +--- .../runtime/test/TestResolvedJavaMethod.java | 1 - .../ci/runtime/test/TestResolvedJavaType.java | 49 +++++----- 24 files changed, 269 insertions(+), 392 deletions(-) create mode 100644 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java rename hotspot/test/compiler/jvmci/compilerToVM/{GetResolvedJavaMethodAtSlotTest.java => AsResolvedJavaMethodTest.java} (61%) diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java index 00d998d69d6..1be9c651e74 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java @@ -26,8 +26,7 @@ package jdk.vm.ci.hotspot; import static jdk.vm.ci.common.InitTimer.timer; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; +import java.lang.reflect.Executable; import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.InstalledCode; @@ -385,10 +384,9 @@ final class CompilerToVM { native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type); /** - * Gets the method corresponding to {@code holder} and slot number {@code slot} (i.e. - * {@link Method#slot} or {@link Constructor#slot}). + * Gets the method corresponding to {@code executable}. */ - native HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(Class holder, int slot); + native HotSpotResolvedJavaMethodImpl asResolvedJavaMethod(Executable executable); /** * Gets the maximum absolute offset of a PC relative call to {@code address} from any position @@ -616,4 +614,9 @@ final class CompilerToVM { */ native int interpreterFrameSize(BytecodeFrame frame); + /** + * Invokes non-public method {@code java.lang.invoke.LambdaForm.compileToBytecode()} on + * {@code lambdaForm} (which must be a {@code java.lang.invoke.LambdaForm} instance). + */ + native void compileToBytecode(Object lambdaForm); } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java index 803f55a21f0..f5489fb18c5 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java @@ -22,7 +22,7 @@ */ package jdk.vm.ci.hotspot; -import java.lang.reflect.Field; +import java.util.Map; import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.code.BytecodeFrame; @@ -56,16 +56,11 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider { @Override public String getMarkName(Mark mark) { int markId = (int) mark.id; - Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); - for (Field f : fields) { - if (f.getName().startsWith("MARKID_")) { - f.setAccessible(true); - try { - if (f.getInt(runtime.getConfig()) == markId) { - return f.getName(); - } - } catch (Exception e) { - } + HotSpotVMConfigStore store = runtime.getConfigStore(); + for (Map.Entry e : store.getConstants().entrySet()) { + String name = e.getKey(); + if (name.startsWith("MARKID_") && e.getValue() == markId) { + return name; } } return CodeCacheProvider.super.getMarkName(mark); @@ -76,17 +71,13 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider { */ @Override public String getTargetName(Call call) { - Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); - for (Field f : fields) { - if (f.getName().endsWith("Stub")) { - f.setAccessible(true); - Object address; - try { - address = f.get(runtime.getConfig()); - if (address.equals(call.target)) { - return f.getName() + ":0x" + Long.toHexString((Long) address); - } - } catch (IllegalArgumentException | IllegalAccessException e) { + if (call.target instanceof HotSpotForeignCallTarget) { + long address = ((HotSpotForeignCallTarget) call.target).address; + HotSpotVMConfigStore store = runtime.getConfigStore(); + for (Map.Entry e : store.getFields().entrySet()) { + VMField field = e.getValue(); + if (field.isStatic() && field.value != null && field.value == address) { + return e.getValue() + ":0x" + Long.toHexString(address); } } } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java index 464237ada43..6a3a38b7ca2 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java @@ -28,11 +28,10 @@ import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass; import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; import java.lang.reflect.Array; -import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.Objects; import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.code.TargetDescription; @@ -78,35 +77,8 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider { return new HotSpotSignature(runtime, signature); } - /** - * {@link Field} object of {@link Method#slot}. - */ - private Field reflectionMethodSlot = getReflectionSlotField(Method.class); - - /** - * {@link Field} object of {@link Constructor#slot}. - */ - private Field reflectionConstructorSlot = getReflectionSlotField(Constructor.class); - - private static Field getReflectionSlotField(Class reflectionClass) { - try { - Field field = reflectionClass.getDeclaredField("slot"); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException | SecurityException e) { - throw new JVMCIError(e); - } - } - public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) { - try { - Class holder = reflectionMethod.getDeclaringClass(); - Field slotField = reflectionMethod instanceof Constructor ? reflectionConstructorSlot : reflectionMethodSlot; - final int slot = slotField.getInt(reflectionMethod); - return runtime.getCompilerToVM().getResolvedJavaMethodAtSlot(holder, slot); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new JVMCIError(e); - } + return runtime.getCompilerToVM().asResolvedJavaMethod(Objects.requireNonNull(reflectionMethod)); } public ResolvedJavaField lookupJavaField(Field reflectionField) { diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java index f6aa30241e2..c6dd6f2410b 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java @@ -24,16 +24,17 @@ package jdk.vm.ci.hotspot; import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; -import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass; + +import java.lang.invoke.MethodHandle; +import java.util.Objects; + import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MethodHandleAccessProvider; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider { @@ -48,88 +49,46 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv * possible after the {@link HotSpotJVMCIRuntime} is fully initialized. */ static class LazyInitialization { + static final ResolvedJavaType lambdaFormType; static final ResolvedJavaField methodHandleFormField; static final ResolvedJavaField lambdaFormVmentryField; - static final ResolvedJavaMethod lambdaFormCompileToBytecodeMethod; static final HotSpotResolvedJavaField memberNameVmtargetField; - static final ResolvedJavaType CLASS = fromObjectClass(LazyInitialization.class); - /** * Search for an instance field with the given name in a class. * - * @param className name of the class to search in + * @param declaringType the type declaring the field * @param fieldName name of the field to be searched * @param fieldType resolved Java type of the field * @return resolved Java field - * @throws ClassNotFoundException * @throws NoSuchFieldError */ - private static ResolvedJavaField findFieldInClass(String className, String fieldName, ResolvedJavaType fieldType) - throws ClassNotFoundException { - Class clazz = Class.forName(className); - ResolvedJavaType type = runtime().fromClass(clazz); - ResolvedJavaField[] fields = type.getInstanceFields(false); + private static ResolvedJavaField findFieldInClass(ResolvedJavaType declaringType, String fieldName, ResolvedJavaType fieldType) { + ResolvedJavaField[] fields = declaringType.getInstanceFields(false); for (ResolvedJavaField field : fields) { if (field.getName().equals(fieldName) && field.getType().equals(fieldType)) { return field; } } - throw new NoSuchFieldError(fieldType.getName() + " " + className + "." + fieldName); + throw new NoSuchFieldError(fieldType.getName() + " " + declaringType + "." + fieldName); } - private static ResolvedJavaMethod findMethodInClass(String className, String methodName, - ResolvedJavaType resultType, ResolvedJavaType[] parameterTypes) throws ClassNotFoundException { - Class clazz = Class.forName(className); - HotSpotResolvedObjectTypeImpl type = fromObjectClass(clazz); - ResolvedJavaMethod result = null; - for (ResolvedJavaMethod method : type.getDeclaredMethods()) { - if (method.getName().equals(methodName) && signatureMatches(method, resultType, parameterTypes)) { - result = method; - } - } - if (result == null) { - StringBuilder sig = new StringBuilder("("); - for (ResolvedJavaType t : parameterTypes) { - sig.append(t.getName()).append(","); - } - if (sig.length() > 1) { - sig.replace(sig.length() - 1, sig.length(), ")"); - } else { - sig.append(')'); - } - throw new NoSuchMethodError(resultType.getName() + " " + className + "." + methodName + sig.toString()); - } - return result; + private static ResolvedJavaType resolveType(Class c) { + return runtime().fromClass(c); } - private static boolean signatureMatches(ResolvedJavaMethod m, ResolvedJavaType resultType, - ResolvedJavaType[] parameterTypes) { - Signature s = m.getSignature(); - if (!s.getReturnType(CLASS).equals(resultType)) { - return false; - } - if (s.getParameterCount(false) != parameterTypes.length) { - return false; - } - for (int i = 0; i < s.getParameterCount(false); ++i) { - if (!s.getParameterType(i, CLASS).equals(parameterTypes[i])) { - return false; - } - } - return true; + private static ResolvedJavaType resolveType(String className) throws ClassNotFoundException { + return resolveType(Class.forName(className)); } static { try { - methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form", - fromObjectClass(Class.forName("java.lang.invoke.LambdaForm"))); - lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry", - fromObjectClass(Class.forName("java.lang.invoke.MemberName"))); - lambdaFormCompileToBytecodeMethod = findMethodInClass("java.lang.invoke.LambdaForm", "compileToBytecode", - new HotSpotResolvedPrimitiveType(JavaKind.Void), new ResolvedJavaType[]{}); - memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass("java.lang.invoke.MemberName", "vmtarget", - new HotSpotResolvedPrimitiveType(JavaKind.Long)); + ResolvedJavaType methodHandleType = resolveType(MethodHandle.class); + ResolvedJavaType memberNameType = resolveType("java.lang.invoke.MemberName"); + lambdaFormType = resolveType("java.lang.invoke.LambdaForm"); + methodHandleFormField = findFieldInClass(methodHandleType, "form", lambdaFormType); + lambdaFormVmentryField = findFieldInClass(lambdaFormType, "vmentry", memberNameType); + memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass(memberNameType, "vmtarget", resolveType(long.class)); } catch (Throwable ex) { throw new JVMCIError(ex); } @@ -173,12 +132,13 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv return null; } - if (forceBytecodeGeneration) { - /* Invoke non-public method: MemberName LambdaForm.compileToBytecode() */ - LazyInitialization.lambdaFormCompileToBytecodeMethod.invoke(lambdaForm, new JavaConstant[0]); - } - /* Load non-public field: MemberName LambdaForm.vmentry */ JavaConstant memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm); + if (memberName.isNull() && forceBytecodeGeneration) { + Object lf = ((HotSpotObjectConstant) lambdaForm).asObject(LazyInitialization.lambdaFormType); + compilerToVM().compileToBytecode(Objects.requireNonNull(lf)); + memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm); + assert memberName.isNonNull(); + } return getTargetMethod(memberName); } @@ -200,4 +160,3 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset()); } } - diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java new file mode 100644 index 00000000000..ba1ea96eb1c --- /dev/null +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotModifiers.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import static java.lang.reflect.Modifier.ABSTRACT; +import static java.lang.reflect.Modifier.FINAL; +import static java.lang.reflect.Modifier.INTERFACE; +import static java.lang.reflect.Modifier.NATIVE; +import static java.lang.reflect.Modifier.PRIVATE; +import static java.lang.reflect.Modifier.PROTECTED; +import static java.lang.reflect.Modifier.PUBLIC; +import static java.lang.reflect.Modifier.STATIC; +import static java.lang.reflect.Modifier.STRICT; +import static java.lang.reflect.Modifier.SYNCHRONIZED; +import static java.lang.reflect.Modifier.TRANSIENT; +import static java.lang.reflect.Modifier.VOLATILE; +import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; + +import java.lang.reflect.Modifier; + +/** + * The non-public modifiers in {@link Modifier} that need to be retrieved from + * {@link HotSpotVMConfig}. + */ +public class HotSpotModifiers { + + // @formatter:off + public static final int ANNOTATION = config().jvmAccAnnotation; + public static final int ENUM = config().jvmAccEnum; + public static final int VARARGS = config().jvmAccVarargs; + public static final int BRIDGE = config().jvmAccBridge; + public static final int SYNTHETIC = config().jvmAccSynthetic; + // @formatter:on + + public static int jvmClassModifiers() { + return PUBLIC | FINAL | INTERFACE | ABSTRACT | ANNOTATION | ENUM | SYNTHETIC; + } + + public static int jvmMethodModifiers() { + return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | BRIDGE | VARARGS | NATIVE | ABSTRACT | STRICT | SYNTHETIC; + } + + public static int jvmFieldModifiers() { + return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | ENUM | SYNTHETIC; + } +} diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java index 3cd69d9a9c0..24287261984 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java @@ -22,6 +22,7 @@ */ package jdk.vm.ci.hotspot; +import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmFieldModifiers; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import java.lang.annotation.Annotation; @@ -29,7 +30,6 @@ import java.lang.reflect.Field; import jdk.internal.vm.annotation.Stable; import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ModifiersProvider; import jdk.vm.ci.meta.ResolvedJavaType; /** @@ -81,7 +81,7 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField { @Override public int getModifiers() { - return modifiers & ModifiersProvider.jvmFieldModifiers(); + return modifiers & jvmFieldModifiers(); } @Override diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java index dd4658d1d3d..6ebdc4b33c1 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java @@ -24,13 +24,15 @@ package jdk.vm.ci.hotspot; import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.HotSpotModifiers.BRIDGE; +import static jdk.vm.ci.hotspot.HotSpotModifiers.SYNTHETIC; +import static jdk.vm.ci.hotspot.HotSpotModifiers.VARARGS; +import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmMethodModifiers; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; import java.lang.annotation.Annotation; import java.lang.reflect.Executable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.HashMap; @@ -42,13 +44,11 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.DefaultProfilingInfo; import jdk.vm.ci.meta.ExceptionHandler; -import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaMethod; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.LineNumberTable; import jdk.vm.ci.meta.Local; import jdk.vm.ci.meta.LocalVariableTable; -import jdk.vm.ci.meta.ModifiersProvider; import jdk.vm.ci.meta.ProfilingInfo; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -210,7 +210,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp @Override public int getModifiers() { - return getAllModifiers() & ModifiersProvider.jvmMethodModifiers(); + return getAllModifiers() & jvmMethodModifiers(); } @Override @@ -490,6 +490,19 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass); } + public boolean isBridge() { + return (BRIDGE & getModifiers()) != 0; + } + + @Override + public boolean isSynthetic() { + return (SYNTHETIC & getModifiers()) != 0; + } + + public boolean isVarArgs() { + return (VARARGS & getModifiers()) != 0; + } + public boolean isDefault() { if (isConstructor()) { return false; @@ -697,27 +710,6 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0; } - @Override - public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) { - assert !isConstructor(); - Method javaMethod = (Method) toJava(); - javaMethod.setAccessible(true); - - Object[] objArguments = new Object[arguments.length]; - for (int i = 0; i < arguments.length; i++) { - objArguments[i] = HotSpotObjectConstantImpl.asBoxedValue(arguments[i]); - } - Object objReceiver = receiver != null && !receiver.isNull() ? ((HotSpotObjectConstantImpl) receiver).object() : null; - - try { - Object objResult = javaMethod.invoke(objReceiver, objArguments); - return javaMethod.getReturnType() == void.class ? null : HotSpotObjectConstantImpl.forBoxedValue(getSignature().getReturnKind(), objResult); - - } catch (IllegalAccessException | InvocationTargetException ex) { - throw new IllegalArgumentException(ex); - } - } - /** * Allocates a compile id for this method by asking the VM for one. * diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java index 875b08b1bf8..a7af6a61935 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java @@ -26,6 +26,7 @@ import static java.util.Objects.requireNonNull; import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; @@ -49,7 +50,6 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; -import jdk.vm.ci.meta.ModifiersProvider; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -152,7 +152,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem if (isArray()) { return (getElementalType().getModifiers() & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) | Modifier.FINAL | Modifier.ABSTRACT; } else { - return getAccessFlags() & ModifiersProvider.jvmClassModifiers(); + return getAccessFlags() & jvmClassModifiers(); } } @@ -507,7 +507,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) { HotSpotResolvedJavaField result = null; - final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers(); + final int flags = rawFlags & HotSpotModifiers.jvmFieldModifiers(); final long id = offset + ((long) flags << 32); diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java index 64ec7c0b886..a731b8aff4d 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -117,8 +117,12 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess { final int jvmAccFieldHasGenericSignature = getConstant("JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE", Integer.class); final int jvmAccIsCloneableFast = getConstant("JVM_ACC_IS_CLONEABLE_FAST", Integer.class); - // Modifier.SYNTHETIC is not public so we get it via vmStructs. + // These modifiers are not public in Modifier so we get them via vmStructs. final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class); + final int jvmAccAnnotation = getConstant("JVM_ACC_ANNOTATION", Integer.class); + final int jvmAccBridge = getConstant("JVM_ACC_BRIDGE", Integer.class); + final int jvmAccVarargs = getConstant("JVM_ACC_VARARGS", Integer.class); + final int jvmAccEnum = getConstant("JVM_ACC_ENUM", Integer.class); // This is only valid on AMD64. final int runtimeCallStackSize = getConstant("frame::arg_reg_save_area_bytes", Integer.class, osArch.equals("amd64") ? null : 0); diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java index c75c449f9dd..61b0f949655 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java @@ -22,8 +22,6 @@ */ package jdk.vm.ci.hotspot; -import java.lang.reflect.Field; - import jdk.internal.misc.Unsafe; /** @@ -31,21 +29,5 @@ import jdk.internal.misc.Unsafe; */ class UnsafeAccess { - static final Unsafe UNSAFE = initUnsafe(); - - private static Unsafe initUnsafe() { - try { - // Fast path when we are trusted. - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - // Slow path when we are not trusted. - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe", e); - } - } - } + static final Unsafe UNSAFE = Unsafe.getUnsafe(); } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java index fc5d260960f..c1d725d20b5 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java @@ -22,9 +22,6 @@ */ package jdk.vm.ci.meta; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; - /** * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients. */ @@ -226,17 +223,4 @@ public class MetaUtil { } return obj.getClass().getName() + "@" + System.identityHashCode(obj); } - - /** - * Used to lookup constants from {@link Modifier} that are not public (VARARGS, SYNTHETIC etc.). - */ - static int getNonPublicModifierStaticField(String name) { - try { - Field field = Modifier.class.getDeclaredField(name); - field.setAccessible(true); - return field.getInt(null); - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw new InternalError(e); - } - } } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java index 2f28c7e31f3..c6cf9f0cec2 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java @@ -22,18 +22,9 @@ */ package jdk.vm.ci.meta; -import static java.lang.reflect.Modifier.ABSTRACT; -import static java.lang.reflect.Modifier.FINAL; -import static java.lang.reflect.Modifier.INTERFACE; -import static java.lang.reflect.Modifier.NATIVE; import static java.lang.reflect.Modifier.PRIVATE; import static java.lang.reflect.Modifier.PROTECTED; import static java.lang.reflect.Modifier.PUBLIC; -import static java.lang.reflect.Modifier.STATIC; -import static java.lang.reflect.Modifier.STRICT; -import static java.lang.reflect.Modifier.SYNCHRONIZED; -import static java.lang.reflect.Modifier.TRANSIENT; -import static java.lang.reflect.Modifier.VOLATILE; import java.lang.reflect.Modifier; @@ -42,17 +33,9 @@ import java.lang.reflect.Modifier; * language {@linkplain #getModifiers() modifiers}. */ public interface ModifiersProvider { - int BRIDGE = MetaUtil.getNonPublicModifierStaticField("BRIDGE"); - int VARARGS = MetaUtil.getNonPublicModifierStaticField("VARARGS"); - int SYNTHETIC = MetaUtil.getNonPublicModifierStaticField("SYNTHETIC"); - int ANNOTATION = MetaUtil.getNonPublicModifierStaticField("ANNOTATION"); - int ENUM = MetaUtil.getNonPublicModifierStaticField("ENUM"); - int MANDATED = MetaUtil.getNonPublicModifierStaticField("MANDATED"); /** - * Returns the Java Virtual Machine modifiers for this element. Note that this can differ from - * standard Java Reflection modifiers. For example at the JVM level, classes ( - * {@link ResolvedJavaType}) can not be private or protected. + * Returns the modifiers for this element. */ int getModifiers(); @@ -161,17 +144,4 @@ public interface ModifiersProvider { default boolean isConcrete() { return !isAbstract(); } - - static int jvmClassModifiers() { - // no SUPER - return PUBLIC | FINAL | INTERFACE | ABSTRACT | ANNOTATION | ENUM | SYNTHETIC; - } - - static int jvmMethodModifiers() { - return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | BRIDGE | VARARGS | NATIVE | ABSTRACT | STRICT | SYNTHETIC; - } - - static int jvmFieldModifiers() { - return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | ENUM | SYNTHETIC; - } } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java index 3b2facc26d9..5a56981e9e4 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java @@ -26,7 +26,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Array; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.lang.reflect.Type; /** @@ -72,14 +71,6 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP */ int getMaxStackSize(); - /** - * {@inheritDoc} - *

- * Only the {@linkplain Modifier#methodModifiers() method flags} specified in the JVM - * specification will be included in the returned mask. - */ - int getModifiers(); - default boolean isFinal() { return ModifiersProvider.super.isFinalFlagSet(); } @@ -88,9 +79,7 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP * Determines if this method is a synthetic method as defined by the Java Language * Specification. */ - default boolean isSynthetic() { - return (SYNTHETIC & getModifiers()) == SYNTHETIC; - } + boolean isSynthetic(); /** * Checks that the method is a @@ -99,9 +88,7 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP * * @return whether the method is a varargs method */ - default boolean isVarArgs() { - return (VARARGS & getModifiers()) == VARARGS; - } + boolean isVarArgs(); /** * Checks that the method is a @@ -110,9 +97,7 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP * * @return whether the method is a bridge method */ - default boolean isBridge() { - return (BRIDGE & getModifiers()) == BRIDGE; - } + boolean isBridge(); /** * Returns {@code true} if this method is a default method; returns {@code false} otherwise. @@ -227,18 +212,6 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP */ LocalVariableTable getLocalVariableTable(); - /** - * Invokes the underlying method represented by this object, on the specified object with the - * specified parameters. This method is similar to a reflective method invocation by - * {@link Method#invoke}. - * - * @param receiver The receiver for the invocation, or {@code null} if it is a static method. - * @param arguments The arguments for the invocation. - * @return The value returned by the method invocation, or {@code null} if the return type is - * {@code void}. - */ - JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments); - /** * Gets the encoding of (that is, a constant representing the value of) this method. * diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java index 43cc6a62d9f..891e7943de3 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java @@ -68,15 +68,6 @@ public interface ResolvedJavaType extends JavaType, ModifiersProvider, Annotated */ boolean isPrimitive(); - /** - * {@inheritDoc} - *

- * Only the flags specified in the JVM specification will be included in the returned mask. This - * method is identical to {@link Class#getModifiers()} in terms of the value return for this - * type. - */ - int getModifiers(); - /* * The setting of the final bit for types is a bit confusing since arrays are marked as final. * This method provides a semantically equivalent test that appropriate for types. diff --git a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp index dc19a497f5e..e81ff4685ab 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp @@ -473,9 +473,20 @@ C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv *, jobject, jobject jvmci_met return (jlong) (address) method->exception_table_start(); C2V_END -C2V_VMENTRY(jobject, getResolvedJavaMethodAtSlot, (JNIEnv *, jobject, jclass holder_handle, jint slot)) - oop java_class = JNIHandles::resolve(holder_handle); - Klass* holder = java_lang_Class::as_Klass(java_class); +C2V_VMENTRY(jobject, asResolvedJavaMethod, (JNIEnv *, jobject, jobject executable_handle)) + oop executable = JNIHandles::resolve(executable_handle); + oop mirror = NULL; + int slot = 0; + + if (executable->klass() == SystemDictionary::reflect_Constructor_klass()) { + mirror = java_lang_reflect_Constructor::clazz(executable); + slot = java_lang_reflect_Constructor::slot(executable); + } else { + assert(executable->klass() == SystemDictionary::reflect_Method_klass(), "wrong type"); + mirror = java_lang_reflect_Method::clazz(executable); + slot = java_lang_reflect_Method::slot(executable); + } + Klass* holder = java_lang_Class::as_Klass(mirror); methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot); oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL); return JNIHandles::make_local(THREAD, result); @@ -1518,6 +1529,17 @@ C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv*, jobject, jobject bytecode_frame return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord; C2V_END +C2V_VMENTRY(void, compileToBytecode, (JNIEnv*, jobject, jobject lambda_form_handle)) + Handle lambda_form = JNIHandles::resolve_non_null(lambda_form_handle); + if (lambda_form->is_a(SystemDictionary::LambdaForm_klass())) { + TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode", CHECK); + JavaValue result(T_VOID); + JavaCalls::call_special(&result, lambda_form, SystemDictionary::LambdaForm_klass(), compileToBytecode, vmSymbols::void_method_signature(), CHECK); + } else { + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), + err_msg("Unexpected type: %s", lambda_form->klass()->external_name())); + } +C2V_END #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -1525,6 +1547,7 @@ C2V_END #define STRING "Ljava/lang/String;" #define OBJECT "Ljava/lang/Object;" #define CLASS "Ljava/lang/Class;" +#define EXECUTABLE "Ljava/lang/reflect/Executable;" #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" #define INSTALLED_CODE "Ljdk/vm/ci/code/InstalledCode;" #define TARGET_DESCRIPTION "Ljdk/vm/ci/code/TargetDescription;" @@ -1572,7 +1595,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "getClassInitializer", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(getClassInitializer)}, {CC "hasFinalizableSubclass", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(hasFinalizableSubclass)}, {CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)}, - {CC "getResolvedJavaMethodAtSlot", CC "(" CLASS "I)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethodAtSlot)}, + {CC "asResolvedJavaMethod", CC "(" EXECUTABLE ")" HS_RESOLVED_METHOD, FN_PTR(asResolvedJavaMethod)}, {CC "getResolvedJavaMethod", CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)}, {CC "getConstantPool", CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)}, {CC "getResolvedJavaType", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)}, @@ -1599,6 +1622,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)}, {CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)}, {CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)}, + {CC "compileToBytecode", CC "(" OBJECT ")V", FN_PTR(compileToBytecode)}, }; int CompilerToVM::methods_count() { diff --git a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp index 3d48df55477..f74d899abcb 100644 --- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp +++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp @@ -327,8 +327,11 @@ declare_constant(JVM_ACC_FIELD_INTERNAL) \ declare_constant(JVM_ACC_FIELD_STABLE) \ declare_constant(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) \ + declare_preprocessor_constant("JVM_ACC_VARARGS", JVM_ACC_VARARGS) \ + declare_preprocessor_constant("JVM_ACC_BRIDGE", JVM_ACC_BRIDGE) \ + declare_preprocessor_constant("JVM_ACC_ANNOTATION", JVM_ACC_ANNOTATION) \ + declare_preprocessor_constant("JVM_ACC_ENUM", JVM_ACC_ENUM) \ declare_preprocessor_constant("JVM_ACC_SYNTHETIC", JVM_ACC_SYNTHETIC) \ - declare_preprocessor_constant("JVM_RECOGNIZED_FIELD_MODIFIERS", JVM_RECOGNIZED_FIELD_MODIFIERS) \ \ declare_constant(JVM_CONSTANT_Utf8) \ declare_constant(JVM_CONSTANT_Unicode) \ diff --git a/hotspot/test/compiler/jvmci/common/CTVMUtilities.java b/hotspot/test/compiler/jvmci/common/CTVMUtilities.java index 03335f6f59a..7ba6d00debf 100644 --- a/hotspot/test/compiler/jvmci/common/CTVMUtilities.java +++ b/hotspot/test/compiler/jvmci/common/CTVMUtilities.java @@ -57,18 +57,7 @@ public class CTVMUtilities { if (!(method instanceof Method || method instanceof Constructor)) { throw new Error("wrong executable type " + method.getClass()); } - Field slotField; - int slot; - try { - slotField = method.getClass().getDeclaredField("slot"); - boolean old = slotField.isAccessible(); - slotField.setAccessible(true); - slot = slotField.getInt(method); - slotField.setAccessible(old); - } catch (ReflectiveOperationException e) { - throw new Error("TEST BUG: Can't get slot field", e); - } - return CompilerToVMHelper.getResolvedJavaMethodAtSlot(cls, slot); + return CompilerToVMHelper.asResolvedJavaMethod(method); } public static HotSpotResolvedJavaMethod getResolvedMethod( diff --git a/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java b/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java index 2985ed89a94..1fa24207d63 100644 --- a/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java +++ b/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java @@ -28,6 +28,7 @@ import jdk.vm.ci.code.InvalidInstalledCodeException; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.ResolvedJavaMethod; +import java.lang.reflect.Executable; /** * A simple "proxy" class to get test access to CompilerToVM package-private methods @@ -171,9 +172,9 @@ public class CompilerToVMHelper { return CTVM.hasFinalizableSubclass((HotSpotResolvedObjectTypeImpl) type); } - public static HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot( - Class holder, int slot) { - return CTVM.getResolvedJavaMethodAtSlot(holder, slot); + public static HotSpotResolvedJavaMethodImpl asResolvedJavaMethod( + Executable executable) { + return CTVM.asResolvedJavaMethod(executable); } public static long getMaxCallTargetOffset(long address) { diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodAtSlotTest.java b/hotspot/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java similarity index 61% rename from hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodAtSlotTest.java rename to hotspot/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java index 49a6e3826bf..1234edb4cd6 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodAtSlotTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java @@ -36,7 +36,7 @@ * jdk.vm.ci/jdk.vm.ci.meta * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * compiler.jvmci.compilerToVM.GetResolvedJavaMethodAtSlotTest + * compiler.jvmci.compilerToVM.AsResolvedJavaMethodTest */ package compiler.jvmci.compilerToVM; @@ -45,10 +45,12 @@ import jdk.test.lib.Asserts; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; -import java.util.HashMap; -import java.util.Map; +import java.lang.reflect.Executable; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; -public class GetResolvedJavaMethodAtSlotTest { +public class AsResolvedJavaMethodTest { private static class A { { @@ -81,41 +83,31 @@ public class GetResolvedJavaMethodAtSlotTest { } public static void main(String[] args) { - Map, Integer> testCases = getTestCases(); - testCases.forEach(GetResolvedJavaMethodAtSlotTest::test); + List> testCases = getTestCases(); + testCases.forEach(AsResolvedJavaMethodTest::test); } - private static Map, Integer> getTestCases() { - Map, Integer> testCases = new HashMap<>(); - testCases.put(A.class, 5); // ctor, init, f1, f2, f3 - testCases.put(S.class, 5); // ctor, cinit, f1, f2, f3 - testCases.put(I.class, 3); // f1, f2, f3 - testCases.put(B.class, 2); // ctor, f4 + private static List> getTestCases() { + List> testCases = new ArrayList<>(); + testCases.add(A.class); + testCases.add(S.class); + testCases.add(I.class); + testCases.add(B.class); return testCases; } - private static void test(Class aClass, int methodNumber) { - testSlotBigger(aClass); - testCorrectMethods(aClass, methodNumber); + private static void test(Class aClass) { + testCorrectMethods(aClass); } - private static void testSlotBigger(Class holder) { - HotSpotResolvedJavaMethod method - = CompilerToVMHelper.getResolvedJavaMethodAtSlot(holder, 50); - Asserts.assertNull(method, "Got method for non existing slot 50 in " - + holder); - } - - private static void testCorrectMethods(Class holder, int methodsNumber) { - for (int i = 0; i < methodsNumber; i++) { - String caseName = String.format("slot %d in %s", - i, holder.getCanonicalName()); + private static void testCorrectMethods(Class holder) { + List executables = new ArrayList<>(); + executables.addAll(Arrays.asList(holder.getDeclaredMethods())); + executables.addAll(Arrays.asList(holder.getDeclaredConstructors())); + for (Executable executable : executables) { HotSpotResolvedJavaMethod method = CompilerToVMHelper - .getResolvedJavaMethodAtSlot(holder, i); - Asserts.assertNotNull(method, caseName + " did not got method"); - Asserts.assertEQ(holder, - CompilerToVMHelper.getMirror(method.getDeclaringClass()), - caseName + " : unexpected declaring class"); + .asResolvedJavaMethod(executable); + Asserts.assertNotNull(method, "could not convert " + method); } } } diff --git a/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java index 32959f2dd86..25cbb97b1b9 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java @@ -74,45 +74,37 @@ public class FindUniqueConcreteMethodTest { private static Set createTestCases() { Set result = new HashSet<>(); // a public method - result.add(new TestCase(true, SingleSubclass.class, - SingleSubclass.class, "usualMethod")); + result.add(new TestCase(true, SingleSubclass.class, "usualMethod")); // overriden method - result.add(new TestCase(true, SingleSubclass.class, - SingleSubclass.class, "overridenMethod")); + result.add(new TestCase(true, SingleSubclass.class, "overridenMethod")); // private method - result.add(new TestCase(true, SingleSubclass.class, - SingleSubclass.class, "privateMethod")); + result.add(new TestCase(true, SingleSubclass.class, "privateMethod")); // protected method - result.add(new TestCase(true, SingleSubclass.class, - SingleSubclass.class, "protectedMethod")); + result.add(new TestCase(true, SingleSubclass.class, "protectedMethod")); // default(package-private) method - result.add(new TestCase(true, SingleSubclass.class, - SingleSubclass.class, "defaultAccessMethod")); + result.add(new TestCase(true, SingleSubclass.class, "defaultAccessMethod")); // default interface method redefined in implementer - result.add(new TestCase(true, MultipleImplementer1.class, - MultipleImplementer1.class, "defaultMethod")); + result.add(new TestCase(true, MultipleImplementer1.class, "defaultMethod")); // interface method - result.add(new TestCase(true, MultipleImplementer1.class, - MultipleImplementer1.class, "testMethod")); + result.add(new TestCase(true, MultipleImplementer1.class, "testMethod")); // default interface method not redefined in implementer - result.add(new TestCase(true, SingleImplementer.class, - SingleImplementerInterface.class, "defaultMethod")); + // result.add(new TestCase(true, SingleImplementer.class, + // SingleImplementerInterface.class, "defaultMethod")); // static method - result.add(new TestCase(false, SingleSubclass.class, - SingleSubclass.class, "staticMethod")); + result.add(new TestCase(false, SingleSubclass.class, "staticMethod")); // interface method result.add(new TestCase(false, MultipleSuperImplementers.class, - DuplicateSimpleSingleImplementerInterface.class, "interfaceMethod", false)); + DuplicateSimpleSingleImplementerInterface.class, "interfaceMethod")); result.add(new TestCase(false, MultipleSuperImplementers.class, - SimpleSingleImplementerInterface.class, "interfaceMethod", false)); + SimpleSingleImplementerInterface.class, "interfaceMethod")); return result; } private void runTest(TestCase tcase) throws NoSuchMethodException { System.out.println(tcase); Method method = tcase.holder.getDeclaredMethod(tcase.methodName); - HotSpotResolvedJavaMethod testMethod = CTVMUtilities - .getResolvedMethod(tcase.methodFromReceiver ? tcase.receiver : tcase.holder, method); + HotSpotResolvedJavaMethod testMethod = CTVMUtilities.getResolvedMethod(method); + HotSpotResolvedObjectType resolvedType = CompilerToVMHelper .lookupType(Utils.toJVMTypeSignature(tcase.receiver), getClass(), /* resolve = */ true); @@ -127,25 +119,23 @@ public class FindUniqueConcreteMethodTest { public final Class holder; public final String methodName; public final boolean isPositive; - public final boolean methodFromReceiver; public TestCase(boolean isPositive, Class clazz, Class holder, - String methodName, boolean methodFromReceiver) { + String methodName) { this.receiver = clazz; this.methodName = methodName; this.isPositive = isPositive; this.holder = holder; - this.methodFromReceiver = methodFromReceiver; } - public TestCase(boolean isPositive, Class clazz, Class holder, String methodName) { - this(isPositive, clazz, holder, methodName, true); + public TestCase(boolean isPositive, Class clazz, String methodName) { + this(isPositive, clazz, clazz, methodName); } @Override public String toString() { - return String.format("CASE: receiver=%s, holder=%s, method=%s, isPositive=%s, methodFromReceiver=%s", - receiver.getName(), holder.getName(), methodName, isPositive, methodFromReceiver); + return String.format("CASE: receiver=%s, holder=%s, method=%s, isPositive=%s", + receiver.getName(), holder.getName(), methodName, isPositive); } } } diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java index c1c382d768d..d1f8faaca66 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java @@ -52,6 +52,7 @@ import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject; import sun.hotspot.WhiteBox; import java.lang.reflect.Field; +import java.lang.reflect.Method; public class GetResolvedJavaMethodTest { private static enum TestCase { @@ -65,9 +66,7 @@ public class GetResolvedJavaMethodTest { JAVA_METHOD_BASE { @Override HotSpotResolvedJavaMethod getResolvedJavaMethod() { - HotSpotResolvedJavaMethod methodInstance - = CompilerToVMHelper.getResolvedJavaMethodAtSlot( - TEST_CLASS, 0); + HotSpotResolvedJavaMethod methodInstance = TEST_METHOD; try { METASPACE_METHOD_FIELD.set(methodInstance, getPtrToMethod()); @@ -82,9 +81,7 @@ public class GetResolvedJavaMethodTest { @Override HotSpotResolvedJavaMethod getResolvedJavaMethod() { long ptr = getPtrToMethod(); - HotSpotResolvedJavaMethod methodInstance - = CompilerToVMHelper.getResolvedJavaMethodAtSlot( - TEST_CLASS, 0); + HotSpotResolvedJavaMethod methodInstance = TEST_METHOD; try { METASPACE_METHOD_FIELD.set(methodInstance, ptr / 2L); } catch (ReflectiveOperationException e) { @@ -98,9 +95,7 @@ public class GetResolvedJavaMethodTest { @Override HotSpotResolvedJavaMethod getResolvedJavaMethod() { long ptr = getPtrToMethod(); - HotSpotResolvedJavaMethod methodInstance - = CompilerToVMHelper.getResolvedJavaMethodAtSlot( - TEST_CLASS, 0); + HotSpotResolvedJavaMethod methodInstance = TEST_METHOD; try { METASPACE_METHOD_FIELD.set(methodInstance, 0L); } catch (ReflectiveOperationException e) { @@ -118,16 +113,21 @@ public class GetResolvedJavaMethodTest { private static final WhiteBox WB = WhiteBox.getWhiteBox(); private static final Field METASPACE_METHOD_FIELD; private static final Class TEST_CLASS = GetResolvedJavaMethodTest.class; + private static final HotSpotResolvedJavaMethod TEST_METHOD; private static final long PTR; static { - HotSpotResolvedJavaMethod method - = CompilerToVMHelper.getResolvedJavaMethodAtSlot(TEST_CLASS, 0); + try { + Method method = TEST_CLASS.getDeclaredMethod("test", TestCase.class); + TEST_METHOD = CompilerToVMHelper.asResolvedJavaMethod(method); + } catch (NoSuchMethodException e) { + throw new Error("TESTBUG : " + e, e); + } try { // jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod - METASPACE_METHOD_FIELD = method.getClass() + METASPACE_METHOD_FIELD = TEST_METHOD.getClass() .getDeclaredField("metaspaceMethod"); METASPACE_METHOD_FIELD.setAccessible(true); - PTR = (long) METASPACE_METHOD_FIELD.get(method); + PTR = (long) METASPACE_METHOD_FIELD.get(TEST_METHOD); } catch (ReflectiveOperationException e) { throw new Error("TESTBUG : " + e, e); } diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderData.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderData.java index 549cc7b76ae..fcbc721caa8 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderData.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderData.java @@ -23,6 +23,10 @@ package jdk.vm.ci.hotspot.test; +import java.lang.reflect.Field; + +import org.testng.annotations.DataProvider; + import jdk.internal.misc.Unsafe; import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider; @@ -32,27 +36,14 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.runtime.JVMCI; -import org.testng.annotations.DataProvider; - -import java.lang.reflect.Field; public class MemoryAccessProviderData { - private static final Unsafe UNSAFE = getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection(); private static final TestClass TEST_OBJECT = new TestClass(); private static final JavaConstant TEST_CONSTANT = CONSTANT_REFLECTION.forObject(TEST_OBJECT); private static final JavaConstant TEST_CLASS_CONSTANT = CONSTANT_REFLECTION.forObject(TestClass.class); - private static Unsafe getUnsafe() { - try { - Field f = Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (Unsafe) f.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException("Unable to get Unsafe instance.", e); - } - } - @DataProvider(name = "positiveObject") public static Object[][] getPositiveObjectJavaKind() { HotSpotJVMCIRuntimeProvider runtime = (HotSpotJVMCIRuntimeProvider) JVMCI.getRuntime(); diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java index 2faefc8bc49..c1474c16c25 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java @@ -438,7 +438,6 @@ public class TestResolvedJavaMethod extends MethodUniverse { // @formatter:off private static final String[] untestedApiMethods = { - "invoke", "newInstance", "getDeclaringClass", "getEncoding", diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index 86e54c9b7bc..be0b05563e1 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -35,28 +35,6 @@ package jdk.vm.ci.runtime.test; -import jdk.internal.reflect.ConstantPool; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.Assumptions.AssumptionResult; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ModifiersProvider; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import org.junit.Test; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - import static java.lang.reflect.Modifier.isAbstract; import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isPrivate; @@ -70,6 +48,28 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +import jdk.internal.reflect.ConstantPool; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.Assumptions.AssumptionResult; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + /** * Tests for {@link ResolvedJavaType}. */ @@ -146,8 +146,9 @@ public class TestResolvedJavaType extends TypeUniverse { public void getModifiersTest() { for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); - int expected = c.getModifiers() & ModifiersProvider.jvmClassModifiers(); - int actual = type.getModifiers() & ModifiersProvider.jvmClassModifiers(); + int mask = Modifier.classModifiers() & ~Modifier.STATIC; + int expected = c.getModifiers() & mask; + int actual = type.getModifiers() & mask; Class elementalType = c; while (elementalType.isArray()) { elementalType = elementalType.getComponentType(); From de89ff8c55ec0006e0700a61c2534f3c3f40665d Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 16 Sep 2016 21:10:56 -0700 Subject: [PATCH 008/207] 8166096: variable tracking size limit exceeded in jvmciCompilerToVM.cpp Turn off var-tracking-assignments for jvmciCompilerToVM.cpp Reviewed-by: dlong --- hotspot/make/lib/JvmOverrideFiles.gmk | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/make/lib/JvmOverrideFiles.gmk b/hotspot/make/lib/JvmOverrideFiles.gmk index f7827ef5c40..dabdf3b4eab 100644 --- a/hotspot/make/lib/JvmOverrideFiles.gmk +++ b/hotspot/make/lib/JvmOverrideFiles.gmk @@ -31,6 +31,7 @@ $(eval $(call IncludeCustomExtension, hotspot, lib/JvmOverrideFiles.gmk)) ifeq ($(TOOLCHAIN_TYPE), gcc) BUILD_LIBJVM_vmStructs.cpp_CXXFLAGS := -fno-var-tracking-assignments -O0 + BUILD_LIBJVM_jvmciCompilerToVM.cpp_CXXFLAGS := -fno-var-tracking-assignments endif ifeq ($(OPENJDK_TARGET_OS), linux) From 2c923c1c9529c75dcd6d0c62d999122f299b616d Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 19 Sep 2016 13:26:37 -0700 Subject: [PATCH 009/207] 8165457: [JVMCI] increase InterpreterCodeSize for JVMCI Reviewed-by: twisti --- hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp index 845959fe4e4..37bba8d3cf9 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp @@ -55,7 +55,7 @@ // Run with +PrintInterpreter to get the VM to print out the size. // Max size with JVMTI #ifdef AMD64 -int TemplateInterpreter::InterpreterCodeSize = 256 * 1024; +int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(268) NOT_JVMCI(256) * 1024; #else int TemplateInterpreter::InterpreterCodeSize = 224 * 1024; #endif // AMD64 From f711aaa04c92e62b9fcb84ba469ffd20315b3034 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Tue, 20 Sep 2016 17:30:33 +0300 Subject: [PATCH 010/207] 8166164: compiler/compilercontrol/share/processors/LogProcessor.java does not close Scanner Reviewed-by: kvn, ppunegov --- .../share/processors/LogProcessor.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/hotspot/test/compiler/compilercontrol/share/processors/LogProcessor.java b/hotspot/test/compiler/compilercontrol/share/processors/LogProcessor.java index 98fce874cb1..a926c7db560 100644 --- a/hotspot/test/compiler/compilercontrol/share/processors/LogProcessor.java +++ b/hotspot/test/compiler/compilercontrol/share/processors/LogProcessor.java @@ -74,7 +74,7 @@ public class LogProcessor implements Consumer { if (loggedMethods.isEmpty()) { return; } - matchTasks(getScanner()); + matchTasks(); } /* @@ -95,19 +95,21 @@ public class LogProcessor implements Consumer { * Parses for <task method='java.lang.String indexOf (I)I' > * and finds if there is a compilation log for this task */ - private void matchTasks(Scanner scanner) { - String task = scanner.findWithinHorizon(TASK_ELEMENT, 0); - while (task != null) { - String element = scanner.findWithinHorizon(ANY_ELEMENT, 0); - if (Pattern.matches(TASK_DONE_ELEMENT, element) - || Pattern.matches(TASK_END_ELEMENT, element)) { - /* If there is nothing between and - except then compilation log is empty. - Check the method in this task should not be logged */ - Asserts.assertFalse(matchMethod(task), "Compilation log " - + "expected. Met: " + element); - } - task = scanner.findWithinHorizon(TASK_ELEMENT, 0); + private void matchTasks() { + try (Scanner scanner = getScanner()) { + String task = scanner.findWithinHorizon(TASK_ELEMENT, 0); + while (task != null) { + String element = scanner.findWithinHorizon(ANY_ELEMENT, 0); + if (Pattern.matches(TASK_DONE_ELEMENT, element) + || Pattern.matches(TASK_END_ELEMENT, element)) { + /* If there is nothing between and + except then compilation log is empty. + Check the method in this task should not be logged */ + Asserts.assertFalse(matchMethod(task), "Compilation log " + + "expected. Met: " + element); + } + task = scanner.findWithinHorizon(TASK_ELEMENT, 0); + } } } From 5b54998a233948048a8de36bae3cbd93457299c7 Mon Sep 17 00:00:00 2001 From: Michael Berg Date: Tue, 20 Sep 2016 16:50:37 -0700 Subject: [PATCH 011/207] 8129376: SPECjvm98-client performance regression in 9-b66 Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp | 2 ++ hotspot/src/cpu/x86/vm/x86_32.ad | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp index a5e533696b2..6d0dbb8756d 100644 --- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp @@ -100,9 +100,11 @@ inline void LinearScan::pd_add_temps(LIR_Op* op) { inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) { int last_xmm_reg = pd_last_xmm_reg; +#ifdef _LP64 if (UseAVX < 3) { last_xmm_reg = pd_first_xmm_reg + (pd_nof_xmm_regs_frame_map / 2) - 1; } +#endif if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::byte_reg)) { assert(cur->type() != T_FLOAT && cur->type() != T_DOUBLE, "cpu regs only"); _first_reg = pd_first_byte_reg; diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index 4f7d3aacfd9..cbfe7668335 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -104,14 +104,14 @@ reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next()); // // Empty fill registers, which are never used, but supply alignment to xmm regs // -reg_def FILL0( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(2)); -reg_def FILL1( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(3)); -reg_def FILL2( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(4)); -reg_def FILL3( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(5)); -reg_def FILL4( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(6)); -reg_def FILL5( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(7)); -reg_def FILL6( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(8)); -reg_def FILL7( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(9)); +reg_def FILL0( SOC, SOC, Op_RegF, 8, VMRegImpl::Bad()); +reg_def FILL1( SOC, SOC, Op_RegF, 9, VMRegImpl::Bad()); +reg_def FILL2( SOC, SOC, Op_RegF, 10, VMRegImpl::Bad()); +reg_def FILL3( SOC, SOC, Op_RegF, 11, VMRegImpl::Bad()); +reg_def FILL4( SOC, SOC, Op_RegF, 12, VMRegImpl::Bad()); +reg_def FILL5( SOC, SOC, Op_RegF, 13, VMRegImpl::Bad()); +reg_def FILL6( SOC, SOC, Op_RegF, 14, VMRegImpl::Bad()); +reg_def FILL7( SOC, SOC, Op_RegF, 15, VMRegImpl::Bad()); // Specify priority of register selection within phases of register // allocation. Highest priority is first. A useful heuristic is to From 466c23ffe05881c92bd60a6ed425acfccb158dea Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Wed, 21 Sep 2016 08:14:46 +0200 Subject: [PATCH 012/207] 8166046: [TESTBUG] compiler/stringopts/TestStringObjectInitialization.java fails with OOME Reduced heap memory consumption of test. Reviewed-by: kvn --- .../stringopts/TestStringObjectInitialization.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hotspot/test/compiler/stringopts/TestStringObjectInitialization.java b/hotspot/test/compiler/stringopts/TestStringObjectInitialization.java index b25c225d413..c371a57ad7a 100644 --- a/hotspot/test/compiler/stringopts/TestStringObjectInitialization.java +++ b/hotspot/test/compiler/stringopts/TestStringObjectInitialization.java @@ -67,6 +67,11 @@ public class TestStringObjectInitialization { add(s + Arrays.toString(sArray) + " const "); } + public void reset() { + // Reset string to avoid OOMEs + myString = ""; + } + private static class Runner implements Runnable { private TestStringObjectInitialization test; @@ -76,8 +81,9 @@ public class TestStringObjectInitialization { public void run() { String[] array = {"a", "b", "c"}; - for (int i = 0; i < 10000; ++i) { + for (int i = 0; i < 100_000; ++i) { test.run("a", array); + test.reset(); } } } From f6ec56f5bbb39bf5e76a31bde2367d747cf4db05 Mon Sep 17 00:00:00 2001 From: Kishor Kharbas Date: Wed, 21 Sep 2016 13:47:56 -0700 Subject: [PATCH 013/207] 8078122: YMM registers upper 128 bits may get clobbered by a JNI call on windows Convert all XMM registers to be Save-on-Call on Win64. Reviewed-by: kvn --- .../src/cpu/x86/vm/macroAssembler_x86_sha.cpp | 8 +- .../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 186 +------- hotspot/src/cpu/x86/vm/x86.ad | 447 ------------------ 3 files changed, 13 insertions(+), 628 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp index a0910f395bb..b8af7c33158 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp @@ -720,19 +720,13 @@ const Register& y2 = r15; enum { _XFER_SIZE = 2*64*4, // 2 blocks, 64 rounds, 4 bytes/round -#ifndef _WIN64 - _XMM_SAVE_SIZE = 0, -#else - _XMM_SAVE_SIZE = 8*16, -#endif _INP_END_SIZE = 8, _INP_SIZE = 8, _CTX_SIZE = 8, _RSP_SIZE = 8, _XFER = 0, - _XMM_SAVE = _XFER + _XFER_SIZE, - _INP_END = _XMM_SAVE + _XMM_SAVE_SIZE, + _INP_END = _XFER + _XFER_SIZE, _INP = _INP_END + _INP_END_SIZE, _CTX = _INP + _INP_SIZE, _RSP = _CTX + _CTX_SIZE, diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 668b3e1e128..4906f9dc89f 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -3236,11 +3236,6 @@ class StubGenerator: public StubCodeGenerator { #ifdef _WIN64 // on win64, fill len_reg from stack position __ movl(len_reg, len_mem); - // save the xmm registers which must be preserved 6-15 - __ subptr(rsp, -rsp_after_call_off * wordSize); - for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { - __ movdqu(xmm_save(i), as_XMMRegister(i)); - } #else __ push(len_reg); // Save #endif @@ -3281,10 +3276,6 @@ class StubGenerator: public StubCodeGenerator { __ movdqu(Address(rvec, 0), xmm_result); // final value of r stored in rvec of CipherBlockChaining object #ifdef _WIN64 - // restore xmm regs belonging to calling function - for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { - __ movdqu(as_XMMRegister(i), xmm_save(i)); - } __ movl(rax, len_mem); #else __ pop(rax); // return length @@ -3446,11 +3437,6 @@ class StubGenerator: public StubCodeGenerator { #ifdef _WIN64 // on win64, fill len_reg from stack position __ movl(len_reg, len_mem); - // save the xmm registers which must be preserved 6-15 - __ subptr(rsp, -rsp_after_call_off * wordSize); - for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { - __ movdqu(xmm_save(i), as_XMMRegister(i)); - } #else __ push(len_reg); // Save #endif @@ -3644,10 +3630,6 @@ class StubGenerator: public StubCodeGenerator { __ movdqu(Address(rvec, 0), xmm_prev_block_cipher); // final value of r stored in rvec of CipherBlockChaining object __ pop(rbx); #ifdef _WIN64 - // restore regs belonging to calling function - for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { - __ movdqu(as_XMMRegister(i), xmm_save(i)); - } __ movl(rax, len_mem); #else __ pop(rax); // return length @@ -3699,25 +3681,12 @@ class StubGenerator: public StubCodeGenerator { __ enter(); -#ifdef _WIN64 - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); -#endif - __ subptr(rsp, 4 * wordSize); __ fast_sha1(abcd, e0, e1, msg0, msg1, msg2, msg3, shuf_mask, buf, state, ofs, limit, rsp, multi_block); __ addptr(rsp, 4 * wordSize); -#ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); -#endif __ leave(); __ ret(0); @@ -3775,22 +3744,6 @@ class StubGenerator: public StubCodeGenerator { const XMMRegister shuf_mask = xmm8; __ enter(); -#ifdef _WIN64 - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 6 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); - __ movdqu(Address(rsp, 4 * wordSize), xmm8); - - if (!VM_Version::supports_sha() && VM_Version::supports_avx2()) { - __ subptr(rsp, 10 * wordSize); - __ movdqu(Address(rsp, 0), xmm9); - __ movdqu(Address(rsp, 2 * wordSize), xmm10); - __ movdqu(Address(rsp, 4 * wordSize), xmm11); - __ movdqu(Address(rsp, 6 * wordSize), xmm12); - __ movdqu(Address(rsp, 8 * wordSize), xmm13); - } -#endif __ subptr(rsp, 4 * wordSize); @@ -3802,21 +3755,7 @@ class StubGenerator: public StubCodeGenerator { buf, state, ofs, limit, rsp, multi_block, shuf_mask); } __ addptr(rsp, 4 * wordSize); -#ifdef _WIN64 - // restore xmm regs belonging to calling function - if (!VM_Version::supports_sha() && VM_Version::supports_avx2()) { - __ movdqu(xmm9, Address(rsp, 0)); - __ movdqu(xmm10, Address(rsp, 2 * wordSize)); - __ movdqu(xmm11, Address(rsp, 4 * wordSize)); - __ movdqu(xmm12, Address(rsp, 6 * wordSize)); - __ movdqu(xmm13, Address(rsp, 8 * wordSize)); - __ addptr(rsp, 10 * wordSize); - } - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ movdqu(xmm8, Address(rsp, 4 * wordSize)); - __ addptr(rsp, 6 * wordSize); -#endif + __ leave(); __ ret(0); return start; @@ -3917,18 +3856,14 @@ class StubGenerator: public StubCodeGenerator { } #ifdef _WIN64 - // save the xmm registers which must be preserved 6-14 - const int XMM_REG_NUM_KEY_LAST = 14; - __ subptr(rsp, -rsp_after_call_off * wordSize); - for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { - __ movdqu(xmm_save(i), as_XMMRegister(i)); - } - - const Address r13_save(rbp, rdi_off * wordSize); - const Address r14_save(rbp, rsi_off * wordSize); - - __ movptr(r13_save, r13); - __ movptr(r14_save, r14); + // allocate spill slots for r13, r14 + enum { + saved_r13_offset, + saved_r14_offset + }; + __ subptr(rsp, 2 * wordSize); + __ movptr(Address(rsp, saved_r13_offset * wordSize), r13); + __ movptr(Address(rsp, saved_r14_offset * wordSize), r14); // on win64, fill len_reg from stack position __ movl(len_reg, len_mem); @@ -4130,13 +4065,10 @@ class StubGenerator: public StubCodeGenerator { __ movdqu(Address(counter, 0), xmm_curr_counter); //save counter back __ pop(rbx); // pop the saved RBX. #ifdef _WIN64 - // restore regs belonging to calling function - for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { - __ movdqu(as_XMMRegister(i), xmm_save(i)); - } __ movl(rax, len_mem); - __ movptr(r13, r13_save); - __ movptr(r14, r14_save); + __ movptr(r13, Address(rsp, saved_r13_offset * wordSize)); + __ movptr(r14, Address(rsp, saved_r14_offset * wordSize)); + __ addptr(rsp, 2 * wordSize); #else __ pop(rax); // return 'len' #endif @@ -4177,10 +4109,6 @@ class StubGenerator: public StubCodeGenerator { const Register data = c_rarg2; const Register blocks = c_rarg3; -#ifdef _WIN64 - const int XMM_REG_LAST = 10; -#endif - const XMMRegister xmm_temp0 = xmm0; const XMMRegister xmm_temp1 = xmm1; const XMMRegister xmm_temp2 = xmm2; @@ -4203,14 +4131,6 @@ class StubGenerator: public StubCodeGenerator { __ kmovql(k1, rax); } -#ifdef _WIN64 - // save the xmm registers which must be preserved 6-10 - __ subptr(rsp, -rsp_after_call_off * wordSize); - for (int i = 6; i <= XMM_REG_LAST; i++) { - __ movdqu(xmm_save(i), as_XMMRegister(i)); - } -#endif - __ movdqu(xmm_temp10, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr())); __ movdqu(xmm_temp0, Address(state, 0)); @@ -4310,12 +4230,6 @@ class StubGenerator: public StubCodeGenerator { __ pshufb(xmm_temp6, xmm_temp10); // Byte swap 16-byte result __ movdqu(Address(state, 0), xmm_temp6); // store the result -#ifdef _WIN64 - // restore xmm regs belonging to calling function - for (int i = 6; i <= XMM_REG_LAST; i++) { - __ movdqu(as_XMMRegister(i), xmm_save(i)); - } -#endif __ leave(); __ ret(0); return start; @@ -4652,21 +4566,8 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("Entry:"); __ enter(); // required for proper stackwalking of RuntimeStub frame -#ifdef _WIN64 - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); -#endif __ fast_exp(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp); -#ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); -#endif - __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -4693,21 +4594,8 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("Entry:"); __ enter(); // required for proper stackwalking of RuntimeStub frame -#ifdef _WIN64 - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); -#endif __ fast_log(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2); -#ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); -#endif - __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -4733,21 +4621,8 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("Entry:"); __ enter(); // required for proper stackwalking of RuntimeStub frame -#ifdef _WIN64 - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); -#endif __ fast_log10(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp); -#ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); -#endif - __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -4776,21 +4651,8 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("Entry:"); __ enter(); // required for proper stackwalking of RuntimeStub frame -#ifdef _WIN64 - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); -#endif __ fast_pow(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4); -#ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); -#endif - __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -4822,18 +4684,10 @@ class StubGenerator: public StubCodeGenerator { #ifdef _WIN64 __ push(rsi); __ push(rdi); - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); #endif __ fast_sin(x0, x1, x2, x3, x4, x5, x6, x7, rax, rbx, rcx, rdx, tmp1, tmp2, tmp3, tmp4); #ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); __ pop(rdi); __ pop(rsi); #endif @@ -4869,18 +4723,10 @@ class StubGenerator: public StubCodeGenerator { #ifdef _WIN64 __ push(rsi); __ push(rdi); - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); #endif __ fast_cos(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4); #ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); __ pop(rdi); __ pop(rsi); #endif @@ -4916,18 +4762,10 @@ class StubGenerator: public StubCodeGenerator { #ifdef _WIN64 __ push(rsi); __ push(rdi); - // save the xmm registers which must be preserved 6-7 - __ subptr(rsp, 4 * wordSize); - __ movdqu(Address(rsp, 0), xmm6); - __ movdqu(Address(rsp, 2 * wordSize), xmm7); #endif __ fast_tan(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4); #ifdef _WIN64 - // restore xmm regs belonging to calling function - __ movdqu(xmm6, Address(rsp, 0)); - __ movdqu(xmm7, Address(rsp, 2 * wordSize)); - __ addptr(rsp, 4 * wordSize); __ pop(rdi); __ pop(rsi); #endif diff --git a/hotspot/src/cpu/x86/vm/x86.ad b/hotspot/src/cpu/x86/vm/x86.ad index a9d727e4cd5..24eab7f3785 100644 --- a/hotspot/src/cpu/x86/vm/x86.ad +++ b/hotspot/src/cpu/x86/vm/x86.ad @@ -176,451 +176,6 @@ reg_def XMM5n( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(13)); reg_def XMM5o( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(14)); reg_def XMM5p( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(15)); -#ifdef _WIN64 - -reg_def XMM6 ( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()); -reg_def XMM6b( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(1)); -reg_def XMM6c( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(2)); -reg_def XMM6d( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(3)); -reg_def XMM6e( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(4)); -reg_def XMM6f( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(5)); -reg_def XMM6g( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(6)); -reg_def XMM6h( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(7)); -reg_def XMM6i( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(8)); -reg_def XMM6j( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(9)); -reg_def XMM6k( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(10)); -reg_def XMM6l( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(11)); -reg_def XMM6m( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(12)); -reg_def XMM6n( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(13)); -reg_def XMM6o( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(14)); -reg_def XMM6p( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(15)); - -reg_def XMM7 ( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()); -reg_def XMM7b( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(1)); -reg_def XMM7c( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(2)); -reg_def XMM7d( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(3)); -reg_def XMM7e( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(4)); -reg_def XMM7f( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(5)); -reg_def XMM7g( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(6)); -reg_def XMM7h( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(7)); -reg_def XMM7i( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(8)); -reg_def XMM7j( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(9)); -reg_def XMM7k( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(10)); -reg_def XMM7l( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(11)); -reg_def XMM7m( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(12)); -reg_def XMM7n( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(13)); -reg_def XMM7o( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(14)); -reg_def XMM7p( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(15)); - -reg_def XMM8 ( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()); -reg_def XMM8b( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(1)); -reg_def XMM8c( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(2)); -reg_def XMM8d( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(3)); -reg_def XMM8e( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(4)); -reg_def XMM8f( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(5)); -reg_def XMM8g( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(6)); -reg_def XMM8h( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(7)); -reg_def XMM8i( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(8)); -reg_def XMM8j( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(9)); -reg_def XMM8k( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(10)); -reg_def XMM8l( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(11)); -reg_def XMM8m( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(12)); -reg_def XMM8n( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(13)); -reg_def XMM8o( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(14)); -reg_def XMM8p( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(15)); - -reg_def XMM9 ( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()); -reg_def XMM9b( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(1)); -reg_def XMM9c( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(2)); -reg_def XMM9d( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(3)); -reg_def XMM9e( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(4)); -reg_def XMM9f( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(5)); -reg_def XMM9g( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(6)); -reg_def XMM9h( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(7)); -reg_def XMM9i( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(8)); -reg_def XMM9j( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(9)); -reg_def XMM9k( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(10)); -reg_def XMM9l( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(11)); -reg_def XMM9m( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(12)); -reg_def XMM9n( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(13)); -reg_def XMM9o( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(14)); -reg_def XMM9p( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(15)); - -reg_def XMM10 ( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()); -reg_def XMM10b( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(1)); -reg_def XMM10c( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(2)); -reg_def XMM10d( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(3)); -reg_def XMM10e( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(4)); -reg_def XMM10f( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(5)); -reg_def XMM10g( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(6)); -reg_def XMM10h( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(7)); -reg_def XMM10i( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(8)); -reg_def XMM10j( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(9)); -reg_def XMM10k( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(10)); -reg_def XMM10l( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(11)); -reg_def XMM10m( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(12)); -reg_def XMM10n( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(13)); -reg_def XMM10o( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(14)); -reg_def XMM10p( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(15)); - -reg_def XMM11 ( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()); -reg_def XMM11b( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(1)); -reg_def XMM11c( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(2)); -reg_def XMM11d( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(3)); -reg_def XMM11e( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(4)); -reg_def XMM11f( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(5)); -reg_def XMM11g( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(6)); -reg_def XMM11h( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(7)); -reg_def XMM11i( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(8)); -reg_def XMM11j( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(9)); -reg_def XMM11k( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(10)); -reg_def XMM11l( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(11)); -reg_def XMM11m( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(12)); -reg_def XMM11n( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(13)); -reg_def XMM11o( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(14)); -reg_def XMM11p( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(15)); - -reg_def XMM12 ( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()); -reg_def XMM12b( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(1)); -reg_def XMM12c( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(2)); -reg_def XMM12d( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(3)); -reg_def XMM12e( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(4)); -reg_def XMM12f( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(5)); -reg_def XMM12g( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(6)); -reg_def XMM12h( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(7)); -reg_def XMM12i( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(8)); -reg_def XMM12j( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(9)); -reg_def XMM12k( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(10)); -reg_def XMM12l( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(11)); -reg_def XMM12m( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(12)); -reg_def XMM12n( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(13)); -reg_def XMM12o( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(14)); -reg_def XMM12p( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(15)); - -reg_def XMM13 ( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()); -reg_def XMM13b( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(1)); -reg_def XMM13c( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(2)); -reg_def XMM13d( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(3)); -reg_def XMM13e( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(4)); -reg_def XMM13f( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(5)); -reg_def XMM13g( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(6)); -reg_def XMM13h( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(7)); -reg_def XMM13i( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(8)); -reg_def XMM13j( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(9)); -reg_def XMM13k( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(10)); -reg_def XMM13l( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(11)); -reg_def XMM13m( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(12)); -reg_def XMM13n( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(13)); -reg_def XMM13o( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(14)); -reg_def XMM13p( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(15)); - -reg_def XMM14 ( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()); -reg_def XMM14b( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(1)); -reg_def XMM14c( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(2)); -reg_def XMM14d( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(3)); -reg_def XMM14e( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(4)); -reg_def XMM14f( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(5)); -reg_def XMM14g( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(6)); -reg_def XMM14h( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(7)); -reg_def XMM14i( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(8)); -reg_def XMM14j( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(9)); -reg_def XMM14k( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(10)); -reg_def XMM14l( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(11)); -reg_def XMM14m( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(12)); -reg_def XMM14n( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(13)); -reg_def XMM14o( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(14)); -reg_def XMM14p( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(15)); - -reg_def XMM15 ( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()); -reg_def XMM15b( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(1)); -reg_def XMM15c( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(2)); -reg_def XMM15d( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(3)); -reg_def XMM15e( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(4)); -reg_def XMM15f( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(5)); -reg_def XMM15g( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(6)); -reg_def XMM15h( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(7)); -reg_def XMM15i( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(8)); -reg_def XMM15j( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(9)); -reg_def XMM15k( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(10)); -reg_def XMM15l( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(11)); -reg_def XMM15m( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(12)); -reg_def XMM15n( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(13)); -reg_def XMM15o( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(14)); -reg_def XMM15p( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(15)); - -reg_def XMM16 ( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()); -reg_def XMM16b( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(1)); -reg_def XMM16c( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(2)); -reg_def XMM16d( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(3)); -reg_def XMM16e( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(4)); -reg_def XMM16f( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(5)); -reg_def XMM16g( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(6)); -reg_def XMM16h( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(7)); -reg_def XMM16i( SOC, SOE, Op_RegF, 16, xmm15->as_VMReg()->next(8)); -reg_def XMM16j( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(9)); -reg_def XMM16k( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(10)); -reg_def XMM16l( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(11)); -reg_def XMM16m( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(12)); -reg_def XMM16n( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(13)); -reg_def XMM16o( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(14)); -reg_def XMM16p( SOC, SOE, Op_RegF, 16, xmm16->as_VMReg()->next(15)); - -reg_def XMM17 ( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()); -reg_def XMM17b( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(1)); -reg_def XMM17c( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(2)); -reg_def XMM17d( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(3)); -reg_def XMM17e( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(4)); -reg_def XMM17f( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(5)); -reg_def XMM17g( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(6)); -reg_def XMM17h( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(7)); -reg_def XMM17i( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(8)); -reg_def XMM17j( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(9)); -reg_def XMM17k( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(10)); -reg_def XMM17l( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(11)); -reg_def XMM17m( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(12)); -reg_def XMM17n( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(13)); -reg_def XMM17o( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(14)); -reg_def XMM17p( SOC, SOE, Op_RegF, 17, xmm17->as_VMReg()->next(15)); - -reg_def XMM18 ( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()); -reg_def XMM18b( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(1)); -reg_def XMM18c( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(2)); -reg_def XMM18d( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(3)); -reg_def XMM18e( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(4)); -reg_def XMM18f( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(5)); -reg_def XMM18g( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(6)); -reg_def XMM18h( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(7)); -reg_def XMM18i( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(8)); -reg_def XMM18j( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(9)); -reg_def XMM18k( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(10)); -reg_def XMM18l( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(11)); -reg_def XMM18m( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(12)); -reg_def XMM18n( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(13)); -reg_def XMM18o( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(14)); -reg_def XMM18p( SOC, SOE, Op_RegF, 18, xmm18->as_VMReg()->next(15)); - -reg_def XMM19 ( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()); -reg_def XMM19b( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(1)); -reg_def XMM19c( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(2)); -reg_def XMM19d( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(3)); -reg_def XMM19e( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(4)); -reg_def XMM19f( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(5)); -reg_def XMM19g( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(6)); -reg_def XMM19h( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(7)); -reg_def XMM19i( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(8)); -reg_def XMM19j( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(9)); -reg_def XMM19k( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(10)); -reg_def XMM19l( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(11)); -reg_def XMM19m( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(12)); -reg_def XMM19n( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(13)); -reg_def XMM19o( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(14)); -reg_def XMM19p( SOC, SOE, Op_RegF, 19, xmm19->as_VMReg()->next(15)); - -reg_def XMM20 ( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()); -reg_def XMM20b( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(1)); -reg_def XMM20c( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(2)); -reg_def XMM20d( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(3)); -reg_def XMM20e( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(4)); -reg_def XMM20f( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(5)); -reg_def XMM20g( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(6)); -reg_def XMM20h( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(7)); -reg_def XMM20i( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(8)); -reg_def XMM20j( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(9)); -reg_def XMM20k( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(10)); -reg_def XMM20l( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(11)); -reg_def XMM20m( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(12)); -reg_def XMM20n( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(13)); -reg_def XMM20o( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(14)); -reg_def XMM20p( SOC, SOE, Op_RegF, 20, xmm20->as_VMReg()->next(15)); - -reg_def XMM21 ( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()); -reg_def XMM21b( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(1)); -reg_def XMM21c( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(2)); -reg_def XMM21d( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(3)); -reg_def XMM21e( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(4)); -reg_def XMM21f( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(5)); -reg_def XMM21g( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(6)); -reg_def XMM21h( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(7)); -reg_def XMM21i( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(8)); -reg_def XMM21j( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(9)); -reg_def XMM21k( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(10)); -reg_def XMM21l( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(11)); -reg_def XMM21m( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(12)); -reg_def XMM21n( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(13)); -reg_def XMM21o( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(14)); -reg_def XMM21p( SOC, SOE, Op_RegF, 21, xmm21->as_VMReg()->next(15)); - -reg_def XMM22 ( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()); -reg_def XMM22b( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(1)); -reg_def XMM22c( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(2)); -reg_def XMM22d( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(3)); -reg_def XMM22e( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(4)); -reg_def XMM22f( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(5)); -reg_def XMM22g( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(6)); -reg_def XMM22h( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(7)); -reg_def XMM22i( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(8)); -reg_def XMM22j( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(9)); -reg_def XMM22k( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(10)); -reg_def XMM22l( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(11)); -reg_def XMM22m( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(12)); -reg_def XMM22n( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(13)); -reg_def XMM22o( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(14)); -reg_def XMM22p( SOC, SOE, Op_RegF, 22, xmm22->as_VMReg()->next(15)); - -reg_def XMM23 ( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()); -reg_def XMM23b( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(1)); -reg_def XMM23c( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(2)); -reg_def XMM23d( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(3)); -reg_def XMM23e( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(4)); -reg_def XMM23f( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(5)); -reg_def XMM23g( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(6)); -reg_def XMM23h( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(7)); -reg_def XMM23i( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(8)); -reg_def XMM23j( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(9)); -reg_def XMM23k( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(10)); -reg_def XMM23l( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(11)); -reg_def XMM23m( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(12)); -reg_def XMM23n( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(13)); -reg_def XMM23o( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(14)); -reg_def XMM23p( SOC, SOE, Op_RegF, 23, xmm23->as_VMReg()->next(15)); - -reg_def XMM24 ( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()); -reg_def XMM24b( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(1)); -reg_def XMM24c( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(2)); -reg_def XMM24d( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(3)); -reg_def XMM24e( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(4)); -reg_def XMM24f( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(5)); -reg_def XMM24g( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(6)); -reg_def XMM24h( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(7)); -reg_def XMM24i( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(8)); -reg_def XMM24j( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(9)); -reg_def XMM24k( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(10)); -reg_def XMM24l( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(11)); -reg_def XMM24m( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(12)); -reg_def XMM24n( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(13)); -reg_def XMM24o( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(14)); -reg_def XMM24p( SOC, SOE, Op_RegF, 24, xmm24->as_VMReg()->next(15)); - -reg_def XMM25 ( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()); -reg_def XMM25b( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(1)); -reg_def XMM25c( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(2)); -reg_def XMM25d( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(3)); -reg_def XMM25e( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(4)); -reg_def XMM25f( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(5)); -reg_def XMM25g( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(6)); -reg_def XMM25h( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(7)); -reg_def XMM25i( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(8)); -reg_def XMM25j( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(9)); -reg_def XMM25k( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(10)); -reg_def XMM25l( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(11)); -reg_def XMM25m( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(12)); -reg_def XMM25n( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(13)); -reg_def XMM25o( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(14)); -reg_def XMM25p( SOC, SOE, Op_RegF, 25, xmm25->as_VMReg()->next(15)); - -reg_def XMM26 ( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()); -reg_def XMM26b( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(1)); -reg_def XMM26c( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(2)); -reg_def XMM26d( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(3)); -reg_def XMM26e( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(4)); -reg_def XMM26f( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(5)); -reg_def XMM26g( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(6)); -reg_def XMM26h( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(7)); -reg_def XMM26i( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(8)); -reg_def XMM26j( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(9)); -reg_def XMM26k( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(10)); -reg_def XMM26l( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(11)); -reg_def XMM26m( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(12)); -reg_def XMM26n( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(13)); -reg_def XMM26o( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(14)); -reg_def XMM26p( SOC, SOE, Op_RegF, 26, xmm26->as_VMReg()->next(15)); - -reg_def XMM27g( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(1)); -reg_def XMM27c( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(2)); -reg_def XMM27d( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(3)); -reg_def XMM27e( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(4)); -reg_def XMM27f( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(5)); -reg_def XMM27g( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(6)); -reg_def XMM27h( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(7)); -reg_def XMM27i( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(8)); -reg_def XMM27j( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(9)); -reg_def XMM27k( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(10)); -reg_def XMM27l( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(11)); -reg_def XMM27m( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(12)); -reg_def XMM27n( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(13)); -reg_def XMM27o( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(14)); -reg_def XMM27p( SOC, SOE, Op_RegF, 27, xmm27->as_VMReg()->next(15)); - -reg_def XMM28 ( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()); -reg_def XMM28b( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(1)); -reg_def XMM28c( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(2)); -reg_def XMM28d( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(3)); -reg_def XMM28e( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(4)); -reg_def XMM28f( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(5)); -reg_def XMM28g( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(6)); -reg_def XMM28h( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(7)); -reg_def XMM28i( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(8)); -reg_def XMM28j( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(9)); -reg_def XMM28k( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(10)); -reg_def XMM28l( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(11)); -reg_def XMM28m( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(12)); -reg_def XMM28n( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(13)); -reg_def XMM28o( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(14)); -reg_def XMM28p( SOC, SOE, Op_RegF, 28, xmm28->as_VMReg()->next(15)); - -reg_def XMM29 ( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()); -reg_def XMM29b( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(1)); -reg_def XMM29c( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(2)); -reg_def XMM29d( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(3)); -reg_def XMM29e( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(4)); -reg_def XMM29f( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(5)); -reg_def XMM29g( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(6)); -reg_def XMM29h( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(7)); -reg_def XMM29i( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(8)); -reg_def XMM29j( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(9)); -reg_def XMM29k( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(10)); -reg_def XMM29l( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(11)); -reg_def XMM29m( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(12)); -reg_def XMM29n( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(13)); -reg_def XMM29o( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(14)); -reg_def XMM29p( SOC, SOE, Op_RegF, 29, xmm29->as_VMReg()->next(15)); - -reg_def XMM30 ( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()); -reg_def XMM30b( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(1)); -reg_def XMM30c( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(2)); -reg_def XMM30d( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(3)); -reg_def XMM30e( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(4)); -reg_def XMM30f( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(5)); -reg_def XMM30g( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(6)); -reg_def XMM30h( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(7)); -reg_def XMM30i( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(8)); -reg_def XMM30j( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(9)); -reg_def XMM30k( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(10)); -reg_def XMM30l( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(11)); -reg_def XMM30m( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(12)); -reg_def XMM30n( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(13)); -reg_def XMM30o( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(14)); -reg_def XMM30p( SOC, SOE, Op_RegF, 30, xmm30->as_VMReg()->next(15)); - -reg_def XMM31 ( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()); -reg_def XMM31b( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(1)); -reg_def XMM31c( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(2)); -reg_def XMM31d( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(3)); -reg_def XMM31e( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(4)); -reg_def XMM31f( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(5)); -reg_def XMM31g( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(6)); -reg_def XMM31h( SOC, SOE, Op_RegF, 31, xmm31>-as_VMReg()->next(7)); -reg_def XMM31i( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(8)); -reg_def XMM31j( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(9)); -reg_def XMM31k( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(10)); -reg_def XMM31l( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(11)); -reg_def XMM31m( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(12)); -reg_def XMM31n( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(13)); -reg_def XMM31o( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(14)); -reg_def XMM31p( SOC, SOE, Op_RegF, 31, xmm31->as_VMReg()->next(15)); - -#else // _WIN64 - reg_def XMM6 ( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()); reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(1)); reg_def XMM6c( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(2)); @@ -1067,8 +622,6 @@ reg_def XMM31p( SOC, SOC, Op_RegF, 31, xmm31->as_VMReg()->next(15)); #endif // _LP64 -#endif // _WIN64 - #ifdef _LP64 reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad()); #else From 4347d96655b1191ea876505d6992d326b0f3f7b4 Mon Sep 17 00:00:00 2001 From: Hiroshi H Horii Date: Thu, 22 Sep 2016 12:17:24 +0200 Subject: [PATCH 014/207] 8164920: ppc: enhancement of CRC32 intrinsic Reviewed-by: goetz, mdoerr --- hotspot/src/cpu/ppc/vm/assembler_ppc.hpp | 4 + .../src/cpu/ppc/vm/assembler_ppc.inline.hpp | 2 + hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp | 559 ++++++++++++++++++ hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp | 7 + hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp | 63 +- hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp | 8 + .../src/cpu/ppc/vm/stubRoutines_ppc_64.cpp | 309 ++++++++++ 7 files changed, 936 insertions(+), 16 deletions(-) diff --git a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp index e81d08e848a..d96f1635e17 100644 --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp @@ -506,6 +506,8 @@ class Assembler : public AbstractAssembler { // Vector-Scalar (VSX) instruction support. LXVD2X_OPCODE = (31u << OPCODE_SHIFT | 844u << 1), STXVD2X_OPCODE = (31u << OPCODE_SHIFT | 972u << 1), + MTVSRD_OPCODE = (31u << OPCODE_SHIFT | 179u << 1), + MFVSRD_OPCODE = (31u << OPCODE_SHIFT | 51u << 1), // Vector Permute and Formatting VPKPX_OPCODE = (4u << OPCODE_SHIFT | 782u ), @@ -2099,6 +2101,8 @@ class Assembler : public AbstractAssembler { // Vector-Scalar (VSX) instructions. inline void lxvd2x( VectorSRegister d, Register a, Register b); inline void stxvd2x( VectorSRegister d, Register a, Register b); + inline void mtvrd( VectorRegister d, Register a); + inline void mfvrd( Register a, VectorRegister d); // AES (introduced with Power 8) inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b); diff --git a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp index 14f25e4eea8..ef129efeefe 100644 --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp @@ -733,6 +733,8 @@ inline void Assembler::lvsr( VectorRegister d, Register s1, Register s2) { emit // Vector-Scalar (VSX) instructions. inline void Assembler::lxvd2x (VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); } inline void Assembler::stxvd2x(VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); } +inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec). +inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec). inline void Assembler::vpkpx( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKPX_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vpkshss( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKSHSS_OPCODE | vrt(d) | vra(a) | vrb(b)); } diff --git a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp index 5d58dab4995..417e6a3a27a 100644 --- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp @@ -4332,6 +4332,565 @@ void MacroAssembler::kernel_crc32_1byte(Register crc, Register buf, Register len BLOCK_COMMENT("} kernel_crc32_1byte"); } +/** + * @param crc register containing existing CRC (32-bit) + * @param buf register pointing to input byte buffer (byte*) + * @param len register containing number of bytes + * @param table register pointing to CRC table + * @param constants register pointing to CRC table for 128-bit aligned memory + * @param barretConstants register pointing to table for barrett reduction + * @param t0 volatile register + * @param t1 volatile register + * @param t2 volatile register + * @param t3 volatile register + */ +void MacroAssembler::kernel_crc32_1word_vpmsumd(Register crc, Register buf, Register len, Register table, + Register constants, Register barretConstants, + Register t0, Register t1, Register t2, Register t3, Register t4) { + assert_different_registers(crc, buf, len, table); + + Label L_alignedHead, L_tail, L_alignTail, L_start, L_end; + + Register prealign = t0; + Register postalign = t0; + + BLOCK_COMMENT("kernel_crc32_1word_vpmsumb {"); + + // 1. use kernel_crc32_1word for shorter than 384bit + clrldi(len, len, 32); + cmpdi(CCR0, len, 384); + bge(CCR0, L_start); + + Register tc0 = t4; + Register tc1 = constants; + Register tc2 = barretConstants; + kernel_crc32_1word(crc, buf, len, table,t0, t1, t2, t3, tc0, tc1, tc2, table); + b(L_end); + + BIND(L_start); + + // 2. ~c + nand(crc, crc, crc); + + // 3. calculate from 0 to first 128bit-aligned address + clrldi_(prealign, buf, 57); + beq(CCR0, L_alignedHead); + + subfic(prealign, prealign, 128); + + subf(len, prealign, len); + update_byteLoop_crc32(crc, buf, prealign, table, t2, false, false); + + // 4. calculate from first 128bit-aligned address to last 128bit-aligned address + BIND(L_alignedHead); + + clrldi(postalign, len, 57); + subf(len, postalign, len); + + // len must be more than 256bit + kernel_crc32_1word_aligned(crc, buf, len, constants, barretConstants, t1, t2, t3); + + // 5. calculate remaining + cmpdi(CCR0, postalign, 0); + beq(CCR0, L_tail); + + update_byteLoop_crc32(crc, buf, postalign, table, t2, false, false); + + BIND(L_tail); + + // 6. ~c + nand(crc, crc, crc); + + BIND(L_end); + + BLOCK_COMMENT("} kernel_crc32_1word_vpmsumb"); +} + +/** + * @param crc register containing existing CRC (32-bit) + * @param buf register pointing to input byte buffer (byte*) + * @param len register containing number of bytes + * @param constants register pointing to CRC table for 128-bit aligned memory + * @param barretConstants register pointing to table for barrett reduction + * @param t0 volatile register + * @param t1 volatile register + * @param t2 volatile register + */ +void MacroAssembler::kernel_crc32_1word_aligned(Register crc, Register buf, Register len, + Register constants, Register barretConstants, Register t0, Register t1, Register t2) { + Label L_mainLoop, L_tail, L_alignTail, L_barrett_reduction, L_end, L_first_warm_up_done, L_first_cool_down, L_second_cool_down, L_XOR, L_test; + Label L_lv0, L_lv1, L_lv2, L_lv3, L_lv4, L_lv5, L_lv6, L_lv7, L_lv8, L_lv9, L_lv10, L_lv11, L_lv12, L_lv13, L_lv14, L_lv15; + Label L_1, L_2, L_3, L_4; + + Register rLoaded = t0; + Register rTmp1 = t1; + Register rTmp2 = t2; + Register off16 = R22; + Register off32 = R23; + Register off48 = R24; + Register off64 = R25; + Register off80 = R26; + Register off96 = R27; + Register off112 = R28; + Register rIdx = R29; + Register rMax = R30; + Register constantsPos = R31; + + VectorRegister mask_32bit = VR24; + VectorRegister mask_64bit = VR25; + VectorRegister zeroes = VR26; + VectorRegister const1 = VR27; + VectorRegister const2 = VR28; + + // Save non-volatile vector registers (frameless). + Register offset = t1; int offsetInt = 0; + offsetInt -= 16; li(offset, -16); stvx(VR20, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR21, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR22, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR23, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR24, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR25, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR26, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR27, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); stvx(VR28, offset, R1_SP); + offsetInt -= 8; std(R22, offsetInt, R1_SP); + offsetInt -= 8; std(R23, offsetInt, R1_SP); + offsetInt -= 8; std(R24, offsetInt, R1_SP); + offsetInt -= 8; std(R25, offsetInt, R1_SP); + offsetInt -= 8; std(R26, offsetInt, R1_SP); + offsetInt -= 8; std(R27, offsetInt, R1_SP); + offsetInt -= 8; std(R28, offsetInt, R1_SP); + offsetInt -= 8; std(R29, offsetInt, R1_SP); + offsetInt -= 8; std(R30, offsetInt, R1_SP); + offsetInt -= 8; std(R31, offsetInt, R1_SP); + + // Set constants + li(off16, 16); + li(off32, 32); + li(off48, 48); + li(off64, 64); + li(off80, 80); + li(off96, 96); + li(off112, 112); + + clrldi(crc, crc, 32); + + vxor(zeroes, zeroes, zeroes); + vspltisw(VR0, -1); + + vsldoi(mask_32bit, zeroes, VR0, 4); + vsldoi(mask_64bit, zeroes, VR0, -8); + + // Get the initial value into v8 + vxor(VR8, VR8, VR8); + mtvrd(VR8, crc); + vsldoi(VR8, zeroes, VR8, -8); // shift into bottom 32 bits + + li (rLoaded, 0); + + rldicr(rIdx, len, 0, 56); + + { + BIND(L_1); + // Checksum in blocks of MAX_SIZE (32768) + lis(rMax, 0); + ori(rMax, rMax, 32768); + mr(rTmp2, rMax); + cmpd(CCR0, rIdx, rMax); + bgt(CCR0, L_2); + mr(rMax, rIdx); + + BIND(L_2); + subf(rIdx, rMax, rIdx); + + // our main loop does 128 bytes at a time + srdi(rMax, rMax, 7); + + /* + * Work out the offset into the constants table to start at. Each + * constant is 16 bytes, and it is used against 128 bytes of input + * data - 128 / 16 = 8 + */ + sldi(rTmp1, rMax, 4); + srdi(rTmp2, rTmp2, 3); + subf(rTmp1, rTmp1, rTmp2); + + // We reduce our final 128 bytes in a separate step + addi(rMax, rMax, -1); + mtctr(rMax); + + // Find the start of our constants + add(constantsPos, constants, rTmp1); + + // zero VR0-v7 which will contain our checksums + vxor(VR0, VR0, VR0); + vxor(VR1, VR1, VR1); + vxor(VR2, VR2, VR2); + vxor(VR3, VR3, VR3); + vxor(VR4, VR4, VR4); + vxor(VR5, VR5, VR5); + vxor(VR6, VR6, VR6); + vxor(VR7, VR7, VR7); + + lvx(const1, constantsPos); + + /* + * If we are looping back to consume more data we use the values + * already in VR16-v23. + */ + cmpdi(CCR0, rLoaded, 1); + beq(CCR0, L_3); + { + + // First warm up pass + lvx(VR16, buf); + lvx(VR17, off16, buf); + lvx(VR18, off32, buf); + lvx(VR19, off48, buf); + lvx(VR20, off64, buf); + lvx(VR21, off80, buf); + lvx(VR22, off96, buf); + lvx(VR23, off112, buf); + addi(buf, buf, 8*16); + + // xor in initial value + vxor(VR16, VR16, VR8); + } + + BIND(L_3); + bdz(L_first_warm_up_done); + + addi(constantsPos, constantsPos, 16); + lvx(const2, constantsPos); + + // Second warm up pass + vpmsumd(VR8, VR16, const1); + lvx(VR16, buf); + + vpmsumd(VR9, VR17, const1); + lvx(VR17, off16, buf); + + vpmsumd(VR10, VR18, const1); + lvx(VR18, off32, buf); + + vpmsumd(VR11, VR19, const1); + lvx(VR19, off48, buf); + + vpmsumd(VR12, VR20, const1); + lvx(VR20, off64, buf); + + vpmsumd(VR13, VR21, const1); + lvx(VR21, off80, buf); + + vpmsumd(VR14, VR22, const1); + lvx(VR22, off96, buf); + + vpmsumd(VR15, VR23, const1); + lvx(VR23, off112, buf); + + addi(buf, buf, 8 * 16); + + bdz(L_first_cool_down); + + /* + * main loop. We modulo schedule it such that it takes three iterations + * to complete - first iteration load, second iteration vpmsum, third + * iteration xor. + */ + { + BIND(L_4); + lvx(const1, constantsPos); addi(constantsPos, constantsPos, 16); + + vxor(VR0, VR0, VR8); + vpmsumd(VR8, VR16, const2); + lvx(VR16, buf); + + vxor(VR1, VR1, VR9); + vpmsumd(VR9, VR17, const2); + lvx(VR17, off16, buf); + + vxor(VR2, VR2, VR10); + vpmsumd(VR10, VR18, const2); + lvx(VR18, off32, buf); + + vxor(VR3, VR3, VR11); + vpmsumd(VR11, VR19, const2); + lvx(VR19, off48, buf); + lvx(const2, constantsPos); + + vxor(VR4, VR4, VR12); + vpmsumd(VR12, VR20, const1); + lvx(VR20, off64, buf); + + vxor(VR5, VR5, VR13); + vpmsumd(VR13, VR21, const1); + lvx(VR21, off80, buf); + + vxor(VR6, VR6, VR14); + vpmsumd(VR14, VR22, const1); + lvx(VR22, off96, buf); + + vxor(VR7, VR7, VR15); + vpmsumd(VR15, VR23, const1); + lvx(VR23, off112, buf); + + addi(buf, buf, 8 * 16); + + bdnz(L_4); + } + + BIND(L_first_cool_down); + + // First cool down pass + lvx(const1, constantsPos); + addi(constantsPos, constantsPos, 16); + + vxor(VR0, VR0, VR8); + vpmsumd(VR8, VR16, const1); + + vxor(VR1, VR1, VR9); + vpmsumd(VR9, VR17, const1); + + vxor(VR2, VR2, VR10); + vpmsumd(VR10, VR18, const1); + + vxor(VR3, VR3, VR11); + vpmsumd(VR11, VR19, const1); + + vxor(VR4, VR4, VR12); + vpmsumd(VR12, VR20, const1); + + vxor(VR5, VR5, VR13); + vpmsumd(VR13, VR21, const1); + + vxor(VR6, VR6, VR14); + vpmsumd(VR14, VR22, const1); + + vxor(VR7, VR7, VR15); + vpmsumd(VR15, VR23, const1); + + BIND(L_second_cool_down); + // Second cool down pass + vxor(VR0, VR0, VR8); + vxor(VR1, VR1, VR9); + vxor(VR2, VR2, VR10); + vxor(VR3, VR3, VR11); + vxor(VR4, VR4, VR12); + vxor(VR5, VR5, VR13); + vxor(VR6, VR6, VR14); + vxor(VR7, VR7, VR15); + + /* + * vpmsumd produces a 96 bit result in the least significant bits + * of the register. Since we are bit reflected we have to shift it + * left 32 bits so it occupies the least significant bits in the + * bit reflected domain. + */ + vsldoi(VR0, VR0, zeroes, 4); + vsldoi(VR1, VR1, zeroes, 4); + vsldoi(VR2, VR2, zeroes, 4); + vsldoi(VR3, VR3, zeroes, 4); + vsldoi(VR4, VR4, zeroes, 4); + vsldoi(VR5, VR5, zeroes, 4); + vsldoi(VR6, VR6, zeroes, 4); + vsldoi(VR7, VR7, zeroes, 4); + + // xor with last 1024 bits + lvx(VR8, buf); + lvx(VR9, off16, buf); + lvx(VR10, off32, buf); + lvx(VR11, off48, buf); + lvx(VR12, off64, buf); + lvx(VR13, off80, buf); + lvx(VR14, off96, buf); + lvx(VR15, off112, buf); + addi(buf, buf, 8 * 16); + + vxor(VR16, VR0, VR8); + vxor(VR17, VR1, VR9); + vxor(VR18, VR2, VR10); + vxor(VR19, VR3, VR11); + vxor(VR20, VR4, VR12); + vxor(VR21, VR5, VR13); + vxor(VR22, VR6, VR14); + vxor(VR23, VR7, VR15); + + li(rLoaded, 1); + cmpdi(CCR0, rIdx, 0); + addi(rIdx, rIdx, 128); + bne(CCR0, L_1); + } + + // Work out how many bytes we have left + andi_(len, len, 127); + + // Calculate where in the constant table we need to start + subfic(rTmp1, len, 128); + add(constantsPos, constantsPos, rTmp1); + + // How many 16 byte chunks are in the tail + srdi(rIdx, len, 4); + mtctr(rIdx); + + /* + * Reduce the previously calculated 1024 bits to 64 bits, shifting + * 32 bits to include the trailing 32 bits of zeros + */ + lvx(VR0, constantsPos); + lvx(VR1, off16, constantsPos); + lvx(VR2, off32, constantsPos); + lvx(VR3, off48, constantsPos); + lvx(VR4, off64, constantsPos); + lvx(VR5, off80, constantsPos); + lvx(VR6, off96, constantsPos); + lvx(VR7, off112, constantsPos); + addi(constantsPos, constantsPos, 8 * 16); + + vpmsumw(VR0, VR16, VR0); + vpmsumw(VR1, VR17, VR1); + vpmsumw(VR2, VR18, VR2); + vpmsumw(VR3, VR19, VR3); + vpmsumw(VR4, VR20, VR4); + vpmsumw(VR5, VR21, VR5); + vpmsumw(VR6, VR22, VR6); + vpmsumw(VR7, VR23, VR7); + + // Now reduce the tail (0 - 112 bytes) + cmpdi(CCR0, rIdx, 0); + beq(CCR0, L_XOR); + + lvx(VR16, buf); addi(buf, buf, 16); + lvx(VR17, constantsPos); + vpmsumw(VR16, VR16, VR17); + vxor(VR0, VR0, VR16); + beq(CCR0, L_XOR); + + lvx(VR16, buf); addi(buf, buf, 16); + lvx(VR17, off16, constantsPos); + vpmsumw(VR16, VR16, VR17); + vxor(VR0, VR0, VR16); + beq(CCR0, L_XOR); + + lvx(VR16, buf); addi(buf, buf, 16); + lvx(VR17, off32, constantsPos); + vpmsumw(VR16, VR16, VR17); + vxor(VR0, VR0, VR16); + beq(CCR0, L_XOR); + + lvx(VR16, buf); addi(buf, buf, 16); + lvx(VR17, off48,constantsPos); + vpmsumw(VR16, VR16, VR17); + vxor(VR0, VR0, VR16); + beq(CCR0, L_XOR); + + lvx(VR16, buf); addi(buf, buf, 16); + lvx(VR17, off64, constantsPos); + vpmsumw(VR16, VR16, VR17); + vxor(VR0, VR0, VR16); + beq(CCR0, L_XOR); + + lvx(VR16, buf); addi(buf, buf, 16); + lvx(VR17, off80, constantsPos); + vpmsumw(VR16, VR16, VR17); + vxor(VR0, VR0, VR16); + beq(CCR0, L_XOR); + + lvx(VR16, buf); addi(buf, buf, 16); + lvx(VR17, off96, constantsPos); + vpmsumw(VR16, VR16, VR17); + vxor(VR0, VR0, VR16); + + // Now xor all the parallel chunks together + BIND(L_XOR); + vxor(VR0, VR0, VR1); + vxor(VR2, VR2, VR3); + vxor(VR4, VR4, VR5); + vxor(VR6, VR6, VR7); + + vxor(VR0, VR0, VR2); + vxor(VR4, VR4, VR6); + + vxor(VR0, VR0, VR4); + + b(L_barrett_reduction); + + BIND(L_first_warm_up_done); + lvx(const1, constantsPos); + addi(constantsPos, constantsPos, 16); + vpmsumd(VR8, VR16, const1); + vpmsumd(VR9, VR17, const1); + vpmsumd(VR10, VR18, const1); + vpmsumd(VR11, VR19, const1); + vpmsumd(VR12, VR20, const1); + vpmsumd(VR13, VR21, const1); + vpmsumd(VR14, VR22, const1); + vpmsumd(VR15, VR23, const1); + b(L_second_cool_down); + + BIND(L_barrett_reduction); + + lvx(const1, barretConstants); + addi(barretConstants, barretConstants, 16); + lvx(const2, barretConstants); + + vsldoi(VR1, VR0, VR0, -8); + vxor(VR0, VR0, VR1); // xor two 64 bit results together + + // shift left one bit + vspltisb(VR1, 1); + vsl(VR0, VR0, VR1); + + vand(VR0, VR0, mask_64bit); + + /* + * The reflected version of Barrett reduction. Instead of bit + * reflecting our data (which is expensive to do), we bit reflect our + * constants and our algorithm, which means the intermediate data in + * our vector registers goes from 0-63 instead of 63-0. We can reflect + * the algorithm because we don't carry in mod 2 arithmetic. + */ + vand(VR1, VR0, mask_32bit); // bottom 32 bits of a + vpmsumd(VR1, VR1, const1); // ma + vand(VR1, VR1, mask_32bit); // bottom 32bits of ma + vpmsumd(VR1, VR1, const2); // qn */ + vxor(VR0, VR0, VR1); // a - qn, subtraction is xor in GF(2) + + /* + * Since we are bit reflected, the result (ie the low 32 bits) is in + * the high 32 bits. We just need to shift it left 4 bytes + * V0 [ 0 1 X 3 ] + * V0 [ 0 X 2 3 ] + */ + vsldoi(VR0, VR0, zeroes, 4); // shift result into top 64 bits of + + // Get it into r3 + mfvrd(crc, VR0); + + BIND(L_end); + + offsetInt = 0; + // Restore non-volatile Vector registers (frameless). + offsetInt -= 16; li(offset, -16); lvx(VR20, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR21, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR22, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR23, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR24, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR25, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR26, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR27, offset, R1_SP); + offsetInt -= 16; addi(offset, offset, -16); lvx(VR28, offset, R1_SP); + offsetInt -= 8; ld(R22, offsetInt, R1_SP); + offsetInt -= 8; ld(R23, offsetInt, R1_SP); + offsetInt -= 8; ld(R24, offsetInt, R1_SP); + offsetInt -= 8; ld(R25, offsetInt, R1_SP); + offsetInt -= 8; ld(R26, offsetInt, R1_SP); + offsetInt -= 8; ld(R27, offsetInt, R1_SP); + offsetInt -= 8; ld(R28, offsetInt, R1_SP); + offsetInt -= 8; ld(R29, offsetInt, R1_SP); + offsetInt -= 8; ld(R30, offsetInt, R1_SP); + offsetInt -= 8; ld(R31, offsetInt, R1_SP); +} + void MacroAssembler::kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp) { assert_different_registers(crc, buf, /* len, not used!! */ table, tmp); diff --git a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp index ed846efb580..3e481d84cf9 100644 --- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp @@ -834,6 +834,13 @@ class MacroAssembler: public Assembler { Register tc0, Register tc1, Register tc2, Register tc3); void kernel_crc32_1byte(Register crc, Register buf, Register len, Register table, Register t0, Register t1, Register t2, Register t3); + void kernel_crc32_1word_vpmsumd(Register crc, Register buf, Register len, Register table, + Register constants, Register barretConstants, + Register t0, Register t1, Register t2, Register t3, Register t4); + void kernel_crc32_1word_aligned(Register crc, Register buf, Register len, + Register constants, Register barretConstants, + Register t0, Register t1, Register t2); + void kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp); // diff --git a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp index cf07f2bd5dc..e638c5a6773 100644 --- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -3205,28 +3205,59 @@ class StubGenerator: public StubCodeGenerator { const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call. const Register data = R4_ARG2; // source byte array const Register dataLen = R5_ARG3; // #bytes to process - const Register table = R6_ARG4; // crc table address - const Register t0 = R2; - const Register t1 = R7; - const Register t2 = R8; - const Register t3 = R9; - const Register tc0 = R10; - const Register tc1 = R11; - const Register tc2 = R12; + const Register table = R6; // crc table address - BLOCK_COMMENT("Stub body {"); - assert_different_registers(crc, data, dataLen, table); +#ifdef VM_LITTLE_ENDIAN + if (VM_Version::has_vpmsumb()) { + const Register constants = R2; // constants address + const Register bconstants = R8; // barret table address - StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table); + const Register t0 = R9; + const Register t1 = R10; + const Register t2 = R11; + const Register t3 = R12; + const Register t4 = R7; - __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table); + BLOCK_COMMENT("Stub body {"); + assert_different_registers(crc, data, dataLen, table); - BLOCK_COMMENT("return"); - __ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET). - __ blr(); + StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table); + StubRoutines::ppc64::generate_load_crc_constants_addr(_masm, constants); + StubRoutines::ppc64::generate_load_crc_barret_constants_addr(_masm, bconstants); + + __ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4); + + BLOCK_COMMENT("return"); + __ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET). + __ blr(); + + BLOCK_COMMENT("} Stub body"); + } else +#endif + { + const Register t0 = R2; + const Register t1 = R7; + const Register t2 = R8; + const Register t3 = R9; + const Register tc0 = R10; + const Register tc1 = R11; + const Register tc2 = R12; + + BLOCK_COMMENT("Stub body {"); + assert_different_registers(crc, data, dataLen, table); + + StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table); + + __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table); + + BLOCK_COMMENT("return"); + __ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET). + __ blr(); + + BLOCK_COMMENT("} Stub body"); + } - BLOCK_COMMENT("} Stub body"); return start; } diff --git a/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp b/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp index b04c99cf64e..5b5b2c270dd 100644 --- a/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp @@ -45,6 +45,8 @@ enum platform_dependent_constants { #else #define CRC32_TABLES 1 #endif +#define CRC32_CONSTANTS_SIZE 1084 +#define CRC32_BARRET_CONSTANTS 10 class ppc64 { friend class StubGenerator; @@ -53,11 +55,17 @@ class ppc64 { // CRC32 Intrinsics. static juint _crc_table[CRC32_TABLES][CRC32_COLUMN_SIZE]; + static juint* _constants; + static juint* _barret_constants; public: // CRC32 Intrinsics. static void generate_load_crc_table_addr(MacroAssembler* masm, Register table); + static void generate_load_crc_constants_addr(MacroAssembler* masm, Register table); + static void generate_load_crc_barret_constants_addr(MacroAssembler* masm, Register table); + static juint* generate_crc_constants(); + static juint* generate_crc_barret_constants(); }; diff --git a/hotspot/src/cpu/ppc/vm/stubRoutines_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/stubRoutines_ppc_64.cpp index bed7f40a501..088d63a2f79 100644 --- a/hotspot/src/cpu/ppc/vm/stubRoutines_ppc_64.cpp +++ b/hotspot/src/cpu/ppc/vm/stubRoutines_ppc_64.cpp @@ -37,6 +37,311 @@ void StubRoutines::ppc64::generate_load_crc_table_addr(MacroAssembler* masm, Reg __ load_const_optimized(table, StubRoutines::_crc_table_adr, R0); } +void StubRoutines::ppc64::generate_load_crc_constants_addr(MacroAssembler* masm, Register table) { + __ load_const_optimized(table, (address)StubRoutines::ppc64::_constants, R0); +} + +void StubRoutines::ppc64::generate_load_crc_barret_constants_addr(MacroAssembler* masm, Register table) { + __ load_const_optimized(table, (address)StubRoutines::ppc64::_barret_constants, R0); +} + +juint* StubRoutines::ppc64::generate_crc_constants() { + juint constants[CRC32_CONSTANTS_SIZE] = { + // Reduce 262144 kbits to 1024 bits + 0x99ea94a8UL, 0x00000000UL, 0x651797d2UL, 0x00000001UL, // x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 + 0x945a8420UL, 0x00000000UL, 0x21e0d56cUL, 0x00000000UL, // x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 + 0x30762706UL, 0x00000000UL, 0x0f95ecaaUL, 0x00000000UL, // x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 + 0xa52fc582UL, 0x00000001UL, 0xebd224acUL, 0x00000001UL, // x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 + 0xa4a7167aUL, 0x00000001UL, 0x0ccb97caUL, 0x00000000UL, // x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 + 0x0c18249aUL, 0x00000000UL, 0x006ec8a8UL, 0x00000001UL, // x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 + 0xa924ae7cUL, 0x00000000UL, 0x4f58f196UL, 0x00000001UL, // x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 + 0xe12ccc12UL, 0x00000001UL, 0xa7192ca6UL, 0x00000001UL, // x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 + 0xa0b9d4acUL, 0x00000000UL, 0x9a64bab2UL, 0x00000001UL, // x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 + 0x95e8ddfeUL, 0x00000000UL, 0x14f4ed2eUL, 0x00000000UL, // x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 + 0x233fddc4UL, 0x00000000UL, 0x1092b6a2UL, 0x00000001UL, // x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 + 0xb4529b62UL, 0x00000001UL, 0xc8a1629cUL, 0x00000000UL, // x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 + 0xa7fa0e64UL, 0x00000001UL, 0x7bf32e8eUL, 0x00000001UL, // x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 + 0xb5334592UL, 0x00000001UL, 0xf8cc6582UL, 0x00000001UL, // x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 + 0x1f8ee1b4UL, 0x00000001UL, 0x8631ddf0UL, 0x00000000UL, // x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 + 0x6252e632UL, 0x00000000UL, 0x7e5a76d0UL, 0x00000000UL, // x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 + 0xab973e84UL, 0x00000000UL, 0x2b09b31cUL, 0x00000000UL, // x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 + 0x7734f5ecUL, 0x00000000UL, 0xb2df1f84UL, 0x00000001UL, // x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 + 0x7c547798UL, 0x00000000UL, 0xd6f56afcUL, 0x00000001UL, // x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 + 0x7ec40210UL, 0x00000000UL, 0xb9b5e70cUL, 0x00000001UL, // x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 + 0xab1695a8UL, 0x00000001UL, 0x34b626d2UL, 0x00000000UL, // x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 + 0x90494bbaUL, 0x00000000UL, 0x4c53479aUL, 0x00000001UL, // x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 + 0x123fb816UL, 0x00000001UL, 0xa6d179a4UL, 0x00000001UL, // x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 + 0xe188c74cUL, 0x00000001UL, 0x5abd16b4UL, 0x00000001UL, // x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 + 0xc2d3451cUL, 0x00000001UL, 0x018f9852UL, 0x00000000UL, // x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 + 0xf55cf1caUL, 0x00000000UL, 0x1fb3084aUL, 0x00000000UL, // x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 + 0xa0531540UL, 0x00000001UL, 0xc53dfb04UL, 0x00000000UL, // x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 + 0x32cd7ebcUL, 0x00000001UL, 0xe10c9ad6UL, 0x00000000UL, // x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 + 0x73ab7f36UL, 0x00000000UL, 0x25aa994aUL, 0x00000000UL, // x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 + 0x41aed1c2UL, 0x00000000UL, 0xfa3a74c4UL, 0x00000000UL, // x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 + 0x36c53800UL, 0x00000001UL, 0x33eb3f40UL, 0x00000000UL, // x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 + 0x26835a30UL, 0x00000001UL, 0x7193f296UL, 0x00000001UL, // x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 + 0x6241b502UL, 0x00000000UL, 0x43f6c86aUL, 0x00000000UL, // x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 + 0xd5196ad4UL, 0x00000000UL, 0x6b513ec6UL, 0x00000001UL, // x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 + 0x9cfa769aUL, 0x00000000UL, 0xc8f25b4eUL, 0x00000000UL, // x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 + 0x920e5df4UL, 0x00000000UL, 0xa45048ecUL, 0x00000001UL, // x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 + 0x69dc310eUL, 0x00000001UL, 0x0c441004UL, 0x00000000UL, // x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 + 0x09fc331cUL, 0x00000000UL, 0x0e17cad6UL, 0x00000000UL, // x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 + 0x0d94a81eUL, 0x00000001UL, 0x253ae964UL, 0x00000001UL, // x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 + 0x27a20ab2UL, 0x00000000UL, 0xd7c88ebcUL, 0x00000001UL, // x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 + 0x14f87504UL, 0x00000001UL, 0xe7ca913aUL, 0x00000001UL, // x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 + 0x4b076d96UL, 0x00000000UL, 0x33ed078aUL, 0x00000000UL, // x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 + 0xda4d1e74UL, 0x00000000UL, 0xe1839c78UL, 0x00000000UL, // x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 + 0x1b81f672UL, 0x00000000UL, 0x322b267eUL, 0x00000001UL, // x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 + 0x9367c988UL, 0x00000000UL, 0x638231b6UL, 0x00000000UL, // x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 + 0x717214caUL, 0x00000001UL, 0xee7f16f4UL, 0x00000001UL, // x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 + 0x9f47d820UL, 0x00000000UL, 0x17d9924aUL, 0x00000001UL, // x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 + 0x0d9a47d2UL, 0x00000001UL, 0xe1a9e0c4UL, 0x00000000UL, // x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 + 0xa696c58cUL, 0x00000000UL, 0x403731dcUL, 0x00000001UL, // x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 + 0x2aa28ec6UL, 0x00000000UL, 0xa5ea9682UL, 0x00000001UL, // x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 + 0xfe18fd9aUL, 0x00000001UL, 0x01c5c578UL, 0x00000001UL, // x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 + 0x9d4fc1aeUL, 0x00000001UL, 0xdddf6494UL, 0x00000000UL, // x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 + 0xba0e3deaUL, 0x00000001UL, 0xf1c3db28UL, 0x00000000UL, // x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 + 0x74b59a5eUL, 0x00000000UL, 0x3112fb9cUL, 0x00000001UL, // x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 + 0xf2b5ea98UL, 0x00000000UL, 0xb680b906UL, 0x00000000UL, // x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 + 0x87132676UL, 0x00000001UL, 0x1a282932UL, 0x00000000UL, // x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 + 0x0a8c6ad4UL, 0x00000001UL, 0x89406e7eUL, 0x00000000UL, // x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 + 0xe21dfe70UL, 0x00000001UL, 0xdef6be8cUL, 0x00000001UL, // x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 + 0xda0050e4UL, 0x00000001UL, 0x75258728UL, 0x00000000UL, // x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 + 0x772172aeUL, 0x00000000UL, 0x9536090aUL, 0x00000001UL, // x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 + 0xe47724aaUL, 0x00000000UL, 0xf2455bfcUL, 0x00000000UL, // x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 + 0x3cd63ac4UL, 0x00000000UL, 0x8c40baf4UL, 0x00000001UL, // x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 + 0xbf47d352UL, 0x00000001UL, 0x4cd390d4UL, 0x00000000UL, // x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 + 0x8dc1d708UL, 0x00000001UL, 0xe4ece95aUL, 0x00000001UL, // x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 + 0x2d4620a4UL, 0x00000000UL, 0x1a3ee918UL, 0x00000000UL, // x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 + 0x58fd1740UL, 0x00000000UL, 0x7c652fb8UL, 0x00000000UL, // x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 + 0xdadd9bfcUL, 0x00000000UL, 0x1c67842cUL, 0x00000001UL, // x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 + 0xea2140beUL, 0x00000001UL, 0x254f759cUL, 0x00000000UL, // x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 + 0x9de128baUL, 0x00000000UL, 0x7ece94caUL, 0x00000000UL, // x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 + 0x3ac3aa8eUL, 0x00000001UL, 0x38f258c2UL, 0x00000000UL, // x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 + 0x99980562UL, 0x00000000UL, 0xcdf17b00UL, 0x00000001UL, // x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 + 0xc1579c86UL, 0x00000001UL, 0x1f882c16UL, 0x00000001UL, // x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 + 0x68dbbf94UL, 0x00000000UL, 0x00093fc8UL, 0x00000001UL, // x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 + 0x4509fb04UL, 0x00000000UL, 0xcd684f16UL, 0x00000001UL, // x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 + 0x202f6398UL, 0x00000001UL, 0x4bc6a70aUL, 0x00000000UL, // x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 + 0x3aea243eUL, 0x00000001UL, 0x4fc7e8e4UL, 0x00000000UL, // x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 + 0xb4052ae6UL, 0x00000001UL, 0x30103f1cUL, 0x00000001UL, // x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 + 0xcd2a0ae8UL, 0x00000001UL, 0x11b0024cUL, 0x00000001UL, // x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 + 0xfe4aa8b4UL, 0x00000001UL, 0x0b3079daUL, 0x00000001UL, // x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 + 0xd1559a42UL, 0x00000001UL, 0x0192bcc2UL, 0x00000001UL, // x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 + 0xf3e05eccUL, 0x00000001UL, 0x74838d50UL, 0x00000000UL, // x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 + 0x04ddd2ccUL, 0x00000001UL, 0x1b20f520UL, 0x00000000UL, // x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 + 0x5393153cUL, 0x00000001UL, 0x50c3590aUL, 0x00000000UL, // x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 + 0x57e942c6UL, 0x00000000UL, 0xb41cac8eUL, 0x00000000UL, // x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 + 0x2c633850UL, 0x00000001UL, 0x0c72cc78UL, 0x00000000UL, // x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 + 0xebcaae4cUL, 0x00000000UL, 0x30cdb032UL, 0x00000000UL, // x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 + 0x3ee532a6UL, 0x00000001UL, 0x3e09fc32UL, 0x00000001UL, // x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 + 0xbf0cbc7eUL, 0x00000001UL, 0x1ed624d2UL, 0x00000000UL, // x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 + 0xd50b7a5aUL, 0x00000000UL, 0x781aee1aUL, 0x00000000UL, // x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 + 0x02fca6e8UL, 0x00000000UL, 0xc4d8348cUL, 0x00000001UL, // x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 + 0x7af40044UL, 0x00000000UL, 0x57a40336UL, 0x00000000UL, // x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 + 0x16178744UL, 0x00000000UL, 0x85544940UL, 0x00000000UL, // x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 + 0x4c177458UL, 0x00000001UL, 0x9cd21e80UL, 0x00000001UL, // x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 + 0x1b6ddf04UL, 0x00000001UL, 0x3eb95bc0UL, 0x00000001UL, // x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 + 0xf3e29cccUL, 0x00000001UL, 0xdfc9fdfcUL, 0x00000001UL, // x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 + 0x35ae7562UL, 0x00000001UL, 0xcd028bc2UL, 0x00000000UL, // x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 + 0x90ef812cUL, 0x00000001UL, 0x90db8c44UL, 0x00000000UL, // x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 + 0x67a2c786UL, 0x00000000UL, 0x0010a4ceUL, 0x00000001UL, // x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 + 0x48b9496cUL, 0x00000000UL, 0xc8f4c72cUL, 0x00000001UL, // x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 + 0x5a422de6UL, 0x00000001UL, 0x1c26170cUL, 0x00000000UL, // x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 + 0xef0e3640UL, 0x00000001UL, 0xe3fccf68UL, 0x00000000UL, // x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 + 0x006d2d26UL, 0x00000001UL, 0xd513ed24UL, 0x00000000UL, // x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 + 0x170d56d6UL, 0x00000001UL, 0x141beadaUL, 0x00000000UL, // x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 + 0xa5fb613cUL, 0x00000000UL, 0x1071aea0UL, 0x00000001UL, // x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 + 0x40bbf7fcUL, 0x00000000UL, 0x2e19080aUL, 0x00000001UL, // x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 + 0x6ac3a5b2UL, 0x00000001UL, 0x00ecf826UL, 0x00000001UL, // x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 + 0xabf16230UL, 0x00000000UL, 0x69b09412UL, 0x00000000UL, // x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 + 0xebe23facUL, 0x00000001UL, 0x22297bacUL, 0x00000001UL, // x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 + 0x8b6a0894UL, 0x00000000UL, 0xe9e4b068UL, 0x00000000UL, // x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 + 0x288ea478UL, 0x00000001UL, 0x4b38651aUL, 0x00000000UL, // x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 + 0x6619c442UL, 0x00000001UL, 0x468360e2UL, 0x00000001UL, // x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 + 0x86230038UL, 0x00000000UL, 0x121c2408UL, 0x00000000UL, // x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 + 0x7746a756UL, 0x00000001UL, 0xda7e7d08UL, 0x00000000UL, // x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 + 0x91b8f8f8UL, 0x00000001UL, 0x058d7652UL, 0x00000001UL, // x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 + 0x8e167708UL, 0x00000000UL, 0x4a098a90UL, 0x00000001UL, // x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 + 0x48b22d54UL, 0x00000001UL, 0x20dbe72eUL, 0x00000000UL, // x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 + 0x44ba2c3cUL, 0x00000000UL, 0x1e7323e8UL, 0x00000001UL, // x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 + 0xb54d2b52UL, 0x00000000UL, 0xd5d4bf94UL, 0x00000000UL, // x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 + 0x05a4fd8aUL, 0x00000000UL, 0x99d8746cUL, 0x00000001UL, // x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 + 0x39f9fc46UL, 0x00000001UL, 0xce9ca8a0UL, 0x00000000UL, // x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 + 0x5a1fa824UL, 0x00000001UL, 0x136edeceUL, 0x00000000UL, // x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 + 0x0a61ae4cUL, 0x00000000UL, 0x9b92a068UL, 0x00000001UL, // x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 + 0x45e9113eUL, 0x00000001UL, 0x71d62206UL, 0x00000000UL, // x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 + 0x6a348448UL, 0x00000000UL, 0xdfc50158UL, 0x00000000UL, // x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 + 0x4d80a08cUL, 0x00000000UL, 0x517626bcUL, 0x00000001UL, // x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 + 0x4b6837a0UL, 0x00000001UL, 0x48d1e4faUL, 0x00000001UL, // x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 + 0x6896a7fcUL, 0x00000001UL, 0x94d8266eUL, 0x00000000UL, // x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 + 0x4f187140UL, 0x00000001UL, 0x606c5e34UL, 0x00000000UL, // x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 + 0x9581b9daUL, 0x00000001UL, 0x9766beaaUL, 0x00000001UL, // x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 + 0x091bc984UL, 0x00000001UL, 0xd80c506cUL, 0x00000001UL, // x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 + 0x1067223cUL, 0x00000000UL, 0x1e73837cUL, 0x00000000UL, // x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 + 0xab16ea02UL, 0x00000001UL, 0x64d587deUL, 0x00000000UL, // x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 + 0x3c4598a8UL, 0x00000001UL, 0xf4a507b0UL, 0x00000000UL, // x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 + 0xb3735430UL, 0x00000000UL, 0x40e342fcUL, 0x00000000UL, // x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 + 0xbb3fc0c0UL, 0x00000001UL, 0xd5ad9c3aUL, 0x00000001UL, // x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 + 0x570ae19cUL, 0x00000001UL, 0x94a691a4UL, 0x00000000UL, // x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 + 0xea910712UL, 0x00000001UL, 0x271ecdfaUL, 0x00000001UL, // x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 + 0x67127128UL, 0x00000001UL, 0x9e54475aUL, 0x00000000UL, // x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 + 0x19e790a2UL, 0x00000000UL, 0xc9c099eeUL, 0x00000000UL, // x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 + 0x3788f710UL, 0x00000000UL, 0x9a2f736cUL, 0x00000000UL, // x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 + 0x682a160eUL, 0x00000001UL, 0xbb9f4996UL, 0x00000000UL, // x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 + 0x7f0ebd2eUL, 0x00000000UL, 0xdb688050UL, 0x00000001UL, // x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 + 0x2b032080UL, 0x00000000UL, 0xe9b10af4UL, 0x00000000UL, // x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 + 0xcfd1664aUL, 0x00000000UL, 0x2d4545e4UL, 0x00000001UL, // x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 + 0xaa1181c2UL, 0x00000000UL, 0x0361139cUL, 0x00000000UL, // x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 + 0xddd08002UL, 0x00000000UL, 0xa5a1a3a8UL, 0x00000001UL, // x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 + 0xe8dd0446UL, 0x00000000UL, 0x6844e0b0UL, 0x00000000UL, // x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 + 0xbbd94a00UL, 0x00000001UL, 0xc3762f28UL, 0x00000000UL, // x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 + 0xab6cd180UL, 0x00000000UL, 0xd26287a2UL, 0x00000001UL, // x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 + 0x31803ce2UL, 0x00000000UL, 0xf6f0bba8UL, 0x00000001UL, // x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 + 0x24f40b0cUL, 0x00000000UL, 0x2ffabd62UL, 0x00000000UL, // x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 + 0xba1d9834UL, 0x00000001UL, 0xfb4516b8UL, 0x00000000UL, // x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 + 0x04de61aaUL, 0x00000001UL, 0x8cfa961cUL, 0x00000001UL, // x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 + 0x13e40d46UL, 0x00000001UL, 0x9e588d52UL, 0x00000001UL, // x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 + 0x415598a0UL, 0x00000001UL, 0x180f0bbcUL, 0x00000001UL, // x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 + 0xbf6c8c90UL, 0x00000000UL, 0xe1d9177aUL, 0x00000000UL, // x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 + 0x788b0504UL, 0x00000001UL, 0x05abc27cUL, 0x00000001UL, // x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 + 0x38385d02UL, 0x00000000UL, 0x972e4a58UL, 0x00000000UL, // x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 + 0xb6c83844UL, 0x00000001UL, 0x83499a5eUL, 0x00000001UL, // x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 + 0x51061a8aUL, 0x00000000UL, 0xc96a8ccaUL, 0x00000001UL, // x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 + 0x7351388aUL, 0x00000001UL, 0xa1a5b60cUL, 0x00000001UL, // x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 + 0x32928f92UL, 0x00000001UL, 0xe4b6ac9cUL, 0x00000000UL, // x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 + 0xe6b4f48aUL, 0x00000000UL, 0x807e7f5aUL, 0x00000001UL, // x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 + 0x39d15e90UL, 0x00000000UL, 0x7a7e3bc8UL, 0x00000001UL, // x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 + 0x312d6074UL, 0x00000000UL, 0xd73975daUL, 0x00000000UL, // x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 + 0x7bbb2cc4UL, 0x00000001UL, 0x7375d038UL, 0x00000001UL, // x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 + 0x6ded3e18UL, 0x00000001UL, 0x193680bcUL, 0x00000000UL, // x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 + 0xf1638b16UL, 0x00000000UL, 0x999b06f6UL, 0x00000000UL, // x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 + 0xd38b9eccUL, 0x00000001UL, 0xf685d2b8UL, 0x00000001UL, // x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 + 0x8b8d09dcUL, 0x00000001UL, 0xf4ecbed2UL, 0x00000001UL, // x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 + 0xe7bc27d2UL, 0x00000000UL, 0xba16f1a0UL, 0x00000000UL, // x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 + 0x275e1e96UL, 0x00000000UL, 0x15aceac4UL, 0x00000001UL, // x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 + 0xe2e3031eUL, 0x00000000UL, 0xaeff6292UL, 0x00000001UL, // x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 + 0x041c84d8UL, 0x00000001UL, 0x9640124cUL, 0x00000000UL, // x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 + 0x706ce672UL, 0x00000000UL, 0x14f41f02UL, 0x00000001UL, // x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 + 0x5d5070daUL, 0x00000001UL, 0x9c5f3586UL, 0x00000000UL, // x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 + 0x38f9493aUL, 0x00000000UL, 0x878275faUL, 0x00000001UL, // x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 + 0xa3348a76UL, 0x00000000UL, 0xddc42ce8UL, 0x00000000UL, // x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 + 0xad0aab92UL, 0x00000001UL, 0x81d2c73aUL, 0x00000001UL, // x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 + 0x9e85f712UL, 0x00000001UL, 0x41c9320aUL, 0x00000001UL, // x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 + 0x5a871e76UL, 0x00000000UL, 0x5235719aUL, 0x00000001UL, // x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 + 0x7249c662UL, 0x00000001UL, 0xbe27d804UL, 0x00000000UL, // x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 + 0x3a084712UL, 0x00000000UL, 0x6242d45aUL, 0x00000000UL, // x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 + 0xed438478UL, 0x00000000UL, 0x9a53638eUL, 0x00000000UL, // x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 + 0xabac34ccUL, 0x00000000UL, 0x001ecfb6UL, 0x00000001UL, // x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 + 0x5f35ef3eUL, 0x00000000UL, 0x6d7c2d64UL, 0x00000001UL, // x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 + 0x47d6608cUL, 0x00000000UL, 0xd0ce46c0UL, 0x00000001UL, // x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 + 0x2d01470eUL, 0x00000000UL, 0x24c907b4UL, 0x00000001UL, // x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 + 0x58bbc7b0UL, 0x00000001UL, 0x18a555caUL, 0x00000000UL, // x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 + 0xc0a23e8eUL, 0x00000000UL, 0x6b0980bcUL, 0x00000000UL, // x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 + 0xebd85c88UL, 0x00000001UL, 0x8bbba964UL, 0x00000000UL, // x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 + 0x9ee20bb2UL, 0x00000001UL, 0x070a5a1eUL, 0x00000001UL, // x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 + 0xacabf2d6UL, 0x00000001UL, 0x2204322aUL, 0x00000000UL, // x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 + 0xb7963d56UL, 0x00000001UL, 0xa27524d0UL, 0x00000000UL, // x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 + 0x7bffa1feUL, 0x00000001UL, 0x20b1e4baUL, 0x00000000UL, // x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 + 0x1f15333eUL, 0x00000000UL, 0x32cc27fcUL, 0x00000000UL, // x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 + 0x8593129eUL, 0x00000001UL, 0x44dd22b8UL, 0x00000000UL, // x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 + 0x9cb32602UL, 0x00000001UL, 0xdffc9e0aUL, 0x00000000UL, // x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 + 0x42b05cc8UL, 0x00000001UL, 0xb7a0ed14UL, 0x00000001UL, // x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 + 0xbe49e7a4UL, 0x00000001UL, 0xc7842488UL, 0x00000000UL, // x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 + 0x08f69d6cUL, 0x00000001UL, 0xc02a4feeUL, 0x00000001UL, // x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 + 0x6c0971f0UL, 0x00000000UL, 0x3c273778UL, 0x00000000UL, // x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 + 0x5b16467aUL, 0x00000000UL, 0xd63f8894UL, 0x00000001UL, // x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 + 0x551a628eUL, 0x00000001UL, 0x6be557d6UL, 0x00000000UL, // x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 + 0x9e42ea92UL, 0x00000001UL, 0x6a7806eaUL, 0x00000000UL, // x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 + 0x2fa83ff2UL, 0x00000001UL, 0x6155aa0cUL, 0x00000001UL, // x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 + 0x1ca9cde0UL, 0x00000001UL, 0x908650acUL, 0x00000000UL, // x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 + 0xc8e5cd74UL, 0x00000000UL, 0xaa5a8084UL, 0x00000000UL, // x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 + 0x96c27f0cUL, 0x00000000UL, 0x91bb500aUL, 0x00000001UL, // x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 + 0x2baed926UL, 0x00000000UL, 0x64e9bed0UL, 0x00000000UL, // x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 + 0x7c8de8d2UL, 0x00000001UL, 0x9444f302UL, 0x00000000UL, // x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 + 0xd43d6068UL, 0x00000000UL, 0x9db07d3cUL, 0x00000001UL, // x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 + 0xcb2c4b26UL, 0x00000000UL, 0x359e3e6eUL, 0x00000001UL, // x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 + 0x45b8da26UL, 0x00000001UL, 0xe4f10dd2UL, 0x00000001UL, // x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 + 0x8fff4b08UL, 0x00000001UL, 0x24f5735eUL, 0x00000001UL, // x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 + 0x50b58ed0UL, 0x00000001UL, 0x24760a4cUL, 0x00000001UL, // x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 + 0x549f39bcUL, 0x00000001UL, 0x0f1fc186UL, 0x00000000UL, // x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 + 0xef4d2f42UL, 0x00000000UL, 0x150e4cc4UL, 0x00000000UL, // x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 + 0xb1468572UL, 0x00000001UL, 0x2a6204e8UL, 0x00000000UL, // x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 + 0x3d7403b2UL, 0x00000001UL, 0xbeb1d432UL, 0x00000000UL, // x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 + 0xa4681842UL, 0x00000001UL, 0x35f3f1f0UL, 0x00000001UL, // x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 + 0x67714492UL, 0x00000001UL, 0x74fe2232UL, 0x00000000UL, // x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 + 0xe599099aUL, 0x00000001UL, 0x1ac6e2baUL, 0x00000000UL, // x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 + 0xfe128194UL, 0x00000000UL, 0x13fca91eUL, 0x00000000UL, // x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 + 0x77e8b990UL, 0x00000000UL, 0x83f4931eUL, 0x00000001UL, // x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 + 0xa267f63aUL, 0x00000001UL, 0xb6d9b4e4UL, 0x00000000UL, // x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 + 0x945c245aUL, 0x00000001UL, 0xb5188656UL, 0x00000000UL, // x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 + 0x49002e76UL, 0x00000001UL, 0x27a81a84UL, 0x00000000UL, // x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 + 0xbb8310a4UL, 0x00000001UL, 0x25699258UL, 0x00000001UL, // x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 + 0x9ec60bccUL, 0x00000001UL, 0xb23de796UL, 0x00000001UL, // x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 + 0x2d8590aeUL, 0x00000001UL, 0xfe4365dcUL, 0x00000000UL, // x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 + 0x65b00684UL, 0x00000000UL, 0xc68f497aUL, 0x00000000UL, // x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 + 0x5e5aeadcUL, 0x00000001UL, 0xfbf521eeUL, 0x00000000UL, // x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 + 0xb77ff2b0UL, 0x00000000UL, 0x5eac3378UL, 0x00000001UL, // x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 + 0x88da2ff6UL, 0x00000001UL, 0x34914b90UL, 0x00000001UL, // x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 + 0x63da929aUL, 0x00000000UL, 0x16335cfeUL, 0x00000000UL, // x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 + 0x389caa80UL, 0x00000001UL, 0x0372d10cUL, 0x00000001UL, // x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 + 0x3db599d2UL, 0x00000001UL, 0x5097b908UL, 0x00000001UL, // x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 + 0x22505a86UL, 0x00000001UL, 0x227a7572UL, 0x00000001UL, // x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 + 0x6bd72746UL, 0x00000001UL, 0x9a8f75c0UL, 0x00000000UL, // x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 + 0xc3faf1d4UL, 0x00000001UL, 0x682c77a2UL, 0x00000000UL, // x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 + 0x111c826cUL, 0x00000001UL, 0x231f091cUL, 0x00000000UL, // x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 + 0x153e9fb2UL, 0x00000000UL, 0x7d4439f2UL, 0x00000000UL, // x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 + 0x2b1f7b60UL, 0x00000000UL, 0x7e221efcUL, 0x00000001UL, // x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 + 0xb1dba570UL, 0x00000000UL, 0x67457c38UL, 0x00000001UL, // x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 + 0xf6397b76UL, 0x00000001UL, 0xbdf081c4UL, 0x00000000UL, // x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 + 0x56335214UL, 0x00000001UL, 0x6286d6b0UL, 0x00000001UL, // x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 + 0xd70e3986UL, 0x00000001UL, 0xc84f001cUL, 0x00000000UL, // x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 + 0x3701a774UL, 0x00000000UL, 0x64efe7c0UL, 0x00000000UL, // x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 + 0xac81ef72UL, 0x00000000UL, 0x0ac2d904UL, 0x00000000UL, // x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 + 0x33212464UL, 0x00000001UL, 0xfd226d14UL, 0x00000000UL, // x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 + 0xe4e45610UL, 0x00000000UL, 0x1cfd42e0UL, 0x00000001UL, // x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 + 0x0c1bd370UL, 0x00000000UL, 0x6e5a5678UL, 0x00000001UL, // x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 + 0xa7b9e7a6UL, 0x00000001UL, 0xd888fe22UL, 0x00000001UL, // x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 + 0x7d657a10UL, 0x00000000UL, 0xaf77fcd4UL, 0x00000001UL, // x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 + + // Reduce final 1024-2048 bits to 64 bits, shifting 32 bits to include the trailing 32 bits of zeros + 0xec447f11UL, 0x99168a18UL, 0x13e8221eUL, 0xed837b26UL, // x^2048 mod p(x)`, x^2016 mod p(x)`, x^1984 mod p(x)`, x^1952 mod p(x)` + 0x8fd2cd3cUL, 0xe23e954eUL, 0x47b9ce5aUL, 0xc8acdd81UL, // x^1920 mod p(x)`, x^1888 mod p(x)`, x^1856 mod p(x)`, x^1824 mod p(x)` + 0x6b1d2b53UL, 0x92f8befeUL, 0xd4277e25UL, 0xd9ad6d87UL, // x^1792 mod p(x)`, x^1760 mod p(x)`, x^1728 mod p(x)`, x^1696 mod p(x)` + 0x291ea462UL, 0xf38a3556UL, 0x33fbca3bUL, 0xc10ec5e0UL, // x^1664 mod p(x)`, x^1632 mod p(x)`, x^1600 mod p(x)`, x^1568 mod p(x)` + 0x62b6ca4bUL, 0x974ac562UL, 0x82e02e2fUL, 0xc0b55b0eUL, // x^1536 mod p(x)`, x^1504 mod p(x)`, x^1472 mod p(x)`, x^1440 mod p(x)` + 0x784d2a56UL, 0x855712b3UL, 0xe172334dUL, 0x71aa1df0UL, // x^1408 mod p(x)`, x^1376 mod p(x)`, x^1344 mod p(x)`, x^1312 mod p(x)` + 0x0eaee722UL, 0xa5abe9f8UL, 0x3969324dUL, 0xfee3053eUL, // x^1280 mod p(x)`, x^1248 mod p(x)`, x^1216 mod p(x)`, x^1184 mod p(x)` + 0xdb54814cUL, 0x1fa0943dUL, 0x3eb2bd08UL, 0xf44779b9UL, // x^1152 mod p(x)`, x^1120 mod p(x)`, x^1088 mod p(x)`, x^1056 mod p(x)` + 0xd7bbfe6aUL, 0xa53ff440UL, 0x00cc3374UL, 0xf5449b3fUL, // x^1024 mod p(x)`, x^992 mod p(x)`, x^960 mod p(x)`, x^928 mod p(x)` + 0x6325605cUL, 0xebe7e356UL, 0xd777606eUL, 0x6f8346e1UL, // x^896 mod p(x)`, x^864 mod p(x)`, x^832 mod p(x)`, x^800 mod p(x)` + 0xe5b592b8UL, 0xc65a272cUL, 0xc0b95347UL, 0xe3ab4f2aUL, // x^768 mod p(x)`, x^736 mod p(x)`, x^704 mod p(x)`, x^672 mod p(x)` + 0x4721589fUL, 0x5705a9caUL, 0x329ecc11UL, 0xaa2215eaUL, // x^640 mod p(x)`, x^608 mod p(x)`, x^576 mod p(x)`, x^544 mod p(x)` + 0x88d14467UL, 0xe3720acbUL, 0xd95efd26UL, 0x1ed8f66eUL, // x^512 mod p(x)`, x^480 mod p(x)`, x^448 mod p(x)`, x^416 mod p(x)` + 0x15141c31UL, 0xba1aca03UL, 0xa700e96aUL, 0x78ed02d5UL, // x^384 mod p(x)`, x^352 mod p(x)`, x^320 mod p(x)`, x^288 mod p(x)` + 0xed627daeUL, 0xad2a31b3UL, 0x32b39da3UL, 0xba8ccbe8UL, // x^256 mod p(x)`, x^224 mod p(x)`, x^192 mod p(x)`, x^160 mod p(x)` + 0xa06a2517UL, 0x6655004fUL, 0xb1e6b092UL, 0xedb88320UL // x^128 mod p(x)`, x^96 mod p(x)`, x^64 mod p(x)`, x^32 mod p(x)` + }; + + juint* ptr = (juint*) malloc(sizeof(juint) * CRC32_CONSTANTS_SIZE); + guarantee(((intptr_t)ptr & 0xF) == 0, "16-byte alignment needed"); + guarantee(ptr != NULL, "allocation error of a crc table"); + memcpy((void*)ptr, constants, sizeof(juint) * CRC32_CONSTANTS_SIZE); + return ptr; +} + +juint* StubRoutines::ppc64::generate_crc_barret_constants() { + juint barret_constants[CRC32_BARRET_CONSTANTS] = { + 0xf7011641UL, 0x00000001UL, 0x00000000UL, 0x00000000UL, + 0xdb710641UL, 0x00000001UL, 0x00000000UL, 0x00000000UL + }; + juint* ptr = (juint*) malloc(sizeof(juint) * CRC32_CONSTANTS_SIZE); + guarantee(((intptr_t)ptr & 0xF) == 0, "16-byte alignment needed"); + guarantee(ptr != NULL, "allocation error of a crc table"); + memcpy((void*) ptr, barret_constants, sizeof(juint) * CRC32_BARRET_CONSTANTS); + return ptr; +} + // CRC32 Intrinsics. /** * crc_table[] from jdk/src/share/native/java/util/zip/zlib-1.2.8/crc32.h @@ -477,3 +782,7 @@ juint StubRoutines::ppc64::_crc_table[CRC32_TABLES][CRC32_COLUMN_SIZE] = { #endif } }; + +juint* StubRoutines::ppc64::_constants = StubRoutines::ppc64::generate_crc_constants(); + +juint* StubRoutines::ppc64::_barret_constants = StubRoutines::ppc64::generate_crc_barret_constants(); From 8474269d183b0b6e1840374abf8783fca5c1b138 Mon Sep 17 00:00:00 2001 From: Pavel Punegov Date: Wed, 17 Aug 2016 18:48:34 +0300 Subject: [PATCH 015/207] 8156852: Convert JSON_test to Gtest Convert test from InternalVMTests to Gtest Reviewed-by: kvn, kzhaldyb --- .../share/vm/utilities/internalVMTests.cpp | 1 - hotspot/src/share/vm/utilities/json.cpp | 285 +--------- hotspot/test/native/utilities/test_json.cpp | 515 ++++++++++++++++++ 3 files changed, 516 insertions(+), 285 deletions(-) create mode 100644 hotspot/test/native/utilities/test_json.cpp diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 76087d52bfe..fecd4855687 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -64,7 +64,6 @@ void InternalVMTests::run() { run_unit_test(ObjectMonitor_test); run_unit_test(Test_linked_list); run_unit_test(TestChunkedList_test); - run_unit_test(JSON_test); run_unit_test(Test_log_tag_combinations_limit); run_unit_test(Test_logtarget); run_unit_test(Test_logstream); diff --git a/hotspot/src/share/vm/utilities/json.cpp b/hotspot/src/share/vm/utilities/json.cpp index cb3bf391006..dca08325a05 100644 --- a/hotspot/src/share/vm/utilities/json.cpp +++ b/hotspot/src/share/vm/utilities/json.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -686,286 +686,3 @@ void JSON::error(JSON_ERROR e, const char* format, ...) { } } -#ifndef PRODUCT -class JSONTest : public JSON { - public: - static void test(); - - private: - JSONTest(const char* text); - static void test(const char* json, bool valid); - - void log(uint level, const char* format, ...) ATTRIBUTE_PRINTF(3, 4); - - bool callback(JSON_TYPE t, JSON_VAL* v, uint level); - JSON_TYPE prev; -}; - -void JSON_test() { - JSONTest::test(); -} - -void JSONTest::test(const char* text, bool should_pass) { - JSONTest json(text); - if (should_pass) { - assert(json.valid() == true, "failed on a valid json string"); - if (VerboseInternalVMTests) { - tty->print_cr("-- json test passed as expected --"); - } - } else { - assert(json.valid() == false, "succeeded on an invalid json string"); - if (VerboseInternalVMTests) { - tty->print_cr("-- json test failed as expected --"); - } - } -} - -JSONTest::JSONTest(const char* text) : JSON(text, !VerboseInternalVMTests, tty) { - prev = JSON_NONE; - parse(); -} - -void JSONTest::test() { - JSONTest::test("{}", true); - JSONTest::test("[]", true); - JSONTest::test(" { } ", true); - JSONTest::test(" [ ] ", true); - - JSONTest::test("\"error\"", false); - JSONTest::test("error", false); - JSONTest::test("1", false); - JSONTest::test("1.2", false); - JSONTest::test("true", false); - JSONTest::test("false", false); - JSONTest::test("null", false); - - JSONTest::test("[ 1 ]", true); - JSONTest::test("[ 1, ]", true); - JSONTest::test("[ true ]", true); - JSONTest::test("[ true, ]", true); - JSONTest::test("[ false ]", true); - JSONTest::test("[ false, ]", true); - JSONTest::test("[ null ]", true); - JSONTest::test("[ null, ]", true); - JSONTest::test("[ \"\" ]", true); - JSONTest::test("[ \"\", ]", true); - JSONTest::test("[ \"elem1\" ]", true); - JSONTest::test("[ \"elem1\", ]", true); - JSONTest::test("[ \"elem1\", ]", true); - JSONTest::test("[ \"elem1\" ]", true); - JSONTest::test("[ \"elem1\", \"elem2\" ]", true); - JSONTest::test("[ \"elem1\", \"elem2\", ]", true); - - - JSONTest::test("[ \"elem1\" ] { }", false); - JSONTest::test("[ elem1, \"elem2\" ]", false); - JSONTest::test("[ \"elem1\"", false); - JSONTest::test("[ \"elem1 ]", false); - JSONTest::test("[ \"elem1\", \"elem2\"", false); - JSONTest::test("[ truefoo ]", false); - JSONTest::test("[ falsefoo ]", false); - JSONTest::test("[ nullfoo ]", false); - - JSONTest::test("{ key : 1 }", true); - JSONTest::test("{ key : 1, }", true); - JSONTest::test("{ key : true }", true); - JSONTest::test("{ key : true, }", true); - JSONTest::test("{ key : false }", true); - JSONTest::test("{ key : false, }", true); - JSONTest::test("{ key : null }", true); - JSONTest::test("{ key : null, }", true); - JSONTest::test("{ \"\" : \"\" }", true); - JSONTest::test("{ \"\" : \"\", }", true); - JSONTest::test("{ \"key1\" : \"val1\" }", true); - JSONTest::test("{ \"key1\" : \"val1\", }", true); - JSONTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\" }", true); - JSONTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\", }", true); - - JSONTest::test("{ \"key\" : \"val\" } [ \"error\" ]", false); - JSONTest::test("{ \"key\" : \"val\" ", false); - - JSONTest::test("/**/ { }", true); - JSONTest::test("/* */ { }", true); - JSONTest::test("/*foo*/ { }", true); - JSONTest::test("/* *foo */ { }", true); - JSONTest::test("/* *foo* */ { }", true); - JSONTest::test("/* /*foo */ { }", true); - JSONTest::test("{ } /* foo */", true); - JSONTest::test("{ } /* foo */ ", true); - JSONTest::test("{ } //", true); - JSONTest::test("{ } // ", true); - JSONTest::test("{ } // foo", true); - - JSONTest::test("/* * / { }", false); - JSONTest::test("/ * */ { }", false); - JSONTest::test("// { }", false); - JSONTest::test("/* { } */", false); - JSONTest::test("/* { } */ ", false); - JSONTest::test("/* { } ", false); - JSONTest::test("{ } /* ", false); - JSONTest::test("/* { } *", false); - JSONTest::test("{ /* } */", false); - JSONTest::test("[ /* ] */", false); - JSONTest::test("{ key : \"val\", /* } */", false); - JSONTest::test("[ \"val\", /* ] */", false); - - JSONTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\", { \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\" : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); - JSONTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\", { \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\" : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); - JSONTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]},\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true); - JSONTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\", \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}", false); // first key needs to be quoted since it contains a space - - - JSONTest::test("[\n]", true); - - JSONTest::test( - "[" "\n" - " {" - " // pattern to match against class+method+signature" "\n" - " // leading and trailing wildcard (*) allowed" "\n" - " match: \"foo.bar.*\"," "\n" - " " "\n" - " // override defaults for specified compiler" "\n" - " // we may differentiate between levels too. TBD." "\n" - " c1: {" "\n" - " //override c1 presets " "\n" - " array_bounds_check_removal: false" "\n" - " }," "\n" - "" "\n" - " c2: {" "\n" - " // control inlining of method" "\n" - " // + force inline, - dont inline" "\n" - " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" - " }," "\n" - "" "\n" - " // directives outside a specific preset applies to all compilers" "\n" - " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" - " print_assembly: true," "\n" - " verify_oopmaps: true," "\n" - " max_loop_unrolling: 5" "\n" - " }," "\n" - " {" "\n" - " // matching several patterns require an array" "\n" - " match: [\"baz.*\",\"frob*\"]," "\n" - "" "\n" - " // only enable c1 for this directive" "\n" - " // all enabled by default. Command disables all not listed" "\n" - " enable: \"c1\"," "\n" - "" "\n" - " // applies to all compilers" "\n" - " // + force inline, - dont inline" "\n" - " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" - " print_inlining: true," "\n" - "" "\n" - " // force matching compiles to be blocking/syncronous" "\n" - " blocking_compile: true" "\n" - " }," "\n" - "]" "\n", true); -} - -void JSONTest::log(uint indent, const char* format, ...) { - if (VerboseInternalVMTests) { - if (prev != JSON_KEY) { - for (uint i = 0; i < indent; i++) { - _st->print(" "); - } - } - va_list args; - va_start(args, format); - _st->vprint(format, args); - va_end(args); - } -} - -bool JSONTest::callback(JSON_TYPE t, JSON_VAL* v, uint rlevel) { - switch (t) { - case JSON_OBJECT_BEGIN: - log(rlevel, "{\n"); - prev = JSON_NONE; // Only care about JSON_KEY, to indent correctly - return true; - - case JSON_OBJECT_END: - log(rlevel, "},\n"); - prev = JSON_NONE; - return true; - - case JSON_ARRAY_BEGIN: - log(rlevel, "[\n"); - prev = JSON_NONE; - return true; - - case JSON_ARRAY_END: - log(rlevel, "],\n"); - prev = JSON_NONE; - return true; - - case JSON_KEY: - if (VerboseInternalVMTests) { - for (uint i = 0; i < rlevel; i++) { - _st->print(" "); - } - _st->print(""); - for (size_t i = 0; i < v->str.length; i++) { - u_char c = v->str.start[i]; - assert(c != 0, "string overrun"); - if (c == 0) { - return false; - } - _st->print("%c", c); - } - _st->print(" : "); - } - prev = JSON_KEY; - return true; - - case JSON_STRING: - if (VerboseInternalVMTests) { - if (prev != JSON_KEY) { - for (uint i = 0; i < rlevel; i++) { - _st->print(" "); - } - } - _st->print(""); - for (size_t i = 0; i < v->str.length; i++) { - u_char c = v->str.start[i]; - assert(c != 0, "string overrun"); - if (c == 0) { - return false; - } - _st->print("%c", c); - } - _st->print(",\n"); - } - prev = JSON_NONE; - return true; - - case JSON_NUMBER_INT: - log(rlevel, "%" PRId64 ",\n", v->int_value); - prev = JSON_NONE; - return true; - - case JSON_NUMBER_FLOAT: - log(rlevel, "%lf,\n", v->double_value); - prev = JSON_NONE; - return true; - - case JSON_TRUE: - log(rlevel, ",\n"); - prev = JSON_NONE; - return true; - - case JSON_FALSE: - log(rlevel, ",\n"); - prev = JSON_NONE; - return true; - - case JSON_NULL: - log(rlevel, ",\n"); - prev = JSON_NONE; - return true; - - default: - error(INTERNAL_ERROR, "unknown JSON type"); - return false; - } -} -#endif diff --git a/hotspot/test/native/utilities/test_json.cpp b/hotspot/test/native/utilities/test_json.cpp new file mode 100644 index 00000000000..6eb9c31696c --- /dev/null +++ b/hotspot/test/native/utilities/test_json.cpp @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "prims/jvm.h" +#include "utilities/json.hpp" +#include "unittest.hpp" + +class JSON_GTest : public JSON { +public: + static void test(const char* json, bool valid); + +private: + JSON_GTest(const char* text); + + void log(uint level, const char* format, ...) ATTRIBUTE_PRINTF(3, 4); + + bool callback(JSON_TYPE t, JSON_VAL* v, uint level); + JSON_TYPE prev; +}; + +void JSON_GTest::test(const char* text, bool should_pass) { + JSON_GTest json(text); + if (should_pass) { + ASSERT_TRUE(json.valid()) << "failed on a valid json string"; + } else { + ASSERT_FALSE(json.valid()) << "succeeded on an invalid json string"; + } +} + +JSON_GTest::JSON_GTest(const char* text) : JSON(text, false, tty) { + prev = JSON_NONE; + parse(); +} + +TEST(utilities, json_curly_braces) { + JSON_GTest::test("{}", true); +} + +TEST(utilities, json_brackets) { + JSON_GTest::test("[]", true); +} + +TEST(utilities, json_space_braces) { + JSON_GTest::test(" { } ", true); +} + +TEST(utilities, json_space_bracketes) { + JSON_GTest::test(" [ ] ", true); +} + +TEST(utilities, json_quoted_error) { + JSON_GTest::test("\"error\"", false); +} + +TEST(utilities, json_error_string) { + JSON_GTest::test("error", false); +} + +TEST(utilities, json_simple_integer) { + JSON_GTest::test("1", false); +} + +TEST(utilities, json_siple_float) { + JSON_GTest::test("1.2", false); +} + +TEST(utilities, json_simple_boolean_true) { + JSON_GTest::test("true", false); +} + +TEST(utilities, json_simple_boolean_false) { + JSON_GTest::test("false", false); +} + +TEST(utilities, json_simple_null) { + JSON_GTest::test("null", false); +} + +TEST(utilities, json_one_element_int_array) { + JSON_GTest::test("[ 1 ]", true); +} + +TEST(utilities, json_int_array) { + JSON_GTest::test("[ 1, ]", true); +} + +TEST(utilities, json_one_element_bool_array) { + JSON_GTest::test("[ true ]", true); +} + +TEST(utilities, json_bool_array) { + JSON_GTest::test("[ true, ]", true); +} + +TEST(utilities, json_one_element_false_array) { + JSON_GTest::test("[ false ]", true); +} + +TEST(utilities, json_false_bool_array) { + JSON_GTest::test("[ false, ]", true); +} + +TEST(utilities, json_one_null_array) { + JSON_GTest::test("[ null ]", true); +} + +TEST(utilities, json_null_array) { + JSON_GTest::test("[ null, ]", true); +} + +TEST(utilities, json_one_empty_string_array) { + JSON_GTest::test("[ \"\" ]", true); +} + +TEST(utilities, json_empty_string_array) { + JSON_GTest::test("[ \"\", ]", true); +} + +TEST(utilities, json_single_string_array) { + JSON_GTest::test("[ \"elem1\" ]", true); +} + +TEST(utilities, json_string_comma_arrray) { + JSON_GTest::test("[ \"elem1\", ]", true); +} + +TEST(utilities, json_two_strings_array) { + JSON_GTest::test("[ \"elem1\", \"elem2\" ]", true); +} + +TEST(utilities, json_two_strings_comma_array) { + JSON_GTest::test("[ \"elem1\", \"elem2\", ]", true); +} + +TEST(utilities, json_curly_braces_outside) { + JSON_GTest::test("[ \"elem1\" ] { }", false); +} + +TEST(utilities, json_element_in_array) { + JSON_GTest::test("[ elem1, \"elem2\" ]", false); +} + +TEST(utilities, json_incorrect_end_array) { + JSON_GTest::test("[ \"elem1\"", false); +} + +TEST(utilities, json_incorrect_string_end) { + JSON_GTest::test("[ \"elem1 ]", false); +} + +TEST(utilities, json_incorrect_end_of_two_elements_array) { + JSON_GTest::test("[ \"elem1\", \"elem2\"", false); +} + +TEST(utilities, json_incorrect_bool_true_array) { + JSON_GTest::test("[ truefoo ]", false); +} + +TEST(utilities, json_incorrect_bool_false_array) { + JSON_GTest::test("[ falsefoo ]", false); +} + +TEST(utilities, json_incorrect_null_array) { + JSON_GTest::test("[ nullfoo ]", false); +} + +TEST(utilities, json_key_pair) { + JSON_GTest::test("{ key : 1 }", true); +} + +TEST(utilities, json_key_pair_comma) { + JSON_GTest::test("{ key : 1, }", true); +} + +TEST(utilities, json_bool_true_key) { + JSON_GTest::test("{ key : true }", true); +} + +TEST(utilities, json_bool_true_key_comma) { + JSON_GTest::test("{ key : true, }", true); +} + +TEST(utilities, json_bool_false_key) { + JSON_GTest::test("{ key : false }", true); +} + +TEST(utilities, json_bool_false_key_comma) { + JSON_GTest::test("{ key : false, }", true); +} + +TEST(utilities, json_null_key) { + JSON_GTest::test("{ key : null }", true); +} + +TEST(utilities, json_null_key_comma) { + JSON_GTest::test("{ key : null, }", true); +} + +TEST(utilities, json_pair_of_empty_strings) { + JSON_GTest::test("{ \"\" : \"\" }", true); +} + +TEST(utilities, json_pair_of_empty_strings_comma) { + JSON_GTest::test("{ \"\" : \"\", }", true); +} + +TEST(utilities, json_pair_of_strings) { + JSON_GTest::test("{ \"key1\" : \"val1\" }", true); +} + +TEST(utilities, json_pair_of_strings_comma) { + JSON_GTest::test("{ \"key1\" : \"val1\", }", true); +} + +TEST(utilities, json_two_pairs_of_strings) { + JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\" }", true); +} + +TEST(utilities, json_two_pairs_of_strings_comma) { + JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\", }", true); +} + +TEST(utilities, json_array_outside) { + JSON_GTest::test("{ \"key\" : \"val\" } [ \"error\" ]", false); +} + +TEST(utilities, json_incorrect_object_end) { + JSON_GTest::test("{ \"key\" : \"val\" ", false); +} + +TEST(utilities, json_empty_comment) { + JSON_GTest::test("/**/ { }", true); +} + +TEST(utilities, json_space_comment) { + JSON_GTest::test("/* */ { }", true); +} + +TEST(utilities, json_comment) { + JSON_GTest::test("/*foo*/ { }", true); +} + +TEST(utilities, json_star_comment) { + JSON_GTest::test("/* *foo */ { }", true); +} + +TEST(utilities, json_stars_comment) { + JSON_GTest::test("/* *foo* */ { }", true); +} + +TEST(utilities, json_special_comment) { + JSON_GTest::test("/* /*foo */ { }", true); +} + +TEST(utilities, json_comment_after) { + JSON_GTest::test("{ } /* foo */", true); +} + +TEST(utilities, json_comment_after_and_space) { + JSON_GTest::test("{ } /* foo */ ", true); +} + +TEST(utilities, json_one_line_empty_comment_after) { + JSON_GTest::test("{ } //", true); +} + +TEST(utilities, json_one_line_space_comment_after) { + JSON_GTest::test("{ } // ", true); +} + +TEST(utilities, json_one_line_comment_after) { + JSON_GTest::test("{ } // foo", true); +} + +TEST(utilities, json_incorrect_multiline_comment) { + JSON_GTest::test("/* * / { }", false); +} + +TEST(utilities, json_incorrect_multiline_comment_begin) { + JSON_GTest::test("/ * */ { }", false); +} + +TEST(utilities, json_oneline_comment_only) { + JSON_GTest::test("// { }", false); +} + +TEST(utilities, json_multiline_comment_only) { + JSON_GTest::test("/* { } */", false); +} + +TEST(utilities, json_multiline_comment_2) { + JSON_GTest::test("/* { } */ ", false); +} + +TEST(utilities, json_incorrectly_commented_object) { + JSON_GTest::test("/* { } ", false); +} + +TEST(utilities, json_missing_multiline_end) { + JSON_GTest::test("{ } /* ", false); +} + +TEST(utilities, json_missing_multiline_slash) { + JSON_GTest::test("/* { } *", false); +} + +TEST(utilities, json_commented_object_end) { + JSON_GTest::test("{ /* } */", false); +} + +TEST(utilities, json_commented_array_end) { + JSON_GTest::test("[ /* ] */", false); +} + +TEST(utilities, json_missing_object_end) { + JSON_GTest::test("{ key : \"val\", /* } */", false); +} + +TEST(utilities, json_missing_array_end) { + JSON_GTest::test("[ \"val\", /* ] */", false); +} + +TEST(utilities, json_key_values_1) { + JSON_GTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," + "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" + " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); +} + +TEST(utilities, json_key_values_2) { + JSON_GTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," + "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" + " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); +} + +TEST(utilities, json_quoted_symbols) { + JSON_GTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]}," + "\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true); +} + +TEST(utilities, json_incorrect_key) { + JSON_GTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\"," + " \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}", + false); // first key needs to be quoted since it contains a space +} + +TEST(utilities, json_array_with_newline) { + JSON_GTest::test("[\n]", true); +} + +TEST(utilities, json_directives_file) { + JSON_GTest::test( + "[" "\n" + " {" + " // pattern to match against class+method+signature" "\n" + " // leading and trailing wildcard (*) allowed" "\n" + " match: \"foo.bar.*\"," "\n" + " " "\n" + " // override defaults for specified compiler" "\n" + " // we may differentiate between levels too. TBD." "\n" + " c1: {" "\n" + " //override c1 presets " "\n" + " array_bounds_check_removal: false" "\n" + " }," "\n" + "" "\n" + " c2: {" "\n" + " // control inlining of method" "\n" + " // + force inline, - dont inline" "\n" + " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" + " }," "\n" + "" "\n" + " // directives outside a specific preset applies to all compilers" "\n" + " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" + " print_assembly: true," "\n" + " verify_oopmaps: true," "\n" + " max_loop_unrolling: 5" "\n" + " }," "\n" + " {" "\n" + " // matching several patterns require an array" "\n" + " match: [\"baz.*\",\"frob*\"]," "\n" + "" "\n" + " // only enable c1 for this directive" "\n" + " // all enabled by default. Command disables all not listed" "\n" + " enable: \"c1\"," "\n" + "" "\n" + " // applies to all compilers" "\n" + " // + force inline, - dont inline" "\n" + " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" + " print_inlining: true," "\n" + "" "\n" + " // force matching compiles to be blocking/syncronous" "\n" + " blocking_compile: true" "\n" + " }," "\n" + "]" "\n", true); +} + +void JSON_GTest::log(uint indent, const char* format, ...) { + if (prev != JSON_KEY) { + for (uint i = 0; i < indent; i++) { + _st->print(" "); + } + } + va_list args; + va_start(args, format); + _st->vprint(format, args); + va_end(args); +} + +bool JSON_GTest::callback(JSON_TYPE t, JSON_VAL* v, uint rlevel) { + switch (t) { + case JSON_OBJECT_BEGIN: + log(rlevel, "{\n"); + prev = JSON_NONE; // Only care about JSON_KEY, to indent correctly + return true; + + case JSON_OBJECT_END: + log(rlevel, "},\n"); + prev = JSON_NONE; + return true; + + case JSON_ARRAY_BEGIN: + log(rlevel, "[\n"); + prev = JSON_NONE; + return true; + + case JSON_ARRAY_END: + log(rlevel, "],\n"); + prev = JSON_NONE; + return true; + + case JSON_KEY: + for (uint i = 0; i < rlevel; i++) { + _st->print(" "); + } + _st->print(""); + for (size_t i = 0; i < v->str.length; i++) { + u_char c = v->str.start[i]; + if (c == 0) { + return false; + } + _st->print("%c", c); + } + _st->print(" : "); + prev = JSON_KEY; + return true; + + case JSON_STRING: + if (prev != JSON_KEY) { + for (uint i = 0; i < rlevel; i++) { + _st->print(" "); + } + } + _st->print(""); + for (size_t i = 0; i < v->str.length; i++) { + u_char c = v->str.start[i]; + if (c == 0) { + return false; + } + _st->print("%c", c); + } + _st->print(",\n"); + prev = JSON_NONE; + return true; + + case JSON_NUMBER_INT: + log(rlevel, "%" PRId64 ",\n", v->int_value); + prev = JSON_NONE; + return true; + + case JSON_NUMBER_FLOAT: + log(rlevel, "%lf,\n", v->double_value); + prev = JSON_NONE; + return true; + + case JSON_TRUE: + log(rlevel, ",\n"); + prev = JSON_NONE; + return true; + + case JSON_FALSE: + log(rlevel, ",\n"); + prev = JSON_NONE; + return true; + + case JSON_NULL: + log(rlevel, ",\n"); + prev = JSON_NONE; + return true; + + default: + error(INTERNAL_ERROR, "unknown JSON type"); + return false; + } +} From 7f3eef9f4d9b7ad15ad5de6dfc25bdc09b2c9052 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 1 Sep 2016 16:46:59 +0200 Subject: [PATCH 016/207] 8165235: [TESTBUG] RTM tests must check OS version Reviewed-by: simonis, fzhinkin --- test/lib/jdk/test/lib/Platform.java | 32 +++++++++++++++++++ .../test/lib/cli/predicate/AndPredicate.java | 10 +++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/test/lib/jdk/test/lib/Platform.java b/test/lib/jdk/test/lib/Platform.java index ec4fa8b63ba..07e8c4973a9 100644 --- a/test/lib/jdk/test/lib/Platform.java +++ b/test/lib/jdk/test/lib/Platform.java @@ -28,6 +28,9 @@ import java.util.regex.Pattern; public class Platform { public static final String vmName = System.getProperty("java.vm.name"); public static final String vmInfo = System.getProperty("java.vm.info"); + private static final String osVersion = System.getProperty("os.version"); + private static int osVersionMajor = -1; + private static int osVersionMinor = -1; 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"); @@ -112,6 +115,35 @@ public class Platform { return osName; } + // Os version support. + private static void init_version() { + try { + final String[] tokens = osVersion.split("\\."); + if (tokens.length > 0) { + osVersionMajor = Integer.parseInt(tokens[0]); + if (tokens.length > 1) { + osVersionMinor = Integer.parseInt(tokens[1]); + } + } + } catch (NumberFormatException e) { + osVersionMajor = osVersionMinor = 0; + } + } + + // Returns major version number from os.version system property. + // E.g. 5 on Solaris 10 and 3 on SLES 11.3 (for the linux kernel version). + public static int getOsVersionMajor() { + if (osVersionMajor == -1) init_version(); + return osVersionMajor; + } + + // Returns minor version number from os.version system property. + // E.g. 10 on Solaris 10 and 0 on SLES 11.3 (for the linux kernel version). + public static int getOsVersionMinor() { + if (osVersionMinor == -1) init_version(); + return osVersionMinor; + } + public static boolean isDebugBuild() { return (jdkDebug.toLowerCase().contains("debug")); } diff --git a/test/lib/jdk/test/lib/cli/predicate/AndPredicate.java b/test/lib/jdk/test/lib/cli/predicate/AndPredicate.java index 1e70abc2e00..8425ed96695 100644 --- a/test/lib/jdk/test/lib/cli/predicate/AndPredicate.java +++ b/test/lib/jdk/test/lib/cli/predicate/AndPredicate.java @@ -28,14 +28,22 @@ import java.util.function.BooleanSupplier; public class AndPredicate implements BooleanSupplier { private final BooleanSupplier a; private final BooleanSupplier b; + private final BooleanSupplier c; public AndPredicate(BooleanSupplier a, BooleanSupplier b) { this.a = a; this.b = b; + this.c = () -> true; // Boolean.TRUE::booleanValue + } + + public AndPredicate(BooleanSupplier a, BooleanSupplier b, BooleanSupplier c) { + this.a = a; + this.b = b; + this.c = c; } @Override public boolean getAsBoolean() { - return a.getAsBoolean() && b.getAsBoolean(); + return a.getAsBoolean() && b.getAsBoolean() && c.getAsBoolean(); } } From 616083ca7695b33d1d5e7e0b1413dbddac7e7243 Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Mon, 5 Sep 2016 20:31:03 +0300 Subject: [PATCH 017/207] 8165439: Convert Test_TempNewSymbol to GTest Reviewed-by: dholmes, coleenp --- .../src/share/vm/classfile/symbolTable.cpp | 50 ------------ .../share/vm/utilities/internalVMTests.cpp | 1 - .../native/classfile/test_symbolTable.cpp | 77 +++++++++++++++++++ 3 files changed, 77 insertions(+), 51 deletions(-) create mode 100644 hotspot/test/native/classfile/test_symbolTable.cpp diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index 8f51f527508..5121fdbcd64 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -710,53 +710,3 @@ int SymboltableDCmd::num_arguments() { return 0; } } - -#ifndef PRODUCT -// Internal test of TempNewSymbol -void Test_TempNewSymbol() { - // Assert messages assume these symbols are unique, and the refcounts start at - // one, but code does not rely on this. - Thread* THREAD = Thread::current(); - Symbol* abc = SymbolTable::new_symbol("abc", CATCH); - int abccount = abc->refcount(); - TempNewSymbol ss = abc; - assert(ss->refcount() == abccount, "only one abc"); - assert(ss->refcount() == abc->refcount(), "should match TempNewSymbol"); - - Symbol* efg = SymbolTable::new_symbol("efg", CATCH); - Symbol* hij = SymbolTable::new_symbol("hij", CATCH); - int efgcount = efg->refcount(); - int hijcount = hij->refcount(); - - TempNewSymbol s1 = efg; - TempNewSymbol s2 = hij; - assert(s1->refcount() == efgcount, "one efg"); - assert(s2->refcount() == hijcount, "one hij"); - - // Assignment operator - s1 = s2; - assert(hij->refcount() == hijcount + 1, "should be two hij"); - assert(efg->refcount() == efgcount - 1, "should be no efg"); - - s1 = ss; // s1 is abc - assert(s1->refcount() == abccount + 1, "should be two abc (s1 and ss)"); - assert(hij->refcount() == hijcount, "should only have one hij now (s2)"); - - s1 = s1; // self assignment - assert(s1->refcount() == abccount + 1, "should still be two abc (s1 and ss)"); - - TempNewSymbol s3; - Symbol* klm = SymbolTable::new_symbol("klm", CATCH); - int klmcount = klm->refcount(); - s3 = klm; // assignment - assert(s3->refcount() == klmcount, "only one klm now"); - - Symbol* xyz = SymbolTable::new_symbol("xyz", CATCH); - int xyzcount = xyz->refcount(); - { // inner scope - TempNewSymbol s_inner = xyz; - } - assert(xyz->refcount() == (xyzcount - 1), - "Should have been decremented by dtor in inner scope"); -} -#endif // PRODUCT diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 76087d52bfe..5ab07de5622 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -82,7 +82,6 @@ void InternalVMTests::run() { run_unit_test(Test_invalid_log_file); run_unit_test(Test_multiline_logging); run_unit_test(DirectivesParser_test); - run_unit_test(Test_TempNewSymbol); #if INCLUDE_VM_STRUCTS run_unit_test(VMStructs_test); #endif diff --git a/hotspot/test/native/classfile/test_symbolTable.cpp b/hotspot/test/native/classfile/test_symbolTable.cpp new file mode 100644 index 00000000000..04e382c448e --- /dev/null +++ b/hotspot/test/native/classfile/test_symbolTable.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "runtime/interfaceSupport.hpp" +#include "classfile/symbolTable.hpp" +#include "unittest.hpp" + +TEST(SymbolTable, temp_new_symbol) { + // Assert messages assume these symbols are unique, and the refcounts start at + // one, but code does not rely on this. + JavaThread* THREAD = JavaThread::current(); + // the thread should be in vm to use locks + ThreadInVMfromNative ThreadInVMfromNative(THREAD); + + Symbol* abc = SymbolTable::new_symbol("abc", CATCH); + int abccount = abc->refcount(); + TempNewSymbol ss = abc; + ASSERT_EQ(ss->refcount(), abccount) << "only one abc"; + ASSERT_EQ(ss->refcount(), abc->refcount()) << "should match TempNewSymbol"; + + Symbol* efg = SymbolTable::new_symbol("efg", CATCH); + Symbol* hij = SymbolTable::new_symbol("hij", CATCH); + int efgcount = efg->refcount(); + int hijcount = hij->refcount(); + + TempNewSymbol s1 = efg; + TempNewSymbol s2 = hij; + ASSERT_EQ(s1->refcount(), efgcount) << "one efg"; + ASSERT_EQ(s2->refcount(), hijcount) << "one hij"; + + // Assignment operator + s1 = s2; + ASSERT_EQ(hij->refcount(), hijcount + 1) << "should be two hij"; + ASSERT_EQ(efg->refcount(), efgcount - 1) << "should be no efg"; + + s1 = ss; // s1 is abc + ASSERT_EQ(s1->refcount(), abccount + 1) << "should be two abc (s1 and ss)"; + ASSERT_EQ(hij->refcount(), hijcount) << "should only have one hij now (s2)"; + + s1 = s1; // self assignment + ASSERT_EQ(s1->refcount(), abccount + 1) << "should still be two abc (s1 and ss)"; + + TempNewSymbol s3; + Symbol* klm = SymbolTable::new_symbol("klm", CATCH); + int klmcount = klm->refcount(); + s3 = klm; // assignment + ASSERT_EQ(s3->refcount(), klmcount) << "only one klm now"; + + Symbol* xyz = SymbolTable::new_symbol("xyz", CATCH); + int xyzcount = xyz->refcount(); + { // inner scope + TempNewSymbol s_inner = xyz; + } + ASSERT_EQ(xyz->refcount(), xyzcount - 1) + << "Should have been decremented by dtor in inner scope"; +} From 21f3d1ae5fec79fc4a612ce9de50f68efd6dbb9d Mon Sep 17 00:00:00 2001 From: Jini George Date: Thu, 15 Sep 2016 10:19:11 +0300 Subject: [PATCH 018/207] 8027920: SA: Add default methods to InstanceKlass Add default methods to InstanceKlass to enable SA to inspect default methods Reviewed-by: dsamersoff, iklam --- .../sun/jvm/hotspot/oops/InstanceKlass.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 79ae9497496..99dbadf0e2b 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -68,6 +68,7 @@ public class InstanceKlass extends Klass { Type type = db.lookupType("InstanceKlass"); arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0); methods = type.getAddressField("_methods"); + defaultMethods = type.getAddressField("_default_methods"); methodOrdering = type.getAddressField("_method_ordering"); localInterfaces = type.getAddressField("_local_interfaces"); transitiveInterfaces = type.getAddressField("_transitive_interfaces"); @@ -128,6 +129,7 @@ public class InstanceKlass extends Klass { private static MetadataField arrayKlasses; private static AddressField methods; + private static AddressField defaultMethods; private static AddressField methodOrdering; private static AddressField localInterfaces; private static AddressField transitiveInterfaces; @@ -335,6 +337,20 @@ public class InstanceKlass extends Klass { // Accessors for declared fields public Klass getArrayKlasses() { return (Klass) arrayKlasses.getValue(this); } public MethodArray getMethods() { return new MethodArray(methods.getValue(getAddress())); } + + public MethodArray getDefaultMethods() { + if (defaultMethods != null) { + Address addr = defaultMethods.getValue(getAddress()); + if ((addr != null) && (addr.getAddressAt(0) != null)) { + return new MethodArray(addr); + } else { + return null; + } + } else { + return null; + } + } + public KlassArray getLocalInterfaces() { return new KlassArray(localInterfaces.getValue(getAddress())); } public KlassArray getTransitiveInterfaces() { return new KlassArray(transitiveInterfaces.getValue(getAddress())); } public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); } From 8a329d56cf54b798ba6292a8dd07613ead707183 Mon Sep 17 00:00:00 2001 From: Alexander Kulyakhtin Date: Wed, 14 Sep 2016 16:20:54 +0300 Subject: [PATCH 019/207] 8165017: Additional test coverage of the JDWP CLASSLOADER and MODULE commands A new JDWP test Reviewed-by: sspitsyn --- .../jdwp/AllModulesCommandTest.java | 52 ++++++++++++++----- hotspot/test/serviceability/jdwp/JdwpCmd.java | 1 - .../serviceability/jdwp/JdwpModuleCmd.java | 34 ++++++++++++ .../serviceability/jdwp/JdwpModuleReply.java | 42 +++++++++++++++ .../jdwp/JdwpVisibleClassesCmd.java | 34 ++++++++++++ .../jdwp/JdwpVisibleClassesReply.java | 49 +++++++++++++++++ 6 files changed, 199 insertions(+), 13 deletions(-) create mode 100644 hotspot/test/serviceability/jdwp/JdwpModuleCmd.java create mode 100644 hotspot/test/serviceability/jdwp/JdwpModuleReply.java create mode 100644 hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java create mode 100644 hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java diff --git a/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java b/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java index 33bb583c59d..5fed0412a03 100644 --- a/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java +++ b/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java @@ -30,7 +30,7 @@ import static jdk.test.lib.Asserts.assertTrue; /** * @test - * @summary Tests AllModules JDWP command + * @summary Tests the modules-related JDWP commands * @library /test/lib * @modules java.base/jdk.internal.misc * @compile AllModulesCommandTestDebuggee.java @@ -87,8 +87,12 @@ public class AllModulesCommandTest implements DebuggeeLauncher.Listener { assertReply(reply); for (int i = 0; i < reply.getModulesCount(); ++i) { long modId = reply.getModuleId(i); - // For each module reported by JDWP get its name using the JDWP NAME command - getModuleName(modId); + // For each module reported by JDWP get its name using the JDWP NAME command + // and store the reply + String modName = getModuleName(modId); + if (modName != null) { // JDWP reports unnamed modules, ignore them + jdwpModuleNames.add(modName); + } // Assert the JDWP CANREAD and CLASSLOADER commands assertCanRead(modId); assertClassLoader(modId); @@ -114,14 +118,10 @@ public class AllModulesCommandTest implements DebuggeeLauncher.Listener { } } - private void getModuleName(long modId) throws IOException { - // Send out the JDWP NAME command and store the reply + private String getModuleName(long modId) throws IOException { JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel); assertReply(reply); - String modName = reply.getModuleName(); - if (modName != null) { // JDWP reports unnamed modules, ignore them - jdwpModuleNames.add(modName); - } + return reply.getModuleName(); } private void assertReply(JdwpReply reply) { @@ -139,11 +139,39 @@ public class AllModulesCommandTest implements DebuggeeLauncher.Listener { } private void assertClassLoader(long modId) throws IOException { - // Simple assert for the CLASSLOADER command + // Verify that the module classloader id is valid JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel); assertReply(reply); - long clId = reply.getClassLoaderId(); - assertTrue(clId >= 0, "bad classloader refId " + clId + " for module id " + modId); + long moduleClassLoader = reply.getClassLoaderId(); + assertTrue(moduleClassLoader >= 0, "bad classloader refId " + moduleClassLoader + " for module id " + modId); + + String clsModName = getModuleName(modId); + if ("java.base".equals(clsModName)) { + // For the java.base module, because there will be some loaded classes, we can verify + // that some of the loaded classes do report the java.base module as the module they belong to + assertGetModule(moduleClassLoader, modId); + } + } + + private void assertGetModule(long moduleClassLoader, long modId) throws IOException { + // Get all the visible classes for the module classloader + JdwpVisibleClassesReply visibleClasses = new JdwpVisibleClassesCmd(moduleClassLoader).send(channel); + assertReply(visibleClasses); + + boolean moduleFound = false; + for (long clsId : visibleClasses.getVisibleClasses()) { + // For each visible class get the module the class belongs to + JdwpModuleReply modReply = new JdwpModuleCmd(clsId).send(channel); + assertReply(modReply); + long clsModId = modReply.getModuleId(); + + // At least one of the visible classes should belong to our module + if (modId == clsModId) { + moduleFound = true; + break; + } + } + assertTrue(moduleFound, "None of the visible classes for the classloader of the module " + getModuleName(modId) + " reports the module as its own"); } } diff --git a/hotspot/test/serviceability/jdwp/JdwpCmd.java b/hotspot/test/serviceability/jdwp/JdwpCmd.java index fe7f28707a8..05dbb6efb7f 100644 --- a/hotspot/test/serviceability/jdwp/JdwpCmd.java +++ b/hotspot/test/serviceability/jdwp/JdwpCmd.java @@ -70,7 +70,6 @@ public abstract class JdwpCmd { } public final T send(JdwpChannel channel) throws IOException { - System.err.println("Sending command: " + this); channel.write(data.array(), HEADER_LEN + getDataLength()); if (reply != null) { reply.initFromStream(channel.getInputStream()); diff --git a/hotspot/test/serviceability/jdwp/JdwpModuleCmd.java b/hotspot/test/serviceability/jdwp/JdwpModuleCmd.java new file mode 100644 index 00000000000..a9ed54419fa --- /dev/null +++ b/hotspot/test/serviceability/jdwp/JdwpModuleCmd.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * The JDWP MODULE command + */ +public class JdwpModuleCmd extends JdwpCmd { + + public JdwpModuleCmd(long refId) { + super(19, 2, JdwpModuleReply.class, refLen()); + putRefId(refId); + } + +} diff --git a/hotspot/test/serviceability/jdwp/JdwpModuleReply.java b/hotspot/test/serviceability/jdwp/JdwpModuleReply.java new file mode 100644 index 00000000000..19baa7a4dde --- /dev/null +++ b/hotspot/test/serviceability/jdwp/JdwpModuleReply.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.DataInputStream; +import java.io.IOException; + +/** + * The reply to the JDWP MODULE command + */ +public class JdwpModuleReply extends JdwpReply { + + private long moduleId; + + protected void parseData(DataInputStream ds) throws IOException { + moduleId = readRefId(ds); + } + + public long getModuleId() { + return moduleId; + } + +} diff --git a/hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java new file mode 100644 index 00000000000..daab8a11d6a --- /dev/null +++ b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * The JDWP VISIBLE CLASSES command + */ +public class JdwpVisibleClassesCmd extends JdwpCmd { + + public JdwpVisibleClassesCmd(long classLoaderId) { + super(1, 14, JdwpVisibleClassesReply.class, refLen()); + putRefId(classLoaderId); + } + +} diff --git a/hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java new file mode 100644 index 00000000000..5381c43c51a --- /dev/null +++ b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.Arrays; + +/** + * The reply to the JDWP VISIBLE CLASSES command + */ +public class JdwpVisibleClassesReply extends JdwpReply { + + private long[] visibleClasses; + + protected void parseData(DataInputStream ds) throws IOException { + int numOfClasses = ds.readInt(); + visibleClasses = new long[numOfClasses]; + for (int i = 0; i < numOfClasses; ++i) { + byte type = ds.readByte(); + long refId = readRefId(ds); + visibleClasses[i] = refId; + } + } + + public long[] getVisibleClasses() { + return Arrays.copyOf(visibleClasses, visibleClasses.length); + } + +} From 94bbcbd378380429129972f7bcd7b539bcb0a86b Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 15 Sep 2016 16:44:19 +0200 Subject: [PATCH 020/207] 8159422: Very high Concurrent Mark mark stack contention Decrease contention on mark stack by splitting locks, and minimizing the amount of time these locks are held. Improve mark stack management. Reviewed-by: kbarrett, mgerdin, eosterlund --- .../src/share/vm/gc/g1/g1CollectedHeap.cpp | 2 - .../src/share/vm/gc/g1/g1ConcurrentMark.cpp | 292 +++++++++++------- .../src/share/vm/gc/g1/g1ConcurrentMark.hpp | 144 +++++---- .../vm/gc/g1/g1ConcurrentMark.inline.hpp | 22 +- hotspot/src/share/vm/gc/g1/g1OopClosures.hpp | 1 - hotspot/src/share/vm/memory/allocation.hpp | 1 + .../src/share/vm/memory/allocation.inline.hpp | 18 ++ hotspot/src/share/vm/runtime/mutexLocker.cpp | 5 + hotspot/src/share/vm/runtime/mutexLocker.hpp | 3 +- 9 files changed, 310 insertions(+), 178 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index 4543ee3e021..935d935b13f 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -3165,7 +3165,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { assert(_verifier->check_cset_fast_test(), "Inconsistency in the InCSetState table."); - _cm->note_start_of_gc(); // We call this after finalize_cset() to // ensure that the CSet has been finalized. _cm->verify_no_cset_oops(); @@ -3251,7 +3250,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { // We redo the verification but now wrt to the new CSet which // has just got initialized after the previous CSet was freed. _cm->verify_no_cset_oops(); - _cm->note_end_of_gc(); // This timing is only used by the ergonomics to handle our pause target. // It is unclear why this should not include the full pause. We will diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp index 9084f46c3be..43b227a7ef8 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp @@ -133,129 +133,184 @@ void G1CMBitMap::clear_range(MemRegion mr) { } G1CMMarkStack::G1CMMarkStack() : - _reserved_space(), + _max_chunk_capacity(0), _base(NULL), - _capacity(0), - _saved_index((size_t)AllBits), + _chunk_capacity(0), + _out_of_memory(false), _should_expand(false) { set_empty(); } bool G1CMMarkStack::resize(size_t new_capacity) { assert(is_empty(), "Only resize when stack is empty."); - assert(new_capacity <= MarkStackSizeMax, - "Trying to resize stack to " SIZE_FORMAT " elements when the maximum is " SIZE_FORMAT, new_capacity, MarkStackSizeMax); + assert(new_capacity <= _max_chunk_capacity, + "Trying to resize stack to " SIZE_FORMAT " chunks when the maximum is " SIZE_FORMAT, new_capacity, _max_chunk_capacity); - size_t reservation_size = ReservedSpace::allocation_align_size_up(new_capacity * sizeof(oop)); + OopChunk* new_base = MmapArrayAllocator::allocate_or_null(new_capacity); - ReservedSpace rs(reservation_size); - if (!rs.is_reserved()) { - log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " elements and size " SIZE_FORMAT "B.", new_capacity, reservation_size); + if (new_base == NULL) { + log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " chunks and size " SIZE_FORMAT "B.", new_capacity, new_capacity * sizeof(OopChunk)); return false; } - - VirtualSpace vs; - - if (!vs.initialize(rs, rs.size())) { - rs.release(); - log_warning(gc)("Failed to commit memory for new overflow mark stack of size " SIZE_FORMAT "B.", rs.size()); - return false; - } - - assert(vs.committed_size() == rs.size(), "Failed to commit all of the mark stack."); - // Release old mapping. - _reserved_space.release(); + if (_base != NULL) { + MmapArrayAllocator::free(_base, _chunk_capacity); + } - // Save new mapping for future unmapping. - _reserved_space = rs; - - MemTracker::record_virtual_memory_type((address)_reserved_space.base(), mtGC); - - _base = (oop*) vs.low(); - _capacity = new_capacity; + _base = new_base; + _chunk_capacity = new_capacity; set_empty(); _should_expand = false; return true; } -bool G1CMMarkStack::allocate(size_t capacity) { - return resize(capacity); +size_t G1CMMarkStack::capacity_alignment() { + return (size_t)lcm(os::vm_allocation_granularity(), sizeof(OopChunk)) / sizeof(void*); +} + +bool G1CMMarkStack::initialize(size_t initial_capacity, size_t max_capacity) { + guarantee(_max_chunk_capacity == 0, "G1CMMarkStack already initialized."); + + size_t const OopChunkSizeInVoidStar = sizeof(OopChunk) / sizeof(void*); + + _max_chunk_capacity = (size_t)align_size_up(max_capacity, capacity_alignment()) / OopChunkSizeInVoidStar; + size_t initial_chunk_capacity = (size_t)align_size_up(initial_capacity, capacity_alignment()) / OopChunkSizeInVoidStar; + + guarantee(initial_chunk_capacity <= _max_chunk_capacity, + "Maximum chunk capacity " SIZE_FORMAT " smaller than initial capacity " SIZE_FORMAT, + _max_chunk_capacity, + initial_chunk_capacity); + + log_debug(gc)("Initialize mark stack with " SIZE_FORMAT " chunks, maximum " SIZE_FORMAT, + initial_chunk_capacity, _max_chunk_capacity); + + return resize(initial_chunk_capacity); } void G1CMMarkStack::expand() { // Clear expansion flag _should_expand = false; - if (_capacity == MarkStackSizeMax) { - log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " elements.", _capacity); + if (_chunk_capacity == _max_chunk_capacity) { + log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " chunks.", _chunk_capacity); return; } - size_t old_capacity = _capacity; + size_t old_capacity = _chunk_capacity; // Double capacity if possible - size_t new_capacity = MIN2(old_capacity * 2, MarkStackSizeMax); + size_t new_capacity = MIN2(old_capacity * 2, _max_chunk_capacity); if (resize(new_capacity)) { - log_debug(gc)("Expanded marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements", + log_debug(gc)("Expanded mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks", old_capacity, new_capacity); } else { - log_warning(gc)("Failed to expand marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements", + log_warning(gc)("Failed to expand mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks", old_capacity, new_capacity); } } G1CMMarkStack::~G1CMMarkStack() { if (_base != NULL) { - _base = NULL; - _reserved_space.release(); + MmapArrayAllocator::free(_base, _chunk_capacity); } } -void G1CMMarkStack::par_push_arr(oop* buffer, size_t n) { - MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); - size_t start = _index; - size_t next_index = start + n; - if (next_index > _capacity) { - _overflow = true; - return; - } - // Otherwise. - _index = next_index; - for (size_t i = 0; i < n; i++) { - size_t ind = start + i; - assert(ind < _capacity, "By overflow test above."); - _base[ind] = buffer[i]; - } +void G1CMMarkStack::add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem) { + elem->next = *list; + *list = elem; } -bool G1CMMarkStack::par_pop_arr(oop* buffer, size_t max, size_t* n) { - MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); - size_t index = _index; - if (index == 0) { - *n = 0; +void G1CMMarkStack::add_chunk_to_chunk_list(OopChunk* elem) { + MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag); + add_chunk_to_list(&_chunk_list, elem); + _chunks_in_chunk_list++; +} + +void G1CMMarkStack::add_chunk_to_free_list(OopChunk* elem) { + MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag); + add_chunk_to_list(&_free_list, elem); +} + +G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_list(OopChunk* volatile* list) { + OopChunk* result = *list; + if (result != NULL) { + *list = (*list)->next; + } + return result; +} + +G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_chunk_list() { + MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag); + OopChunk* result = remove_chunk_from_list(&_chunk_list); + if (result != NULL) { + _chunks_in_chunk_list--; + } + return result; +} + +G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_free_list() { + MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag); + return remove_chunk_from_list(&_free_list); +} + +G1CMMarkStack::OopChunk* G1CMMarkStack::allocate_new_chunk() { + // This dirty read of _hwm is okay because we only ever increase the _hwm in parallel code. + // Further this limits _hwm to a value of _chunk_capacity + #threads, avoiding + // wraparound of _hwm. + if (_hwm >= _chunk_capacity) { + return NULL; + } + + size_t cur_idx = Atomic::add(1, &_hwm) - 1; + if (cur_idx >= _chunk_capacity) { + return NULL; + } + + OopChunk* result = ::new (&_base[cur_idx]) OopChunk; + result->next = NULL; + return result; +} + +bool G1CMMarkStack::par_push_chunk(oop* ptr_arr) { + // Get a new chunk. + OopChunk* new_chunk = remove_chunk_from_free_list(); + + if (new_chunk == NULL) { + // Did not get a chunk from the free list. Allocate from backing memory. + new_chunk = allocate_new_chunk(); + } + + if (new_chunk == NULL) { + _out_of_memory = true; return false; - } else { - size_t k = MIN2(max, index); - size_t new_ind = index - k; - for (size_t j = 0; j < k; j++) { - buffer[j] = _base[new_ind + j]; - } - _index = new_ind; - *n = k; - return true; } + + Copy::conjoint_oops_atomic(ptr_arr, new_chunk->data, OopsPerChunk); + + add_chunk_to_chunk_list(new_chunk); + + return true; } -void G1CMMarkStack::note_start_of_gc() { - assert(_saved_index == (size_t)AllBits, "note_start_of_gc()/end_of_gc() calls bracketed incorrectly"); - _saved_index = _index; +bool G1CMMarkStack::par_pop_chunk(oop* ptr_arr) { + OopChunk* cur = remove_chunk_from_chunk_list(); + + if (cur == NULL) { + return false; + } + + Copy::conjoint_oops_atomic(cur->data, ptr_arr, OopsPerChunk); + + add_chunk_to_free_list(cur); + return true; } -void G1CMMarkStack::note_end_of_gc() { - guarantee(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index); - - _saved_index = (size_t)AllBits; +void G1CMMarkStack::set_empty() { + _chunks_in_chunk_list = 0; + _hwm = 0; + clear_out_of_memory(); + _chunk_list = NULL; + _free_list = NULL; } G1CMRootRegions::G1CMRootRegions() : @@ -483,9 +538,8 @@ G1ConcurrentMark::G1ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* } } - if (!_global_mark_stack.allocate(MarkStackSize)) { + if (!_global_mark_stack.initialize(MarkStackSize, MarkStackSizeMax)) { vm_exit_during_initialization("Failed to allocate initial concurrent mark overflow mark stack."); - return; } _tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC); @@ -1695,10 +1749,10 @@ void G1ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { // oop closures will set the has_overflown flag if we overflow the // global marking stack. - assert(_global_mark_stack.overflow() || _global_mark_stack.is_empty(), - "mark stack should be empty (unless it overflowed)"); + assert(_global_mark_stack.is_out_of_memory() || _global_mark_stack.is_empty(), + "Mark stack should be empty (unless it is out of memory)"); - if (_global_mark_stack.overflow()) { + if (_global_mark_stack.is_out_of_memory()) { // This should have been done already when we tried to push an // entry on to the global mark stack. But let's do it again. set_has_overflown(); @@ -2343,49 +2397,54 @@ void G1CMTask::decrease_limits() { } void G1CMTask::move_entries_to_global_stack() { - // local array where we'll store the entries that will be popped - // from the local queue - oop buffer[global_stack_transfer_size]; + // Local array where we'll store the entries that will be popped + // from the local queue. + oop buffer[G1CMMarkStack::OopsPerChunk]; - int n = 0; + size_t n = 0; oop obj; - while (n < global_stack_transfer_size && _task_queue->pop_local(obj)) { + while (n < G1CMMarkStack::OopsPerChunk && _task_queue->pop_local(obj)) { buffer[n] = obj; ++n; } + if (n < G1CMMarkStack::OopsPerChunk) { + buffer[n] = NULL; + } if (n > 0) { - // we popped at least one entry from the local queue - - if (!_cm->mark_stack_push(buffer, n)) { + if (!_cm->mark_stack_push(buffer)) { set_has_aborted(); } } - // this operation was quite expensive, so decrease the limits + // This operation was quite expensive, so decrease the limits. decrease_limits(); } -void G1CMTask::get_entries_from_global_stack() { - // local array where we'll store the entries that will be popped +bool G1CMTask::get_entries_from_global_stack() { + // Local array where we'll store the entries that will be popped // from the global stack. - oop buffer[global_stack_transfer_size]; - size_t n; - _cm->mark_stack_pop(buffer, global_stack_transfer_size, &n); - assert(n <= global_stack_transfer_size, - "we should not pop more than the given limit"); - if (n > 0) { - // yes, we did actually pop at least one entry - for (size_t i = 0; i < n; ++i) { - bool success = _task_queue->push(buffer[i]); - // We only call this when the local queue is empty or under a - // given target limit. So, we do not expect this push to fail. - assert(success, "invariant"); - } + oop buffer[G1CMMarkStack::OopsPerChunk]; + + if (!_cm->mark_stack_pop(buffer)) { + return false; } - // this operation was quite expensive, so decrease the limits + // We did actually pop at least one entry. + for (size_t i = 0; i < G1CMMarkStack::OopsPerChunk; ++i) { + oop elem = buffer[i]; + if (elem == NULL) { + break; + } + bool success = _task_queue->push(elem); + // We only call this when the local queue is empty or under a + // given target limit. So, we do not expect this push to fail. + assert(success, "invariant"); + } + + // This operation was quite expensive, so decrease the limits decrease_limits(); + return true; } void G1CMTask::drain_local_queue(bool partially) { @@ -2429,20 +2488,21 @@ void G1CMTask::drain_global_stack(bool partially) { // Decide what the target size is, depending whether we're going to // drain it partially (so that other tasks can steal if they run out - // of things to do) or totally (at the very end). Notice that, - // because we move entries from the global stack in chunks or - // because another task might be doing the same, we might in fact - // drop below the target. But, this is not a problem. - size_t target_size; + // of things to do) or totally (at the very end). + // Notice that when draining the global mark stack partially, due to the racyness + // of the mark stack size update we might in fact drop below the target. But, + // this is not a problem. + // In case of total draining, we simply process until the global mark stack is + // totally empty, disregarding the size counter. if (partially) { - target_size = _cm->partial_mark_stack_size_target(); - } else { - target_size = 0; - } - - if (_cm->mark_stack_size() > target_size) { + size_t const target_size = _cm->partial_mark_stack_size_target(); while (!has_aborted() && _cm->mark_stack_size() > target_size) { - get_entries_from_global_stack(); + if (get_entries_from_global_stack()) { + drain_local_queue(partially); + } + } + } else { + while (!has_aborted() && get_entries_from_global_stack()) { drain_local_queue(partially); } } diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp index 0331976a4a6..68cc2b42bb8 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp @@ -149,42 +149,98 @@ class G1CMBitMap : public G1CMBitMapRO { // // Stores oops in a huge buffer in virtual memory that is always fully committed. // Resizing may only happen during a STW pause when the stack is empty. +// +// Memory is allocated on a "chunk" basis, i.e. a set of oops. For this, the mark +// stack memory is split into evenly sized chunks of oops. Users can only +// add or remove entries on that basis. +// Chunks are filled in increasing address order. Not completely filled chunks +// have a NULL element as a terminating element. +// +// Every chunk has a header containing a single pointer element used for memory +// management. This wastes some space, but is negligible (< .1% with current sizing). +// +// Memory management is done using a mix of tracking a high water-mark indicating +// that all chunks at a lower address are valid chunks, and a singly linked free +// list connecting all empty chunks. class G1CMMarkStack VALUE_OBJ_CLASS_SPEC { - ReservedSpace _reserved_space; // Space currently reserved for the mark stack. +public: + // Number of oops that can fit in a single chunk. + static const size_t OopsPerChunk = 1024 - 1 /* One reference for the next pointer */; +private: + struct OopChunk { + OopChunk* next; + oop data[OopsPerChunk]; + }; - oop* _base; // Bottom address of allocated memory area. - size_t _capacity; // Maximum number of elements. - size_t _index; // One more than last occupied index. + size_t _max_chunk_capacity; // Maximum number of OopChunk elements on the stack. - size_t _saved_index; // Value of _index saved at start of GC to detect mark stack modifications during that time. + OopChunk* _base; // Bottom address of allocated memory area. + size_t _chunk_capacity; // Current maximum number of OopChunk elements. + + char _pad0[DEFAULT_CACHE_LINE_SIZE]; + OopChunk* volatile _free_list; // Linked list of free chunks that can be allocated by users. + char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*)]; + OopChunk* volatile _chunk_list; // List of chunks currently containing data. + volatile size_t _chunks_in_chunk_list; + char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*) - sizeof(size_t)]; + + volatile size_t _hwm; // High water mark within the reserved space. + char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)]; + + // Allocate a new chunk from the reserved memory, using the high water mark. Returns + // NULL if out of memory. + OopChunk* allocate_new_chunk(); + + volatile bool _out_of_memory; + + // Atomically add the given chunk to the list. + void add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem); + // Atomically remove and return a chunk from the given list. Returns NULL if the + // list is empty. + OopChunk* remove_chunk_from_list(OopChunk* volatile* list); + + void add_chunk_to_chunk_list(OopChunk* elem); + void add_chunk_to_free_list(OopChunk* elem); + + OopChunk* remove_chunk_from_chunk_list(); + OopChunk* remove_chunk_from_free_list(); - bool _overflow; bool _should_expand; // Resizes the mark stack to the given new capacity. Releases any previous // memory if successful. bool resize(size_t new_capacity); - bool stack_modified() const { return _index != _saved_index; } public: G1CMMarkStack(); ~G1CMMarkStack(); - bool allocate(size_t capacity); + // Alignment and minimum capacity of this mark stack in number of oops. + static size_t capacity_alignment(); - // Pushes the first "n" elements of the given buffer on the stack. - void par_push_arr(oop* buffer, size_t n); + // Allocate and initialize the mark stack with the given number of oops. + bool initialize(size_t initial_capacity, size_t max_capacity); - // Moves up to max elements from the stack into the given buffer. Returns - // the number of elements pushed, and false if the array has been empty. - // Returns true if the buffer contains at least one element. - bool par_pop_arr(oop* buffer, size_t max, size_t* n); + // Pushes the given buffer containing at most OopsPerChunk elements on the mark + // stack. If less than OopsPerChunk elements are to be pushed, the array must + // be terminated with a NULL. + // Returns whether the buffer contents were successfully pushed to the global mark + // stack. + bool par_push_chunk(oop* buffer); - bool is_empty() const { return _index == 0; } - size_t capacity() const { return _capacity; } + // Pops a chunk from this mark stack, copying them into the given buffer. This + // chunk may contain up to OopsPerChunk elements. If there are less, the last + // element in the array is a NULL pointer. + bool par_pop_chunk(oop* buffer); - bool overflow() const { return _overflow; } - void clear_overflow() { _overflow = false; } + // Return whether the chunk list is empty. Racy due to unsynchronized access to + // _chunk_list. + bool is_empty() const { return _chunk_list == NULL; } + + size_t capacity() const { return _chunk_capacity; } + + bool is_out_of_memory() const { return _out_of_memory; } + void clear_out_of_memory() { _out_of_memory = false; } bool should_expand() const { return _should_expand; } void set_should_expand(bool value) { _should_expand = value; } @@ -192,20 +248,15 @@ class G1CMMarkStack VALUE_OBJ_CLASS_SPEC { // Expand the stack, typically in response to an overflow condition void expand(); - size_t size() const { return _index; } + // Return the approximate number of oops on this mark stack. Racy due to + // unsynchronized access to _chunks_in_chunk_list. + size_t size() const { return _chunks_in_chunk_list * OopsPerChunk; } - void set_empty() { _index = 0; clear_overflow(); } + void set_empty(); - // Record the current index. - void note_start_of_gc(); - - // Make sure that we have not added any entries to the stack during GC. - void note_end_of_gc(); - - // Apply fn to each oop in the mark stack, up to the bound recorded - // via one of the above "note" functions. The mark stack must not + // Apply Fn to every oop on the mark stack. The mark stack must not // be modified while iterating. - template void iterate(Fn fn); + template void iterate(Fn fn) const PRODUCT_RETURN; }; // Root Regions are regions that are not empty at the beginning of a @@ -278,7 +329,6 @@ class G1ConcurrentMark: public CHeapObj { friend class G1CMDrainMarkingStackClosure; friend class G1CMBitMapClosure; friend class G1CMConcurrentMarkingTask; - friend class G1CMMarkStack; friend class G1CMRemarkTask; friend class G1CMTask; @@ -479,22 +529,20 @@ protected: public: // Manipulation of the global mark stack. // The push and pop operations are used by tasks for transfers - // between task-local queues and the global mark stack, and use - // locking for concurrency safety. - bool mark_stack_push(oop* arr, size_t n) { - _global_mark_stack.par_push_arr(arr, n); - if (_global_mark_stack.overflow()) { + // between task-local queues and the global mark stack. + bool mark_stack_push(oop* arr) { + if (!_global_mark_stack.par_push_chunk(arr)) { set_has_overflown(); return false; } return true; } - void mark_stack_pop(oop* arr, size_t max, size_t* n) { - _global_mark_stack.par_pop_arr(arr, max, n); + bool mark_stack_pop(oop* arr) { + return _global_mark_stack.par_pop_chunk(arr); } size_t mark_stack_size() { return _global_mark_stack.size(); } size_t partial_mark_stack_size_target() { return _global_mark_stack.capacity()/3; } - bool mark_stack_overflow() { return _global_mark_stack.overflow(); } + bool mark_stack_overflow() { return _global_mark_stack.is_out_of_memory(); } bool mark_stack_empty() { return _global_mark_stack.is_empty(); } G1CMRootRegions* root_regions() { return &_root_regions; } @@ -599,16 +647,6 @@ public: // read-only, so use this carefully! void clearRangePrevBitmap(MemRegion mr); - // Notify data structures that a GC has started. - void note_start_of_gc() { - _global_mark_stack.note_start_of_gc(); - } - - // Notify data structures that a GC is finished. - void note_end_of_gc() { - _global_mark_stack.note_end_of_gc(); - } - // Verify that there are no CSet oops on the stacks (taskqueues / // global mark stack) and fingers (global / per-task). // If marking is not in progress, it's a no-op. @@ -670,10 +708,7 @@ private: // references reaches this limit refs_reached_period = 384, // Initial value for the hash seed, used in the work stealing code - init_hash_seed = 17, - // How many entries will be transferred between global stack and - // local queues at once. - global_stack_transfer_size = 1024 + init_hash_seed = 17 }; uint _worker_id; @@ -858,9 +893,10 @@ public: // It pushes an object on the local queue. inline void push(oop obj); - // These two move entries to/from the global stack. + // Move entries to the global stack. void move_entries_to_global_stack(); - void get_entries_from_global_stack(); + // Move entries from the global stack, return true if we were successful to do so. + bool get_entries_from_global_stack(); // It pops and scans objects from the local queue. If partially is // true, then it stops when the queue size is of a given limit. If diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp index 40336ae6885..af42c85920c 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp @@ -89,14 +89,28 @@ inline bool G1CMBitMap::parMark(HeapWord* addr) { #undef check_mark +#ifndef PRODUCT template -inline void G1CMMarkStack::iterate(Fn fn) { +inline void G1CMMarkStack::iterate(Fn fn) const { assert_at_safepoint(true); - assert(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index); - for (size_t i = 0; i < _index; ++i) { - fn(_base[i]); + + size_t num_chunks = 0; + + OopChunk* cur = _chunk_list; + while (cur != NULL) { + guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks); + + for (size_t i = 0; i < OopsPerChunk; ++i) { + if (cur->data[i] == NULL) { + break; + } + fn(cur->data[i]); + } + cur = cur->next; + num_chunks++; } } +#endif // It scans an object and visits its children. inline void G1CMTask::scan_object(oop obj) { process_grey_object(obj); } diff --git a/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp b/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp index 5de38f71bd2..bc594ed86e9 100644 --- a/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp +++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp @@ -34,7 +34,6 @@ class G1RemSet; class G1ConcurrentMark; class DirtyCardToOopClosure; class G1CMBitMap; -class G1CMMarkStack; class G1ParScanThreadState; class G1CMTask; class ReferenceProcessor; diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp index 5d9e7c830f6..c9a5f28405c 100644 --- a/hotspot/src/share/vm/memory/allocation.hpp +++ b/hotspot/src/share/vm/memory/allocation.hpp @@ -738,6 +738,7 @@ class MmapArrayAllocator : public AllStatic { static size_t size_for(size_t length); public: + static E* allocate_or_null(size_t length); static E* allocate(size_t length); static void free(E* addr, size_t length); }; diff --git a/hotspot/src/share/vm/memory/allocation.inline.hpp b/hotspot/src/share/vm/memory/allocation.inline.hpp index db09c0cfb0e..f1035490163 100644 --- a/hotspot/src/share/vm/memory/allocation.inline.hpp +++ b/hotspot/src/share/vm/memory/allocation.inline.hpp @@ -152,6 +152,24 @@ size_t MmapArrayAllocator::size_for(size_t length) { return align_size_up(size, alignment); } +template +E* MmapArrayAllocator::allocate_or_null(size_t length) { + size_t size = size_for(length); + int alignment = os::vm_allocation_granularity(); + + char* addr = os::reserve_memory(size, NULL, alignment, F); + if (addr == NULL) { + return NULL; + } + + if (os::commit_memory(addr, size, !ExecMem, "Allocator (commit)")) { + return (E*)addr; + } else { + os::release_memory(addr, size); + return NULL; + } +} + template E* MmapArrayAllocator::allocate(size_t length) { size_t size = size_for(length); diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp index a01b4888500..88f5ab04457 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp @@ -77,6 +77,8 @@ Mutex* Shared_SATB_Q_lock = NULL; Mutex* DirtyCardQ_FL_lock = NULL; Monitor* DirtyCardQ_CBL_mon = NULL; Mutex* Shared_DirtyCardQ_lock = NULL; +Mutex* MarkStackFreeList_lock = NULL; +Mutex* MarkStackChunkList_lock = NULL; Mutex* ParGCRareEvent_lock = NULL; Mutex* DerivedPointerTableGC_lock = NULL; Mutex* Compile_lock = NULL; @@ -194,6 +196,9 @@ void mutex_init() { def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); def(StringDedupTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); + + def(MarkStackFreeList_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); + def(MarkStackChunkList_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); } def(ParGCRareEvent_lock , Mutex , leaf , true, Monitor::_safepoint_check_sometimes); def(DerivedPointerTableGC_lock , Mutex, leaf, true, Monitor::_safepoint_check_never); diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp index ae4c79954ea..c0db4e9f4e6 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.hpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp @@ -81,7 +81,8 @@ extern Monitor* DirtyCardQ_CBL_mon; // Protects dirty card Q extern Mutex* Shared_DirtyCardQ_lock; // Lock protecting dirty card // queue shared by // non-Java threads. - // (see option ExplicitGCInvokesConcurrent) +extern Mutex* MarkStackFreeList_lock; // Protects access to the global mark stack free list. +extern Mutex* MarkStackChunkList_lock; // Protects access to the global mark stack chunk list. extern Mutex* ParGCRareEvent_lock; // Synchronizes various (rare) parallel GC ops. extern Mutex* Compile_lock; // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc) extern Monitor* MethodCompileQueue_lock; // a lock held when method compilations are enqueued, dequeued From b77d0de3d9509cfbc852f0bb590241ee1b90e020 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Thu, 15 Sep 2016 12:10:43 -0400 Subject: [PATCH 021/207] 8165808: Add release barriers when allocating objects with concurrent collection Add release_set_klass, use in slow-path allocators. Reviewed-by: jmasa, dholmes --- .../src/share/vm/gc/shared/collectedHeap.hpp | 3 - .../vm/gc/shared/collectedHeap.inline.hpp | 65 +++++++++---------- hotspot/src/share/vm/oops/oop.hpp | 1 + hotspot/src/share/vm/oops/oop.inline.hpp | 22 ++++++- 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp index af26fc892e9..d5ae7733114 100644 --- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp +++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp @@ -304,9 +304,6 @@ class CollectedHeap : public CHeapObj { inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS); inline static oop class_allocate(KlassHandle klass, int size, TRAPS); - inline static void post_allocation_install_obj_klass(KlassHandle klass, - oop obj); - // Raw memory allocation facilities // The obj and array allocate methods are covers for these methods. // mem_allocate() should never be diff --git a/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp b/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp index 36ef86f98c9..cd54e1fdc5b 100644 --- a/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp @@ -41,14 +41,22 @@ // Inline allocation implementations. void CollectedHeap::post_allocation_setup_common(KlassHandle klass, - HeapWord* obj) { - post_allocation_setup_no_klass_install(klass, obj); - post_allocation_install_obj_klass(klass, oop(obj)); + HeapWord* obj_ptr) { + post_allocation_setup_no_klass_install(klass, obj_ptr); + oop obj = (oop)obj_ptr; +#if ! INCLUDE_ALL_GCS + obj->set_klass(klass()); +#else + // Need a release store to ensure array/class length, mark word, and + // object zeroing are visible before setting the klass non-NULL, for + // concurrent collectors. + obj->release_set_klass(klass()); +#endif } void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass, - HeapWord* objPtr) { - oop obj = (oop)objPtr; + HeapWord* obj_ptr) { + oop obj = (oop)obj_ptr; assert(obj != NULL, "NULL object pointer"); if (UseBiasedLocking && (klass() != NULL)) { @@ -59,18 +67,6 @@ void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass, } } -void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass, - oop obj) { - // These asserts are kind of complicated because of klassKlass - // and the beginning of the world. - assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass"); - assert(klass() == NULL || klass()->is_klass(), "not a klass"); - assert(obj != NULL, "NULL object pointer"); - obj->set_klass(klass()); - assert(!Universe::is_fully_initialized() || obj->klass() != NULL, - "missing klass"); -} - // Support for jvmti and dtrace inline void post_allocation_notify(KlassHandle klass, oop obj, int size) { // support low memory notifications (no-op if not enabled) @@ -88,25 +84,26 @@ inline void post_allocation_notify(KlassHandle klass, oop obj, int size) { } void CollectedHeap::post_allocation_setup_obj(KlassHandle klass, - HeapWord* obj, + HeapWord* obj_ptr, int size) { - post_allocation_setup_common(klass, obj); + post_allocation_setup_common(klass, obj_ptr); + oop obj = (oop)obj_ptr; assert(Universe::is_bootstrapping() || - !((oop)obj)->is_array(), "must not be an array"); + !obj->is_array(), "must not be an array"); // notify jvmti and dtrace - post_allocation_notify(klass, (oop)obj, size); + post_allocation_notify(klass, obj, size); } void CollectedHeap::post_allocation_setup_class(KlassHandle klass, - HeapWord* obj, + HeapWord* obj_ptr, int size) { - // Set oop_size field before setting the _klass field - // in post_allocation_setup_common() because the klass field - // indicates that the object is parsable by concurrent GC. - oop new_cls = (oop)obj; + // Set oop_size field before setting the _klass field because a + // non-NULL _klass field indicates that the object is parsable by + // concurrent GC. + oop new_cls = (oop)obj_ptr; assert(size > 0, "oop_size must be positive."); java_lang_Class::set_oop_size(new_cls, size); - post_allocation_setup_common(klass, obj); + post_allocation_setup_common(klass, obj_ptr); assert(Universe::is_bootstrapping() || !new_cls->is_array(), "must not be an array"); // notify jvmti and dtrace @@ -114,15 +111,15 @@ void CollectedHeap::post_allocation_setup_class(KlassHandle klass, } void CollectedHeap::post_allocation_setup_array(KlassHandle klass, - HeapWord* obj, + HeapWord* obj_ptr, int length) { - // Set array length before setting the _klass field - // in post_allocation_setup_common() because the klass field - // indicates that the object is parsable by concurrent GC. + // Set array length before setting the _klass field because a + // non-NULL klass field indicates that the object is parsable by + // concurrent GC. assert(length >= 0, "length should be non-negative"); - ((arrayOop)obj)->set_length(length); - post_allocation_setup_common(klass, obj); - oop new_obj = (oop)obj; + ((arrayOop)obj_ptr)->set_length(length); + post_allocation_setup_common(klass, obj_ptr); + oop new_obj = (oop)obj_ptr; assert(new_obj->is_array(), "must be an array"); // notify jvmti and dtrace (must be after length is set for dtrace) post_allocation_notify(klass, new_obj, new_obj->size()); diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp index 23d73067178..647cec8c83a 100644 --- a/hotspot/src/share/vm/oops/oop.hpp +++ b/hotspot/src/share/vm/oops/oop.hpp @@ -87,6 +87,7 @@ class oopDesc { inline narrowKlass* compressed_klass_addr(); inline void set_klass(Klass* k); + inline void release_set_klass(Klass* k); // For klass field compression inline int klass_gap() const; diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index 578bcc4e520..9a981e05c19 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -129,10 +129,14 @@ narrowKlass* oopDesc::compressed_klass_addr() { return &_metadata._compressed_klass; } +#define CHECK_SET_KLASS(k) \ + do { \ + assert(Universe::is_bootstrapping() || k != NULL, "NULL Klass"); \ + assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass"); \ + } while (0) + 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*"); + CHECK_SET_KLASS(k); if (UseCompressedClassPointers) { *compressed_klass_addr() = Klass::encode_klass_not_null(k); } else { @@ -140,6 +144,18 @@ void oopDesc::set_klass(Klass* k) { } } +void oopDesc::release_set_klass(Klass* k) { + CHECK_SET_KLASS(k); + if (UseCompressedClassPointers) { + OrderAccess::release_store(compressed_klass_addr(), + Klass::encode_klass_not_null(k)); + } else { + OrderAccess::release_store_ptr(klass_addr(), k); + } +} + +#undef CHECK_SET_KLASS + int oopDesc::klass_gap() const { return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()); } From 317f1aa044a8a71c52cfe733f1f4baf656c22c4c Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Fri, 16 Sep 2016 11:33:47 +0200 Subject: [PATCH 022/207] 8157952: Parallelize Memory Pretouch Use multiple threads to pretouch memory using -XX:+AlwaysPreTouch to use more memory bandwidth Reviewed-by: jmasa, sangheki --- .../src/share/vm/gc/g1/g1CollectedHeap.cpp | 12 ++--- .../src/share/vm/gc/g1/g1CollectedHeap.hpp | 2 +- .../vm/gc/g1/g1PageBasedVirtualSpace.cpp | 54 +++++++++++++++++-- .../vm/gc/g1/g1PageBasedVirtualSpace.hpp | 4 ++ .../share/vm/gc/g1/g1RegionToSpaceMapper.cpp | 31 +++++++++-- .../share/vm/gc/g1/g1RegionToSpaceMapper.hpp | 4 +- .../src/share/vm/gc/g1/heapRegionManager.cpp | 28 +++++----- .../src/share/vm/gc/g1/heapRegionManager.hpp | 11 ++-- hotspot/src/share/vm/gc/shared/workgroup.hpp | 7 ++- hotspot/src/share/vm/runtime/globals.hpp | 4 ++ hotspot/src/share/vm/runtime/os.cpp | 4 +- hotspot/src/share/vm/runtime/os.hpp | 2 +- 12 files changed, 124 insertions(+), 39 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index 935d935b13f..9ffbaeaad8b 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -1479,7 +1479,7 @@ void G1CollectedHeap::resize_if_necessary_after_full_collection() { "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)", capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio); - expand(expand_bytes); + expand(expand_bytes, _workers); // No expansion, now see if we want to shrink } else if (capacity_after_gc > maximum_desired_capacity) { @@ -1599,7 +1599,7 @@ HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size, AllocationConte word_size * HeapWordSize); - if (expand(expand_bytes)) { + if (expand(expand_bytes, _workers)) { _hrm.verify_optional(); _verifier->verify_region_sets_optional(); return attempt_allocation_at_safepoint(word_size, @@ -1609,7 +1609,7 @@ HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size, AllocationConte return NULL; } -bool G1CollectedHeap::expand(size_t expand_bytes, double* expand_time_ms) { +bool G1CollectedHeap::expand(size_t expand_bytes, WorkGang* pretouch_workers, double* expand_time_ms) { size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); aligned_expand_bytes = align_size_up(aligned_expand_bytes, HeapRegion::GrainBytes); @@ -1626,7 +1626,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes, double* expand_time_ms) { uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes); assert(regions_to_expand > 0, "Must expand by at least one region"); - uint expanded_by = _hrm.expand_by(regions_to_expand); + uint expanded_by = _hrm.expand_by(regions_to_expand, pretouch_workers); if (expand_time_ms != NULL) { *expand_time_ms = (os::elapsedTime() - expand_heap_start_time_sec) * MILLIUNITS; } @@ -1927,7 +1927,7 @@ jint G1CollectedHeap::initialize() { _cmThread = _cm->cmThread(); // Now expand into the initial heap size. - if (!expand(init_byte_size)) { + if (!expand(init_byte_size, _workers)) { vm_shutdown_during_initialization("Failed to allocate initial heap."); return JNI_ENOMEM; } @@ -3240,7 +3240,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { // No need for an ergo logging here, // expansion_amount() does this when it returns a value > 0. double expand_ms; - if (!expand(expand_bytes, &expand_ms)) { + if (!expand(expand_bytes, _workers, &expand_ms)) { // We failed to expand the heap. Cannot do anything about it. } g1_policy()->phase_times()->record_expand_heap_time(expand_ms); diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp index 4aadccbe916..d1e8dcafb14 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp @@ -557,7 +557,7 @@ public: // Returns true if the heap was expanded by the requested amount; // false otherwise. // (Rounds up to a HeapRegion boundary.) - bool expand(size_t expand_bytes, double* expand_time_ms = NULL); + bool expand(size_t expand_bytes, WorkGang* pretouch_workers = NULL, double* expand_time_ms = NULL); // Returns the PLAB statistics for a given destination. inline G1EvacStats* alloc_buffer_stats(InCSetState dest); diff --git a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp index 7f419bd409f..254baeab68e 100644 --- a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp +++ b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp @@ -24,8 +24,10 @@ #include "precompiled.hpp" #include "gc/g1/g1PageBasedVirtualSpace.hpp" +#include "gc/shared/workgroup.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.inline.hpp" #include "services/memTracker.hpp" #include "utilities/bitMap.inline.hpp" @@ -177,7 +179,7 @@ void G1PageBasedVirtualSpace::pretouch_internal(size_t start_page, size_t end_pa guarantee(start_page < end_page, "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page); - os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page)); + os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page), _page_size); } bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) { @@ -198,9 +200,6 @@ bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) { } _committed.set_range(start_page, end_page); - if (AlwaysPreTouch) { - pretouch_internal(start_page, end_page); - } return zero_filled; } @@ -227,6 +226,53 @@ void G1PageBasedVirtualSpace::uncommit(size_t start_page, size_t size_in_pages) _committed.clear_range(start_page, end_page); } +class G1PretouchTask : public AbstractGangTask { +private: + char* volatile _cur_addr; + char* const _start_addr; + char* const _end_addr; + size_t const _page_size; +public: + G1PretouchTask(char* start_address, char* end_address, size_t page_size) : + AbstractGangTask("G1 PreTouch", + Universe::is_fully_initialized() ? GCId::current_raw() : + // During VM initialization there is + // no GC cycle that this task can be + // associated with. + GCId::undefined()), + _cur_addr(start_address), + _start_addr(start_address), + _end_addr(end_address), + _page_size(page_size) { + } + + virtual void work(uint worker_id) { + size_t const actual_chunk_size = MAX2(chunk_size(), _page_size); + while (true) { + char* touch_addr = (char*)Atomic::add_ptr((intptr_t)actual_chunk_size, (volatile void*) &_cur_addr) - actual_chunk_size; + if (touch_addr < _start_addr || touch_addr >= _end_addr) { + break; + } + char* end_addr = touch_addr + MIN2(actual_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char))); + os::pretouch_memory(touch_addr, end_addr, _page_size); + } + } + + static size_t chunk_size() { return PreTouchParallelChunkSize; } +}; + +void G1PageBasedVirtualSpace::pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang) { + guarantee(pretouch_gang != NULL, "No pretouch gang specified."); + + size_t num_chunks = MAX2((size_t)1, size_in_pages * _page_size / MAX2(G1PretouchTask::chunk_size(), _page_size)); + + uint num_workers = MIN2((uint)num_chunks, pretouch_gang->active_workers()); + G1PretouchTask cl(page_start(start_page), bounded_end_addr(start_page + size_in_pages), _page_size); + log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.", + cl.name(), num_workers, num_chunks, size_in_pages * _page_size); + pretouch_gang->run_task(&cl, num_workers); +} + bool G1PageBasedVirtualSpace::contains(const void* p) const { return _low_boundary <= (const char*) p && (const char*) p < _high_boundary; } diff --git a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp index ed16fac9553..f684c103f0b 100644 --- a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp +++ b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp @@ -30,6 +30,8 @@ #include "memory/virtualspace.hpp" #include "utilities/bitMap.hpp" +class WorkGang; + // Virtual space management helper for a virtual space with an OS page allocation // granularity. // (De-)Allocation requests are always OS page aligned by passing a page index @@ -117,6 +119,8 @@ class G1PageBasedVirtualSpace VALUE_OBJ_CLASS_SPEC { // Uncommit the given area of pages starting at start being size_in_pages large. void uncommit(size_t start_page, size_t size_in_pages); + void pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang = NULL); + // Initialize the given reserved space with the given base address and the size // actually used. // Prefer to commit in page_size chunks. diff --git a/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp b/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp index 80b794153ed..efcd5ce7e92 100644 --- a/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp +++ b/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp @@ -66,8 +66,12 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper { guarantee(alloc_granularity >= page_size, "allocation granularity smaller than commit granularity"); } - virtual void commit_regions(uint start_idx, size_t num_regions) { - bool zero_filled = _storage.commit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region); + virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) { + size_t const start_page = (size_t)start_idx * _pages_per_region; + bool zero_filled = _storage.commit(start_page, num_regions * _pages_per_region); + if (AlwaysPreTouch) { + _storage.pretouch(start_page, num_regions * _pages_per_region, pretouch_gang); + } _commit_map.set_range(start_idx, start_idx + num_regions); fire_on_commit(start_idx, num_regions, zero_filled); } @@ -110,19 +114,38 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper { _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + align_size_up(rs.size(), page_size)), page_size); } - virtual void commit_regions(uint start_idx, size_t num_regions) { + virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) { + size_t const NoPage = ~(size_t)0; + + size_t first_committed = NoPage; + size_t num_committed = 0; + + bool all_zero_filled = true; + for (uint i = start_idx; i < start_idx + num_regions; i++) { assert(!_commit_map.at(i), "Trying to commit storage at region %u that is already committed", i); size_t idx = region_idx_to_page_idx(i); uint old_refcount = _refcounts.get_by_index(idx); + bool zero_filled = false; if (old_refcount == 0) { + if (first_committed == NoPage) { + first_committed = idx; + num_committed = 1; + } else { + num_committed++; + } zero_filled = _storage.commit(idx, 1); } + all_zero_filled &= zero_filled; + _refcounts.set_by_index(idx, old_refcount + 1); _commit_map.set_bit(i); - fire_on_commit(i, 1, zero_filled); } + if (AlwaysPreTouch && num_committed > 0) { + _storage.pretouch(first_committed, num_committed, pretouch_gang); + } + fire_on_commit(start_idx, num_regions, all_zero_filled); } virtual void uncommit_regions(uint start_idx, size_t num_regions) { diff --git a/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp b/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp index 218ae1550ae..bcde9a5aa04 100644 --- a/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp +++ b/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp @@ -29,6 +29,8 @@ #include "memory/allocation.hpp" #include "utilities/debug.hpp" +class WorkGang; + class G1MappingChangedListener VALUE_OBJ_CLASS_SPEC { public: // Fired after commit of the memory, i.e. the memory this listener is registered @@ -68,7 +70,7 @@ class G1RegionToSpaceMapper : public CHeapObj { return _commit_map.at(idx); } - virtual void commit_regions(uint start_idx, size_t num_regions = 1) = 0; + virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL) = 0; virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0; // Creates an appropriate G1RegionToSpaceMapper for the given parameters. diff --git a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp index 1f6bc95b1ad..f0887f93688 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,22 +72,22 @@ HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) { return g1h->new_heap_region(hrm_index, mr); } -void HeapRegionManager::commit_regions(uint index, size_t num_regions) { +void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) { guarantee(num_regions > 0, "Must commit more than zero regions"); guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions"); _num_committed += (uint)num_regions; - _heap_mapper->commit_regions(index, num_regions); + _heap_mapper->commit_regions(index, num_regions, pretouch_gang); // Also commit auxiliary data - _prev_bitmap_mapper->commit_regions(index, num_regions); - _next_bitmap_mapper->commit_regions(index, num_regions); + _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang); + _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang); - _bot_mapper->commit_regions(index, num_regions); - _cardtable_mapper->commit_regions(index, num_regions); + _bot_mapper->commit_regions(index, num_regions, pretouch_gang); + _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang); - _card_counts_mapper->commit_regions(index, num_regions); + _card_counts_mapper->commit_regions(index, num_regions, pretouch_gang); } void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) { @@ -117,9 +117,9 @@ void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) { _card_counts_mapper->uncommit_regions(start, num_regions); } -void HeapRegionManager::make_regions_available(uint start, uint num_regions) { +void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) { guarantee(num_regions > 0, "No point in calling this for zero regions"); - commit_regions(start, num_regions); + commit_regions(start, num_regions, pretouch_gang); for (uint i = start; i < start + num_regions; i++) { if (_regions.get_by_index(i) == NULL) { HeapRegion* new_hr = new_heap_region(i); @@ -163,11 +163,11 @@ MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const { return MemoryUsage(0, used_sz, committed_sz, committed_sz); } -uint HeapRegionManager::expand_by(uint num_regions) { - return expand_at(0, num_regions); +uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) { + return expand_at(0, num_regions, pretouch_workers); } -uint HeapRegionManager::expand_at(uint start, uint num_regions) { +uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) { if (num_regions == 0) { return 0; } @@ -181,7 +181,7 @@ uint HeapRegionManager::expand_at(uint start, uint num_regions) { while (expanded < num_regions && (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) { uint to_expand = MIN2(num_regions - expanded, num_last_found); - make_regions_available(idx_last_found, to_expand); + make_regions_available(idx_last_found, to_expand, pretouch_workers); expanded += to_expand; cur = idx_last_found + num_last_found + 1; } diff --git a/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp index 8644d3e56e6..07c84da348b 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ class HeapRegion; class HeapRegionClosure; class HeapRegionClaimer; class FreeRegionList; +class WorkGang; class G1HeapRegionTable : public G1BiasedMappedArray { protected: @@ -94,10 +95,10 @@ class HeapRegionManager: public CHeapObj { HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); } HeapWord* heap_end() const {return _regions.end_address_mapped(); } - void make_regions_available(uint index, uint num_regions = 1); + void make_regions_available(uint index, uint num_regions = 1, WorkGang* pretouch_gang = NULL); // Pass down commit calls to the VirtualSpace. - void commit_regions(uint index, size_t num_regions = 1); + void commit_regions(uint index, size_t num_regions = 1, WorkGang* pretouch_gang = NULL); void uncommit_regions(uint index, size_t num_regions = 1); // Notify other data structures about change in the heap layout. @@ -209,12 +210,12 @@ public: // HeapRegions, or re-use existing ones. Returns the number of regions the // sequence was expanded by. If a HeapRegion allocation fails, the resulting // number of regions might be smaller than what's desired. - uint expand_by(uint num_regions); + uint expand_by(uint num_regions, WorkGang* pretouch_workers = NULL); // Makes sure that the regions from start to start+num_regions-1 are available // for allocation. Returns the number of regions that were committed to achieve // this. - uint expand_at(uint start, uint num_regions); + uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers = NULL); // Find a contiguous set of empty regions of length num. Returns the start index of // that set, or G1_NO_HRM_INDEX. diff --git a/hotspot/src/share/vm/gc/shared/workgroup.hpp b/hotspot/src/share/vm/gc/shared/workgroup.hpp index 20491b66536..b71b3e0e23a 100644 --- a/hotspot/src/share/vm/gc/shared/workgroup.hpp +++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp @@ -62,7 +62,12 @@ class AbstractGangTask VALUE_OBJ_CLASS_SPEC { AbstractGangTask(const char* name) : _name(name), _gc_id(GCId::current_raw()) - {} + {} + + AbstractGangTask(const char* name, const uint gc_id) : + _name(name), + _gc_id(gc_id) + {} // The abstract work method. // The argument tells you which member of the gang you are. diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 1978313e48e..1c20ecf1174 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1596,6 +1596,10 @@ public: product(bool, AlwaysPreTouch, false, \ "Force all freshly committed pages to be pre-touched") \ \ + product(size_t, PreTouchParallelChunkSize, 1 * G, \ + "Per-thread chunk size for parallel memory pre-touch.") \ + range(1, SIZE_MAX / 2) \ + \ product_pd(size_t, CMSYoungGenPerWorker, \ "The maximum size of young gen chosen by default per GC worker " \ "thread available") \ diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 7089f6a6629..b73a4fa612d 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -1705,8 +1705,8 @@ bool os::release_memory(char* addr, size_t bytes) { return res; } -void os::pretouch_memory(void* start, void* end) { - for (volatile char *p = (char*)start; p < (char*)end; p += os::vm_page_size()) { +void os::pretouch_memory(void* start, void* end, size_t page_size) { + for (volatile char *p = (char*)start; p < (char*)end; p += page_size) { *p = 0; } } diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 4f714e3cec2..0077b36d345 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -324,7 +324,7 @@ class os: AllStatic { // to make the OS back the memory range with actual memory. // Current implementation may not touch the last page if unaligned addresses // are passed. - static void pretouch_memory(void* start, void* end); + static void pretouch_memory(void* start, void* end, size_t page_size = vm_page_size()); enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX }; static bool protect_memory(char* addr, size_t bytes, ProtType prot, From ba4a3fbd2089ec7b539b58ad3f6465d4f8f0c5cb Mon Sep 17 00:00:00 2001 From: Gerard Ziemski Date: Fri, 16 Sep 2016 12:09:53 -0500 Subject: [PATCH 023/207] 8136766: Enable ThreadStackSize range test Re-enabled max range check for StackSize runtime options Reviewed-by: dcubed --- .../CommandLine/OptionsValidation/TestOptionsWithRanges.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java index bd188d6cec8..fa3b79909c7 100644 --- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java +++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java @@ -110,10 +110,6 @@ public class TestOptionsWithRanges { excludeTestMaxRange("OldSize"); excludeTestMaxRange("ParallelGCThreads"); - excludeTestMaxRange("CompilerThreadStackSize"); - excludeTestMaxRange("ThreadStackSize"); - excludeTestMaxRange("VMThreadStackSize"); - /* * Remove parameters controlling the code cache. As these * parameters have implications on the physical memory From 38eb4a4f6f98af2bc1c10cfdcf386286b233fa96 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Tue, 6 Sep 2016 13:01:27 +0200 Subject: [PATCH 024/207] 8165489: Missing G1 barrier in Unsafe_GetObjectVolatile Add missing barrier, sharing code with Unsafe_GetObject. Reviewed-by: kbarrett, mgerdin, pliden --- hotspot/src/share/vm/prims/unsafe.cpp | 56 ++++++++++++++------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp index 6703b7471c3..1c98add775b 100644 --- a/hotspot/src/share/vm/prims/unsafe.cpp +++ b/hotspot/src/share/vm/prims/unsafe.cpp @@ -272,6 +272,31 @@ public: // Get/PutObject must be special-cased, since it works with handles. +// We could be accessing the referent field in a reference +// object. If G1 is enabled then we need to register non-null +// referent with the SATB barrier. + +#if INCLUDE_ALL_GCS +static bool is_java_lang_ref_Reference_access(oop o, jlong offset) { + if (offset == java_lang_ref_Reference::referent_offset && o != NULL) { + Klass* k = o->klass(); + if (InstanceKlass::cast(k)->reference_type() != REF_NONE) { + assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity"); + return true; + } + } + return false; +} +#endif + +static void ensure_satb_referent_alive(oop o, jlong offset, oop v) { +#if INCLUDE_ALL_GCS + if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) { + G1SATBCardTableModRefBS::enqueue(v); + } +#endif +} + // These functions allow a null base pointer with an arbitrary address. // But if the base pointer is non-null, the offset should make some sense. // That is, it should be in the range [0, MAX_OBJECT_SIZE]. @@ -286,34 +311,9 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, v = *(oop*)index_oop_from_field_offset_long(p, offset); } - jobject ret = JNIHandles::make_local(env, v); + ensure_satb_referent_alive(p, offset, v); -#if INCLUDE_ALL_GCS - // We could be accessing the referent field in a reference - // object. If G1 is enabled then we need to register non-null - // referent with the SATB barrier. - if (UseG1GC) { - bool needs_barrier = false; - - if (ret != NULL) { - if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) { - oop o = JNIHandles::resolve(obj); - Klass* k = o->klass(); - if (InstanceKlass::cast(k)->reference_type() != REF_NONE) { - assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity"); - needs_barrier = true; - } - } - } - - if (needs_barrier) { - oop referent = JNIHandles::resolve(ret); - G1SATBCardTableModRefBS::enqueue(referent); - } - } -#endif // INCLUDE_ALL_GCS - - return ret; + return JNIHandles::make_local(env, v); } UNSAFE_END UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { @@ -344,6 +344,8 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobj (void)const_cast(v = *(volatile oop*) addr); } + ensure_satb_referent_alive(p, offset, v); + OrderAccess::acquire(); return JNIHandles::make_local(env, v); } UNSAFE_END From 6075eea5057c542a7dbe543719ee4491c9428bcc Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Thu, 8 Sep 2016 15:23:05 +0300 Subject: [PATCH 025/207] 8165433: Convert Test_linked_list to Gtest Reviewed-by: coleenp, dholmes, iignatyev --- .../share/vm/utilities/internalVMTests.cpp | 1 - .../native/utilities/test_linkedlist.cpp} | 87 ++++++++++--------- 2 files changed, 47 insertions(+), 41 deletions(-) rename hotspot/{src/share/vm/utilities/linkedlist.cpp => test/native/utilities/test_linkedlist.cpp} (53%) diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 655df4970b6..b9e8b84309e 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -60,7 +60,6 @@ void InternalVMTests::run() { run_unit_test(TestBitMap_test); run_unit_test(TestResourcehash_test); run_unit_test(ObjectMonitor_test); - run_unit_test(Test_linked_list); run_unit_test(TestChunkedList_test); run_unit_test(JSON_test); run_unit_test(Test_log_tag_combinations_limit); diff --git a/hotspot/src/share/vm/utilities/linkedlist.cpp b/hotspot/test/native/utilities/test_linkedlist.cpp similarity index 53% rename from hotspot/src/share/vm/utilities/linkedlist.cpp rename to hotspot/test/native/utilities/test_linkedlist.cpp index ba96b2e247f..34aa774ebdc 100644 --- a/hotspot/src/share/vm/utilities/linkedlist.cpp +++ b/hotspot/test/native/utilities/test_linkedlist.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,96 +19,103 @@ * 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" - -/////////////// Unit tests /////////////// - -#ifndef PRODUCT - -#include "runtime/os.hpp" +#include "unittest.hpp" #include "utilities/linkedlist.hpp" -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" class Integer : public StackObj { private: - int _value; + int _value; public: - Integer(int i) : _value(i) { } - int value() const { return _value; } - bool equals(const Integer& i) const { - return _value == i.value(); + Integer(int i) : _value(i) { + } + + int value() const { + return _value; + } + + bool equals(const Integer& i) const { + return _value == i.value(); + } + + static int compare(const Integer& i1, const Integer& i2) { + return i1.value() - i2.value(); } }; -int compare_Integer(const Integer& i1, const Integer& i2) { - return i1.value() - i2.value(); -} - -void check_list_values(const int* expected, const LinkedList* list) { +static void check_list_values(const int* expected, const LinkedList* list) { LinkedListNode* head = list->head(); int index = 0; while (head != NULL) { - assert(head->peek()->value() == expected[index], "Unexpected value"); + ASSERT_EQ(expected[index], head->peek()->value()) + << "Unexpected value at index " << index; head = head->next(); - index ++; + index++; } } -void Test_linked_list() { - LinkedListImpl ll; +const Integer one(1), two(2), three(3), four(4), five(5), six(6); +// Test regular linked list +TEST(LinkedList, simple) { + LinkedListImpl ll; - // Test regular linked list - assert(ll.is_empty(), "Start with empty list"); - Integer one(1), two(2), three(3), four(4), five(5), six(6); + ASSERT_TRUE(ll.is_empty()) << "Start with empty list"; ll.add(six); - assert(!ll.is_empty(), "Should not be empty"); + ASSERT_TRUE(!ll.is_empty()) << "Should not be empty"; Integer* i = ll.find(six); - assert(i != NULL, "Should find it"); + ASSERT_TRUE(i != NULL) << "Should find it"; + ASSERT_EQ(six.value(), i->value()) << "Should be 6"; i = ll.find(three); - assert(i == NULL, "Not in the list"); + ASSERT_EQ(NULL, i) << "Not in the list"; LinkedListNode* node = ll.find_node(six); - assert(node != NULL, "6 is in the list"); + ASSERT_TRUE(node != NULL) << "6 is in the list"; ll.insert_after(three, node); ll.insert_before(one, node); int expected[3] = {1, 6, 3}; check_list_values(expected, &ll); +} +// Test sorted linked list +TEST(SortedLinkedList, simple) { + LinkedListImpl ll; + ll.add(one); + ll.add(six); + ll.add(three); ll.add(two); ll.add(four); ll.add(five); - // Test sorted linked list - SortedLinkedList sl; - assert(sl.is_empty(), "Start with empty list"); + SortedLinkedList sl; + ASSERT_TRUE(sl.is_empty()) << "Start with empty list"; size_t ll_size = ll.size(); sl.move(&ll); size_t sl_size = sl.size(); - assert(ll_size == sl_size, "Should be the same size"); - assert(ll.is_empty(), "No more entires"); + ASSERT_EQ(ll_size, sl_size) << "Should be the same size"; + ASSERT_TRUE(ll.is_empty()) << "No more entries"; // sorted result int sorted_result[] = {1, 2, 3, 4, 5, 6}; check_list_values(sorted_result, &sl); + if (HasFatalFailure()) { + return; + } - node = sl.find_node(four); - assert(node != NULL, "4 is in the list"); + LinkedListNode* node = sl.find_node(four); + ASSERT_TRUE(node != NULL) << "4 is in the list"; sl.remove_before(node); sl.remove_after(node); int remains[] = {1, 2, 4, 6}; check_list_values(remains, &sl); } -#endif // PRODUCT - From 4eab390a81b7f190abb18affb48e44fcd67e3138 Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Thu, 8 Sep 2016 18:41:10 +0300 Subject: [PATCH 026/207] 8165601: Convert arrayOopDesc_test to Gtest Reviewed-by: coleenp, iignatyev --- hotspot/src/share/vm/oops/arrayOop.cpp | 62 ------------- hotspot/src/share/vm/oops/arrayOop.hpp | 7 +- .../share/vm/utilities/internalVMTests.cpp | 1 - hotspot/test/native/oops/test_arrayOop.cpp | 89 +++++++++++++++++++ 4 files changed, 91 insertions(+), 68 deletions(-) delete mode 100644 hotspot/src/share/vm/oops/arrayOop.cpp create mode 100644 hotspot/test/native/oops/test_arrayOop.cpp diff --git a/hotspot/src/share/vm/oops/arrayOop.cpp b/hotspot/src/share/vm/oops/arrayOop.cpp deleted file mode 100644 index cd9ffcd8529..00000000000 --- a/hotspot/src/share/vm/oops/arrayOop.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 1997, 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. - * - */ - -#include "precompiled.hpp" - -/////////////// Unit tests /////////////// - -#ifndef PRODUCT - -#include "oops/arrayOop.hpp" -#include "oops/oop.inline.hpp" -#include "utilities/globalDefinitions.hpp" - -bool arrayOopDesc::check_max_length_overflow(BasicType type) { - julong length = max_array_length(type); - julong bytes_per_element = type2aelembytes(type); - julong bytes = length * bytes_per_element + header_size_in_bytes(); - return (julong)(size_t)bytes == bytes; -} - -static void test_max_array_length() { - assert(arrayOopDesc::check_max_length_overflow(T_BOOLEAN), "size_t overflow for boolean array"); - assert(arrayOopDesc::check_max_length_overflow(T_CHAR), "size_t overflow for char array"); - assert(arrayOopDesc::check_max_length_overflow(T_FLOAT), "size_t overflow for float array"); - assert(arrayOopDesc::check_max_length_overflow(T_DOUBLE), "size_t overflow for double array"); - assert(arrayOopDesc::check_max_length_overflow(T_BYTE), "size_t overflow for byte array"); - assert(arrayOopDesc::check_max_length_overflow(T_SHORT), "size_t overflow for short array"); - assert(arrayOopDesc::check_max_length_overflow(T_INT), "size_t overflow for int array"); - assert(arrayOopDesc::check_max_length_overflow(T_LONG), "size_t overflow for long array"); - assert(arrayOopDesc::check_max_length_overflow(T_OBJECT), "size_t overflow for object array"); - assert(arrayOopDesc::check_max_length_overflow(T_ARRAY), "size_t overflow for array array"); - assert(arrayOopDesc::check_max_length_overflow(T_NARROWOOP), "size_t overflow for narrowOop array"); - - // T_VOID and T_ADDRESS are not supported by max_array_length() -} - -void arrayOopDesc_test() { - test_max_array_length(); -} - -#endif //PRODUCT diff --git a/hotspot/src/share/vm/oops/arrayOop.hpp b/hotspot/src/share/vm/oops/arrayOop.hpp index 8e9c2af6c8a..be439a28735 100644 --- a/hotspot/src/share/vm/oops/arrayOop.hpp +++ b/hotspot/src/share/vm/oops/arrayOop.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ class arrayOopDesc : public oopDesc { friend class VMStructs; + friend class arrayOopDescTest; // Interpreter/Compiler offsets @@ -124,10 +125,6 @@ class arrayOopDesc : public oopDesc { return (int32_t)max_elements_per_size_t; } -// for unit testing -#ifndef PRODUCT - static bool check_max_length_overflow(BasicType type); -#endif }; #endif // SHARE_VM_OOPS_ARRAYOOP_HPP diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 5ab07de5622..92b42b434b0 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -52,7 +52,6 @@ void InternalVMTests::run() { run_unit_test(TestVirtualSpaceNode_test); run_unit_test(TestGlobalDefinitions_test); run_unit_test(GCTimer_test); - run_unit_test(arrayOopDesc_test); run_unit_test(CollectedHeap_test); run_unit_test(QuickSort_test); run_unit_test(GuardedMemory_test); diff --git a/hotspot/test/native/oops/test_arrayOop.cpp b/hotspot/test/native/oops/test_arrayOop.cpp new file mode 100644 index 00000000000..915ff34380f --- /dev/null +++ b/hotspot/test/native/oops/test_arrayOop.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "oops/arrayOop.hpp" +#include "oops/oop.inline.hpp" +#include "unittest.hpp" +#include "utilities/globalDefinitions.hpp" + +class arrayOopDescTest { + public: + + static int header_size_in_bytes() { + return arrayOopDesc::header_size_in_bytes(); + } +}; + +static bool check_max_length_overflow(BasicType type) { + julong length = arrayOopDesc::max_array_length(type); + julong bytes_per_element = type2aelembytes(type); + julong bytes = length * bytes_per_element + + arrayOopDescTest::header_size_in_bytes(); + return (julong) (size_t) bytes == bytes; +} + +TEST(arrayOopDesc, boolean) { + ASSERT_PRED1(check_max_length_overflow, T_BOOLEAN); +} + +TEST(arrayOopDesc, char) { + ASSERT_PRED1(check_max_length_overflow, T_CHAR); +} + +TEST(arrayOopDesc, float) { + ASSERT_PRED1(check_max_length_overflow, T_FLOAT); +} + +TEST(arrayOopDesc, double) { + ASSERT_PRED1(check_max_length_overflow, T_DOUBLE); +} + +TEST(arrayOopDesc, byte) { + ASSERT_PRED1(check_max_length_overflow, T_BYTE); +} + +TEST(arrayOopDesc, short) { + ASSERT_PRED1(check_max_length_overflow, T_SHORT); +} + +TEST(arrayOopDesc, int) { + ASSERT_PRED1(check_max_length_overflow, T_INT); +} + +TEST(arrayOopDesc, long) { + ASSERT_PRED1(check_max_length_overflow, T_LONG); +} + +TEST(arrayOopDesc, object) { + ASSERT_PRED1(check_max_length_overflow, T_OBJECT); +} + +TEST(arrayOopDesc, array) { + ASSERT_PRED1(check_max_length_overflow, T_ARRAY); +} + +TEST(arrayOopDesc, narrowOop) { + ASSERT_PRED1(check_max_length_overflow, T_NARROWOOP); +} +// T_VOID and T_ADDRESS are not supported by max_array_length() From 490797cd1aa91251c608b7f6ac8c512d960b79fb Mon Sep 17 00:00:00 2001 From: Jayathirth D V Date: Wed, 14 Sep 2016 12:13:46 +0530 Subject: [PATCH 027/207] 8162461: Hang due to JNI up-call made whilst holding JNI critical lock Reviewed-by: prr, psadhukhan --- .../share/native/libjavajpeg/imageioJPEG.c | 80 +++++++++++++------ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c index b54ad836f69..9be3de81285 100644 --- a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c +++ b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -553,30 +553,43 @@ sun_jpeg_error_exit (j_common_ptr cinfo) METHODDEF(void) sun_jpeg_output_message (j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; - jstring string; - imageIODataPtr data = (imageIODataPtr) cinfo->client_data; - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - jobject theObject; + char buffer[JMSG_LENGTH_MAX]; + jstring string; + imageIODataPtr data = (imageIODataPtr) cinfo->client_data; + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + jobject theObject; - /* Create the message */ - (*cinfo->err->format_message) (cinfo, buffer); + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); - // Create a new java string from the message - string = (*env)->NewStringUTF(env, buffer); - CHECK_NULL(string); + // Create a new java string from the message + string = (*env)->NewStringUTF(env, buffer); + CHECK_NULL(string); - theObject = data->imageIOobj; + theObject = data->imageIOobj; - if (cinfo->is_decompressor) { - (*env)->CallVoidMethod(env, theObject, - JPEGImageReader_warningWithMessageID, - string); - } else { - (*env)->CallVoidMethod(env, theObject, - JPEGImageWriter_warningWithMessageID, - string); - } + if (cinfo->is_decompressor) { + struct jpeg_source_mgr *src = ((j_decompress_ptr)cinfo)->src; + RELEASE_ARRAYS(env, data, src->next_input_byte); + (*env)->CallVoidMethod(env, theObject, + JPEGImageReader_warningWithMessageID, + string); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit(cinfo); + } + } else { + struct jpeg_destination_mgr *dest = ((j_compress_ptr)cinfo)->dest; + RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); + (*env)->CallVoidMethod(env, theObject, + JPEGImageWriter_warningWithMessageID, + string); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, + (const JOCTET **)(&dest->next_output_byte))) { + cinfo->err->error_exit(cinfo); + } + } } /* End of verbatim copy from jpegdecoder.c */ @@ -1043,6 +1056,7 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo) if (!GET_ARRAYS(env, data, &(src->next_input_byte))) { cinfo->err->error_exit((j_common_ptr) cinfo); } + RELEASE_ARRAYS(env, data, src->next_input_byte); return; } @@ -1798,9 +1812,14 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader cinfo->out_color_space, cinfo->num_components, profileData); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } if (reset) { jpeg_abort_decompress(cinfo); } + RELEASE_ARRAYS(env, data, src->next_input_byte); } return retval; @@ -2010,6 +2029,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage jpeg_start_decompress(cinfo); if (numBands != cinfo->output_components) { + RELEASE_ARRAYS(env, data, src->next_input_byte); JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid argument to native readImage"); return data->abortFlag; @@ -2018,6 +2038,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage if (cinfo->output_components <= 0 || cinfo->image_width > (0xffffffffu / (unsigned int)cinfo->output_components)) { + RELEASE_ARRAYS(env, data, src->next_input_byte); JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid number of output components"); return data->abortFlag; @@ -2041,15 +2062,24 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage // the first interesting pass. jpeg_start_output(cinfo, cinfo->input_scan_number); if (wantUpdates) { + RELEASE_ARRAYS(env, data, src->next_input_byte); (*env)->CallVoidMethod(env, this, JPEGImageReader_passStartedID, cinfo->input_scan_number-1); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } } } else if (wantUpdates) { + RELEASE_ARRAYS(env, data, src->next_input_byte); (*env)->CallVoidMethod(env, this, JPEGImageReader_passStartedID, 0); - + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } } // Skip until the first interesting line @@ -2137,8 +2167,13 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage done = TRUE; } if (wantUpdates) { + RELEASE_ARRAYS(env, data, src->next_input_byte); (*env)->CallVoidMethod(env, this, JPEGImageReader_passCompleteID); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } } } @@ -2837,7 +2872,6 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage if (setjmp(jerr->setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error while writing. */ - RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); if (!(*env)->ExceptionOccurred(env)) { char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message) ((j_common_ptr) cinfo, From c8171aea49e8b4f81d3980929309779b848e9add Mon Sep 17 00:00:00 2001 From: Ambarish Rapte Date: Wed, 14 Sep 2016 21:50:44 +0530 Subject: [PATCH 028/207] 8160056: TextField.setText breaks the contract of EOL Reviewed-by: serb, alexsch --- .../share/classes/java/awt/TextField.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/java/awt/TextField.java b/jdk/src/java.desktop/share/classes/java/awt/TextField.java index d052ef526b0..f57572bc918 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/TextField.java +++ b/jdk/src/java.desktop/share/classes/java/awt/TextField.java @@ -159,8 +159,8 @@ public class TextField extends TextComponent { * @param text the text to be displayed. If * {@code text} is {@code null}, the empty * string {@code ""} will be displayed. - * If {@code text} contains EOL character, then - * it will be replaced by space character. + * If {@code text} contains EOL and/or LF characters, then + * each will be replaced by space character. * @exception HeadlessException if GraphicsEnvironment.isHeadless() * returns true. * @see java.awt.GraphicsEnvironment#isHeadless @@ -192,8 +192,8 @@ public class TextField extends TextComponent { * @param text the text to be displayed. If * {@code text} is {@code null}, the empty * string {@code ""} will be displayed. - * If {@code text} contains EOL character, then - * it will be replaced by space character. + * If {@code text} contains EOL and/or LF characters, then + * each will be replaced by space character. * @param columns the number of columns. If * {@code columns} is less than {@code 0}, * {@code columns} is set to {@code 0}. @@ -300,8 +300,8 @@ public class TextField extends TextComponent { * @param t the new text. If * {@code t} is {@code null}, the empty * string {@code ""} will be displayed. - * If {@code t} contains EOL character, then - * it will be replaced by space character. + * If {@code t} contains EOL and/or LF characters, then + * each will be replaced by space character. * @see java.awt.TextComponent#getText */ public void setText(String t) { From 0170925204acf9f9e60e931d4ef91d088390a650 Mon Sep 17 00:00:00 2001 From: Ambarish Rapte Date: Thu, 15 Sep 2016 01:36:56 +0530 Subject: [PATCH 029/207] 8162102: access denied to System Property awt.robot.gtk Reviewed-by: ssadetsky, serb --- .../java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java index 10b28cdfafb..c300431cf88 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java @@ -26,6 +26,8 @@ package sun.awt.X11; import java.awt.*; import java.awt.peer.*; +import java.security.AccessController; +import java.security.PrivilegedAction; import sun.awt.AWTAccessor; import sun.awt.SunToolkit; @@ -38,7 +40,8 @@ class XRobotPeer implements RobotPeer { static final boolean tryGtk; static { loadNativeLibraries(); - tryGtk = Boolean.getBoolean("awt.robot.gtk"); + tryGtk = AccessController.doPrivileged((PrivilegedAction)() + -> Boolean.getBoolean("awt.robot.gtk")); } private static boolean isGtkSupported = false; From 5e5d4783a8562c08bee6b50ecddae06addc4e9b3 Mon Sep 17 00:00:00 2001 From: Manajit Halder Date: Thu, 15 Sep 2016 12:25:16 +0530 Subject: [PATCH 030/207] 8163270: [macosx] Robot(gc) issue on dual-screen system Reviewed-by: serb, aghaisas --- .../SpuriousMouseEvents.java | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 jdk/test/java/awt/Robot/SpuriousMouseEvents/SpuriousMouseEvents.java diff --git a/jdk/test/java/awt/Robot/SpuriousMouseEvents/SpuriousMouseEvents.java b/jdk/test/java/awt/Robot/SpuriousMouseEvents/SpuriousMouseEvents.java new file mode 100644 index 00000000000..0b19682cb78 --- /dev/null +++ b/jdk/test/java/awt/Robot/SpuriousMouseEvents/SpuriousMouseEvents.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + @test + @key headful + @bug 5097801 8163270 + @summary Tests that no mouse events are sent to component if robot is + moving mouse on another screen, Xinerama + @run main SpuriousMouseEvents + */ +import java.awt.AWTException; +import java.awt.GraphicsEnvironment; +import java.awt.GraphicsDevice; +import java.awt.Robot; +import java.awt.GraphicsConfiguration; +import java.awt.Frame; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseEvent; + +public class SpuriousMouseEvents { + + private static volatile boolean testPassed = true; + + public static void main(String args[]) throws AWTException { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gds = ge.getScreenDevices(); + if (gds.length < 2) { + return; + } + + Robot r = null; + try { + r = new Robot(); + } catch (Exception e) { + throw new RuntimeException("Couldn't create AWT robot" + e); + } + + for (int i = 1; i >= 0; i--) { + GraphicsDevice gd = gds[i]; + GraphicsDevice gdo = gds[1 - i]; + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + GraphicsConfiguration gco = gdo.getDefaultConfiguration(); + Frame f = new Frame("Frame", gc); + f.setBounds(gc.getBounds().x + 100, gc.getBounds().y + 100, 200, 200); + f.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent me) { + testPassed = false; + } + }); + f.setVisible(true); + + r = new Robot(gdo); + int x = (int) gco.getBounds().x; + for (int j = x; j < x + 400; j += 10) { + r.mouseMove(j, 200); + r.delay(10); + } + r.delay(1000); + + f.setVisible(false); + f.dispose(); + + if (!testPassed) { + break; + } + } + + if (!testPassed) { + throw new RuntimeException("Wrong mouse events are sent"); + } + } +} From 8ac9764ee7a9ce3f3ed6e691d464d42662988b17 Mon Sep 17 00:00:00 2001 From: Rajeev Chamyal Date: Thu, 15 Sep 2016 16:12:08 +0530 Subject: [PATCH 031/207] 8150176: [hidpi] wrong resolution variant of multi-res. image is used for TrayIcon Reviewed-by: serb, alexsch --- .../sun/awt/windows/WTrayIconPeer.java | 19 +- .../MultiResolutionTrayIconTest.html | 41 ---- .../MultiResolutionTrayIconTest.java | 219 ++++++++++++------ 3 files changed, 164 insertions(+), 115 deletions(-) delete mode 100644 jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.html diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java index b2828e2503f..93a44c29126 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java @@ -28,16 +28,19 @@ package sun.awt.windows; import java.awt.Graphics2D; import java.awt.AWTEvent; import java.awt.Frame; +import java.awt.GraphicsEnvironment; import java.awt.PopupMenu; import java.awt.Point; import java.awt.TrayIcon; import java.awt.Image; +import java.awt.geom.AffineTransform; import java.awt.peer.TrayIconPeer; import java.awt.image.*; import sun.awt.AWTAccessor; import sun.awt.SunToolkit; import sun.awt.image.IntegerComponentRaster; +import sun.java2d.pipe.Region; final class WTrayIconPeer extends WObjectPeer implements TrayIconPeer { static final int TRAY_ICON_WIDTH = 16; @@ -123,16 +126,22 @@ final class WTrayIconPeer extends WObjectPeer implements TrayIconPeer { return; boolean autosize = ((TrayIcon)target).isImageAutoSize(); - - BufferedImage bufImage = new BufferedImage(TRAY_ICON_WIDTH, TRAY_ICON_HEIGHT, - BufferedImage.TYPE_INT_ARGB); + AffineTransform tx = GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(). + getDefaultTransform(); + int w = Region.clipScale(TRAY_ICON_WIDTH, tx.getScaleX()); + int h = Region.clipScale(TRAY_ICON_HEIGHT, tx.getScaleY()); + int imgWidth = Region.clipScale(image.getWidth(observer), tx.getScaleX()); + int imgHeight = Region.clipScale(image.getHeight(observer), tx.getScaleY()); + BufferedImage bufImage = new BufferedImage(w, + h, BufferedImage.TYPE_INT_ARGB); Graphics2D gr = bufImage.createGraphics(); if (gr != null) { try { gr.setPaintMode(); - gr.drawImage(image, 0, 0, (autosize ? TRAY_ICON_WIDTH : image.getWidth(observer)), - (autosize ? TRAY_ICON_HEIGHT : image.getHeight(observer)), observer); + gr.drawImage(image, 0, 0, (autosize ? w : imgWidth), + (autosize ? h : imgHeight), observer); createNativeImage(bufImage); diff --git a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.html b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.html deleted file mode 100644 index 7ff1134a69d..00000000000 --- a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - MultiResolutionTrayIconTest - - - - -To run test please push "Start" (if system tray is not supported, push "Pass"). - -Two tray icons will appear (note: sometimes they can go to the tray icons pool). - -Please check if both of them have correct size and -the same colouring (white rectagle in a blue mount). In this case please push "Pass". - -Otherwise (if the 2nd red-white small icon appears) please push "Fail". - - - diff --git a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java index bb0a7525ec7..3f3627f4a7f 100644 --- a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java +++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java @@ -22,96 +22,177 @@ */ -/* - @test - @bug 8150176 8151773 - @summary Check if correct resolution variant is used for tray icon. - @author a.stepanov - @run applet/manual=yesno MultiResolutionTrayIconTest.html -*/ +/** + * @test + * @key headful + * @bug 8150176 8151773 8150176 + * @summary Check if correct resolution variant is used for tray icon. + * @run main/manual/othervm -Dsun.java2d.uiScale=2 MultiResolutionTrayIconTest + */ +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BaseMultiResolutionImage; +import java.awt.image.BufferedImage; +import javax.swing.JFrame; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +public class MultiResolutionTrayIconTest { + private static SystemTray tray; + private static TrayIcon icon; + private static GridBagLayout layout; + private static JPanel mainControlPanel; + private static JPanel resultButtonPanel; + private static JLabel instructionText; + private static JButton passButton; + private static JButton failButton; + private static JButton startButton; + private static JFrame mainFrame; + private static CountDownLatch latch; -import java.applet.Applet; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; - - -public class MultiResolutionTrayIconTest extends Applet { - - private SystemTray tray; - private TrayIcon icon, iconMRI; - - public void init() { this.setLayout(new BorderLayout()); } - - public void start() { - - boolean trayIsSupported = SystemTray.isSupported(); - Button b = new Button("Start"); - if (trayIsSupported) { - - prepareIcons(); - b.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { doTest(); } - }); - } else { - b.setLabel("not supported"); - b.setEnabled(false); - System.out.println("system tray is not supported"); - } - add(b, BorderLayout.CENTER); - - validate(); - setVisible(true); + public static void main(String[] args) throws Exception { + latch = new CountDownLatch(1); + createUI(); + latch.await(200, TimeUnit.SECONDS); } - private BufferedImage generateImage(int w, int h, Color c) { + public static void createUI() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + mainFrame = new JFrame("TrayIcon Test"); + boolean trayIsSupported = SystemTray.isSupported(); + tray = SystemTray.getSystemTray(); + Dimension d = tray.getTrayIconSize(); + icon = new TrayIcon(createIcon(d.width, d.height)); + icon.setImageAutoSize(true); + layout = new GridBagLayout(); + mainControlPanel = new JPanel(layout); + resultButtonPanel = new JPanel(layout); - BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + GridBagConstraints gbc = new GridBagConstraints(); + String instructions + = "INSTRUCTIONS:
" + + "Press start button to add icon to system tray.

" + + "If Icon color is green test" + + " passes else failed.

"; + + instructionText = new JLabel(); + instructionText.setText(instructions); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.HORIZONTAL; + mainControlPanel.add(instructionText, gbc); + startButton = new JButton("Start"); + startButton.setActionCommand("Start"); + if (trayIsSupported) { + + startButton.addActionListener((ActionEvent e) -> { + doTest(); + }); + } else { + startButton.setEnabled(false); + System.out.println("system tray is not supported"); + latch.countDown(); + } + gbc.gridx = 0; + gbc.gridy = 0; + resultButtonPanel.add(startButton, gbc); + + passButton = new JButton("Pass"); + passButton.setActionCommand("Pass"); + passButton.addActionListener((ActionEvent e) -> { + latch.countDown(); + removeIcon(); + mainFrame.dispose(); + }); + failButton = new JButton("Fail"); + failButton.setActionCommand("Fail"); + failButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + removeIcon(); + latch.countDown(); + mainFrame.dispose(); + throw new RuntimeException("Test Failed"); + } + }); + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(passButton, gbc); + gbc.gridx = 2; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 1; + mainControlPanel.add(resultButtonPanel, gbc); + + mainFrame.add(mainControlPanel); + mainFrame.setSize(400, 200); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + + mainFrame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + removeIcon(); + latch.countDown(); + mainFrame.dispose(); + } + }); + } + }); + + } + + private static BaseMultiResolutionImage createIcon(int w, int h) { + return new BaseMultiResolutionImage( + new BufferedImage[]{generateImage(w, h, 1, Color.RED), + generateImage(w, h, 2, Color.GREEN)}); + } + + private static BufferedImage generateImage(int w, int h, int scale, Color c) { + + int x = w * scale, y = h * scale; + BufferedImage img = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB); Graphics g = img.getGraphics(); g.setColor(c); - g.fillRect(0, 0, w, h); + g.fillRect(0, 0, x, y); g.setColor(Color.WHITE); - int r = (Math.min(w, h) >= 8) ? 3 : 1; - g.fillRect(r, r, w - 2 * r, h - 2 * r); + g.fillRect(x / 3, y / 3, x / 3, y / 3); return img; } - private void prepareIcons() { + private static void doTest() { - tray = SystemTray.getSystemTray(); - Dimension d = tray.getTrayIconSize(); - int w = d.width, h = d.height; - - BufferedImage img = generateImage(w, h, Color.BLUE); - // use wrong icon size for "nok" - BufferedImage nok = generateImage(w / 2 + 2, h / 2 + 2, Color.RED); - BaseMultiResolutionImage mri = - new BaseMultiResolutionImage(new BufferedImage[] {nok, img}); - icon = new TrayIcon(img); - icon.setImageAutoSize(true); // just in case - iconMRI = new TrayIcon(mri); - iconMRI.setImageAutoSize(true); - } - - private void doTest() { - - if (tray.getTrayIcons().length > 0) { return; } // icons were added already + if (tray.getTrayIcons().length > 0) { + return; + } try { tray.add(icon); - tray.add(iconMRI); } catch (Exception e) { throw new RuntimeException(e); } } - public void stop() { - - // check for null, just in case + private static void removeIcon() { if (tray != null) { tray.remove(icon); - tray.remove(iconMRI); } } } + From c0c4200524042c61d3bb8943545bcd45798c6a6c Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Fri, 23 Sep 2016 18:23:12 -0400 Subject: [PATCH 032/207] 8166583: Add oopDesc::klass_or_null_acquire() Added new function. Reviewed-by: dholmes, tschatzl --- hotspot/src/share/vm/oops/oop.hpp | 1 + hotspot/src/share/vm/oops/oop.inline.hpp | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp index 647cec8c83a..3bcab3c8a38 100644 --- a/hotspot/src/share/vm/oops/oop.hpp +++ b/hotspot/src/share/vm/oops/oop.hpp @@ -83,6 +83,7 @@ class oopDesc { inline Klass* klass() const; inline Klass* klass_or_null() const volatile; + inline Klass* klass_or_null_acquire() const volatile; inline Klass** klass_addr(); inline narrowKlass* compressed_klass_addr(); diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index 9a981e05c19..7697d703a1e 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -109,7 +109,6 @@ Klass* oopDesc::klass() const { } Klass* oopDesc::klass_or_null() const volatile { - // can be NULL in CMS if (UseCompressedClassPointers) { return Klass::decode_klass(_metadata._compressed_klass); } else { @@ -117,6 +116,17 @@ Klass* oopDesc::klass_or_null() const volatile { } } +Klass* oopDesc::klass_or_null_acquire() const volatile { + if (UseCompressedClassPointers) { + // Workaround for non-const load_acquire parameter. + const volatile narrowKlass* addr = &_metadata._compressed_klass; + volatile narrowKlass* xaddr = const_cast(addr); + return Klass::decode_klass(OrderAccess::load_acquire(xaddr)); + } else { + return (Klass*)OrderAccess::load_ptr_acquire(&_metadata._klass); + } +} + Klass** oopDesc::klass_addr() { // Only used internally and with CMS and will not work with // UseCompressedOops From 1d00efa1c6400b59f80533a1e591e7c19521d757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Sat, 24 Sep 2016 16:02:29 -0400 Subject: [PATCH 033/207] 8165858: heapRegionManager is missing volatile specifier for _claims Added volatile specifier. Reviewed-by: kbarrett, tschatzl --- hotspot/src/share/vm/gc/g1/heapRegionManager.cpp | 5 +++-- hotspot/src/share/vm/gc/g1/heapRegionManager.hpp | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp index f0887f93688..7854671bf48 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp @@ -482,8 +482,9 @@ void HeapRegionManager::verify_optional() { HeapRegionClaimer::HeapRegionClaimer(uint n_workers) : _n_workers(n_workers), _n_regions(G1CollectedHeap::heap()->_hrm._allocated_heapregions_length), _claims(NULL) { assert(n_workers > 0, "Need at least one worker."); - _claims = NEW_C_HEAP_ARRAY(uint, _n_regions, mtGC); - memset(_claims, Unclaimed, sizeof(*_claims) * _n_regions); + uint* new_claims = NEW_C_HEAP_ARRAY(uint, _n_regions, mtGC); + memset(new_claims, Unclaimed, sizeof(*_claims) * _n_regions); + _claims = new_claims; } HeapRegionClaimer::~HeapRegionClaimer() { diff --git a/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp index 07c84da348b..4f8863861f2 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp @@ -259,9 +259,9 @@ public: // The HeapRegionClaimer is used during parallel iteration over heap regions, // allowing workers to claim heap regions, gaining exclusive rights to these regions. class HeapRegionClaimer : public StackObj { - uint _n_workers; - uint _n_regions; - uint* _claims; + uint _n_workers; + uint _n_regions; + volatile uint* _claims; static const uint Unclaimed = 0; static const uint Claimed = 1; @@ -285,4 +285,3 @@ class HeapRegionClaimer : public StackObj { bool claim_region(uint region_index); }; #endif // SHARE_VM_GC_G1_HEAPREGIONMANAGER_HPP - From 9665140a14d217e7a82c08ad626e2193e2cfdbbf Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Thu, 15 Sep 2016 18:18:39 +0300 Subject: [PATCH 034/207] 8165602: Convert TestChunkedList_test to GTest Reviewed-by: iignatyev, dfazunen --- .../share/vm/utilities/internalVMTests.cpp | 1 - .../native/utilities/test_chunkedList.cpp} | 91 ++++++++++++------- 2 files changed, 56 insertions(+), 36 deletions(-) rename hotspot/{src/share/vm/utilities/chunkedList.cpp => test/native/utilities/test_chunkedList.cpp} (57%) diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index b9e8b84309e..f37c9dfc690 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -60,7 +60,6 @@ void InternalVMTests::run() { run_unit_test(TestBitMap_test); run_unit_test(TestResourcehash_test); run_unit_test(ObjectMonitor_test); - run_unit_test(TestChunkedList_test); run_unit_test(JSON_test); run_unit_test(Test_log_tag_combinations_limit); run_unit_test(Test_logtarget); diff --git a/hotspot/src/share/vm/utilities/chunkedList.cpp b/hotspot/test/native/utilities/test_chunkedList.cpp similarity index 57% rename from hotspot/src/share/vm/utilities/chunkedList.cpp rename to hotspot/test/native/utilities/test_chunkedList.cpp index caf80e7c102..73a54886606 100644 --- a/hotspot/src/share/vm/utilities/chunkedList.cpp +++ b/hotspot/test/native/utilities/test_chunkedList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,42 +19,40 @@ * 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 "unittest.hpp" #include "utilities/chunkedList.hpp" -#include "utilities/debug.hpp" -/////////////// Unit tests /////////////// - -#ifndef PRODUCT +class Metadata; template class TestChunkedList { typedef ChunkedList ChunkedListT; public: + static void testEmpty() { ChunkedListT buffer; - assert(buffer.size() == 0, "assert"); + ASSERT_EQ((size_t) 0, buffer.size()); } static void testFull() { ChunkedListT buffer; for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { - buffer.push((T)i); + buffer.push((T) i); } - assert(buffer.size() == ChunkedListT::BufferSize, "assert"); - assert(buffer.is_full(), "assert"); + ASSERT_EQ((size_t) ChunkedListT::BufferSize, buffer.size()); + ASSERT_TRUE(buffer.is_full()); } static void testSize() { ChunkedListT buffer; for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { - assert(buffer.size() == i, "assert"); - buffer.push((T)i); - assert(buffer.size() == i + 1, "assert"); + ASSERT_EQ((size_t) i, buffer.size()); + buffer.push((T) i); + ASSERT_EQ((size_t) (i + 1), buffer.size()); } } @@ -62,48 +60,71 @@ class TestChunkedList { ChunkedListT buffer; buffer.clear(); - assert(buffer.size() == 0, "assert"); + ASSERT_EQ((size_t) 0, buffer.size()); for (uintptr_t i = 0; i < ChunkedListT::BufferSize / 2; i++) { - buffer.push((T)i); + buffer.push((T) i); } buffer.clear(); - assert(buffer.size() == 0, "assert"); + ASSERT_EQ((size_t) 0, buffer.size()); for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { - buffer.push((T)i); + buffer.push((T) i); } buffer.clear(); - assert(buffer.size() == 0, "assert"); + ASSERT_EQ((size_t) 0, buffer.size()); } static void testAt() { ChunkedListT buffer; for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { - buffer.push((T)i); - assert(buffer.at(i) == (T)i, "assert"); + buffer.push((T) i); + ASSERT_EQ((T) i, buffer.at(i)); } for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { - assert(buffer.at(i) == (T)i, "assert"); + ASSERT_EQ((T) i, buffer.at(i)); } } - - static void test() { - testEmpty(); - testFull(); - testSize(); - testClear(); - testAt(); - } }; -class Metadata; - -void TestChunkedList_test() { - TestChunkedList::test(); - TestChunkedList::test(); +TEST(ChunkedList, metadata_empty) { + TestChunkedList::testEmpty(); } -#endif +TEST(ChunkedList, metadata_full) { + TestChunkedList::testFull(); +} + +TEST(ChunkedList, metadata_size) { + TestChunkedList::testSize(); +} + +TEST(ChunkedList, metadata_clear) { + TestChunkedList::testSize(); +} + +TEST(ChunkedList, metadata_at) { + TestChunkedList::testAt(); +} + +TEST(ChunkedList, size_t_empty) { + TestChunkedList::testEmpty(); +} + +TEST(ChunkedList, size_t_full) { + TestChunkedList::testFull(); +} + +TEST(ChunkedList, size_t_size) { + TestChunkedList::testSize(); +} + +TEST(ChunkedList, size_t_clear) { + TestChunkedList::testSize(); +} + +TEST(ChunkedList, size_t_at) { + TestChunkedList::testAt(); +} From 045f06e85d44babcfe940af956cceadae53ed5a1 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 16 Sep 2016 17:28:06 +0300 Subject: [PATCH 035/207] 8165717: [macosx] Various memory leaks in jdk9 Reviewed-by: ant, ssadetsky --- jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m | 1 - 1 file changed, 1 deletion(-) diff --git a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m index 579056f7117..2edec65f318 100644 --- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m +++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m @@ -376,7 +376,6 @@ AWT_ASSERT_APPKIT_THREAD; { void (^copy)() = [block copy]; NSInteger encode = (NSInteger) copy; - [copy retain]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined location: NSMakePoint(0,0) From 0581d8c4cb9f5aa80272a1af75743467e0aad1ab Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Fri, 16 Sep 2016 19:49:03 +0300 Subject: [PATCH 036/207] 8165613: Convert TestKlass_test to Gtest Reviewed-by: coleenp, rehn --- hotspot/src/share/vm/oops/klass.cpp | 24 ------------------- .../share/vm/utilities/internalVMTests.cpp | 1 - .../{runtime => oops}/test_instanceKlass.cpp | 15 ++++++++++-- 3 files changed, 13 insertions(+), 27 deletions(-) rename hotspot/test/native/{runtime => oops}/test_instanceKlass.cpp (74%) diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index 4953f383120..64c5c46c63e 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -734,27 +734,3 @@ bool Klass::verify_itable_index(int i) { } #endif - -/////////////// Unit tests /////////////// - -#ifndef PRODUCT - -class TestKlass { - public: - static void test_oop_is_instanceClassLoader() { - Klass* klass = SystemDictionary::ClassLoader_klass(); - guarantee(klass->is_instance_klass(), "assert"); - guarantee(InstanceKlass::cast(klass)->is_class_loader_instance_klass(), "test failed"); - - klass = SystemDictionary::String_klass(); - guarantee(!klass->is_instance_klass() || - !InstanceKlass::cast(klass)->is_class_loader_instance_klass(), - "test failed"); - } -}; - -void TestKlass_test() { - TestKlass::test_oop_is_instanceClassLoader(); -} - -#endif // PRODUCT diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 92b42b434b0..655df4970b6 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -57,7 +57,6 @@ void InternalVMTests::run() { run_unit_test(GuardedMemory_test); run_unit_test(TestNewSize_test); run_unit_test(TestOldSize_test); - run_unit_test(TestKlass_test); run_unit_test(TestBitMap_test); run_unit_test(TestResourcehash_test); run_unit_test(ObjectMonitor_test); diff --git a/hotspot/test/native/runtime/test_instanceKlass.cpp b/hotspot/test/native/oops/test_instanceKlass.cpp similarity index 74% rename from hotspot/test/native/runtime/test_instanceKlass.cpp rename to hotspot/test/native/oops/test_instanceKlass.cpp index 493a4e5d58c..2e223bc3bed 100644 --- a/hotspot/test/native/runtime/test_instanceKlass.cpp +++ b/hotspot/test/native/oops/test_instanceKlass.cpp @@ -19,18 +19,29 @@ * 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 "classfile/symbolTable.hpp" +#include "classfile/systemDictionary.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" #include "unittest.hpp" // Tests InstanceKlass::package_from_name() -TEST_VM(instanceKlass, null_symbol) { +TEST_VM(InstanceKlass, null_symbol) { ResourceMark rm; TempNewSymbol package_sym = InstanceKlass::package_from_name(NULL, NULL); ASSERT_TRUE(package_sym == NULL) << "Wrong package for NULL symbol"; } + +// Tests for InstanceKlass::is_class_loader_instance_klass() function +TEST_VM(InstanceKlass, class_loader_class) { + InstanceKlass* klass = SystemDictionary::ClassLoader_klass(); + ASSERT_TRUE(klass->is_class_loader_instance_klass()); +} + +TEST_VM(InstanceKlass, string_klass) { + InstanceKlass* klass = SystemDictionary::String_klass(); + ASSERT_TRUE(!klass->is_class_loader_instance_klass()); +} From eb529507040fb016dc5e3c7d34b928c30d320097 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Sun, 18 Sep 2016 21:10:48 -0400 Subject: [PATCH 037/207] 8078644: CDS needs to support JVMTI CFLH Support posting CLFH for shared classes. Tests are contributed by Misha Seledtsov. Reviewed-by: iklam, coleenp, acorn, dcubed, sspitsyn --- .../src/share/vm/classfile/klassFactory.cpp | 96 +++++++++- .../src/share/vm/classfile/klassFactory.hpp | 6 + .../share/vm/classfile/systemDictionary.cpp | 29 ++- hotspot/src/share/vm/memory/filemap.cpp | 2 +- hotspot/src/share/vm/memory/filemap.hpp | 25 ++- hotspot/src/share/vm/memory/metaspace.cpp | 48 ++--- .../src/share/vm/memory/metaspaceShared.cpp | 45 ++++- .../src/share/vm/memory/metaspaceShared.hpp | 13 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 27 ++- hotspot/src/share/vm/oops/instanceKlass.hpp | 9 +- hotspot/src/share/vm/utilities/debug.cpp | 6 + hotspot/src/share/vm/utilities/debug.hpp | 3 +- .../SharedArchiveFile/CDSTestUtils.java | 115 +++++++++++ .../transformRelatedClasses/Implementor.java | 37 ++++ .../transformRelatedClasses/Interface.java | 31 +++ .../transformRelatedClasses/SubClass.java | 40 ++++ .../transformRelatedClasses/SuperClazz.java | 32 ++++ .../transformRelatedClasses/TestEntry.java | 45 +++++ .../TransformInterfaceAndImplementor.java | 50 +++++ .../TransformRelatedClasses.java | 179 ++++++++++++++++++ .../TransformSuperAndSubClasses.java | 51 +++++ .../TransformSuperSubTwoPckgs.java | 52 +++++ .../TransformTestCommon.java | 114 +++++++++++ .../myPkg1/SuperClazz.java | 33 ++++ .../myPkg2/SubClass.java | 56 ++++++ .../test/testlibrary/jvmti/TransformUtil.java | 75 ++++++++ .../testlibrary/jvmti/TransformerAgent.java | 100 ++++++++++ .../testlibrary/jvmti/TransformerAgent.mf | 5 + 28 files changed, 1256 insertions(+), 68 deletions(-) create mode 100644 hotspot/test/runtime/SharedArchiveFile/CDSTestUtils.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Implementor.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Interface.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SubClass.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SuperClazz.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TestEntry.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformRelatedClasses.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformTestCommon.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg1/SuperClazz.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg2/SubClass.java create mode 100644 hotspot/test/testlibrary/jvmti/TransformUtil.java create mode 100644 hotspot/test/testlibrary/jvmti/TransformerAgent.java create mode 100644 hotspot/test/testlibrary/jvmti/TransformerAgent.mf diff --git a/hotspot/src/share/vm/classfile/klassFactory.cpp b/hotspot/src/share/vm/classfile/klassFactory.cpp index dc5f3963d1a..0c95ac7907d 100644 --- a/hotspot/src/share/vm/classfile/klassFactory.cpp +++ b/hotspot/src/share/vm/classfile/klassFactory.cpp @@ -25,12 +25,85 @@ #include "precompiled.hpp" #include "classfile/classFileParser.hpp" #include "classfile/classFileStream.hpp" +#include "classfile/classLoader.hpp" #include "classfile/classLoaderData.hpp" +#include "classfile/classLoaderData.inline.hpp" #include "classfile/klassFactory.hpp" +#include "classfile/sharedClassUtil.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "prims/jvmtiEnvBase.hpp" +#include "prims/jvmtiRedefineClasses.hpp" #include "trace/traceMacros.hpp" +// called during initial loading of a shared class +instanceKlassHandle KlassFactory::check_shared_class_file_load_hook( + instanceKlassHandle ik, + Symbol* class_name, + Handle class_loader, + Handle protection_domain, TRAPS) { +#if INCLUDE_CDS && INCLUDE_JVMTI + assert(ik.not_null(), "sanity"); + assert(ik()->is_shared(), "expecting a shared class"); + + if (JvmtiExport::should_post_class_file_load_hook()) { + assert(THREAD->is_Java_thread(), "must be JavaThread"); + + // Post the CFLH + JvmtiCachedClassFileData* cached_class_file = NULL; + JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data(); + assert(archived_class_data != NULL, "shared class has no archived class data"); + unsigned char* ptr = + VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data); + unsigned char* end_ptr = + ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data); + unsigned char* old_ptr = ptr; + JvmtiExport::post_class_file_load_hook(class_name, + class_loader, + protection_domain, + &ptr, + &end_ptr, + &cached_class_file); + if (old_ptr != ptr) { + // JVMTI agent has modified class file data. + // Set new class file stream using JVMTI agent modified class file data. + ClassLoaderData* loader_data = + ClassLoaderData::class_loader_data(class_loader()); + int path_index = ik->shared_classpath_index(); + SharedClassPathEntry* ent = + (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index); + ClassFileStream* stream = new ClassFileStream(ptr, + end_ptr - ptr, + ent->_name, + ClassFileStream::verify); + ClassFileParser parser(stream, + class_name, + loader_data, + protection_domain, + NULL, + NULL, + ClassFileParser::BROADCAST, // publicity level + CHECK_NULL); + instanceKlassHandle new_ik = parser.create_instance_klass(true /* changed_by_loadhook */, + CHECK_NULL); + if (cached_class_file != NULL) { + new_ik->set_cached_class_file(cached_class_file); + } + + if (class_loader.is_null()) { + ResourceMark rm; + ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD); + } + + return new_ik; + } + } +#endif + + return NULL; +} + + static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream, Symbol* name, ClassLoaderData* loader_data, @@ -97,7 +170,6 @@ instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream, const InstanceKlass* host_klass, GrowableArray* cp_patches, TRAPS) { - assert(stream != NULL, "invariant"); assert(loader_data != NULL, "invariant"); assert(THREAD->is_Java_thread(), "must be a JavaThread"); @@ -142,5 +214,27 @@ instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream, TRACE_KLASS_CREATION(result, parser, THREAD); +#if INCLUDE_CDS && INCLUDE_JVMTI + if (DumpSharedSpaces) { + assert(cached_class_file == NULL, "Sanity"); + // Archive the class stream data into the optional data section + JvmtiCachedClassFileData *p; + int len; + const unsigned char *bytes; + // event based tracing might set cached_class_file + if ((bytes = result->get_cached_class_file_bytes()) != NULL) { + len = result->get_cached_class_file_len(); + } else { + len = stream->length(); + bytes = stream->buffer(); + } + p = (JvmtiCachedClassFileData*)MetaspaceShared::optional_data_space_alloc( + offset_of(JvmtiCachedClassFileData, data) + len); + p->length = len; + memcpy(p->data, bytes, len); + result->set_archived_class_data(p); + } +#endif + return result; } diff --git a/hotspot/src/share/vm/classfile/klassFactory.hpp b/hotspot/src/share/vm/classfile/klassFactory.hpp index 72dcc0dd6e4..6624e31658e 100644 --- a/hotspot/src/share/vm/classfile/klassFactory.hpp +++ b/hotspot/src/share/vm/classfile/klassFactory.hpp @@ -75,6 +75,12 @@ class KlassFactory : AllStatic { const InstanceKlass* host_klass, GrowableArray* cp_patches, TRAPS); + public: + static instanceKlassHandle check_shared_class_file_load_hook( + instanceKlassHandle ik, + Symbol* class_name, + Handle class_loader, + Handle protection_domain, TRAPS); }; #endif // SHARE_VM_CLASSFILE_KLASSFACTORY_HPP diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index f3b667eaf43..02e1dbae6bc 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -1210,16 +1210,12 @@ Klass* SystemDictionary::find_shared_class(Symbol* class_name) { instanceKlassHandle SystemDictionary::load_shared_class( Symbol* class_name, Handle class_loader, TRAPS) { - // Don't load shared class when JvmtiExport::should_post_class_file_load_hook() - // is enabled since posting CFLH is not supported when loading shared class. - if (!JvmtiExport::should_post_class_file_load_hook()) { - instanceKlassHandle ik (THREAD, find_shared_class(class_name)); - // Make sure we only return the boot class for the NULL classloader. - if (ik.not_null() && - ik->is_shared_boot_class() && class_loader.is_null()) { - Handle protection_domain; - return load_shared_class(ik, class_loader, protection_domain, THREAD); - } + instanceKlassHandle ik (THREAD, find_shared_class(class_name)); + // Make sure we only return the boot class for the NULL classloader. + if (ik.not_null() && + ik->is_shared_boot_class() && class_loader.is_null()) { + Handle protection_domain; + return load_shared_class(ik, class_loader, protection_domain, THREAD); } return instanceKlassHandle(); } @@ -1303,11 +1299,6 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik, Handle class_loader, Handle protection_domain, TRAPS) { instanceKlassHandle nh = instanceKlassHandle(); // null Handle - if (JvmtiExport::should_post_class_file_load_hook()) { - // Don't load shared class when JvmtiExport::should_post_class_file_load_hook() - // is enabled since posting CFLH is not supported when loading shared class. - return nh; - } if (ik.not_null()) { Symbol* class_name = ik->name(); @@ -1358,6 +1349,14 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik, } } + instanceKlassHandle new_ik = KlassFactory::check_shared_class_file_load_hook( + ik, class_name, class_loader, protection_domain, CHECK_(nh)); + if (new_ik.not_null()) { + // The class is changed by CFLH. Return the new class. The shared class is + // not used. + return new_ik; + } + // Adjust methods to recover missing data. They need addresses for // interpreter entry points and their default native method address // must be reset. diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index 6dc7d1fb1c6..08a79f11f3b 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -649,7 +649,7 @@ ReservedSpace FileMapInfo::reserve_shared_memory() { // Memory map a region in the address space. static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode", - "String1", "String2" }; + "String1", "String2", "OptionalData" }; char* FileMapInfo::map_region(int i) { assert(!MetaspaceShared::is_string_region(i), "sanity"); diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp index 2c02b427f0b..baffd299436 100644 --- a/hotspot/src/share/vm/memory/filemap.hpp +++ b/hotspot/src/share/vm/memory/filemap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -252,10 +252,27 @@ public: bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false); void print_shared_spaces() NOT_CDS_RETURN; + // The ro+rw+md+mc spaces size + static size_t core_spaces_size() { + return align_size_up((SharedReadOnlySize + SharedReadWriteSize + + SharedMiscDataSize + SharedMiscCodeSize), + os::vm_allocation_granularity()); + } + + // The estimated optional space size. + // + // Currently the optional space only has archived class bytes. + // The core_spaces_size is the size of all class metadata, which is a good + // estimate of the total class bytes to be archived. Only the portion + // containing data is written out to the archive and mapped at runtime. + // There is no memory waste due to unused portion in optional space. + static size_t optional_space_size() { + return core_spaces_size(); + } + + // Total shared_spaces size includes the ro, rw, md, mc and od spaces static size_t shared_spaces_size() { - return align_size_up(SharedReadOnlySize + SharedReadWriteSize + - SharedMiscDataSize + SharedMiscCodeSize, - os::vm_allocation_granularity()); + return core_spaces_size() + optional_space_size(); } // Stop CDS sharing and unmap CDS regions. diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 1801a7c21cf..4ba897e7ab9 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -3172,36 +3172,28 @@ void Metaspace::global_initialize() { address cds_address = NULL; FileMapInfo* mapinfo = new FileMapInfo(); - if (JvmtiExport::should_post_class_file_load_hook()) { - // Currently CDS does not support JVMTI CFLH when loading shared class. - // If JvmtiExport::should_post_class_file_load_hook is already enabled, - // just disable UseSharedSpaces. - FileMapInfo::fail_continue("Tool agent requires sharing to be disabled."); - delete mapinfo; - } else { - // Open the shared archive file, read and validate the header. If - // initialization fails, shared spaces [UseSharedSpaces] are - // disabled and the file is closed. - // Map in spaces now also - if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) { - cds_total = FileMapInfo::shared_spaces_size(); - cds_address = (address)mapinfo->header()->region_addr(0); + // Open the shared archive file, read and validate the header. If + // initialization fails, shared spaces [UseSharedSpaces] are + // disabled and the file is closed. + // Map in spaces now also + if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) { + cds_total = FileMapInfo::shared_spaces_size(); + cds_address = (address)mapinfo->header()->region_addr(0); #ifdef _LP64 - if (using_class_space()) { - char* cds_end = (char*)(cds_address + cds_total); - cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment); - // If UseCompressedClassPointers is set then allocate the metaspace area - // above the heap and above the CDS area (if it exists). - allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address); - // Map the shared string space after compressed pointers - // because it relies on compressed class pointers setting to work - mapinfo->map_string_regions(); - } -#endif // _LP64 - } else { - assert(!mapinfo->is_open() && !UseSharedSpaces, - "archive file not closed or shared spaces not disabled."); + if (using_class_space()) { + char* cds_end = (char*)(cds_address + cds_total); + cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment); + // If UseCompressedClassPointers is set then allocate the metaspace area + // above the heap and above the CDS area (if it exists). + allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address); + // Map the shared string space after compressed pointers + // because it relies on compressed class pointers setting to work + mapinfo->map_string_regions(); } +#endif // _LP64 + } else { + assert(!mapinfo->is_open() && !UseSharedSpaces, + "archive file not closed or shared spaces not disabled."); } } #endif // INCLUDE_CDS diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index 66366273f19..61d6fa37b41 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -65,6 +65,7 @@ address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL; size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0; SharedMiscRegion MetaspaceShared::_mc; SharedMiscRegion MetaspaceShared::_md; +SharedMiscRegion MetaspaceShared::_od; void SharedMiscRegion::initialize(ReservedSpace rs, size_t committed_byte_size, SharedSpaceType space_type) { _vs.initialize(rs, committed_byte_size); @@ -93,16 +94,24 @@ void MetaspaceShared::initialize_shared_rs(ReservedSpace* rs) { assert(DumpSharedSpaces, "dump time only"); _shared_rs = rs; - // Split up and initialize the misc code and data spaces + size_t core_spaces_size = FileMapInfo::core_spaces_size(); size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize; - ReservedSpace shared_ro_rw = _shared_rs->first_part(metadata_size); - ReservedSpace misc_section = _shared_rs->last_part(metadata_size); - // Now split into misc sections. + // Split into the core and optional sections + ReservedSpace core_data = _shared_rs->first_part(core_spaces_size); + ReservedSpace optional_data = _shared_rs->last_part(core_spaces_size); + + // The RO/RW and the misc sections + ReservedSpace shared_ro_rw = core_data.first_part(metadata_size); + ReservedSpace misc_section = core_data.last_part(metadata_size); + + // Now split the misc code and misc data sections. ReservedSpace md_rs = misc_section.first_part(SharedMiscDataSize); ReservedSpace mc_rs = misc_section.last_part(SharedMiscDataSize); + _md.initialize(md_rs, SharedMiscDataSize, SharedMiscData); - _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscData); + _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscCode); + _od.initialize(optional_data, metadata_size, SharedOptional); } // Read/write a data stream for restoring/preserving metadata pointers and @@ -521,6 +530,7 @@ private: GrowableArray *_class_promote_order; VirtualSpace _md_vs; VirtualSpace _mc_vs; + VirtualSpace _od_vs; GrowableArray *_string_regions; public: @@ -598,15 +608,19 @@ void VM_PopulateDumpSharedSpace::doit() { remove_unshareable_in_classes(); tty->print_cr("done. "); - // Set up the share data and shared code segments. + // Set up the misc data, misc code and optional data segments. _md_vs = *MetaspaceShared::misc_data_region()->virtual_space(); _mc_vs = *MetaspaceShared::misc_code_region()->virtual_space(); + _od_vs = *MetaspaceShared::optional_data_region()->virtual_space(); char* md_low = _md_vs.low(); char* md_top = MetaspaceShared::misc_data_region()->alloc_top(); char* md_end = _md_vs.high(); char* mc_low = _mc_vs.low(); char* mc_top = MetaspaceShared::misc_code_region()->alloc_top(); char* mc_end = _mc_vs.high(); + char* od_low = _od_vs.low(); + char* od_top = MetaspaceShared::optional_data_region()->alloc_top(); + char* od_end = _od_vs.high(); // Reserve space for the list of Klass*s whose vtables are used // for patching others as needed. @@ -661,28 +675,32 @@ void VM_PopulateDumpSharedSpace::doit() { const size_t rw_alloced = rw_space->capacity_bytes_slow(Metaspace::NonClassType); const size_t md_alloced = md_end-md_low; const size_t mc_alloced = mc_end-mc_low; + const size_t od_alloced = od_end-od_low; const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced - + ss_bytes; + + ss_bytes + od_alloced; // Occupied size of each space. const size_t ro_bytes = ro_space->used_bytes_slow(Metaspace::NonClassType); const size_t rw_bytes = rw_space->used_bytes_slow(Metaspace::NonClassType); const size_t md_bytes = size_t(md_top - md_low); const size_t mc_bytes = size_t(mc_top - mc_low); + const size_t od_bytes = size_t(od_top - od_low); // Percent of total size - const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes; + const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes + od_bytes; const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0; const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0; const double md_t_perc = md_bytes / double(total_bytes) * 100.0; const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0; const double ss_t_perc = ss_bytes / double(total_bytes) * 100.0; + const double od_t_perc = od_bytes / double(total_bytes) * 100.0; // Percent of fullness of each space const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0; const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0; const double md_u_perc = md_bytes / double(md_alloced) * 100.0; const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0; + const double od_u_perc = od_bytes / double(od_alloced) * 100.0; const double total_u_perc = total_bytes / double(total_alloced) * 100.0; #define fmt_space "%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT @@ -691,6 +709,7 @@ void VM_PopulateDumpSharedSpace::doit() { tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, p2i(md_low)); tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, p2i(mc_low)); tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes, 100.0, p2i(ss_low)); + tty->print_cr(fmt_space, "od", od_bytes, od_t_perc, od_alloced, od_u_perc, p2i(od_low)); tty->print_cr("total : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]", total_bytes, total_alloced, total_u_perc); @@ -734,6 +753,10 @@ void VM_PopulateDumpSharedSpace::doit() { SharedMiscCodeSize, true, true); mapinfo->write_string_regions(_string_regions); + mapinfo->write_region(MetaspaceShared::od, _od_vs.low(), + pointer_delta(od_top, _od_vs.low(), sizeof(char)), + pointer_delta(od_end, _od_vs.low(), sizeof(char)), + true, false); } mapinfo->close(); @@ -1049,8 +1072,6 @@ void MetaspaceShared::print_shared_spaces() { // Map shared spaces at requested addresses and return if succeeded. -// Need to keep the bounds of the ro and rw space for the Metaspace::contains -// call, or is_in_shared_space. bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { size_t image_alignment = mapinfo->alignment(); @@ -1068,6 +1089,7 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { char* _rw_base = NULL; char* _md_base = NULL; char* _mc_base = NULL; + char* _od_base = NULL; // Map each shared region if ((_ro_base = mapinfo->map_region(ro)) != NULL && @@ -1078,6 +1100,8 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { mapinfo->verify_region_checksum(md) && (_mc_base = mapinfo->map_region(mc)) != NULL && mapinfo->verify_region_checksum(mc) && + (_od_base = mapinfo->map_region(od)) != NULL && + mapinfo->verify_region_checksum(od) && (image_alignment == (size_t)max_alignment()) && mapinfo->validate_classpath_entry_table()) { // Success (no need to do anything) @@ -1089,6 +1113,7 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { if (_rw_base != NULL) mapinfo->unmap_region(rw); if (_md_base != NULL) mapinfo->unmap_region(md); if (_mc_base != NULL) mapinfo->unmap_region(mc); + if (_od_base != NULL) mapinfo->unmap_region(od); #ifndef _WINDOWS // Release the entire mapped region shared_rs.release(); diff --git a/hotspot/src/share/vm/memory/metaspaceShared.hpp b/hotspot/src/share/vm/memory/metaspaceShared.hpp index c60e8207328..cb96021af66 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.hpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp @@ -132,6 +132,7 @@ class MetaspaceShared : AllStatic { // Used only during dumping. static SharedMiscRegion _md; static SharedMiscRegion _mc; + static SharedMiscRegion _od; public: enum { vtbl_list_size = DEFAULT_VTBL_LIST_SIZE, @@ -148,7 +149,10 @@ class MetaspaceShared : AllStatic { max_strings = 2, // max number of string regions in string space num_non_strings = 4, // number of non-string regions first_string = num_non_strings, // index of first string region - n_regions = max_strings + num_non_strings // total number of regions + // The optional data region is the last region. + // Currently it only contains class file data. + od = max_strings + num_non_strings, + n_regions = od + 1 // total number of regions }; // Accessor functions to save shared space created for metadata, which has @@ -222,9 +226,10 @@ class MetaspaceShared : AllStatic { static int count_class(const char* classlist_file); static void estimate_regions_size() NOT_CDS_RETURN; - // Allocate a block of memory from the "mc" or "md" regions. + // Allocate a block of memory from the "mc", "md", or "od" regions. static char* misc_code_space_alloc(size_t num_bytes) { return _mc.alloc(num_bytes); } static char* misc_data_space_alloc(size_t num_bytes) { return _md.alloc(num_bytes); } + static char* optional_data_space_alloc(size_t num_bytes) { return _od.alloc(num_bytes); } static address cds_i2i_entry_code_buffers(size_t total_size); @@ -243,5 +248,9 @@ class MetaspaceShared : AllStatic { assert(DumpSharedSpaces, "used during dumping only"); return &_md; } + static SharedMiscRegion* optional_data_region() { + assert(DumpSharedSpaces, "used during dumping only"); + return &_od; + } }; #endif // SHARE_VM_MEMORY_METASPACESHARED_HPP diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index aaebc235e9d..54e54162c7f 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -41,6 +41,7 @@ #include "memory/heapInspection.hpp" #include "memory/iterator.inline.hpp" #include "memory/metadataFactory.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/fieldStreams.hpp" @@ -1972,11 +1973,6 @@ void InstanceKlass::remove_unshareable_info() { m->remove_unshareable_info(); } - // cached_class_file might be pointing to a malloc'ed buffer allocated by - // event-based tracing code at CDS dump time. It's not usable at runtime - // so let's clear it. - set_cached_class_file(NULL); - // do array classes also. array_klasses_do(remove_unshareable_in_class); } @@ -2070,6 +2066,7 @@ void InstanceKlass::release_C_heap_structures(InstanceKlass* ik) { } void InstanceKlass::release_C_heap_structures() { + assert(!this->is_shared(), "should not be called for a shared class"); // Can't release the constant pool here because the constant pool can be // deallocated separately from the InstanceKlass for default methods and @@ -3653,6 +3650,15 @@ Method* InstanceKlass::method_with_orig_idnum(int idnum, int version) { } #if INCLUDE_JVMTI +JvmtiCachedClassFileData* InstanceKlass::get_cached_class_file() { + if (MetaspaceShared::is_in_shared_space(_cached_class_file)) { + // Ignore the archived class stream data + return NULL; + } else { + return _cached_class_file; + } +} + jint InstanceKlass::get_cached_class_file_len() { return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file); } @@ -3660,4 +3666,15 @@ jint InstanceKlass::get_cached_class_file_len() { unsigned char * InstanceKlass::get_cached_class_file_bytes() { return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file); } + +#if INCLUDE_CDS +JvmtiCachedClassFileData* InstanceKlass::get_archived_class_data() { + assert(this->is_shared(), "class should be shared"); + if (MetaspaceShared::is_in_shared_space(_cached_class_file)) { + return _cached_class_file; + } else { + return NULL; + } +} +#endif #endif diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 330f373f001..cdba02b1119 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -783,7 +783,7 @@ public: void set_cached_class_file(JvmtiCachedClassFileData *data) { _cached_class_file = data; } - JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; } + JvmtiCachedClassFileData * get_cached_class_file(); jint get_cached_class_file_len(); unsigned char * get_cached_class_file_bytes(); @@ -795,6 +795,13 @@ public: return _jvmti_cached_class_field_map; } +#if INCLUDE_CDS + void set_archived_class_data(JvmtiCachedClassFileData* data) { + _cached_class_file = data; + } + + JvmtiCachedClassFileData * get_archived_class_data(); +#endif // INCLUDE_CDS #else // INCLUDE_JVMTI static void purge_previous_versions(InstanceKlass* ik) { return; }; diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp index d48479c303d..a6fd15bdaf1 100644 --- a/hotspot/src/share/vm/utilities/debug.cpp +++ b/hotspot/src/share/vm/utilities/debug.cpp @@ -282,6 +282,12 @@ void report_untested(const char* file, int line, const char* message) { } void report_out_of_shared_space(SharedSpaceType shared_space) { + if (shared_space == SharedOptional) { + // The estimated shared_optional_space size is large enough + // for all class bytes. It should not run out of space. + ShouldNotReachHere(); + } + static const char* name[] = { "shared read only space", "shared read write space", diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp index d5da6db4cab..3a4483e681e 100644 --- a/hotspot/src/share/vm/utilities/debug.hpp +++ b/hotspot/src/share/vm/utilities/debug.hpp @@ -271,7 +271,8 @@ enum SharedSpaceType { SharedReadOnly, SharedReadWrite, SharedMiscData, - SharedMiscCode + SharedMiscCode, + SharedOptional }; void report_out_of_shared_space(SharedSpaceType space_type); diff --git a/hotspot/test/runtime/SharedArchiveFile/CDSTestUtils.java b/hotspot/test/runtime/SharedArchiveFile/CDSTestUtils.java new file mode 100644 index 00000000000..8392b756eab --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/CDSTestUtils.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import jdk.test.lib.process.OutputAnalyzer; + + +// This class contains common test utilities for CDS testing +public class CDSTestUtils { + + // check result of 'dump' operation + public static void checkDump(OutputAnalyzer output, String... extraMatches) + throws Exception { + + output.shouldContain("Loading classes to share"); + output.shouldHaveExitValue(0); + + for (String match : extraMatches) { + output.shouldContain(match); + } + } + + + // check the output for indication that mapping of the archive failed + public static boolean isUnableToMap(OutputAnalyzer output) { + String outStr = output.getOutput(); + if ((output.getExitValue() == 1) && ( + outStr.contains("Unable to reserve shared space at required address") || + outStr.contains("Unable to map ReadOnly shared space at required address") || + outStr.contains("Unable to map ReadWrite shared space at required address") || + outStr.contains("Unable to map MiscData shared space at required address") || + outStr.contains("Unable to map MiscCode shared space at required address") || + outStr.contains("Unable to map shared string space at required address") || + outStr.contains("Could not allocate metaspace at a compatible address") || + outStr.contains("Unable to allocate shared string space: range is not within java heap") )) + { + return true; + } + + return false; + } + + // check result of 'exec' operation, that is when JVM is run using the archive + public static void checkExec(OutputAnalyzer output, String... extraMatches) throws Exception { + if (isUnableToMap(output)) { + System.out.println("Unable to map shared archive: test did not complete; assumed PASS"); + return; + } + output.shouldContain("sharing"); + output.shouldHaveExitValue(0); + + for (String match : extraMatches) { + output.shouldContain(match); + } + } + + + // get the file object for the test artifact + private static File getTestArtifactFile(String prefix, String name) { + File dir = new File(System.getProperty("test.classes", ".")); + return new File(dir, prefix + name); + } + + + // create file containing the specified class list + public static File makeClassList(String testCaseName, String classes[]) + throws Exception { + + File classList = getTestArtifactFile(testCaseName, "test.classlist"); + FileOutputStream fos = new FileOutputStream(classList); + PrintStream ps = new PrintStream(fos); + + addToClassList(ps, classes); + + ps.close(); + fos.close(); + + return classList; + } + + + private static void addToClassList(PrintStream ps, String classes[]) + throws IOException + { + if (classes != null) { + for (String s : classes) { + ps.println(s); + } + } + } + +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Implementor.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Implementor.java new file mode 100644 index 00000000000..96320a39468 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Implementor.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class Implementor implements Interface { + public static void main(String[] args) { + System.out.println("Implementor: entering main()"); + test(); + } + + public static void test() { + // from interface + (new Implementor()).printString(); + // from implementor + System.out.println(TransformUtil.ChildCheckPattern + + TransformUtil.BeforePattern); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Interface.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Interface.java new file mode 100644 index 00000000000..1510915ca26 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Interface.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public interface Interface { + public static final String stringToBeTransformed = + TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern; + + default void printString() { + System.out.println(stringToBeTransformed); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SubClass.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SubClass.java new file mode 100644 index 00000000000..e9205918b0b --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SubClass.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class SubClass extends SuperClazz { + public static void main(String[] args) { + System.out.println("SubClass: entering main()"); + test(); + } + + public static void test() { + // The line below will be used to check for successful class transformation + System.out.println(TransformUtil.ChildCheckPattern + + TransformUtil.BeforePattern); + (new SubClass()).callParent(); + } + + private void callParent() { + super.testParent(); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SuperClazz.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SuperClazz.java new file mode 100644 index 00000000000..a3224c7f91e --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SuperClazz.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +public class SuperClazz { + public static void testParent() { + System.out.println("SuperClazz: entering testParent()"); + + // The line below will be used to check for successful class transformation + System.out.println(TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TestEntry.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TestEntry.java new file mode 100644 index 00000000000..b388af2a15c --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TestEntry.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +// Test Entry - a single entry in a test table +// that defines a test case +// See TransformRelatedClasses.java for more details +public class TestEntry { + int testCaseId; + boolean transformParent; + boolean transformChild; + boolean isParentExpectedShared; + boolean isChildExpectedShared; + + public TestEntry(int testCaseId, + boolean transformParent, boolean transformChild, + boolean isParentExpectedShared, boolean isChildExpectedShared) { + this.testCaseId = testCaseId; + this.transformParent = transformParent; + this.transformChild = transformChild; + this.isParentExpectedShared = isParentExpectedShared; + this.isChildExpectedShared = isChildExpectedShared; + } +} + diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java new file mode 100644 index 00000000000..7cf738baae1 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Exercise initial transformation (ClassFileLoadHook) + * with CDS with Interface/Implementor pair + * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti + * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true) + * @requires vm.flavor != "minimal" + * @modules java.base/jdk.internal.misc + * jdk.jartool/sun.tools.jar + * java.management + * java.instrument + * @build TransformUtil TransformerAgent Interface Implementor + * @run main/othervm TransformRelatedClasses Interface Implementor + */ + +// Clarification on @requires declarations: +// CDS is not supported w/o the use of Compressed OOPs +// JVMTI's ClassFileLoadHook is not supported under minimal VM + +// This test class uses TransformRelatedClasses to do its work. +// The goal of this test is to exercise transformation of related interface +// and its implementor in combination with CDS. +// The transformation is done via ClassFileLoadHook mechanism. +// Both superclass and subclass reside in the shared archive. +// The test consists of 4 test cases where transformation is applied +// to an interface and an implementor in a combinatorial manner. +// Please see TransformRelatedClasses.java for details. diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformRelatedClasses.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformRelatedClasses.java new file mode 100644 index 00000000000..25cc42dfd82 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformRelatedClasses.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +// This is the main test class for testing transformation of related classes +// in combination with CDS, to ensure these features work well together. +// The relationships that can be tested using this test class are: +// superclass/subclass, and interface/implementor relationships. +// +// The test uses combinatorial approach. +// For details on test table and test cases see main() method in this class. +// +// This test consists of multiple classes for better flexibility and reuse, +// and also relies on certain common utility code. +// Here are the details on the structure of the test +// +// Structure of the test: +// TransformRelatedClasses -- common main test driver +// The TransformRelatedClasses is invoked from test driver classes: +// TransformInterfaceAndImplementor, TransformSuperAndSubClasses +// It is responsible for preparing test artifacts (test jar, agent jar +// and the shared archive), running test cases and checking the results. +// The following test classes below are launched in a sub-process with use +// of shared archive: +// SuperClazz, SubClass -- super/sub class pair under test +// Interface, Implementor -- classes under test +// This test will transform these classes, based on the test case data, +// by changing a predefined unique string in each class. +// For more details, see the test classes' code and comments. +// +// Other related classes: +// TestEntry - a class representing a single test case, as test entry in the table +// TransformTestCommon - common methods for transformation test cases +// +// Other utility/helper classes and files used in this test: +// TransformerAgent - an agent that is used when JVM-under-test is executed +// to transform specific strings inside specified classes +// TransformerAgent.mf - accompanies transformer agent +// CDSTestUtils - Test Utilities common to all CDS tests + +import java.io.File; +import java.util.ArrayList; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + + +public class TransformRelatedClasses { + static final String archiveName = "./TransformRelatedClasses.jsa"; + static String agentClasses[] = { + "TransformerAgent", + "TransformerAgent$SimpleTransformer", + "TransformUtil" + }; + + String parent; + String child; + String[] testClasses = new String[2]; + String[] testNames = new String[2]; + String testJar; + String agentJar; + + + private static void log(String msg) { + System.out.println("TransformRelatedClasses: " + msg); + } + + + // This class is intended to test 2 parent-child relationships: + // 1. Base Class (parent) and Derived Class (child) + // 2. Interface (parent) and Implementor (child) + // Parameters to main(): parent, child + public static void main(String args[]) throws Exception { + TransformRelatedClasses test = new TransformRelatedClasses(args[0], args[1]); + test.prepare(); + + // Test Table + // TestEntry: (testCaseId, transformParent, tranformChild, + // isParentExpectedShared, isChildExpectedShared) + ArrayList testTable = new ArrayList<>(); + + // base case - no tranformation - all expected to be shared + testTable.add(new TestEntry(0, false, false, true, true)); + + // transform parent only - both parent and child should not be shared + testTable.add(new TestEntry(1, true, false, false, false)); + + // transform parent and child - both parent and child should not be shared + testTable.add(new TestEntry(2, true, true, false, false)); + + // transform child only - parent should still be shared, but not child + testTable.add(new TestEntry(3, false, true, true, false)); + + // run the tests + for (TestEntry entry : testTable) { + test.runTest(entry); + } + } + + + public TransformRelatedClasses(String parent, String child) { + log("Constructor: parent = " + parent + ", child = " + child); + this.parent = parent; + this.child = child; + testClasses[0] = parent; + testClasses[1] = child; + testNames[0] = parent.replace('.', '/'); + testNames[1] = child.replace('.', '/'); + } + + + // same test jar and archive can be used for all test cases + private void prepare() throws Exception { + // create agent jar + // Agent is the same for all test cases + String pathToManifest = "../../../../testlibrary/jvmti/TransformerAgent.mf"; + agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar", + ClassFileInstaller.Manifest.fromSourceFile(pathToManifest), + agentClasses); + + // create a test jar + testJar = + ClassFileInstaller.writeJar(parent + "-" + child + ".jar", + testClasses); + + // create an archive + File classList = CDSTestUtils.makeClassList("transform-" + parent, + testNames); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + "-Xbootclasspath/a:" + testJar, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:ExtraSharedClassListFile=" + + classList.getPath(), + "-XX:SharedArchiveFile=" + archiveName, + "-XX:+PrintSharedSpaces", + "-Xshare:dump"); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + CDSTestUtils.checkDump(out); + } + + + private void runTest(TestEntry entry) throws Exception { + log("runTest(): testCaseId = " + entry.testCaseId); + + // execute with archive + String agentParam = "-javaagent:" + agentJar + "=" + + TransformTestCommon.getAgentParams(entry, parent, child); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + "-Xbootclasspath/a:" + testJar, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + archiveName, + "-Xlog:class+load=info", + "-Xshare:on", "-showversion", + agentParam, child); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + + TransformTestCommon.checkResults(entry, out, parent, child); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java new file mode 100644 index 00000000000..1309c1b4a35 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + * @test + * @summary Exercise initial transformation (ClassFileLoadHook) + * with CDS with SubClass and SuperClass + * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti + * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true) + * @requires vm.flavor != "minimal" + * @modules java.base/jdk.internal.misc + * jdk.jartool/sun.tools.jar + * java.management + * java.instrument + * @build TransformUtil TransformerAgent SubClass SuperClazz + * @run main/othervm TransformRelatedClasses SuperClazz SubClass +*/ + +// Clarification on @requires declarations: +// CDS is not supported w/o the use of Compressed OOPs +// JVMTI's ClassFileLoadHook is not supported under minimal VM + +// This test class uses TransformRelatedClasses to do its work. +// The goal of this test is to exercise transformation of related superclass +// and subclass in combination with CDS. +// The transformation is done via ClassFileLoadHook mechanism. +// Both superclass and subclass reside in the shared archive. +// The test consists of 4 test cases where transformation is applied +// to a parent and child in combinatorial manner. +// Please see TransformRelatedClasses.java for details. diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java new file mode 100644 index 00000000000..da35b7e0336 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + * @test + * @summary Exercise initial transformation (ClassFileLoadHook) + * with CDS with SubClass and SuperClass, each lives in own separate package + * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti + * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true) + * @requires vm.flavor != "minimal" + * @modules java.base/jdk.internal.misc + * jdk.jartool/sun.tools.jar + * java.management + * java.instrument + * @build TransformUtil TransformerAgent SubClass SuperClazz + * @compile myPkg2/SubClass.java myPkg1/SuperClazz.java + * @run main/othervm TransformRelatedClasses myPkg1.SuperClazz myPkg2.SubClass +*/ + +// Clarification on @requires declarations: +// CDS is not supported w/o the use of Compressed OOPs +// JVMTI's ClassFileLoadHook is not supported under minimal VM + +// This test class uses TransformRelatedClasses to do its work. +// The goal of this test is to exercise transformation of related superclass +// and subclass in combination with CDS; each class lives in its own package. +// The transformation is done via ClassFileLoadHook mechanism. +// Both superclass and subclass reside in the shared archive. +// The test consists of 4 test cases where transformation is applied +// to a parent and child in combinatorial manner. +// Please see TransformRelatedClasses.java for details. diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformTestCommon.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformTestCommon.java new file mode 100644 index 00000000000..00e25bce83c --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformTestCommon.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.process.OutputAnalyzer; + + +// This class contains methods common to all transformation test cases +public class TransformTestCommon { + + // get parameters to an agent depending on the test case + // these parameters will instruct the agent which classes should be + // transformed + public static String getAgentParams(TestEntry entry, + String parent, String child) { + + if (entry.transformParent && entry.transformChild) + return parent + "," + child; + if (entry.transformParent) + return parent; + if (entry.transformChild) + return child; + + return ""; + } + + + private static void checkTransformationResults(TestEntry entry, + OutputAnalyzer out) + throws Exception { + + if (entry.transformParent) + out.shouldContain(TransformUtil.ParentCheckPattern + + TransformUtil.AfterPattern); + + if (entry.transformChild) + out.shouldContain(TransformUtil.ChildCheckPattern + + TransformUtil.AfterPattern); + } + + + private static void checkSharingByClass(TestEntry entry, OutputAnalyzer out, + String parent, String child) + throws Exception { + + String parentSharedMatch = parent + " source: shared objects file"; + String childSharedMatch = child + " source: shared objects file"; + + if (entry.isParentExpectedShared) + out.shouldContain(parentSharedMatch); + else + out.shouldNotContain(parentSharedMatch); + + if (entry.isChildExpectedShared) + out.shouldContain(childSharedMatch); + else + out.shouldNotContain(childSharedMatch); + } + + + // Both parent and child classes should be passed to ClassFileTransformer.transform() + // exactly once. + private static void checkTransformationCounts(TestEntry entry, OutputAnalyzer out, + String parent, String child) + throws Exception { + + String patternBase = "TransformerAgent: SimpleTransformer called for: "; + + out.shouldContain(patternBase + child + "@1"); + out.shouldContain(patternBase + parent + "@1"); + + out.shouldNotContain(patternBase + child + "@2"); + out.shouldNotContain(patternBase + parent + "@2"); + } + + + public static void checkResults(TestEntry entry, OutputAnalyzer out, + String parent, String child) + throws Exception { + + // If we were not able to map an archive, + // then do not perform other checks, since + // there was no sharing at all + if (CDSTestUtils.isUnableToMap(out)) + return; + + String childVmName = child.replace('.', '/'); + String parentVmName = parent.replace('.', '/'); + + CDSTestUtils.checkExec(out); + checkTransformationCounts(entry, out, parentVmName, childVmName); + checkTransformationResults(entry, out); + checkSharingByClass(entry, out, parent, child); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg1/SuperClazz.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg1/SuperClazz.java new file mode 100644 index 00000000000..c04770dbc3c --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg1/SuperClazz.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package myPkg1; + +public class SuperClazz { + public static void testParent() { + System.out.println("SuperClazz: entering testParent()"); + + // The line below will be used to check for successful class transformation + System.out.println("parent-transform-check: this-should-be-transformed"); + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg2/SubClass.java b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg2/SubClass.java new file mode 100644 index 00000000000..ab67b3a6bfd --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg2/SubClass.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package myPkg2; + +import myPkg1.SuperClazz; + +public class SubClass extends SuperClazz { + public static void main(String[] args) { + System.out.println("SubClass: entering main()"); + test(); + } + + public static void test() { + // The line below will be used to check for successful class transformation + System.out.println("child-transform-check: this-should-be-transformed"); + (new SubClass()).callParent(); + + // Get the system packages, which should contain myPkg1 and myPkag2 + Package[] pkgs = Package.getPackages(); + for (int i = 0; i < pkgs.length; i++) { + if (pkgs[i].getName().equals("myPkg1")) { + for (int j = 0; j < pkgs.length; j++) { + if (pkgs[j].getName().equals("myPkg2")) { + return; // found myPkg1 & myPkg1 + } + } + } + } + throw new RuntimeException("Missing system package"); + } + + private void callParent() { + super.testParent(); + } +} diff --git a/hotspot/test/testlibrary/jvmti/TransformUtil.java b/hotspot/test/testlibrary/jvmti/TransformUtil.java new file mode 100644 index 00000000000..dfaf61a42a3 --- /dev/null +++ b/hotspot/test/testlibrary/jvmti/TransformUtil.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +public class TransformUtil { + public static final String BeforePattern = "this-should-be-transformed"; + public static final String AfterPattern = "this-has-been--transformed"; + public static final String ParentCheckPattern = "parent-transform-check: "; + public static final String ChildCheckPattern = "child-transform-check: "; + + /** + * @return the number of occurrences of the from string that + * have been replaced. + */ + public static int replace(byte buff[], String from, String to) { + if (to.length() != from.length()) { + throw new RuntimeException("bad strings"); + } + byte f[] = asciibytes(from); + byte t[] = asciibytes(to); + byte f0 = f[0]; + + int numReplaced = 0; + int max = buff.length - f.length; + for (int i = 0; i < max; ) { + if (buff[i] == f0 && replace(buff, f, t, i)) { + i += f.length; + numReplaced++; + } else { + i++; + } + } + return numReplaced; + } + + public static boolean replace(byte buff[], byte f[], byte t[], int i) { + for (int x = 0; x < f.length; x++) { + if (buff[x+i] != f[x]) { + return false; + } + } + for (int x = 0; x < f.length; x++) { + buff[x+i] = t[x]; + } + return true; + } + + static byte[] asciibytes(String s) { + byte b[] = new byte[s.length()]; + for (int i = 0; i < b.length; i++) { + b[i] = (byte)s.charAt(i); + } + return b; + } +} diff --git a/hotspot/test/testlibrary/jvmti/TransformerAgent.java b/hotspot/test/testlibrary/jvmti/TransformerAgent.java new file mode 100644 index 00000000000..7f520050487 --- /dev/null +++ b/hotspot/test/testlibrary/jvmti/TransformerAgent.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.security.ProtectionDomain; +import java.util.HashMap; + +// This is a test utility class used to transform +// specified classes via initial transformation (ClassFileLoadHook). +// Names of classes to be transformed are supplied as arguments, +// the phrase to be transformed is a hard-coded predefined +// fairly unique phrase. + +public class TransformerAgent { + private static String[] classesToTransform; + + + private static void log(String msg) { + System.out.println("TransformerAgent: " + msg); + } + + + // arguments are comma-separated list of classes to transform + public static void premain(String agentArguments, Instrumentation instrumentation) { + log("premain() is called, arguments = " + agentArguments); + classesToTransform = agentArguments.split(","); + instrumentation.addTransformer(new SimpleTransformer(), /*canRetransform=*/true); + } + + + public static void agentmain(String args, Instrumentation inst) throws Exception { + log("agentmain() is called"); + premain(args, inst); + } + + + static class SimpleTransformer implements ClassFileTransformer { + public byte[] transform(ClassLoader loader, String name, Class classBeingRedefined, + ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException { + + log("SimpleTransformer called for: " + name + "@" + incrCounter(name)); + if (!shouldTransform(name)) + return null; + + log("transforming: class name = " + name); + int nrOfReplacements = TransformUtil.replace(buffer, TransformUtil.BeforePattern, + TransformUtil.AfterPattern); + log("replaced the string, nrOfReplacements = " + nrOfReplacements); + return buffer; + } + + // Check class name pattern, since test should only transform certain classes + private static boolean shouldTransform(String name) { + for (String match : classesToTransform) { + if (name.matches(match)) { + log("shouldTransform: match-found, match = " + match); + return true; + } + } + + return false; + } + } + + + static HashMap counterMap = new HashMap<>(); + + static Integer incrCounter(String className) { + Integer i = counterMap.get(className); + if (i == null) { + i = new Integer(1); + } else { + i = new Integer(i.intValue() + 1); + } + counterMap.put(className, i); + return i; + } +} diff --git a/hotspot/test/testlibrary/jvmti/TransformerAgent.mf b/hotspot/test/testlibrary/jvmti/TransformerAgent.mf new file mode 100644 index 00000000000..9f59980a5c2 --- /dev/null +++ b/hotspot/test/testlibrary/jvmti/TransformerAgent.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Premain-Class: TransformerAgent +Agent-Class: TransformerAgent +Can-Retransform-Classes: true +Can-Redefine-Classes: false From 36c39d5c25a4d9abbcee7b928e2d42a82a87fbcc Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Mon, 26 Sep 2016 08:51:36 +0200 Subject: [PATCH 038/207] 8161085: PreserveFPRegistersTest fails with 'AssertionError: Final value has changed' C1's G1 barriers should save/restore vector registers before calling into the runtime. Reviewed-by: kvn, vlivanov --- hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp index 283f260886d..5530a85cb4c 100644 --- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -881,20 +881,15 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ delayed()->st_ptr(tmp, G2_thread, satb_q_index_byte_offset); __ bind(refill); - __ save_frame(0); - __ mov(pre_val, L0); - __ mov(tmp, L1); - __ mov(tmp2, L2); + save_live_registers(sasm); __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SATBMarkQueueSet::handle_zero_index_for_thread), G2_thread); - __ mov(L0, pre_val); - __ mov(L1, tmp); - __ mov(L2, tmp2); + restore_live_registers(sasm); __ br(Assembler::always, /*annul*/false, Assembler::pt, restart); __ delayed()->restore(); @@ -986,20 +981,15 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ delayed()->st_ptr(tmp3, G2_thread, dirty_card_q_index_byte_offset); __ bind(refill); - __ save_frame(0); - __ mov(tmp2, L0); - __ mov(tmp3, L1); - __ mov(tmp4, L2); + save_live_registers(sasm); __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, DirtyCardQueueSet::handle_zero_index_for_thread), G2_thread); - __ mov(L0, tmp2); - __ mov(L1, tmp3); - __ mov(L2, tmp4); + restore_live_registers(sasm); __ br(Assembler::always, /*annul*/false, Assembler::pt, restart); __ delayed()->restore(); From 8180ee5c6aa8ecf6204217d11ba9115fd962055d Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Mon, 19 Sep 2016 15:08:03 +0200 Subject: [PATCH 039/207] 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms Reviewed-by: kvn --- .../aarch64/vm/c1_LIRGenerator_aarch64.cpp | 27 ++++++++-------- .../src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp | 31 ++++++++++--------- .../cpu/sparc/vm/c1_LIRGenerator_sparc.cpp | 31 ++++++++++--------- .../src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 4 +-- 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp index 3a968ccb87d..033741723e8 100644 --- a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp @@ -140,10 +140,11 @@ LIR_Opr LIRGenerator::safepoint_poll_register() { LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, int shift, int disp, BasicType type) { assert(base->is_register(), "must be"); + intx large_disp = disp; // accumulate fixed displacements if (index->is_constant()) { - disp += index->as_constant_ptr()->as_jint() << shift; + large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift; index = LIR_OprFact::illegalOpr; } @@ -154,31 +155,31 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, __ shift_left(index, shift, tmp); index = tmp; } - if (disp != 0) { + if (large_disp != 0) { LIR_Opr tmp = new_pointer_register(); - if (Assembler::operand_valid_for_add_sub_immediate(disp)) { - __ add(tmp, tmp, LIR_OprFact::intptrConst(disp)); + if (Assembler::operand_valid_for_add_sub_immediate(large_disp)) { + __ add(tmp, tmp, LIR_OprFact::intptrConst(large_disp)); index = tmp; } else { - __ move(tmp, LIR_OprFact::intptrConst(disp)); + __ move(tmp, LIR_OprFact::intptrConst(large_disp)); __ add(tmp, index, tmp); index = tmp; } - disp = 0; + large_disp = 0; } - } else if (disp != 0 && !Address::offset_ok_for_immed(disp, shift)) { + } else if (large_disp != 0 && !Address::offset_ok_for_immed(large_disp, shift)) { // index is illegal so replace it with the displacement loaded into a register index = new_pointer_register(); - __ move(LIR_OprFact::intptrConst(disp), index); - disp = 0; + __ move(LIR_OprFact::intptrConst(large_disp), index); + large_disp = 0; } // at this point we either have base + index or base + displacement - if (disp == 0) { + if (large_disp == 0) { return new LIR_Address(base, index, type); } else { - assert(Address::offset_ok_for_immed(disp, 0), "must be"); - return new LIR_Address(base, disp, type); + assert(Address::offset_ok_for_immed(large_disp, 0), "must be"); + return new LIR_Address(base, large_disp, type); } } @@ -192,7 +193,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o LIR_Address* addr; if (index_opr->is_constant()) { addr = new LIR_Address(array_opr, - offset_in_bytes + index_opr->as_jint() * elem_size, type); + offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); } else { if (offset_in_bytes) { LIR_Opr tmp = new_pointer_register(); diff --git a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp index 04056ba2d4e..2cb7fe73e79 100644 --- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp @@ -157,10 +157,11 @@ LIR_Opr LIRGenerator::safepoint_poll_register() { LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, int shift, int disp, BasicType type) { assert(base->is_register(), "must be"); + intx large_disp = disp; // Accumulate fixed displacements. if (index->is_constant()) { - disp += index->as_constant_ptr()->as_jint() << shift; + large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift; index = LIR_OprFact::illegalOpr; } @@ -171,31 +172,31 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, __ shift_left(index, shift, tmp); index = tmp; } - if (disp != 0) { + if (large_disp != 0) { LIR_Opr tmp = new_pointer_register(); - if (Assembler::is_simm16(disp)) { - __ add(index, LIR_OprFact::intptrConst(disp), tmp); + if (Assembler::is_simm16(large_disp)) { + __ add(index, LIR_OprFact::intptrConst(large_disp), tmp); index = tmp; } else { - __ move(LIR_OprFact::intptrConst(disp), tmp); + __ move(LIR_OprFact::intptrConst(large_disp), tmp); __ add(tmp, index, tmp); index = tmp; } - disp = 0; + large_disp = 0; } - } else if (!Assembler::is_simm16(disp)) { + } else if (!Assembler::is_simm16(large_disp)) { // Index is illegal so replace it with the displacement loaded into a register. index = new_pointer_register(); - __ move(LIR_OprFact::intptrConst(disp), index); - disp = 0; + __ move(LIR_OprFact::intptrConst(large_disp), index); + large_disp = 0; } // At this point we either have base + index or base + displacement. - if (disp == 0) { + if (large_disp == 0) { return new LIR_Address(base, index, type); } else { - assert(Assembler::is_simm16(disp), "must be"); - return new LIR_Address(base, disp, type); + assert(Assembler::is_simm16(large_disp), "must be"); + return new LIR_Address(base, large_disp, type); } } @@ -206,11 +207,11 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o int shift = exact_log2(elem_size); LIR_Opr base_opr; - int offset = arrayOopDesc::base_offset_in_bytes(type); + intx offset = arrayOopDesc::base_offset_in_bytes(type); if (index_opr->is_constant()) { - int i = index_opr->as_constant_ptr()->as_jint(); - int array_offset = i * elem_size; + intx i = index_opr->as_constant_ptr()->as_jint(); + intx array_offset = i * elem_size; if (Assembler::is_simm16(array_offset + offset)) { base_opr = array_opr; offset = array_offset + offset; diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index b299d5f1f0f..36d3059739c 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -147,10 +147,11 @@ LIR_Opr LIRGenerator::safepoint_poll_register() { LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, int shift, int disp, BasicType type) { assert(base->is_register(), "must be"); + intx large_disp = disp; // accumulate fixed displacements if (index->is_constant()) { - disp += index->as_constant_ptr()->as_jint() << shift; + large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift; index = LIR_OprFact::illegalOpr; } @@ -161,31 +162,31 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, __ shift_left(index, shift, tmp); index = tmp; } - if (disp != 0) { + if (large_disp != 0) { LIR_Opr tmp = new_pointer_register(); - if (Assembler::is_simm13(disp)) { - __ add(tmp, LIR_OprFact::intptrConst(disp), tmp); + if (Assembler::is_simm13(large_disp)) { + __ add(tmp, LIR_OprFact::intptrConst(large_disp), tmp); index = tmp; } else { - __ move(LIR_OprFact::intptrConst(disp), tmp); + __ move(LIR_OprFact::intptrConst(large_disp), tmp); __ add(tmp, index, tmp); index = tmp; } - disp = 0; + large_disp = 0; } - } else if (disp != 0 && !Assembler::is_simm13(disp)) { + } else if (large_disp != 0 && !Assembler::is_simm13(large_disp)) { // index is illegal so replace it with the displacement loaded into a register index = new_pointer_register(); - __ move(LIR_OprFact::intptrConst(disp), index); - disp = 0; + __ move(LIR_OprFact::intptrConst(large_disp), index); + large_disp = 0; } // at this point we either have base + index or base + displacement - if (disp == 0) { + if (large_disp == 0) { return new LIR_Address(base, index, type); } else { - assert(Assembler::is_simm13(disp), "must be"); - return new LIR_Address(base, disp, type); + assert(Assembler::is_simm13(large_disp), "must be"); + return new LIR_Address(base, large_disp, type); } } @@ -196,11 +197,11 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o int shift = exact_log2(elem_size); LIR_Opr base_opr; - int offset = arrayOopDesc::base_offset_in_bytes(type); + intx offset = arrayOopDesc::base_offset_in_bytes(type); if (index_opr->is_constant()) { - int i = index_opr->as_constant_ptr()->as_jint(); - int array_offset = i * elem_size; + intx i = index_opr->as_constant_ptr()->as_jint(); + intx array_offset = i * elem_size; if (Assembler::is_simm13(array_offset + offset)) { base_opr = array_opr; offset = array_offset + offset; diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index 2bbe4b58cab..c5bec4b7e0b 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -152,7 +152,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, assert(base->is_register(), "must be"); if (index->is_constant()) { return new LIR_Address(base, - (index->as_constant_ptr()->as_jint() << shift) + disp, + ((intx)(index->as_constant_ptr()->as_jint()) << shift) + disp, type); } else { return new LIR_Address(base, index, (LIR_Address::Scale)shift, disp, type); @@ -168,7 +168,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o if (index_opr->is_constant()) { int elem_size = type2aelembytes(type); addr = new LIR_Address(array_opr, - offset_in_bytes + index_opr->as_jint() * elem_size, type); + offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); } else { #ifdef _LP64 if (index_opr->type() == T_INT) { From 368585d0dbf0ddc6231557869ed493f4a7c34a2d Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Mon, 19 Sep 2016 12:04:28 -0400 Subject: [PATCH 040/207] 8163406: The fixup_module_list must be protected by Module_lock when inserting new entries In java_lang_Class::create_mirror, restructure the check for adding a class to the fixup_module_list, guarded by Module_lock. Reviewed-by: acorn, coleenp, dholmes, zgu --- .../src/share/vm/classfile/classLoader.cpp | 4 +- .../src/share/vm/classfile/javaClasses.cpp | 49 ++++++++++++++----- .../src/share/vm/classfile/javaClasses.hpp | 1 + .../src/share/vm/classfile/moduleEntry.cpp | 21 +++++--- .../src/share/vm/classfile/moduleEntry.hpp | 18 +++---- hotspot/src/share/vm/classfile/modules.cpp | 7 +-- hotspot/src/share/vm/oops/instanceKlass.cpp | 4 +- hotspot/src/share/vm/oops/klass.cpp | 2 +- hotspot/src/share/vm/oops/typeArrayKlass.cpp | 4 +- .../share/vm/utilities/hashtable.inline.hpp | 10 ++-- 10 files changed, 75 insertions(+), 45 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index 2cb586f1f54..6e74496d80c 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -1358,7 +1358,7 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArraydo_local_static_fields(&initialize_static_field, mirror, CHECK); } +// Set the java.lang.reflect.Module module field in the java_lang_Class mirror +void java_lang_Class::set_mirror_module_field(KlassHandle k, Handle mirror, Handle module, TRAPS) { + if (module.is_null()) { + // During startup, the module may be NULL only if java.base has not been defined yet. + // Put the class on the fixup_module_list to patch later when the java.lang.reflect.Module + // for java.base is known. + assert(!Universe::is_module_initialized(), "Incorrect java.lang.reflect.Module pre module system initialization"); + MutexLocker m1(Module_lock, THREAD); + // Keep list of classes needing java.base module fixup + if (!ModuleEntryTable::javabase_defined()) { + if (fixup_module_field_list() == NULL) { + GrowableArray* list = + new (ResourceObj::C_HEAP, mtModule) GrowableArray(500, true); + set_fixup_module_field_list(list); + } + k->class_loader_data()->inc_keep_alive(); + fixup_module_field_list()->push(k()); + } else { + // java.base was defined at some point between calling create_mirror() + // and obtaining the Module_lock, patch this particular class with java.base. + ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry(); + assert(javabase_entry != NULL && javabase_entry->module() != NULL, + "Setting class module field, java.base should be defined"); + Handle javabase_handle(THREAD, JNIHandles::resolve(javabase_entry->module())); + set_module(mirror(), javabase_handle()); + } + } else { + assert(Universe::is_module_initialized() || + (ModuleEntryTable::javabase_defined() && + (module() == JNIHandles::resolve(ModuleEntryTable::javabase_moduleEntry()->module()))), + "Incorrect java.lang.reflect.Module specification while creating mirror"); + set_module(mirror(), module()); + } +} + void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, Handle module, Handle protection_domain, TRAPS) { assert(k->java_mirror() == NULL, "should only assign mirror once"); @@ -835,25 +870,13 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, set_class_loader(mirror(), class_loader()); // set the module field in the java_lang_Class instance - // This may be null during bootstrap but will get fixed up later on. - set_module(mirror(), module()); + set_mirror_module_field(k, mirror, module, THREAD); // Setup indirection from klass->mirror last // after any exceptions can happen during allocations. if (!k.is_null()) { k->set_java_mirror(mirror()); } - - // Keep list of classes needing java.base module fixup. - if (!ModuleEntryTable::javabase_defined()) { - if (fixup_module_field_list() == NULL) { - GrowableArray* list = - new (ResourceObj::C_HEAP, mtModule) GrowableArray(500, true); - set_fixup_module_field_list(list); - } - k->class_loader_data()->inc_keep_alive(); - fixup_module_field_list()->push(k()); - } } else { if (fixup_mirror_list() == NULL) { GrowableArray* list = diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 307cd65d5f8..448bb4d5bd8 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -219,6 +219,7 @@ class java_lang_Class : AllStatic { static void set_class_loader(oop java_class, oop class_loader); static void set_component_mirror(oop java_class, oop comp_mirror); static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS); + static void set_mirror_module_field(KlassHandle K, Handle mirror, Handle module, TRAPS); public: static void compute_offsets(); diff --git a/hotspot/src/share/vm/classfile/moduleEntry.cpp b/hotspot/src/share/vm/classfile/moduleEntry.cpp index a8b67c54e64..2be85c2ebd8 100644 --- a/hotspot/src/share/vm/classfile/moduleEntry.cpp +++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp @@ -92,7 +92,7 @@ bool ModuleEntry::can_read(ModuleEntry* m) const { // read java.base. If either of these conditions // hold, readability has been established. if (!this->is_named() || - (m == ModuleEntryTable::javabase_module())) { + (m == ModuleEntryTable::javabase_moduleEntry())) { return true; } @@ -358,16 +358,27 @@ void ModuleEntryTable::finalize_javabase(Handle module_handle, Symbol* version, } // Set java.lang.reflect.Module, version and location for java.base - ModuleEntry* jb_module = javabase_module(); + ModuleEntry* jb_module = javabase_moduleEntry(); assert(jb_module != NULL, "java.base ModuleEntry not defined"); - jb_module->set_module(boot_loader_data->add_handle(module_handle)); jb_module->set_version(version); jb_module->set_location(location); + // Once java.base's ModuleEntry _module field is set with the known + // java.lang.reflect.Module, java.base is considered "defined" to the VM. + jb_module->set_module(boot_loader_data->add_handle(module_handle)); + // Store pointer to the ModuleEntry for java.base in the java.lang.reflect.Module object. java_lang_reflect_Module::set_module_entry(module_handle(), jb_module); + + // Patch any previously loaded classes' module field with java.base's java.lang.reflect.Module. + patch_javabase_entries(module_handle); } +// Within java.lang.Class instances there is a java.lang.reflect.Module field +// that must be set with the defining module. During startup, prior to java.base's +// definition, classes needing their module field set are added to the fixup_module_list. +// Their module field is set once java.base's java.lang.reflect.Module is known to the VM. void ModuleEntryTable::patch_javabase_entries(Handle module_handle) { + assert(Module_lock->owned_by_self(), "should have the Module_lock"); if (module_handle.is_null()) { fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module"); } @@ -389,9 +400,7 @@ void ModuleEntryTable::patch_javabase_entries(Handle module_handle) { for (int i = 0; i < list_length; i++) { Klass* k = list->at(i); assert(k->is_klass(), "List should only hold classes"); - Thread* THREAD = Thread::current(); - KlassHandle kh(THREAD, k); - java_lang_Class::fixup_module_field(kh, module_handle); + java_lang_Class::fixup_module_field(KlassHandle(k), module_handle); k->class_loader_data()->dec_keep_alive(); } diff --git a/hotspot/src/share/vm/classfile/moduleEntry.hpp b/hotspot/src/share/vm/classfile/moduleEntry.hpp index 8ec8237ec3f..82f0747a2ae 100644 --- a/hotspot/src/share/vm/classfile/moduleEntry.hpp +++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp @@ -78,11 +78,11 @@ public: _must_walk_reads = false; } - Symbol* name() const { return literal(); } - void set_name(Symbol* n) { set_literal(n); } + Symbol* name() const { return literal(); } + void set_name(Symbol* n) { set_literal(n); } - jobject module() const { return _module; } - void set_module(jobject j) { _module = j; } + jobject module() const { return _module; } + void set_module(jobject j) { _module = j; } // The shared ProtectionDomain reference is set once the VM loads a shared class // originated from the current Module. The referenced ProtectionDomain object is @@ -217,13 +217,13 @@ public: // Special handling for unnamed module, one per class loader's ModuleEntryTable void create_unnamed_module(ClassLoaderData* loader_data); - ModuleEntry* unnamed_module() { return _unnamed_module; } + ModuleEntry* unnamed_module() { return _unnamed_module; } // Special handling for java.base - static ModuleEntry* javabase_module() { return _javabase_module; } - static void set_javabase_module(ModuleEntry* java_base) { _javabase_module = java_base; } - static bool javabase_defined() { return ((_javabase_module != NULL) && - (_javabase_module->module() != NULL)); } + static ModuleEntry* javabase_moduleEntry() { return _javabase_module; } + static void set_javabase_moduleEntry(ModuleEntry* java_base) { _javabase_module = java_base; } + static bool javabase_defined() { return ((_javabase_module != NULL) && + (_javabase_module->module() != NULL)); } static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location); static void patch_javabase_entries(Handle module_handle); diff --git a/hotspot/src/share/vm/classfile/modules.cpp b/hotspot/src/share/vm/classfile/modules.cpp index 8986eb64e96..f7b15b141d7 100644 --- a/hotspot/src/share/vm/classfile/modules.cpp +++ b/hotspot/src/share/vm/classfile/modules.cpp @@ -206,7 +206,7 @@ static void define_javabase_module(jobject module, jstring version, assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table"); // Ensure java.base's ModuleEntry has been created - assert(ModuleEntryTable::javabase_module() != NULL, "No ModuleEntry for java.base"); + assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "No ModuleEntry for java.base"); bool duplicate_javabase = false; { @@ -226,7 +226,7 @@ static void define_javabase_module(jobject module, jstring version, for (int x = 0; x < pkg_list->length(); x++) { // Some of java.base's packages were added early in bootstrapping, ignore duplicates. if (package_table->lookup_only(pkg_list->at(x)) == NULL) { - pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_module()); + pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_moduleEntry()); assert(pkg != NULL, "Unable to create a java.base package entry"); } // Unable to have a GrowableArray of TempNewSymbol. Must decrement the refcount of @@ -255,9 +255,6 @@ static void define_javabase_module(jobject module, jstring version, log_trace(modules)("define_javabase_module(): creation of package %s for module java.base", (pkg_list->at(x))->as_C_string()); } - - // Patch any previously loaded classes' module field with java.base's jlr.Module. - ModuleEntryTable::patch_javabase_entries(module_handle); } void Modules::define_module(jobject module, jstring version, diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 54e54162c7f..ea49b1baf85 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2247,8 +2247,8 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) { // the java.base module. If a non-java.base package is erroneously placed // in the java.base module it will be caught later when java.base // is defined by ModuleEntryTable::verify_javabase_packages check. - assert(ModuleEntryTable::javabase_module() != NULL, "java.base module is NULL"); - _package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_module()); + assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "java.base module is NULL"); + _package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_moduleEntry()); } else { assert(loader_data->modules()->unnamed_module() != NULL, "unnamed module is NULL"); _package_entry = loader_data->packages()->lookup(pkg_name, diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index 804d02d0b08..4953f383120 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -530,7 +530,7 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec InstanceKlass* ik = (InstanceKlass*) k; module_entry = ik->module(); } else { - module_entry = ModuleEntryTable::javabase_module(); + module_entry = ModuleEntryTable::javabase_moduleEntry(); } // Obtain java.lang.reflect.Module, if available Handle module_handle(THREAD, ((module_entry != NULL) ? JNIHandles::resolve(module_entry->module()) : (oop)NULL)); diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.cpp b/hotspot/src/share/vm/oops/typeArrayKlass.cpp index 580c4694512..5ce156026a9 100644 --- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp +++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp @@ -72,7 +72,7 @@ TypeArrayKlass* TypeArrayKlass::create_klass(BasicType type, null_loader_data->add_class(ak); // Call complete_create_array_klass after all instance variables have been initialized. - complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_module(), CHECK_NULL); + complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_moduleEntry(), CHECK_NULL); return ak; } @@ -347,7 +347,7 @@ const char* TypeArrayKlass::internal_name() const { // A TypeArrayKlass is an array of a primitive type, its defining module is java.base ModuleEntry* TypeArrayKlass::module() const { - return ModuleEntryTable::javabase_module(); + return ModuleEntryTable::javabase_moduleEntry(); } PackageEntry* TypeArrayKlass::package() const { diff --git a/hotspot/src/share/vm/utilities/hashtable.inline.hpp b/hotspot/src/share/vm/utilities/hashtable.inline.hpp index 8497193bdc4..e6d7c61d4d5 100644 --- a/hotspot/src/share/vm/utilities/hashtable.inline.hpp +++ b/hotspot/src/share/vm/utilities/hashtable.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,8 +79,8 @@ template inline BasicHashtableEntry* BasicHashtable::bucket(i template inline void HashtableBucket::set_entry(BasicHashtableEntry* l) { - // Warning: Preserve store ordering. The SystemDictionary is read - // without locks. The new SystemDictionaryEntry must be + // Warning: Preserve store ordering. The PackageEntryTable, ModuleEntryTable and + // SystemDictionary are read without locks. The new entry must be // complete before other threads can be allowed to see it // via a store to _buckets[index]. OrderAccess::release_store_ptr(&_entry, l); @@ -88,8 +88,8 @@ template inline void HashtableBucket::set_entry(BasicHashtableEn template inline BasicHashtableEntry* HashtableBucket::get_entry() const { - // Warning: Preserve load ordering. The SystemDictionary is read - // without locks. The new SystemDictionaryEntry must be + // Warning: Preserve load ordering. The PackageEntryTable, ModuleEntryTable and + // SystemDictionary are read without locks. The new entry must be // complete before other threads can be allowed to see it // via a store to _buckets[index]. return (BasicHashtableEntry*) OrderAccess::load_ptr_acquire(&_entry); From 8617484bde07ea83d2a39d4d9093fc75ec5b1a65 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 19 Sep 2016 13:12:26 -0400 Subject: [PATCH 041/207] 8166229: Eliminate ParNew's use of klass_or_null() Use list_ptr_from_klass instead of klass_or_null. Reviewed-by: mgerdin, jmasa --- .../src/share/vm/gc/cms/parNewGeneration.cpp | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp index ddc80ce3a76..78839d983f6 100644 --- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp @@ -1366,22 +1366,25 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan return false; } assert(prefix != NULL && prefix != BUSY, "Error"); - size_t i = 1; oop cur = prefix; - while (i < objsFromOverflow && cur->klass_or_null() != NULL) { - i++; cur = cur->list_ptr_from_klass(); + for (size_t i = 1; i < objsFromOverflow; ++i) { + oop next = cur->list_ptr_from_klass(); + if (next == NULL) break; + cur = next; } + assert(cur != NULL, "Loop postcondition"); // Reattach remaining (suffix) to overflow list - if (cur->klass_or_null() == NULL) { + oop suffix = cur->list_ptr_from_klass(); + if (suffix == NULL) { // Write back the NULL in lieu of the BUSY we wrote // above and it is still the same value. if (_overflow_list == BUSY) { (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); } } else { - assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error"); - oop suffix = cur->list_ptr_from_klass(); // suffix will be put back on global list + assert(suffix != BUSY, "Error"); + // suffix will be put back on global list cur->set_klass_to_list_ptr(NULL); // break off suffix // It's possible that the list is still in the empty(busy) state // we left it in a short while ago; in that case we may be @@ -1401,8 +1404,10 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan // Too bad, someone else got in in between; we'll need to do a splice. // Find the last item of suffix list oop last = suffix; - while (last->klass_or_null() != NULL) { - last = last->list_ptr_from_klass(); + while (true) { + oop next = last->list_ptr_from_klass(); + if (next == NULL) break; + last = next; } // Atomically prepend suffix to current overflow list observed_overflow_list = _overflow_list; From c354a6230116c6e7d4999ff62a0ecd5d147be6ff Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 19 Sep 2016 22:55:26 +0200 Subject: [PATCH 042/207] 8166207: Use of Copy::conjoint_oops_atomic in global mark stack causes crashes on arm64 Use Copy::conjoint_memory_atomic() instead. Reviewed-by: kbarrett --- hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp index 43b227a7ef8..52a9f4817ab 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp @@ -285,7 +285,7 @@ bool G1CMMarkStack::par_push_chunk(oop* ptr_arr) { return false; } - Copy::conjoint_oops_atomic(ptr_arr, new_chunk->data, OopsPerChunk); + Copy::conjoint_memory_atomic(ptr_arr, new_chunk->data, OopsPerChunk * sizeof(oop)); add_chunk_to_chunk_list(new_chunk); @@ -299,7 +299,7 @@ bool G1CMMarkStack::par_pop_chunk(oop* ptr_arr) { return false; } - Copy::conjoint_oops_atomic(cur->data, ptr_arr, OopsPerChunk); + Copy::conjoint_memory_atomic(cur->data, ptr_arr, OopsPerChunk * sizeof(oop)); add_chunk_to_free_list(cur); return true; From 2e74f81187c4568c1d335429f6cec58cf9a84659 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Mon, 19 Sep 2016 19:25:09 -0400 Subject: [PATCH 043/207] 8166312: Backout 8165017 Backout of the change for JDK-8165017 because tests failed on windows Reviewed-by: ctornqvi, dholmes, gtriantafill --- .../jdwp/AllModulesCommandTest.java | 52 +++++-------------- hotspot/test/serviceability/jdwp/JdwpCmd.java | 1 + .../serviceability/jdwp/JdwpModuleCmd.java | 34 ------------ .../serviceability/jdwp/JdwpModuleReply.java | 42 --------------- .../jdwp/JdwpVisibleClassesCmd.java | 34 ------------ .../jdwp/JdwpVisibleClassesReply.java | 49 ----------------- 6 files changed, 13 insertions(+), 199 deletions(-) delete mode 100644 hotspot/test/serviceability/jdwp/JdwpModuleCmd.java delete mode 100644 hotspot/test/serviceability/jdwp/JdwpModuleReply.java delete mode 100644 hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java delete mode 100644 hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java diff --git a/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java b/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java index 5fed0412a03..33bb583c59d 100644 --- a/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java +++ b/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java @@ -30,7 +30,7 @@ import static jdk.test.lib.Asserts.assertTrue; /** * @test - * @summary Tests the modules-related JDWP commands + * @summary Tests AllModules JDWP command * @library /test/lib * @modules java.base/jdk.internal.misc * @compile AllModulesCommandTestDebuggee.java @@ -87,12 +87,8 @@ public class AllModulesCommandTest implements DebuggeeLauncher.Listener { assertReply(reply); for (int i = 0; i < reply.getModulesCount(); ++i) { long modId = reply.getModuleId(i); - // For each module reported by JDWP get its name using the JDWP NAME command - // and store the reply - String modName = getModuleName(modId); - if (modName != null) { // JDWP reports unnamed modules, ignore them - jdwpModuleNames.add(modName); - } + // For each module reported by JDWP get its name using the JDWP NAME command + getModuleName(modId); // Assert the JDWP CANREAD and CLASSLOADER commands assertCanRead(modId); assertClassLoader(modId); @@ -118,10 +114,14 @@ public class AllModulesCommandTest implements DebuggeeLauncher.Listener { } } - private String getModuleName(long modId) throws IOException { + private void getModuleName(long modId) throws IOException { + // Send out the JDWP NAME command and store the reply JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel); assertReply(reply); - return reply.getModuleName(); + String modName = reply.getModuleName(); + if (modName != null) { // JDWP reports unnamed modules, ignore them + jdwpModuleNames.add(modName); + } } private void assertReply(JdwpReply reply) { @@ -139,39 +139,11 @@ public class AllModulesCommandTest implements DebuggeeLauncher.Listener { } private void assertClassLoader(long modId) throws IOException { - // Verify that the module classloader id is valid + // Simple assert for the CLASSLOADER command JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel); assertReply(reply); - long moduleClassLoader = reply.getClassLoaderId(); - assertTrue(moduleClassLoader >= 0, "bad classloader refId " + moduleClassLoader + " for module id " + modId); - - String clsModName = getModuleName(modId); - if ("java.base".equals(clsModName)) { - // For the java.base module, because there will be some loaded classes, we can verify - // that some of the loaded classes do report the java.base module as the module they belong to - assertGetModule(moduleClassLoader, modId); - } - } - - private void assertGetModule(long moduleClassLoader, long modId) throws IOException { - // Get all the visible classes for the module classloader - JdwpVisibleClassesReply visibleClasses = new JdwpVisibleClassesCmd(moduleClassLoader).send(channel); - assertReply(visibleClasses); - - boolean moduleFound = false; - for (long clsId : visibleClasses.getVisibleClasses()) { - // For each visible class get the module the class belongs to - JdwpModuleReply modReply = new JdwpModuleCmd(clsId).send(channel); - assertReply(modReply); - long clsModId = modReply.getModuleId(); - - // At least one of the visible classes should belong to our module - if (modId == clsModId) { - moduleFound = true; - break; - } - } - assertTrue(moduleFound, "None of the visible classes for the classloader of the module " + getModuleName(modId) + " reports the module as its own"); + long clId = reply.getClassLoaderId(); + assertTrue(clId >= 0, "bad classloader refId " + clId + " for module id " + modId); } } diff --git a/hotspot/test/serviceability/jdwp/JdwpCmd.java b/hotspot/test/serviceability/jdwp/JdwpCmd.java index 05dbb6efb7f..fe7f28707a8 100644 --- a/hotspot/test/serviceability/jdwp/JdwpCmd.java +++ b/hotspot/test/serviceability/jdwp/JdwpCmd.java @@ -70,6 +70,7 @@ public abstract class JdwpCmd { } public final T send(JdwpChannel channel) throws IOException { + System.err.println("Sending command: " + this); channel.write(data.array(), HEADER_LEN + getDataLength()); if (reply != null) { reply.initFromStream(channel.getInputStream()); diff --git a/hotspot/test/serviceability/jdwp/JdwpModuleCmd.java b/hotspot/test/serviceability/jdwp/JdwpModuleCmd.java deleted file mode 100644 index a9ed54419fa..00000000000 --- a/hotspot/test/serviceability/jdwp/JdwpModuleCmd.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * The JDWP MODULE command - */ -public class JdwpModuleCmd extends JdwpCmd { - - public JdwpModuleCmd(long refId) { - super(19, 2, JdwpModuleReply.class, refLen()); - putRefId(refId); - } - -} diff --git a/hotspot/test/serviceability/jdwp/JdwpModuleReply.java b/hotspot/test/serviceability/jdwp/JdwpModuleReply.java deleted file mode 100644 index 19baa7a4dde..00000000000 --- a/hotspot/test/serviceability/jdwp/JdwpModuleReply.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.DataInputStream; -import java.io.IOException; - -/** - * The reply to the JDWP MODULE command - */ -public class JdwpModuleReply extends JdwpReply { - - private long moduleId; - - protected void parseData(DataInputStream ds) throws IOException { - moduleId = readRefId(ds); - } - - public long getModuleId() { - return moduleId; - } - -} diff --git a/hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java deleted file mode 100644 index daab8a11d6a..00000000000 --- a/hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * The JDWP VISIBLE CLASSES command - */ -public class JdwpVisibleClassesCmd extends JdwpCmd { - - public JdwpVisibleClassesCmd(long classLoaderId) { - super(1, 14, JdwpVisibleClassesReply.class, refLen()); - putRefId(classLoaderId); - } - -} diff --git a/hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java deleted file mode 100644 index 5381c43c51a..00000000000 --- a/hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Arrays; - -/** - * The reply to the JDWP VISIBLE CLASSES command - */ -public class JdwpVisibleClassesReply extends JdwpReply { - - private long[] visibleClasses; - - protected void parseData(DataInputStream ds) throws IOException { - int numOfClasses = ds.readInt(); - visibleClasses = new long[numOfClasses]; - for (int i = 0; i < numOfClasses; ++i) { - byte type = ds.readByte(); - long refId = readRefId(ds); - visibleClasses[i] = refId; - } - } - - public long[] getVisibleClasses() { - return Arrays.copyOf(visibleClasses, visibleClasses.length); - } - -} From 9b7c58376f2463e2845a5acf76a30918431e9f1d Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 19 Sep 2016 19:59:28 -0400 Subject: [PATCH 044/207] 8166228: Remove unused HeapRegion::object_iterate_mem_careful() Removed unused function. Reviewed-by: mgerdin, tschatzl --- hotspot/src/share/vm/gc/g1/heapRegion.cpp | 29 ----------------------- hotspot/src/share/vm/gc/g1/heapRegion.hpp | 11 --------- 2 files changed, 40 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.cpp b/hotspot/src/share/vm/gc/g1/heapRegion.cpp index 33d8268855d..6944bcf0c44 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp @@ -352,35 +352,6 @@ void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark, _prev_marked_bytes = marked_bytes; } -HeapWord* -HeapRegion::object_iterate_mem_careful(MemRegion mr, - ObjectClosure* cl) { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - // We used to use "block_start_careful" here. But we're actually happy - // to update the BOT while we do this... - HeapWord* cur = block_start(mr.start()); - mr = mr.intersection(used_region()); - if (mr.is_empty()) return NULL; - // Otherwise, find the obj that extends onto mr.start(). - - assert(cur <= mr.start() - && (oop(cur)->klass_or_null() == NULL || - cur + oop(cur)->size() > mr.start()), - "postcondition of block_start"); - oop obj; - while (cur < mr.end()) { - obj = oop(cur); - if (obj->klass_or_null() == NULL) { - // Ran into an unparseable point. - return cur; - } else if (!g1h->is_obj_dead(obj)) { - cl->do_object(obj); - } - cur += block_size(cur); - } - return NULL; -} - HeapWord* HeapRegion:: oops_on_card_seq_iterate_careful(MemRegion mr, diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.hpp b/hotspot/src/share/vm/gc/g1/heapRegion.hpp index f4bf95e055b..9542b9ffb11 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp @@ -653,17 +653,6 @@ class HeapRegion: public G1ContiguousSpace { } } - // Requires that "mr" be entirely within the region. - // Apply "cl->do_object" to all objects that intersect with "mr". - // If the iteration encounters an unparseable portion of the region, - // or if "cl->abort()" is true after a closure application, - // terminate the iteration and return the address of the start of the - // subregion that isn't done. (The two can be distinguished by querying - // "cl->abort()".) Return of "NULL" indicates that the iteration - // completed. - HeapWord* - object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl); - // filter_young: if true and the region is a young region then we // skip the iteration. // card_ptr: if not NULL, and we decide that the card is not young From 93e6430d9fef60e6333a1f2a8e94377d4b815242 Mon Sep 17 00:00:00 2001 From: Ambarish Rapte Date: Tue, 20 Sep 2016 11:46:34 +0530 Subject: [PATCH 045/207] 8163261: regression on Linux: java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java Reviewed-by: serb, alexsch --- .../share/classes/sun/swing/CachedPainter.java | 10 +++++++--- .../LWDispatcherMemoryLeakTest.java | 13 ++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java b/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java index 92c0e3bad8e..752b42d34c1 100644 --- a/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java +++ b/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java @@ -25,7 +25,6 @@ package sun.swing; import java.awt.*; -import java.awt.geom.AffineTransform; import java.awt.image.*; import java.util.*; @@ -60,7 +59,11 @@ public abstract class CachedPainter { synchronized(CachedPainter.class) { ImageCache cache = cacheMap.get(key); if (cache == null) { - cache = new ImageCache(1); + if (key == PainterMultiResolutionCachedImage.class) { + cache = new ImageCache(32); + } else { + cache = new ImageCache(1); + } cacheMap.put(key, cache); } return cache; @@ -271,7 +274,8 @@ public abstract class CachedPainter { public Image getResolutionVariant(double destWidth, double destHeight) { int w = (int) Math.ceil(destWidth); int h = (int) Math.ceil(destHeight); - return getImage(this, c, baseWidth, baseHeight, w, h, args); + return getImage(PainterMultiResolutionCachedImage.class, + c, baseWidth, baseHeight, w, h, args); } @Override diff --git a/jdk/test/java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java b/jdk/test/java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java index 22a68122995..8e577a48e72 100644 --- a/jdk/test/java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java +++ b/jdk/test/java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ import test.java.awt.regtesthelpers.Util; /* @test @key headful - @bug 7079254 + @bug 7079254 8163261 @summary Toolkit eventListener leaks memory @library ../regtesthelpers @build Util @@ -93,8 +93,15 @@ public class LWDispatcherMemoryLeakTest { } } alloc = null; + String leakObjs = ""; if (button.get() != null) { - throw new Exception("Test failed: JButton was not collected"); + leakObjs = "JButton"; + } + if (p.get() != null) { + leakObjs += " JPanel"; + } + if (leakObjs != "") { + throw new Exception("Test failed: " + leakObjs + " not collected"); } } From 80d4e131f603f1cb77180ec1f9fae3bed3fe6228 Mon Sep 17 00:00:00 2001 From: Ambarish Rapte Date: Tue, 20 Sep 2016 12:37:54 +0530 Subject: [PATCH 046/207] 8166015: [PIT][TEST_BUG] stray character in java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java Reviewed-by: aghaisas, ssadetsky --- .../ModalDialogActivationTest.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/jdk/test/java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java b/jdk/test/java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java index deff8ee33a4..63db32398a2 100644 --- a/jdk/test/java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java +++ b/jdk/test/java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java @@ -23,15 +23,21 @@ * questions. */ -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JDialog; +import javax.swing.JFrame; /* @test - @bug 8160570 - @summary Tests that a modal dialog receives WINDOW_ACTIVATED & WINDOW_GAINED_FOCUS on first show. + @key headful + @bug 8160570 8166015 + @summary Tests that a modal dialog receives WINDOW_ACTIVATED + & WINDOW_GAINED_FOCUS on first show. */ + public class ModalDialogActivationTest { static final Object lock = new Object(); static volatile boolean activated; @@ -48,7 +54,8 @@ public class ModalDialogActivationTest { } } if (!activated || !focused) { - throw new RuntimeException("Test FAILED: activated: " + activated + ", focused: " + focused); + throw new RuntimeException("Test FAILED: activated: " + activated + + ", focused: " + focused); } System.out.println("Test PASSED"); } @@ -79,7 +86,7 @@ public class ModalDialogActivationTest { } static class MyModalDialog extends JDialog { - public MyModalDialog(Frame owner, String title)ª { + public MyModalDialog(Frame owner, String title) { super(owner, title, true); } From 6085d008cc4391b2723e9a2f23c31ad7d449c2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Tue, 20 Sep 2016 11:41:43 +0200 Subject: [PATCH 047/207] 8165860: WorkGroup classes are missing volatile specifiers for lock-free code Reviewed-by: mgerdin, tschatzl --- hotspot/src/share/vm/gc/shared/workgroup.cpp | 12 +++++------- hotspot/src/share/vm/gc/shared/workgroup.hpp | 8 ++++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/hotspot/src/share/vm/gc/shared/workgroup.cpp b/hotspot/src/share/vm/gc/shared/workgroup.cpp index 6df874b2510..a7f6342c634 100644 --- a/hotspot/src/share/vm/gc/shared/workgroup.cpp +++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp @@ -472,23 +472,21 @@ bool SequentialSubTasksDone::valid() { } bool SequentialSubTasksDone::is_task_claimed(uint& t) { - uint* n_claimed_ptr = &_n_claimed; - t = *n_claimed_ptr; + t = _n_claimed; while (t < _n_tasks) { - jint res = Atomic::cmpxchg(t+1, n_claimed_ptr, t); + jint res = Atomic::cmpxchg(t+1, &_n_claimed, t); if (res == (jint)t) { return false; } - t = *n_claimed_ptr; + t = res; } return true; } bool SequentialSubTasksDone::all_tasks_completed() { - uint* n_completed_ptr = &_n_completed; - uint complete = *n_completed_ptr; + uint complete = _n_completed; while (true) { - uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete); + uint res = Atomic::cmpxchg(complete+1, &_n_completed, complete); if (res == complete) { break; } diff --git a/hotspot/src/share/vm/gc/shared/workgroup.hpp b/hotspot/src/share/vm/gc/shared/workgroup.hpp index b71b3e0e23a..320652a993c 100644 --- a/hotspot/src/share/vm/gc/shared/workgroup.hpp +++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp @@ -318,9 +318,9 @@ public: // enumeration type. class SubTasksDone: public CHeapObj { - uint* _tasks; + volatile uint* _tasks; uint _n_tasks; - uint _threads_completed; + volatile uint _threads_completed; #ifdef ASSERT volatile uint _claimed; #endif @@ -363,11 +363,11 @@ public: class SequentialSubTasksDone : public StackObj { protected: uint _n_tasks; // Total number of tasks available. - uint _n_claimed; // Number of tasks claimed. + volatile uint _n_claimed; // Number of tasks claimed. // _n_threads is used to determine when a sub task is done. // See comments on SubTasksDone::_n_threads uint _n_threads; // Total number of parallel threads. - uint _n_completed; // Number of completed threads. + volatile uint _n_completed; // Number of completed threads. void clear(); From 0086595519168b90a1a5617851ecd61f607c2c9a Mon Sep 17 00:00:00 2001 From: Joseph Provino Date: Tue, 20 Sep 2016 10:27:51 -0400 Subject: [PATCH 048/207] 8164482: [REDO] G1 does not implement millis_since_last_gc which is needed by RMI GC G1 does not return a correct value for the CollectedHeap::millis_since_last_gc() Reviewed-by: tschatzl, kbarrett --- hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp | 12 ++++++++++-- hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp | 5 ++++- hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp | 4 ++++ hotspot/src/share/vm/gc/g1/g1Policy.hpp | 2 ++ hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp | 13 ++++++------- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index 9ffbaeaad8b..8179b6e3062 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -2474,8 +2474,16 @@ size_t G1CollectedHeap::max_capacity() const { } jlong G1CollectedHeap::millis_since_last_gc() { - // assert(false, "NYI"); - return 0; + // See the notes in GenCollectedHeap::millis_since_last_gc() + // for more information about the implementation. + jlong ret_val = (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) - + _g1_policy->collection_pause_end_millis(); + if (ret_val < 0) { + log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT + ". returning zero instead.", ret_val); + return 0; + } + return ret_val; } void G1CollectedHeap::prepare_for_verify() { diff --git a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp index 803c1b62d79..68200527033 100644 --- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp +++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp @@ -66,7 +66,8 @@ G1DefaultPolicy::G1DefaultPolicy() : _phase_times(new G1GCPhaseTimes(ParallelGCThreads)), _tenuring_threshold(MaxTenuringThreshold), _max_survivor_regions(0), - _survivors_age_table(true) { } + _survivors_age_table(true), + _collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC) { } G1DefaultPolicy::~G1DefaultPolicy() { delete _ihop_control; @@ -575,6 +576,8 @@ void G1DefaultPolicy::record_collection_pause_end(double pause_time_ms, size_t c record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec); + _collection_pause_end_millis = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; + last_pause_included_initial_mark = collector_state()->during_initial_mark_pause(); if (last_pause_included_initial_mark) { record_concurrent_mark_init_end(0.0); diff --git a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp index 6eba7e76e20..658754e7e0e 100644 --- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp +++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp @@ -64,6 +64,8 @@ class G1DefaultPolicy: public G1Policy { double _full_collection_start_sec; + jlong _collection_pause_end_millis; + uint _young_list_target_length; uint _young_list_fixed_length; @@ -237,6 +239,8 @@ public: double reclaimable_bytes_perc(size_t reclaimable_bytes) const; + jlong collection_pause_end_millis() { return _collection_pause_end_millis; } + private: // Sets up marking if proper conditions are met. void maybe_start_marking(); diff --git a/hotspot/src/share/vm/gc/g1/g1Policy.hpp b/hotspot/src/share/vm/gc/g1/g1Policy.hpp index 92aa6050e70..ec1ea47abb9 100644 --- a/hotspot/src/share/vm/gc/g1/g1Policy.hpp +++ b/hotspot/src/share/vm/gc/g1/g1Policy.hpp @@ -119,6 +119,8 @@ public: virtual void record_full_collection_start() = 0; virtual void record_full_collection_end() = 0; + virtual jlong collection_pause_end_millis() = 0; + // Must currently be called while the world is stopped. virtual void record_concurrent_mark_init_end(double mark_init_elapsed_time_ms) = 0; diff --git a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp index 049b675bd51..d3e018f4461 100644 --- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp @@ -1256,21 +1256,20 @@ class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure { }; jlong GenCollectedHeap::millis_since_last_gc() { - // We need a monotonically non-decreasing time in ms but - // os::javaTimeMillis() does not guarantee monotonicity. + // javaTimeNanos() is guaranteed to be monotonically non-decreasing + // provided the underlying platform provides such a time source + // (and it is bug free). So we still have to guard against getting + // back a time later than 'now'. jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; GenTimeOfLastGCClosure tolgc_cl(now); // iterate over generations getting the oldest // time that a generation was collected generation_iterate(&tolgc_cl, false); - // javaTimeNanos() is guaranteed to be monotonically non-decreasing - // provided the underlying platform provides such a time source - // (and it is bug free). So we still have to guard against getting - // back a time later than 'now'. jlong retVal = now - tolgc_cl.time(); if (retVal < 0) { - NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);) + log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT + ". returning zero instead.", retVal); return 0; } return retVal; From 453166437ed6ff727294bcbe17f20532bed3b912 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Tue, 20 Sep 2016 10:04:55 -0700 Subject: [PATCH 049/207] 8165372: StackWalker performance regression following JDK-8147039 Stack walking can use javaVFrame or vframeStream Reviewed-by: coleenp, mchung --- hotspot/src/share/vm/prims/jvm.cpp | 4 +- hotspot/src/share/vm/prims/stackwalk.cpp | 135 +++++++++++++---------- hotspot/src/share/vm/prims/stackwalk.hpp | 101 ++++++++++++----- 3 files changed, 151 insertions(+), 89 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 549e9f47109..23575de98a8 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -562,8 +562,8 @@ JVM_ENTRY(jint, JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, } Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream)); - return StackWalk::moreFrames(stackStream_h, mode, anchor, frame_count, - start_index, frames_array_h, THREAD); + return StackWalk::fetchNextBatch(stackStream_h, mode, anchor, frame_count, + start_index, frames_array_h, THREAD); JVM_END JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack)) diff --git a/hotspot/src/share/vm/prims/stackwalk.cpp b/hotspot/src/share/vm/prims/stackwalk.cpp index 62a0a663cad..6821e6fc1ee 100644 --- a/hotspot/src/share/vm/prims/stackwalk.cpp +++ b/hotspot/src/share/vm/prims/stackwalk.cpp @@ -37,42 +37,47 @@ #include "utilities/globalDefinitions.hpp" // setup and cleanup actions -void JavaFrameStream::setup_magic_on_entry(objArrayHandle frames_array) { +void BaseFrameStream::setup_magic_on_entry(objArrayHandle frames_array) { frames_array->obj_at_put(magic_pos, _thread->threadObj()); _anchor = address_value(); assert(check_magic(frames_array), "invalid magic"); } -bool JavaFrameStream::check_magic(objArrayHandle frames_array) { +bool BaseFrameStream::check_magic(objArrayHandle frames_array) { oop m1 = frames_array->obj_at(magic_pos); jlong m2 = _anchor; if (m1 == _thread->threadObj() && m2 == address_value()) return true; return false; } -bool JavaFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) { +bool BaseFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) { bool ok = check_magic(frames_array); frames_array->obj_at_put(magic_pos, NULL); _anchor = 0L; return ok; } -// Returns JavaFrameStream for the current stack being traversed. +JavaFrameStream::JavaFrameStream(JavaThread* thread, int mode) + : BaseFrameStream(thread), _vfst(thread) { + _need_method_info = StackWalk::need_method_info(mode); +} + +// Returns the BaseFrameStream for the current stack being traversed. // // Parameters: // thread Current Java thread. // magic Magic value used for each stack walking // frames_array User-supplied buffers. The 0th element is reserved -// to this JavaFrameStream to use +// for this BaseFrameStream to use // -JavaFrameStream* JavaFrameStream::from_current(JavaThread* thread, jlong magic, +BaseFrameStream* BaseFrameStream::from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array) { assert(thread != NULL && thread->is_Java_thread(), ""); oop m1 = frames_array->obj_at(magic_pos); if (m1 != thread->threadObj()) return NULL; if (magic == 0L) return NULL; - JavaFrameStream* stream = (JavaFrameStream*) (intptr_t) magic; + BaseFrameStream* stream = (BaseFrameStream*) (intptr_t) magic; if (!stream->is_valid_in(thread, frames_array)) return NULL; return stream; } @@ -85,7 +90,7 @@ JavaFrameStream* JavaFrameStream::from_current(JavaThread* thread, jlong magic, // // Parameters: // mode Restrict which frames to be decoded. -// JavaFrameStream stream of javaVFrames +// BaseFrameStream stream of frames // max_nframes Maximum number of frames to be filled. // start_index Start index to the user-supplied buffers. // frames_array Buffer to store Class or StackFrame in, starting at start_index. @@ -96,7 +101,7 @@ JavaFrameStream* JavaFrameStream::from_current(JavaThread* thread, jlong magic, // // Returns the number of frames whose information was transferred into the buffers. // -int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream, +int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream, int max_nframes, int start_index, objArrayHandle frames_array, int& end_index, TRAPS) { @@ -110,7 +115,6 @@ int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream, int frames_decoded = 0; for (; !stream.at_end(); stream.next()) { Method* method = stream.method(); - int bci = stream.bci(); if (method == NULL) continue; @@ -129,35 +133,42 @@ int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream, int index = end_index++; if (TraceStackWalk) { tty->print(" %d: frame method: ", index); method->print_short_name(); - tty->print_cr(" bci=%d", bci); + tty->print_cr(" bci=%d", stream.bci()); } + if (!need_method_info(mode) && get_caller_class(mode) && + index == start_index && method->caller_sensitive()) { + ResourceMark rm(THREAD); + THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), + err_msg("StackWalker::getCallerClass called from @CallerSensitive %s method", + method->name_and_sig_as_C_string())); + } // fill in StackFrameInfo and initialize MemberName - if (live_frame_info(mode)) { - assert (use_frames_array(mode), "Bad mode for get live frame"); - Handle stackFrame(frames_array->obj_at(index)); - fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0); - } else if (need_method_info(mode)) { - assert (use_frames_array(mode), "Bad mode for get stack frame"); - Handle stackFrame(frames_array->obj_at(index)); - fill_stackframe(stackFrame, method, bci); - } else { - assert (use_frames_array(mode) == false, "Bad mode for filling in Class object"); - if (get_caller_class(mode) && index == start_index && method->caller_sensitive()) { - ResourceMark rm(THREAD); - THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), - err_msg("StackWalker::getCallerClass called from @CallerSensitive %s method", - method->name_and_sig_as_C_string())); - } - - frames_array->obj_at_put(index, method->method_holder()->java_mirror()); - } + stream.fill_frame(index, frames_array, method, CHECK_0); if (++frames_decoded >= max_nframes) break; } return frames_decoded; } -static oop create_primitive_value_instance(StackValueCollection* values, int i, TRAPS) { +// Fill in the LiveStackFrameInfo at the given index in frames_array +void LiveFrameStream::fill_frame(int index, objArrayHandle frames_array, + const methodHandle& method, TRAPS) { + Handle stackFrame(THREAD, frames_array->obj_at(index)); + fill_live_stackframe(stackFrame, method, CHECK); +} + +// Fill in the StackFrameInfo at the given index in frames_array +void JavaFrameStream::fill_frame(int index, objArrayHandle frames_array, + const methodHandle& method, TRAPS) { + if (_need_method_info) { + Handle stackFrame(THREAD, frames_array->obj_at(index)); + fill_stackframe(stackFrame, method); + } else { + frames_array->obj_at_put(index, method->method_holder()->java_mirror()); + } +} + +oop LiveFrameStream::create_primitive_value_instance(StackValueCollection* values, int i, TRAPS) { Klass* k = SystemDictionary::resolve_or_null(vmSymbols::java_lang_LiveStackFrameInfo(), CHECK_NULL); instanceKlassHandle ik (THREAD, k); @@ -228,7 +239,7 @@ static oop create_primitive_value_instance(StackValueCollection* values, int i, return (instanceOop) result.get_jobject(); } -static objArrayHandle values_to_object_array(StackValueCollection* values, TRAPS) { +objArrayHandle LiveFrameStream::values_to_object_array(StackValueCollection* values, TRAPS) { objArrayHandle empty; int length = values->size(); objArrayOop array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), @@ -243,7 +254,7 @@ static objArrayHandle values_to_object_array(StackValueCollection* values, TRAPS return array_h; } -static objArrayHandle monitors_to_object_array(GrowableArray* monitors, TRAPS) { +objArrayHandle LiveFrameStream::monitors_to_object_array(GrowableArray* monitors, TRAPS) { int length = monitors->length(); objArrayOop array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), length, CHECK_(objArrayHandle())); @@ -256,19 +267,19 @@ static objArrayHandle monitors_to_object_array(GrowableArray* moni } // Fill StackFrameInfo with declaringClass and bci and initialize memberName -void StackWalk::fill_stackframe(Handle stackFrame, const methodHandle& method, int bci) { +void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method) { java_lang_StackFrameInfo::set_declaringClass(stackFrame(), method->method_holder()->java_mirror()); - java_lang_StackFrameInfo::set_method_and_bci(stackFrame(), method, bci); + java_lang_StackFrameInfo::set_method_and_bci(stackFrame(), method, bci()); } // Fill LiveStackFrameInfo with locals, monitors, and expressions -void StackWalk::fill_live_stackframe(Handle stackFrame, const methodHandle& method, - int bci, javaVFrame* jvf, TRAPS) { - fill_stackframe(stackFrame, method, bci); - if (jvf != NULL) { - StackValueCollection* locals = jvf->locals(); - StackValueCollection* expressions = jvf->expressions(); - GrowableArray* monitors = jvf->monitors(); +void LiveFrameStream::fill_live_stackframe(Handle stackFrame, + const methodHandle& method, TRAPS) { + fill_stackframe(stackFrame, method); + if (_jvf != NULL) { + StackValueCollection* locals = _jvf->locals(); + StackValueCollection* expressions = _jvf->expressions(); + GrowableArray* monitors = _jvf->monitors(); if (!locals->is_empty()) { objArrayHandle locals_h = values_to_object_array(locals, CHECK); @@ -315,15 +326,26 @@ oop StackWalk::walk(Handle stackStream, jlong mode, THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL); } - Klass* stackWalker_klass = SystemDictionary::StackWalker_klass(); - Klass* abstractStackWalker_klass = SystemDictionary::AbstractStackWalker_klass(); + // Setup traversal onto my stack. + if (live_frame_info(mode)) { + assert (use_frames_array(mode), "Bad mode for get live frame"); + RegisterMap regMap(jt, true); + LiveFrameStream stream(jt, ®Map); + return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, CHECK_NULL); + } else { + JavaFrameStream stream(jt, mode); + return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, CHECK_NULL); + } +} +oop StackWalk::fetchFirstBatch(BaseFrameStream& stream, Handle stackStream, + jlong mode, int skip_frames, int frame_count, + int start_index, objArrayHandle frames_array, TRAPS) { methodHandle m_doStackWalk(THREAD, Universe::do_stack_walk_method()); - // Setup traversal onto my stack. - RegisterMap regMap(jt, true); - JavaFrameStream stream(jt, ®Map); { + Klass* stackWalker_klass = SystemDictionary::StackWalker_klass(); + Klass* abstractStackWalker_klass = SystemDictionary::AbstractStackWalker_klass(); while (!stream.at_end()) { InstanceKlass* ik = stream.method()->method_holder(); if (ik != stackWalker_klass && @@ -341,10 +363,7 @@ oop StackWalk::walk(Handle stackStream, jlong mode, // from the stack frame at depth == skip_frames. for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) { if (TraceStackWalk) { - tty->print(" skip "); stream.method()->print_short_name(); - tty->print_cr(" frame id: " PTR_FORMAT " pc: " PTR_FORMAT, - p2i(stream.java_frame()->fr().id()), - p2i(stream.java_frame()->fr().pc())); + tty->print(" skip "); stream.method()->print_short_name(); tty->cr(); } } } @@ -402,13 +421,13 @@ oop StackWalk::walk(Handle stackStream, jlong mode, // // Returns the end index of frame filled in the buffer. // -jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic, - int frame_count, int start_index, - objArrayHandle frames_array, - TRAPS) +jint StackWalk::fetchNextBatch(Handle stackStream, jlong mode, jlong magic, + int frame_count, int start_index, + objArrayHandle frames_array, + TRAPS) { JavaThread* jt = (JavaThread*)THREAD; - JavaFrameStream* existing_stream = JavaFrameStream::from_current(jt, magic, frames_array); + BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array); if (existing_stream == NULL) { THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L); } @@ -418,7 +437,7 @@ jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic, } if (TraceStackWalk) { - tty->print_cr("StackWalk::moreFrames frame_count %d existing_stream " PTR_FORMAT " start %d frames %d", + tty->print_cr("StackWalk::fetchNextBatch frame_count %d existing_stream " PTR_FORMAT " start %d frames %d", frame_count, p2i(existing_stream), start_index, frames_array->length()); } int end_index = start_index; @@ -429,7 +448,7 @@ jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic, int count = frame_count + start_index; assert (frames_array->length() >= count, "not enough space in buffers"); - JavaFrameStream& stream = (*existing_stream); + BaseFrameStream& stream = (*existing_stream); if (!stream.at_end()) { stream.next(); // advance past the last frame decoded in previous batch if (!stream.at_end()) { diff --git a/hotspot/src/share/vm/prims/stackwalk.hpp b/hotspot/src/share/vm/prims/stackwalk.hpp index 580c953b197..161a74599c3 100644 --- a/hotspot/src/share/vm/prims/stackwalk.hpp +++ b/hotspot/src/share/vm/prims/stackwalk.hpp @@ -29,31 +29,34 @@ #include "oops/oop.hpp" #include "runtime/vframe.hpp" -// -// JavaFrameStream is used by StackWalker to iterate through Java stack frames -// on the given JavaThread. -// -class JavaFrameStream : public StackObj { +// BaseFrameStream is an abstract base class for encapsulating the VM-side +// implementation of the StackWalker API. There are two concrete subclasses: +// - JavaFrameStream: +// -based on vframeStream; used in most instances +// - LiveFrameStream: +// -based on javaVFrame; used for retrieving locals/monitors/operands for +// LiveStackFrame +class BaseFrameStream : public StackObj { private: enum { magic_pos = 0 }; JavaThread* _thread; - javaVFrame* _jvf; jlong _anchor; +protected: + void fill_stackframe(Handle stackFrame, const methodHandle& method); public: - JavaFrameStream(JavaThread* thread, RegisterMap* rm) - : _thread(thread), _anchor(0L) { - _jvf = _thread->last_java_vframe(rm); - } + BaseFrameStream(JavaThread* thread) : _thread(thread), _anchor(0L) {} - javaVFrame* java_frame() { return _jvf; } - void next() { _jvf = _jvf->java_sender(); } - bool at_end() { return _jvf == NULL; } + virtual void next()=0; + virtual bool at_end()=0; - Method* method() { return _jvf->method(); } - int bci() { return _jvf->bci(); } + virtual Method* method()=0; + virtual int bci()=0; + + virtual void fill_frame(int index, objArrayHandle frames_array, + const methodHandle& method, TRAPS)=0; void setup_magic_on_entry(objArrayHandle frames_array); bool check_magic(objArrayHandle frames_array); @@ -67,35 +70,72 @@ public: return (jlong) castable_address(this); } - static JavaFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array); + static BaseFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array); +}; + +class JavaFrameStream : public BaseFrameStream { +private: + vframeStream _vfst; + bool _need_method_info; +public: + JavaFrameStream(JavaThread* thread, int mode); + + void next() { _vfst.next();} + bool at_end() { return _vfst.at_end(); } + + Method* method() { return _vfst.method(); } + int bci() { return _vfst.bci(); } + + void fill_frame(int index, objArrayHandle frames_array, + const methodHandle& method, TRAPS); +}; + +class LiveFrameStream : public BaseFrameStream { +private: + javaVFrame* _jvf; + + void fill_live_stackframe(Handle stackFrame, const methodHandle& method, TRAPS); + static oop create_primitive_value_instance(StackValueCollection* values, + int i, TRAPS); + static objArrayHandle monitors_to_object_array(GrowableArray* monitors, + TRAPS); + static objArrayHandle values_to_object_array(StackValueCollection* values, TRAPS); +public: + LiveFrameStream(JavaThread* thread, RegisterMap* rm) : BaseFrameStream(thread) { + _jvf = thread->last_java_vframe(rm); + } + + void next() { _jvf = _jvf->java_sender(); } + bool at_end() { return _jvf == NULL; } + + Method* method() { return _jvf->method(); } + int bci() { return _jvf->bci(); } + + void fill_frame(int index, objArrayHandle frames_array, + const methodHandle& method, TRAPS); }; class StackWalk : public AllStatic { private: - static int fill_in_frames(jlong mode, JavaFrameStream& stream, + static int fill_in_frames(jlong mode, BaseFrameStream& stream, int max_nframes, int start_index, objArrayHandle frames_array, int& end_index, TRAPS); - static void fill_stackframe(Handle stackFrame, const methodHandle& method, int bci); - - static void fill_live_stackframe(Handle stackFrame, const methodHandle& method, int bci, - javaVFrame* jvf, TRAPS); - static inline bool get_caller_class(int mode) { return (mode & JVM_STACKWALK_GET_CALLER_CLASS) != 0; } static inline bool skip_hidden_frames(int mode) { return (mode & JVM_STACKWALK_SHOW_HIDDEN_FRAMES) == 0; } - static inline bool need_method_info(int mode) { - return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0; - } static inline bool live_frame_info(int mode) { return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0; } public: + static inline bool need_method_info(int mode) { + return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0; + } static inline bool use_frames_array(int mode) { return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0; } @@ -104,9 +144,12 @@ public: objArrayHandle frames_array, TRAPS); - static jint moreFrames(Handle stackStream, jlong mode, jlong magic, - int frame_count, int start_index, - objArrayHandle frames_array, - TRAPS); + static oop fetchFirstBatch(BaseFrameStream& stream, Handle stackStream, + jlong mode, int skip_frames, int frame_count, + int start_index, objArrayHandle frames_array, TRAPS); + + static jint fetchNextBatch(Handle stackStream, jlong mode, jlong magic, + int frame_count, int start_index, + objArrayHandle frames_array, TRAPS); }; #endif // SHARE_VM_PRIMS_STACKWALK_HPP From f9707ab4cdeea8f71550d5d29f3b50f54364d0eb Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Tue, 20 Sep 2016 10:37:19 -0700 Subject: [PATCH 050/207] 8164011: --patch-module support for CDS Allows the use of the --patch-module vm option with CDS. However, classes found in --patch-module during dump time will not be archived. Reviewed-by: iklam, dcubed, lfoltan --- .../src/share/vm/classfile/classLoader.cpp | 143 ++++++++++++++++-- .../src/share/vm/classfile/classLoader.hpp | 8 + .../vm/classfile/sharedPathsMiscInfo.cpp | 27 +++- .../vm/classfile/sharedPathsMiscInfo.hpp | 22 ++- hotspot/src/share/vm/memory/filemap.cpp | 23 ++- hotspot/src/share/vm/memory/filemap.hpp | 1 + hotspot/src/share/vm/runtime/arguments.cpp | 4 - .../modules/PatchModule/PatchModuleCDS.java | 78 +++++++--- 8 files changed, 268 insertions(+), 38 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index 6e74496d80c..46847f67644 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -85,6 +85,7 @@ typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsig typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n); typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg); typedef jint (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len); +typedef void (JNICALL *FreeEntry_t)(jzfile *zip, jzentry *entry); static ZipOpen_t ZipOpen = NULL; static ZipClose_t ZipClose = NULL; @@ -95,6 +96,7 @@ static GetNextEntry_t GetNextEntry = NULL; static canonicalize_fn_t CanonicalizeEntry = NULL; static ZipInflateFully_t ZipInflateFully = NULL; static Crc32_t Crc32 = NULL; +static FreeEntry_t FreeEntry = NULL; // Entry points for jimage.dll for loading jimage file entries @@ -150,6 +152,7 @@ int ClassLoader::_num_entries = 0; GrowableArray* ClassLoader::_boot_modules_array = NULL; GrowableArray* ClassLoader::_platform_modules_array = NULL; SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL; +int ClassLoader::_num_patch_mod_prefixes = 0; #endif // helper routines @@ -319,6 +322,20 @@ ClassPathZipEntry::~ClassPathZipEntry() { FREE_C_HEAP_ARRAY(char, _zip_name); } +bool ClassPathZipEntry::stream_exists(const char* name) { + // enable call to C land + JavaThread* thread = JavaThread::current(); + ThreadToNativeFromVM ttn(thread); + // check whether zip archive contains name + jint name_len, filesize; + jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len); + if (entry != NULL) { + (*FreeEntry)(_zip, entry); + return true; + } + return false; +} + u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) { // enable call to C land JavaThread* thread = JavaThread::current(); @@ -640,7 +657,7 @@ void ClassLoader::check_shared_classpath(const char *path) { struct stat st; if (os::stat(path, &st) == 0) { - if ((st.st_mode & S_IFREG) != S_IFREG) { // is directory + if ((st.st_mode & S_IFMT) != S_IFREG) { // is not a regular file if (!os::dir_is_empty(path)) { tty->print_cr("Error: non-empty directory '%s'", path); exit_with_path_failure("CDS allows only empty directories in archived classpaths", NULL); @@ -693,8 +710,6 @@ void ClassLoader::setup_patch_mod_entries() { GrowableArray* patch_mod_args = Arguments::get_patch_mod_prefix(); int num_of_entries = patch_mod_args->length(); - assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with --patch-module"); - assert(!UseSharedSpaces, "UseSharedSpaces not supported with --patch-module"); // Set up the boot loader's _patch_mod_entries list _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray(num_of_entries, true); @@ -851,7 +866,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str bool is_boot_append, TRAPS) { JavaThread* thread = JavaThread::current(); ClassPathEntry* new_entry = NULL; - if ((st->st_mode & S_IFREG) == S_IFREG) { + if ((st->st_mode & S_IFMT) == S_IFREG) { ResourceMark rm(thread); // Regular file, should be a zip or jimage file // Canonicalized filename @@ -914,7 +929,7 @@ ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path, bo // check for a regular file struct stat st; if (os::stat(path, &st) == 0) { - if ((st.st_mode & S_IFREG) == S_IFREG) { + if ((st.st_mode & S_IFMT) == S_IFREG) { char canonical_path[JVM_MAXPATHLEN]; if (get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { char* error_msg = NULL; @@ -1068,6 +1083,7 @@ void ClassLoader::load_zip_library() { GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry")); ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully")); Crc32 = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32")); + FreeEntry = CAST_TO_FN_PTR(FreeEntry_t, os::dll_lookup(handle, "ZIP_FreeEntry")); // ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL || @@ -1395,6 +1411,57 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArraylength(); + char* class_module_name = NULL; + ResourceMark rm; + const char *pkg_name = package_from_name(file_name); + // Using the jimage to obtain the class' module name. + // The ModuleEntryTable cannot be used at this point during dump time + // because the module system hasn't been initialized yet. + if (pkg_name != NULL) { + JImageFile *jimage = _jrt_entry->jimage(); + class_module_name = (char*)(*JImagePackageToModule)(jimage, pkg_name); + } + + if (class_module_name == NULL) { + return false; + } + + // Loop through all the patch module entries looking for module + for (int i = 0; i < num_of_entries; i++) { + ModuleClassPathList* module_cpl = _patch_mod_entries->at(i); + Symbol* module_cpl_name = module_cpl->module_name(); + + if (strcmp(module_cpl_name->as_C_string(), class_module_name) == 0) { + // Class' module has been located, attempt to locate + // the class from the module's ClassPathEntry list. + ClassPathEntry* e = module_cpl->module_first_entry(); + while (e != NULL) { + if (e->is_jar_file()) { + if (e->stream_exists(file_name)) { + return true; + } else { + e = e->next(); + } + } + } + } + } + + return false; +} +#endif // INCLUDE_CDS + instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) { assert(name != NULL, "invariant"); assert(THREAD->is_Java_thread(), "must be a JavaThread"); @@ -1420,8 +1487,8 @@ instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_onl // If DumpSharedSpaces is true boot loader visibility boundaries are set to: // - [jimage] + [_first_append_entry to _last_append_entry] (all path entries). - // No --patch-module entries or exploded module builds are included since CDS - // is not supported if --patch-module or exploded module builds are used. + // If a class is found in the --patch-module entries, the class will not be included in the + // CDS archive. Also, CDS is not supported if exploded module builds are used. // // If search_append_only is true, boot loader visibility boundaries are // set to be _first_append_entry to the end. This includes: @@ -1444,8 +1511,17 @@ instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_onl // found within its module specification, the search should continue to Load Attempt #2. // Note: The --patch-module entries are never searched if the boot loader's // visibility boundary is limited to only searching the append entries. - if (_patch_mod_entries != NULL && !search_append_only && !DumpSharedSpaces) { - stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL); + if (_patch_mod_entries != NULL && !search_append_only) { + if (!DumpSharedSpaces) { + stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL); + } else { +#if INCLUDE_CDS + if (is_in_patch_module(file_name)) { + tty->print_cr("Preload Warning: Skip archiving class %s found in --patch-module entry", class_name); + return NULL; + } +#endif + } } // Load Attempt #2: [jimage | exploded build] @@ -1596,8 +1672,57 @@ void ClassLoader::initialize() { } #if INCLUDE_CDS +// Capture all the --patch-module entries specified during CDS dump time. +// It also captures the non-existing path(s) and the required file(s) during inspecting +// the entries. +void ClassLoader::setup_patch_mod_path() { + assert(DumpSharedSpaces, "only used with -Xshare:dump"); + ResourceMark rm; + GrowableArray* patch_mod_args = Arguments::get_patch_mod_prefix(); + if (patch_mod_args != NULL) { + int num_of_entries = patch_mod_args->length(); + for (int i = 0; i < num_of_entries; i++) { + const char* module_name = (patch_mod_args->at(i))->module_name(); + const char* module_path = (patch_mod_args->at(i))->path_string(); + int path_len = (int)strlen(module_path); + int name_len = (int)strlen(module_name); + int buf_len = name_len + path_len + 2; // add 2 for the '=' and NULL terminator + int end = 0; + char* buf = NEW_C_HEAP_ARRAY(char, buf_len, mtInternal); + // Iterate over the module's class path entries + for (int start = 0; start < path_len; start = end) { + while (module_path[end] && module_path[end] != os::path_separator()[0]) { + end++; + } + strncpy(buf, &module_path[start], end - start); + buf[end - start] = '\0'; + struct stat st; + if (os::stat(buf, &st) != 0) { + // File not found + _shared_paths_misc_info->add_nonexist_path(buf); + } else { + if ((st.st_mode & S_IFMT) != S_IFREG) { // is not a regular file + vm_exit_during_initialization( + "--patch-module requires a regular file during dumping", buf); + } else { + _shared_paths_misc_info->add_required_file(buf); + } + } + while (module_path[end] == os::path_separator()[0]) { + end++; + } + }; + jio_snprintf(buf, buf_len, "%s=%s", module_name, module_path); + _shared_paths_misc_info->add_patch_mod_classpath((const char*)buf); + _num_patch_mod_prefixes++; + FREE_C_HEAP_ARRAY(char, buf); + } + } +} + void ClassLoader::initialize_shared_path() { if (DumpSharedSpaces) { + setup_patch_mod_path(); ClassLoaderExt::setup_search_paths(); _shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check() } diff --git a/hotspot/src/share/vm/classfile/classLoader.hpp b/hotspot/src/share/vm/classfile/classLoader.hpp index 35c000a6be1..8e7811af1b1 100644 --- a/hotspot/src/share/vm/classfile/classLoader.hpp +++ b/hotspot/src/share/vm/classfile/classLoader.hpp @@ -69,6 +69,7 @@ public: // Attempt to locate file_name through this class path entry. // Returns a class file parsing stream if successfull. virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0; + virtual bool stream_exists(const char* name) = 0; // Debugging NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;) }; @@ -83,6 +84,7 @@ class ClassPathDirEntry: public ClassPathEntry { JImageFile* jimage() const { return NULL; } ClassPathDirEntry(const char* dir); ClassFileStream* open_stream(const char* name, TRAPS); + bool stream_exists(const char* name) { return false; } // Debugging NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) }; @@ -126,6 +128,7 @@ class ClassPathZipEntry: public ClassPathEntry { ClassFileStream* open_stream(const char* name, TRAPS); void contents_do(void f(const char* name, void* context), void* context); bool is_multiple_versioned(TRAPS) NOT_CDS_RETURN_(false); + bool stream_exists(const char* name); // Debugging NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) }; @@ -145,6 +148,7 @@ public: ClassPathImageEntry(JImageFile* jimage, const char* name); ~ClassPathImageEntry(); ClassFileStream* open_stream(const char* name, TRAPS); + bool stream_exists(const char* name) { return false; } // Debugging NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) @@ -255,6 +259,7 @@ class ClassLoader: AllStatic { // Info used by CDS CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;) + CDS_ONLY(static int _num_patch_mod_prefixes;) // Initialization: // - setup the boot loader's system class path @@ -427,6 +432,9 @@ class ClassLoader: AllStatic { static void initialize_module_loader_map(JImageFile* jimage); static s2 classloader_type(Symbol* class_name, ClassPathEntry* e, int classpath_index, TRAPS); + static bool is_in_patch_module(const char* const file_name); + static void setup_patch_mod_path(); // Only when -Xshare:dump + static int num_patch_mod_prefixes() { return _num_patch_mod_prefixes; } #endif static void trace_class_path(const char* msg, const char* name = NULL); diff --git a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp index 36cf234c2d1..178444988b0 100644 --- a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp +++ b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp @@ -86,6 +86,9 @@ void SharedPathsMiscInfo::print_path(int type, const char* path) { case REQUIRED: out->print("Expecting that file %s must exist and is not altered", path); break; + case PATCH_MOD: + out->print("Expecting --patch-module=%s", path); + break; default: ShouldNotReachHere(); } @@ -146,6 +149,9 @@ bool SharedPathsMiscInfo::check(jint type, const char* path) { // But we want it to not exist -> fail return fail("File must not exist"); } + if ((st.st_mode & S_IFMT) != S_IFREG) { + return fail("Did not get a regular file as expected."); + } time_t timestamp; long filesize; @@ -161,7 +167,26 @@ bool SharedPathsMiscInfo::check(jint type, const char* path) { } } break; - + case PATCH_MOD: + { + GrowableArray* patch_mod_args = Arguments::get_patch_mod_prefix(); + if (patch_mod_args != NULL) { + int num_of_entries = patch_mod_args->length(); + for (int i = 0; i < num_of_entries; i++) { + const char* module_name = (patch_mod_args->at(i))->module_name(); + const char* path_string = (patch_mod_args->at(i))->path_string(); + size_t n = strlen(module_name); + // path contains the module name, followed by '=', and one or more entries. + // E.g.: "java.base=foo" or "java.naming=dir1:dir2:dir3" + if ((strncmp(module_name, path, n) != 0) || + (path[n] != '=') || + (strcmp(path + n + 1, path_string) != 0)) { + return fail("--patch-module mismatch, path not found in run time: ", path); + } + } + } + } + break; default: return fail("Corrupted archive file header"); } diff --git a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp index 77de03b0a33..c680d3f7643 100644 --- a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp +++ b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp @@ -104,10 +104,28 @@ public: add_path(path, NON_EXIST); } + // The path must exist and have required size and modification time + void add_required_file(const char* path) { + add_path(path, REQUIRED); + + struct stat st; + if (os::stat(path, &st) != 0) { + assert(0, "sanity"); +#if INCLUDE_CDS + ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen +#endif + } + write_time(st.st_mtime); + write_long(st.st_size); + } + // The path must exist, and must contain exactly files/dirs void add_boot_classpath(const char* path) { add_path(path, BOOT); } + void add_patch_mod_classpath(const char* path) { + add_path(path, PATCH_MOD); + } int write_jint(jint num) { write(&num, sizeof(num)); return 0; @@ -129,7 +147,8 @@ public: enum { BOOT = 1, NON_EXIST = 2, - REQUIRED = 3 + REQUIRED = 3, + PATCH_MOD = 4 }; virtual const char* type_name(int type) { @@ -137,6 +156,7 @@ public: case BOOT: return "BOOT"; case NON_EXIST: return "NON_EXIST"; case REQUIRED: return "REQUIRED"; + case PATCH_MOD: return "PATCH_MOD"; default: ShouldNotReachHere(); return "?"; } } diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index 08a79f11f3b..8c64dc53540 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -179,6 +179,7 @@ void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment _classpath_entry_table_size = mapinfo->_classpath_entry_table_size; _classpath_entry_table = mapinfo->_classpath_entry_table; _classpath_entry_size = mapinfo->_classpath_entry_size; + _num_patch_mod_prefixes = ClassLoader::num_patch_mod_prefixes(); // The following fields are for sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's @@ -911,11 +912,6 @@ bool FileMapInfo::FileMapHeader::validate() { return false; } - if (Arguments::get_patch_mod_prefix() != NULL) { - FileMapInfo::fail_continue("The shared archive file cannot be used with --patch-module."); - return false; - } - if (!Arguments::has_jimage()) { FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build."); return false; @@ -952,6 +948,23 @@ bool FileMapInfo::FileMapHeader::validate() { return false; } + // Check if there is a mismatch in --patch-module entry counts between dump time and run time. + // More checks will be performed on individual --patch-module entry in the + // SharedPathsMiscInfo::check() function. + GrowableArray* patch_mod_args = Arguments::get_patch_mod_prefix(); + if (patch_mod_args != NULL) { + if (_num_patch_mod_prefixes == 0) { + FileMapInfo::fail_stop("--patch-module found in run time but none was specified in dump time"); + } + if (patch_mod_args->length() != _num_patch_mod_prefixes) { + FileMapInfo::fail_stop("mismatched --patch-module entry counts between dump time and run time"); + } + } else { + if (_num_patch_mod_prefixes > 0) { + FileMapInfo::fail_stop("--patch-module specified in dump time but none was specified in run time"); + } + } + return true; } diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp index baffd299436..fa1a0502ae2 100644 --- a/hotspot/src/share/vm/memory/filemap.hpp +++ b/hotspot/src/share/vm/memory/filemap.hpp @@ -155,6 +155,7 @@ public: // loading failures during runtime. int _classpath_entry_table_size; size_t _classpath_entry_size; + int _num_patch_mod_prefixes; // number of --patch-module entries SharedClassPathEntry* _classpath_entry_table; char* region_addr(int idx); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index e7e45e9fcd1..8dc6519381d 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -3897,10 +3897,6 @@ jint Arguments::parse_options_buffer(const char* name, char* buffer, const size_ void Arguments::set_shared_spaces_flags() { if (DumpSharedSpaces) { - if (Arguments::get_patch_mod_prefix() != NULL) { - vm_exit_during_initialization( - "Cannot use the following option when dumping the shared archive: --patch-module"); - } if (RequireSharedSpaces) { warning("Cannot dump shared archive while using shared archive"); diff --git a/hotspot/test/runtime/modules/PatchModule/PatchModuleCDS.java b/hotspot/test/runtime/modules/PatchModule/PatchModuleCDS.java index a7f4784223b..82d5c385846 100644 --- a/hotspot/test/runtime/modules/PatchModule/PatchModuleCDS.java +++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleCDS.java @@ -23,41 +23,83 @@ /* * @test + * @summary test that --patch-module works with CDS * @library /test/lib * @modules java.base/jdk.internal.misc + * jdk.jartool/sun.tools.jar + * @build PatchModuleMain * @run main PatchModuleCDS */ import java.io.File; +import jdk.test.lib.InMemoryJavaCompiler; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; public class PatchModuleCDS { public static void main(String args[]) throws Throwable { - System.out.println("Test that --patch-module and -Xshare:dump are incompatibable"); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming", "-Xshare:dump"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module"); - System.out.println("Test that --patch-module and -Xshare:on are incompatibable"); + // Case 1: Test that --patch-module and -Xshare:dump are compatible String filename = "patch_module.jsa"; - pb = ProcessTools.createJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename, - "-Xshare:dump"); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("ro space:"); // Make sure archive got created. - - pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", - "-XX:SharedArchiveFile=" + filename, - "-Xshare:on", - "--patch-module=java.naming=mods/java.naming", + "-Xshare:dump", + "--patch-module=java.naming=no/such/directory", + "-Xlog:class+path=info", "-version"); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("The shared archive file cannot be used with --patch-module"); + new OutputAnalyzer(pb.start()) + .shouldContain("ro space:"); // Make sure archive got created. - output.shouldHaveExitValue(1); + // Case 2: Test that only jar file in --patch-module is supported for CDS dumping + // Create a class file in the module java.base. + String source = "package javax.naming.spi; " + + "public class NamingManager { " + + " static { " + + " System.out.println(\"I pass!\"); " + + " } " + + "}"; + + ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager", + InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"), + System.getProperty("test.classes")); + + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + filename, + "-Xshare:dump", + "--patch-module=java.base=" + System.getProperty("test.classes"), + "-Xlog:class+path=info", + "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("--patch-module requires a regular file during dumping"); + + // Case 3a: Test CDS dumping with jar file in --patch-module + BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager"); + String moduleJar = BasicJarBuilder.getTestJar("javanaming.jar"); + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + filename, + "-Xshare:dump", + "--patch-module=java.naming=" + moduleJar, + "-Xlog:class+load", + "-Xlog:class+path=info", + "PatchModuleMain", "javax.naming.spi.NamingManager"); + new OutputAnalyzer(pb.start()) + .shouldContain("ro space:"); // Make sure archive got created. + + // Case 3b: Test CDS run with jar file in --patch-module + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + filename, + "-Xshare:auto", + "--patch-module=java.naming=" + moduleJar, + "-Xlog:class+load", + "-Xlog:class+path=info", + "PatchModuleMain", "javax.naming.spi.NamingManager"); + new OutputAnalyzer(pb.start()) + .shouldContain("I pass!") + .shouldHaveExitValue(0); } } From 30661bb2691e598a85b1a8ec52200f677628b0eb Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Tue, 20 Sep 2016 21:26:33 +0300 Subject: [PATCH 051/207] 8140311: SwingInterop crashes at window close Reviewed-by: serb, ssadetsky --- .../java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m index 9d8326ade6d..54253484173 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m @@ -117,7 +117,7 @@ static long eventCount; } - (void)dealloc { - JNIEnv *env = [ThreadUtilities getJNIEnv]; + JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; if (self.runnable) { (*env)->DeleteGlobalRef(env, self.runnable); } @@ -125,7 +125,7 @@ static long eventCount; } - (void)perform { - JNIEnv* env = [ThreadUtilities getJNIEnv]; + JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; static JNF_CLASS_CACHE(sjc_Runnable, "java/lang/Runnable"); static JNF_MEMBER_CACHE(jm_Runnable_run, sjc_Runnable, "run", "()V"); JNFCallVoidMethod(env, self.runnable, jm_Runnable_run); From f6f5dfdb4a08de9bd3d1c8685e97c52aaf4a9e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Tue, 20 Sep 2016 15:42:17 -0400 Subject: [PATCH 052/207] 8033552: Fix missing missing volatile specifiers in CAS operations in GC code Add missing volatile specifiers. Reviewed-by: kbarrett, tschatzl --- .../src/share/vm/gc/cms/cmsOopClosures.hpp | 21 +++++++++--------- .../gc/cms/concurrentMarkSweepGeneration.cpp | 22 +++++++++---------- .../gc/cms/concurrentMarkSweepGeneration.hpp | 12 +++++----- .../src/share/vm/gc/g1/heapRegionRemSet.cpp | 4 ++-- hotspot/src/share/vm/gc/g1/sparsePRT.cpp | 2 +- hotspot/src/share/vm/gc/g1/sparsePRT.hpp | 2 +- .../src/share/vm/gc/parallel/mutableSpace.hpp | 6 ++--- .../vm/gc/parallel/parallelScavengeHeap.hpp | 4 ++-- .../src/share/vm/gc/parallel/psYoungGen.hpp | 4 ++-- .../vm/gc/parallel/vmStructs_parallelgc.hpp | 7 +++--- .../share/vm/gc/serial/defNewGeneration.cpp | 2 +- .../share/vm/gc/serial/defNewGeneration.hpp | 4 ++-- .../src/share/vm/gc/shared/collectedHeap.hpp | 2 +- .../share/vm/gc/shared/genCollectedHeap.cpp | 2 +- .../share/vm/gc/shared/genCollectedHeap.hpp | 2 +- hotspot/src/share/vm/gc/shared/generation.hpp | 2 +- .../src/share/vm/jvmci/jvmciCompilerToVM.cpp | 5 ++--- .../src/share/vm/jvmci/jvmciCompilerToVM.hpp | 2 +- .../src/share/vm/jvmci/vmStructs_jvmci.cpp | 2 +- hotspot/src/share/vm/runtime/vmStructs.cpp | 13 ++++++----- 20 files changed, 61 insertions(+), 59 deletions(-) diff --git a/hotspot/src/share/vm/gc/cms/cmsOopClosures.hpp b/hotspot/src/share/vm/gc/cms/cmsOopClosures.hpp index 165ab17e682..11416afebc9 100644 --- a/hotspot/src/share/vm/gc/cms/cmsOopClosures.hpp +++ b/hotspot/src/share/vm/gc/cms/cmsOopClosures.hpp @@ -258,16 +258,15 @@ class PushOrMarkClosure: public MetadataAwareOopClosure { // the closure ParMarkFromRootsClosure. class ParPushOrMarkClosure: public MetadataAwareOopClosure { private: - CMSCollector* _collector; - MemRegion _whole_span; - MemRegion _span; // local chunk - CMSBitMap* _bit_map; - OopTaskQueue* _work_queue; - CMSMarkStack* _overflow_stack; - HeapWord* const _finger; - HeapWord** const _global_finger_addr; - ParMarkFromRootsClosure* const - _parent; + CMSCollector* _collector; + MemRegion _whole_span; + MemRegion _span; // local chunk + CMSBitMap* _bit_map; + OopTaskQueue* _work_queue; + CMSMarkStack* _overflow_stack; + HeapWord* const _finger; + HeapWord* volatile* const _global_finger_addr; + ParMarkFromRootsClosure* const _parent; protected: DO_OOP_WORK_DEFN public: @@ -277,7 +276,7 @@ class ParPushOrMarkClosure: public MetadataAwareOopClosure { OopTaskQueue* work_queue, CMSMarkStack* mark_stack, HeapWord* finger, - HeapWord** global_finger_addr, + HeapWord* volatile* global_finger_addr, ParMarkFromRootsClosure* parent); virtual void do_oop(oop* p); virtual void do_oop(narrowOop* p); diff --git a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp index 2a1be1af777..77584314dcf 100644 --- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp @@ -3025,14 +3025,14 @@ class CMSConcMarkingTerminatorTerminator: public TerminatorTerminator { // MT Concurrent Marking Task class CMSConcMarkingTask: public YieldingFlexibleGangTask { - CMSCollector* _collector; - uint _n_workers; // requested/desired # workers - bool _result; - CompactibleFreeListSpace* _cms_space; - char _pad_front[64]; // padding to ... - HeapWord* _global_finger; // ... avoid sharing cache line - char _pad_back[64]; - HeapWord* _restart_addr; + CMSCollector* _collector; + uint _n_workers; // requested/desired # workers + bool _result; + CompactibleFreeListSpace* _cms_space; + char _pad_front[64]; // padding to ... + HeapWord* volatile _global_finger; // ... avoid sharing cache line + char _pad_back[64]; + HeapWord* _restart_addr; // Exposed here for yielding support Mutex* const _bit_map_lock; @@ -3068,7 +3068,7 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask { OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); } - HeapWord** global_finger_addr() { return &_global_finger; } + HeapWord* volatile* global_finger_addr() { return &_global_finger; } CMSConcMarkingTerminator* terminator() { return &_term; } @@ -6554,7 +6554,7 @@ void ParMarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) { // Note: the local finger doesn't advance while we drain // the stack below, but the global finger sure can and will. - HeapWord** gfa = _task->global_finger_addr(); + HeapWord* volatile* gfa = _task->global_finger_addr(); ParPushOrMarkClosure pushOrMarkClosure(_collector, _span, _bit_map, _work_queue, @@ -6721,7 +6721,7 @@ ParPushOrMarkClosure::ParPushOrMarkClosure(CMSCollector* collector, OopTaskQueue* work_queue, CMSMarkStack* overflow_stack, HeapWord* finger, - HeapWord** global_finger_addr, + HeapWord* volatile* global_finger_addr, ParMarkFromRootsClosure* parent) : MetadataAwareOopClosure(collector->ref_processor()), _collector(collector), diff --git a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp index 414aaa7a9c9..a5b7f9157b2 100644 --- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp @@ -724,12 +724,12 @@ class CMSCollector: public CHeapObj { // Support for parallelizing young gen rescan in CMS remark phase ParNewGeneration* _young_gen; - HeapWord** _top_addr; // ... Top of Eden - HeapWord** _end_addr; // ... End of Eden - Mutex* _eden_chunk_lock; - HeapWord** _eden_chunk_array; // ... Eden partitioning array - size_t _eden_chunk_index; // ... top (exclusive) of array - size_t _eden_chunk_capacity; // ... max entries in array + HeapWord* volatile* _top_addr; // ... Top of Eden + HeapWord** _end_addr; // ... End of Eden + Mutex* _eden_chunk_lock; + HeapWord** _eden_chunk_array; // ... Eden partitioning array + size_t _eden_chunk_index; // ... top (exclusive) of array + size_t _eden_chunk_capacity; // ... max entries in array // Support for parallelizing survivor space rescan HeapWord** _survivor_chunk_array; diff --git a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp index 9aa4da68968..7967d6cf001 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp @@ -56,7 +56,7 @@ class PerRegionTable: public CHeapObj { PerRegionTable * _collision_list_next; // Global free list of PRTs - static PerRegionTable* _free_list; + static PerRegionTable* volatile _free_list; protected: // We need access in order to union things into the base table. @@ -249,7 +249,7 @@ public: static void test_fl_mem_size(); }; -PerRegionTable* PerRegionTable::_free_list = NULL; +PerRegionTable* volatile PerRegionTable::_free_list = NULL; size_t OtherRegionsTable::_max_fine_entries = 0; size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0; diff --git a/hotspot/src/share/vm/gc/g1/sparsePRT.cpp b/hotspot/src/share/vm/gc/g1/sparsePRT.cpp index 44e43465ce6..4dd00b04b38 100644 --- a/hotspot/src/share/vm/gc/g1/sparsePRT.cpp +++ b/hotspot/src/share/vm/gc/g1/sparsePRT.cpp @@ -283,7 +283,7 @@ size_t RSHashTable::mem_size() const { // ---------------------------------------------------------------------- -SparsePRT* SparsePRT::_head_expanded_list = NULL; +SparsePRT* volatile SparsePRT::_head_expanded_list = NULL; void SparsePRT::add_to_expanded_list(SparsePRT* sprt) { // We could expand multiple times in a pause -- only put on list once. diff --git a/hotspot/src/share/vm/gc/g1/sparsePRT.hpp b/hotspot/src/share/vm/gc/g1/sparsePRT.hpp index 5ea825ced8c..d19a5507be2 100644 --- a/hotspot/src/share/vm/gc/g1/sparsePRT.hpp +++ b/hotspot/src/share/vm/gc/g1/sparsePRT.hpp @@ -250,7 +250,7 @@ class SparsePRT VALUE_OBJ_CLASS_SPEC { bool should_be_on_expanded_list(); - static SparsePRT* _head_expanded_list; + static SparsePRT* volatile _head_expanded_list; public: SparsePRT(HeapRegion* hr); diff --git a/hotspot/src/share/vm/gc/parallel/mutableSpace.hpp b/hotspot/src/share/vm/gc/parallel/mutableSpace.hpp index e731edd4e11..c8bc1ef8947 100644 --- a/hotspot/src/share/vm/gc/parallel/mutableSpace.hpp +++ b/hotspot/src/share/vm/gc/parallel/mutableSpace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ class MutableSpace: public ImmutableSpace { MemRegion _last_setup_region; size_t _alignment; protected: - HeapWord* _top; + HeapWord* volatile _top; MutableSpaceMangler* mangler() { return _mangler; } @@ -69,7 +69,7 @@ class MutableSpace: public ImmutableSpace { HeapWord* top() const { return _top; } virtual void set_top(HeapWord* value) { _top = value; } - HeapWord** top_addr() { return &_top; } + HeapWord* volatile* top_addr() { return &_top; } HeapWord** end_addr() { return &_end; } virtual void set_bottom(HeapWord* value) { _bottom = value; } diff --git a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp index e2794db1478..654de480817 100644 --- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp +++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,7 +175,7 @@ class ParallelScavengeHeap : public CollectedHeap { bool supports_inline_contig_alloc() const { return !UseNUMA; } - HeapWord** top_addr() const { return !UseNUMA ? young_gen()->top_addr() : (HeapWord**)-1; } + HeapWord* volatile* top_addr() const { return !UseNUMA ? young_gen()->top_addr() : (HeapWord* volatile*)-1; } HeapWord** end_addr() const { return !UseNUMA ? young_gen()->end_addr() : (HeapWord**)-1; } void ensure_parsability(bool retire_tlabs); diff --git a/hotspot/src/share/vm/gc/parallel/psYoungGen.hpp b/hotspot/src/share/vm/gc/parallel/psYoungGen.hpp index 1b51c435a53..4ee669dad96 100644 --- a/hotspot/src/share/vm/gc/parallel/psYoungGen.hpp +++ b/hotspot/src/share/vm/gc/parallel/psYoungGen.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -162,7 +162,7 @@ class PSYoungGen : public CHeapObj { return result; } - HeapWord** top_addr() const { return eden_space()->top_addr(); } + HeapWord* volatile* top_addr() const { return eden_space()->top_addr(); } HeapWord** end_addr() const { return eden_space()->end_addr(); } // Iteration. diff --git a/hotspot/src/share/vm/gc/parallel/vmStructs_parallelgc.hpp b/hotspot/src/share/vm/gc/parallel/vmStructs_parallelgc.hpp index 65d2f092171..fdaafc20fb4 100644 --- a/hotspot/src/share/vm/gc/parallel/vmStructs_parallelgc.hpp +++ b/hotspot/src/share/vm/gc/parallel/vmStructs_parallelgc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ #define SHARE_VM_GC_PARALLEL_VMSTRUCTS_PARALLELGC_HPP #define VM_STRUCTS_PARALLELGC(nonstatic_field, \ - static_field) \ + volatile_nonstatic_field, \ + static_field) \ \ /**********************/ \ /* Parallel GC fields */ \ @@ -40,7 +41,7 @@ nonstatic_field(ImmutableSpace, _bottom, HeapWord*) \ nonstatic_field(ImmutableSpace, _end, HeapWord*) \ \ - nonstatic_field(MutableSpace, _top, HeapWord*) \ + volatile_nonstatic_field(MutableSpace, _top, HeapWord*) \ \ nonstatic_field(PSYoungGen, _reserved, MemRegion) \ nonstatic_field(PSYoungGen, _virtual_space, PSVirtualSpace*) \ diff --git a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp index e7f96a22228..58801231438 100644 --- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp +++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp @@ -512,7 +512,7 @@ size_t DefNewGeneration::contiguous_available() const { } -HeapWord** DefNewGeneration::top_addr() const { return eden()->top_addr(); } +HeapWord* volatile* DefNewGeneration::top_addr() const { return eden()->top_addr(); } HeapWord** DefNewGeneration::end_addr() const { return eden()->end_addr(); } void DefNewGeneration::object_iterate(ObjectClosure* blk) { diff --git a/hotspot/src/share/vm/gc/serial/defNewGeneration.hpp b/hotspot/src/share/vm/gc/serial/defNewGeneration.hpp index f258491ae32..12aef0f24c2 100644 --- a/hotspot/src/share/vm/gc/serial/defNewGeneration.hpp +++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -225,7 +225,7 @@ protected: size_t max_survivor_size() const { return _max_survivor_size; } bool supports_inline_contig_alloc() const { return true; } - HeapWord** top_addr() const; + HeapWord* volatile* top_addr() const; HeapWord** end_addr() const; // Thread-local allocation buffers diff --git a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp index d5ae7733114..b13fa976595 100644 --- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp +++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp @@ -350,7 +350,7 @@ class CollectedHeap : public CHeapObj { // These functions return the addresses of the fields that define the // boundaries of the contiguous allocation area. (These fields should be // physically near to one another.) - virtual HeapWord** top_addr() const { + virtual HeapWord* volatile* top_addr() const { guarantee(false, "inline contiguous allocation not supported"); return NULL; } diff --git a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp index 049b675bd51..8aa7260e0ee 100644 --- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp @@ -721,7 +721,7 @@ bool GenCollectedHeap::supports_inline_contig_alloc() const { return _young_gen->supports_inline_contig_alloc(); } -HeapWord** GenCollectedHeap::top_addr() const { +HeapWord* volatile* GenCollectedHeap::top_addr() const { return _young_gen->top_addr(); } diff --git a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp index 9a469d14f7d..2e22d47a51d 100644 --- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp @@ -184,7 +184,7 @@ public: // We may support a shared contiguous allocation area, if the youngest // generation does. bool supports_inline_contig_alloc() const; - HeapWord** top_addr() const; + HeapWord* volatile* top_addr() const; HeapWord** end_addr() const; // Perform a full collection of the heap; intended for use in implementing diff --git a/hotspot/src/share/vm/gc/shared/generation.hpp b/hotspot/src/share/vm/gc/shared/generation.hpp index d71e6a1f220..7507e7763b3 100644 --- a/hotspot/src/share/vm/gc/shared/generation.hpp +++ b/hotspot/src/share/vm/gc/shared/generation.hpp @@ -263,7 +263,7 @@ class Generation: public CHeapObj { // These functions return the addresses of the fields that define the // boundaries of the contiguous allocation area. (These fields should be // physically near to one another.) - virtual HeapWord** top_addr() const { return NULL; } + virtual HeapWord* volatile* top_addr() const { return NULL; } virtual HeapWord** end_addr() const { return NULL; } // Thread-local allocation buffers diff --git a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp index dc19a497f5e..afc49b13a9a 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp @@ -112,7 +112,7 @@ uintptr_t CompilerToVM::Data::Universe_verify_oop_bits; bool CompilerToVM::Data::_supports_inline_contig_alloc; HeapWord** CompilerToVM::Data::_heap_end_addr; -HeapWord** CompilerToVM::Data::_heap_top_addr; +HeapWord* volatile* CompilerToVM::Data::_heap_top_addr; int CompilerToVM::Data::_max_oop_map_stack_offset; jbyte* CompilerToVM::Data::cardtable_start_address; @@ -153,7 +153,7 @@ void CompilerToVM::Data::initialize() { _supports_inline_contig_alloc = Universe::heap()->supports_inline_contig_alloc(); _heap_end_addr = _supports_inline_contig_alloc ? Universe::heap()->end_addr() : (HeapWord**) -1; - _heap_top_addr = _supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord**) -1; + _heap_top_addr = _supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord* volatile*) -1; _max_oop_map_stack_offset = (OopMapValue::register_mask - VMRegImpl::stack2reg(0)->value()) * VMRegImpl::stack_slot_size; int max_oop_map_stack_index = _max_oop_map_stack_offset / VMRegImpl::stack_slot_size; @@ -1604,4 +1604,3 @@ JNINativeMethod CompilerToVM::methods[] = { int CompilerToVM::methods_count() { return sizeof(methods) / sizeof(JNINativeMethod); } - diff --git a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp index 364be048220..e16dae86ea3 100644 --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp @@ -58,7 +58,7 @@ class CompilerToVM { static bool _supports_inline_contig_alloc; static HeapWord** _heap_end_addr; - static HeapWord** _heap_top_addr; + static HeapWord* volatile* _heap_top_addr; static int _max_oop_map_stack_offset; static jbyte* cardtable_start_address; diff --git a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp index 3d48df55477..f4cd06d0a04 100644 --- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp +++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp @@ -69,7 +69,7 @@ \ static_field(CompilerToVM::Data, _supports_inline_contig_alloc, bool) \ static_field(CompilerToVM::Data, _heap_end_addr, HeapWord**) \ - static_field(CompilerToVM::Data, _heap_top_addr, HeapWord**) \ + static_field(CompilerToVM::Data, _heap_top_addr, HeapWord* volatile*) \ \ static_field(CompilerToVM::Data, _max_oop_map_stack_offset, int) \ \ diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 84eb6fa7d86..2526f6e3174 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -2970,6 +2970,7 @@ VMStructEntry VMStructs::localHotSpotVMStructs[] = { #if INCLUDE_ALL_GCS VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY) VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, @@ -2982,7 +2983,7 @@ VMStructEntry VMStructs::localHotSpotVMStructs[] = { #if INCLUDE_TRACE VM_STRUCTS_TRACE(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, - GENERATE_STATIC_VM_STRUCT_ENTRY) + GENERATE_STATIC_VM_STRUCT_ENTRY) #endif VM_STRUCTS_EXT(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, @@ -3168,11 +3169,12 @@ VMStructs::init() { #if INCLUDE_ALL_GCS VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY, - CHECK_STATIC_VM_STRUCT_ENTRY); + CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY, + CHECK_STATIC_VM_STRUCT_ENTRY); VM_STRUCTS_CMS(CHECK_NONSTATIC_VM_STRUCT_ENTRY, - CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY, - CHECK_STATIC_VM_STRUCT_ENTRY); + CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY, + CHECK_STATIC_VM_STRUCT_ENTRY); VM_STRUCTS_G1(CHECK_NONSTATIC_VM_STRUCT_ENTRY, CHECK_STATIC_VM_STRUCT_ENTRY); @@ -3181,7 +3183,7 @@ VMStructs::init() { #if INCLUDE_TRACE VM_STRUCTS_TRACE(CHECK_NONSTATIC_VM_STRUCT_ENTRY, - CHECK_STATIC_VM_STRUCT_ENTRY); + CHECK_STATIC_VM_STRUCT_ENTRY); #endif VM_STRUCTS_EXT(CHECK_NONSTATIC_VM_STRUCT_ENTRY, @@ -3293,6 +3295,7 @@ VMStructs::init() { CHECK_NO_OP)); #if INCLUDE_ALL_GCS debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, + ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT)); debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT, From 70c7173745b86a0f641e4e7c8a3f94379116b8b1 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Wed, 21 Sep 2016 01:33:21 -0700 Subject: [PATCH 053/207] 8147943: jvmti.h generated with GPL header Generate the jvmti.h with the GPL+CP header Reviewed-by: dcubed, alanb --- hotspot/src/share/vm/prims/jvmti.xml | 1 - hotspot/src/share/vm/prims/jvmtiH.xsl | 2 +- hotspot/src/share/vm/prims/jvmtiLib.xsl | 47 +++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmti.xml b/hotspot/src/share/vm/prims/jvmti.xml index 48b58c3f7c7..bcbfc998567 100644 --- a/hotspot/src/share/vm/prims/jvmti.xml +++ b/hotspot/src/share/vm/prims/jvmti.xml @@ -21,7 +21,6 @@ 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 file for the Java(tm) Virtual Machine Tool Interface */ diff --git a/hotspot/src/share/vm/prims/jvmtiLib.xsl b/hotspot/src/share/vm/prims/jvmtiLib.xsl index 3c6a89e1ea1..fda6abc99c5 100644 --- a/hotspot/src/share/vm/prims/jvmtiLib.xsl +++ b/hotspot/src/share/vm/prims/jvmtiLib.xsl @@ -43,13 +43,56 @@ + + + + + + + * 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. + + /* - - + + */ + + /* * + + + + + */ + + + + + /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ + + /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ From 25c6510309d866a156a70b8e7229ea87650eccef Mon Sep 17 00:00:00 2001 From: Dmitry Dmitriev Date: Wed, 21 Sep 2016 16:46:13 +0300 Subject: [PATCH 054/207] 8150758: [TESTBUG] need jvmti tests for module aware agents Reviewed-by: sspitsyn, dsamersoff --- hotspot/make/test/JtregNative.gmk | 6 + .../MAAClassFileLoadHook.java | 53 +++ .../libMAAClassFileLoadHook.c | 278 +++++++++++++++ .../ClassLoadPrepare/MAAClassLoadPrepare.java | 54 +++ .../ClassLoadPrepare/libMAAClassLoadPrepare.c | 319 ++++++++++++++++++ .../ThreadStart/MAAThreadStart.java | 51 +++ .../ThreadStart/libMAAThreadStart.c | 177 ++++++++++ 7 files changed, 938 insertions(+) create mode 100644 hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/MAAClassFileLoadHook.java create mode 100644 hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/libMAAClassFileLoadHook.c create mode 100644 hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/MAAClassLoadPrepare.java create mode 100644 hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/libMAAClassLoadPrepare.c create mode 100644 hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java create mode 100644 hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/libMAAThreadStart.c diff --git a/hotspot/make/test/JtregNative.gmk b/hotspot/make/test/JtregNative.gmk index 8c818122765..dc6def4fbe6 100644 --- a/hotspot/make/test/JtregNative.gmk +++ b/hotspot/make/test/JtregNative.gmk @@ -55,6 +55,9 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \ $(HOTSPOT_TOPDIR)/test/testlibrary/jvmti \ $(HOTSPOT_TOPDIR)/test/compiler/jvmci/jdk.vm.ci.code.test \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetModulesInfo \ + $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook \ + $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare \ + $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart \ # # Add conditional directories here when needed. @@ -75,6 +78,9 @@ ifeq ($(TOOLCHAIN_TYPE), solstudio) BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_liboverflow := -lc BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libSimpleClassFileLoadHook := -lc BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetNamedModuleTest := -lc + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAClassFileLoadHook := -lc + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAClassLoadPrepare := -lc + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAThreadStart := -lc endif ifeq ($(OPENJDK_TARGET_OS), linux) diff --git a/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/MAAClassFileLoadHook.java b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/MAAClassFileLoadHook.java new file mode 100644 index 00000000000..0fa42bd599b --- /dev/null +++ b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/MAAClassFileLoadHook.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @run main/othervm/native -agentlib:MAAClassFileLoadHook MAAClassFileLoadHook + * @run main/othervm/native -agentlib:MAAClassFileLoadHook=with_early_vmstart MAAClassFileLoadHook + * @run main/othervm/native -agentlib:MAAClassFileLoadHook=with_early_class_hook MAAClassFileLoadHook + * @run main/othervm/native -agentlib:MAAClassFileLoadHook=with_early_vmstart,with_early_class_hook MAAClassFileLoadHook + */ + +public class MAAClassFileLoadHook { + + static { + try { + System.loadLibrary("MAAClassFileLoadHook"); + } catch (UnsatisfiedLinkError ule) { + System.err.println("Could not load MAAClassFileLoadHook library"); + System.err.println("java.library.path: " + + System.getProperty("java.library.path")); + throw ule; + } + } + + native static int check(); + + public static void main(String args[]) { + int status = check(); + if (status != 0) { + throw new RuntimeException("Non-zero status returned from the agent: " + status); + } + } +} diff --git a/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/libMAAClassFileLoadHook.c b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/libMAAClassFileLoadHook.c new file mode 100644 index 00000000000..04ecb68867d --- /dev/null +++ b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/libMAAClassFileLoadHook.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include "jvmti.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef JNI_ENV_ARG + +#ifdef __cplusplus +#define JNI_ENV_ARG(x, y) y +#define JNI_ENV_PTR(x) x +#else +#define JNI_ENV_ARG(x,y) x, y +#define JNI_ENV_PTR(x) (*x) +#endif + +#endif + +#define TranslateError(err) "JVMTI error" + +#define PASSED 0 +#define FAILED 2 + +static const char *EXPECTED_NAME = "java/util/Collections"; +static const char *EXC_CNAME = "java/lang/Exception"; + +static jvmtiEnv *jvmti = NULL; +static jint result = PASSED; +static jboolean printdump = JNI_FALSE; + +static jboolean with_early_vm_start_capability = JNI_FALSE; +static jboolean with_early_class_hook_capability = JNI_FALSE; + +static jboolean found_class_in_vm_start = JNI_FALSE; +static jboolean found_class_in_primordial = JNI_FALSE; +static jboolean found_class_in_cflh_events = JNI_FALSE; + +static int cflh_events_primordial_count = 0; +static int cflh_events_vm_start_count = 0; + +static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); + +JNIEXPORT +jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { + return JNI_VERSION_9; +} + +static +jint throw_exc(JNIEnv *env, char *msg) { + jclass exc_class = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, EXC_CNAME)); + + if (exc_class == NULL) { + printf("throw_exc: Error in FindClass(env, %s)\n", EXC_CNAME); + return -1; + } + return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg); +} + +static void JNICALL +Callback_ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *env, + jclass class_being_redefined, + jobject loader, const char* name, jobject protection_domain, + jint class_data_len, const unsigned char* class_data, + jint *new_class_data_len, unsigned char** new_class_data) { + jvmtiPhase phase; + jvmtiError err; + + err = (*jvmti)->GetPhase(jvmti_env, &phase); + if (err != JVMTI_ERROR_NONE) { + printf("ClassFileLoadHook event: GetPhase error: %s (%d)\n", TranslateError(err), err); + result = FAILED; + return; + } + + if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) { + if (phase == JVMTI_PHASE_START) { + cflh_events_vm_start_count++; + if(strcmp(name, EXPECTED_NAME) == 0) { + found_class_in_vm_start = JNI_TRUE; + } + } else { + cflh_events_primordial_count++; + if(strcmp(name, EXPECTED_NAME) == 0) { + found_class_in_primordial = JNI_TRUE; + } + } + } + + if(strcmp(name, EXPECTED_NAME) == 0) { + found_class_in_cflh_events = JNI_TRUE; + } + + if (printdump == JNI_TRUE) { + printf(">>> ClassFileLoadHook event: phase(%d), class name %s\n", phase, name); + } +} + +static +jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { + jint res, size; + jvmtiCapabilities caps; + jvmtiEventCallbacks callbacks; + jvmtiError err; + + if (options != NULL) { + if (strstr(options, "with_early_vmstart") != NULL) { + with_early_vm_start_capability = JNI_TRUE; + } + if (strstr(options, "with_early_class_hook") != NULL) { + with_early_class_hook_capability = JNI_TRUE; + } + if (strstr(options, "printdump") != NULL) { + printdump = JNI_TRUE; + } + } + + res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), + JVMTI_VERSION_9); + if (res != JNI_OK || jvmti == NULL) { + printf(" Error: wrong result of a valid call to GetEnv!\n"); + return JNI_ERR; + } + + printf("Enabling following capabilities: can_generate_all_class_hook_events"); + memset(&caps, 0, sizeof(caps)); + caps.can_generate_all_class_hook_events = 1; + if (with_early_vm_start_capability == JNI_TRUE) { + printf(", can_generate_early_vmstart"); + caps.can_generate_early_vmstart = 1; + } + if (with_early_class_hook_capability == JNI_TRUE) { + printf(", can_generate_early_class_hook_events"); + caps.can_generate_early_class_hook_events = 1; + } + printf("\n"); + + err = (*jvmti)->AddCapabilities(jvmti, &caps); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in AddCapabilites: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + size = (jint)sizeof(callbacks); + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.ClassFileLoadHook = Callback_ClassFileLoadHook; + + err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + return JNI_OK; +} + +JNIEXPORT jint JNICALL +Java_MAAClassFileLoadHook_check(JNIEnv *env, jclass cls) { + jobject loader = NULL; + + if (jvmti == NULL) { + throw_exc(env, "JVMTI client was not properly loaded!\n"); + return FAILED; + } + + /* + * Expecting that we always get ClassFileLoadHook events in the VM Start phase. + */ + if (cflh_events_vm_start_count == 0) { + throw_exc(env, "Didn't get ClassFileLoadHook events in start phase!\n"); + return FAILED; + } + + if (with_early_class_hook_capability == JNI_TRUE) { + /* + * Expecting that we get ClassFileLoadHook events in the Primordial phase + * when can_generate_all_class_hook_events and can_generate_early_class_hook_events + * capabilities are enabled. + */ + if (cflh_events_primordial_count == 0) { + throw_exc(env, "Didn't get ClassFileLoadHook events in primordial phase!\n"); + return FAILED; + } + } else { + /* + * Expecting that we don't get ClassFileLoadHook events in the Primordial phase + * when can_generate_early_class_hook_events capability is disabled. + */ + if (cflh_events_primordial_count != 0) { + throw_exc(env, "Get ClassFileLoadHook events in primordial phase!\n"); + return FAILED; + } + } + + + if (with_early_vm_start_capability == JNI_TRUE) { + /* + * Expecting that "java/util/Collections" class from java.base module is present in the + * ClassFileLoadHook events during VM Start phase when can_generate_early_vmstart + * capability is enabled. + */ + printf("Expecting to find '%s' class in ClassFileLoadHook events during VM early start phase.\n", EXPECTED_NAME); + if (found_class_in_vm_start == JNI_FALSE) { + throw_exc(env, "Unable to find expected class in ClassLoad events during VM early start phase!\n"); + return FAILED; + } + } else if (with_early_class_hook_capability == JNI_TRUE) { + /* + * Expecting that "java/util/Collections" class from java.base module is present in the + * ClassFileLoadHook events during Primordial phase when can_generate_all_class_hook_events + * and can_generate_early_class_hook_events capabilities are enabled and can_generate_early_vmstart + * capability is disabled. + */ + printf("Expecting to find '%s' class in ClassFileLoadHook events during VM primordial phase.\n", EXPECTED_NAME); + if (found_class_in_primordial == JNI_FALSE) { + throw_exc(env, "Unable to find expected class in ClassFileLoadHook events during primordial phase!\n"); + return FAILED; + } + } else { + /* + * Expecting that "java/util/Collections" class from java.base module is not present in the + * ClassFileLoadHook events when can_generate_all_class_hook_events, can_generate_early_class_hook_events + * and can_generate_early_vmstart capabilities are disabled. + */ + printf("Expecting that '%s' class is absent in ClassLoadHook events.\n", EXPECTED_NAME); + if (found_class_in_cflh_events == JNI_TRUE) { + throw_exc(env, "Class is found in ClassFileLoadHook events!\n"); + return FAILED; + } + } + + return result; +} + +#ifdef __cplusplus +} +#endif diff --git a/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/MAAClassLoadPrepare.java b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/MAAClassLoadPrepare.java new file mode 100644 index 00000000000..98661c281c9 --- /dev/null +++ b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/MAAClassLoadPrepare.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8165681 + * @summary Verify ClassLoad and ClassPrepare JVMTI event with + * and without can_generate_early_vmstart capability + * @run main/othervm/native -agentlib:MAAClassLoadPrepare MAAClassLoadPrepare + * @run main/othervm/native -agentlib:MAAClassLoadPrepare=with_early_vmstart MAAClassLoadPrepare + */ + +public class MAAClassLoadPrepare { + + static { + try { + System.loadLibrary("MAAClassLoadPrepare"); + } catch (UnsatisfiedLinkError ule) { + System.err.println("Could not load MAAClassLoadPrepare library"); + System.err.println("java.library.path: " + + System.getProperty("java.library.path")); + throw ule; + } + } + + native static int check(); + + public static void main(String args[]) { + int status = check(); + if (status != 0) { + throw new RuntimeException("Non-zero status returned from the agent: " + status); + } + } +} diff --git a/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/libMAAClassLoadPrepare.c b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/libMAAClassLoadPrepare.c new file mode 100644 index 00000000000..dbfff1a15df --- /dev/null +++ b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/libMAAClassLoadPrepare.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include "jvmti.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef JNI_ENV_ARG + +#ifdef __cplusplus +#define JNI_ENV_ARG(x, y) y +#define JNI_ENV_PTR(x) x +#else +#define JNI_ENV_ARG(x,y) x, y +#define JNI_ENV_PTR(x) (*x) +#endif + +#endif + +#define TranslateError(err) "JVMTI error" + +#define PASSED 0 +#define FAILED 2 + +static const char *EXPECTED_SIGNATURE = "Ljava/util/Collections;"; +static const char *EXC_CNAME = "java/lang/Exception"; + +static jvmtiEnv *jvmti = NULL; +static jint result = PASSED; +static jboolean printdump = JNI_FALSE; + +static jboolean with_early_vm_start_capability = JNI_FALSE; + +static jboolean class_in_class_load_events_vm_start = JNI_FALSE; +static jboolean class_in_class_load_events_vm_live = JNI_FALSE; +static jboolean class_in_class_prepare_events_vm_start = JNI_FALSE; +static jboolean class_in_class_prepare_events_vm_live = JNI_FALSE; + +static int class_load_events_vm_start_count = 0; +static int class_prepare_events_vm_start_count = 0; + +static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); + +JNIEXPORT +jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { + return JNI_VERSION_9; +} + +static +jint throw_exc(JNIEnv *env, char *msg) { + jclass exc_class = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, EXC_CNAME)); + + if (exc_class == NULL) { + printf("throw_exc: Error in FindClass(env, %s)\n", EXC_CNAME); + return -1; + } + return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg); +} + +static void JNICALL +Callback_ClassFileLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) { + jvmtiPhase phase; + char *sig, *generic; + jvmtiError err; + + err = (*jvmti)->GetPhase(jvmti_env,&phase); + if (err != JVMTI_ERROR_NONE) { + printf("ClassLoad event: GetPhase error: %s (%d)\n", TranslateError(err), err); + result = FAILED; + return; + } + + if (phase == JVMTI_PHASE_START || phase == JVMTI_PHASE_LIVE) { + + err = (*jvmti)->GetClassSignature(jvmti_env, klass, &sig, &generic); + + if (err != JVMTI_ERROR_NONE) { + printf("ClassLoad event: GetClassSignature error: %s (%d)\n", TranslateError(err), err); + result = FAILED; + return; + } + + if (phase == JVMTI_PHASE_START) { + class_load_events_vm_start_count++; + if(strcmp(sig, EXPECTED_SIGNATURE) == 0) { + class_in_class_load_events_vm_start = JNI_TRUE; + } + } else { + if(strcmp(sig, EXPECTED_SIGNATURE) == 0) { + class_in_class_load_events_vm_live = JNI_TRUE; + } + } + + if (printdump == JNI_TRUE) { + printf(">>> ClassLoad event: phase(%d), class signature %s\n", phase, sig == NULL ? "null": sig); + } + } else { + printf("ClassLoad event: get event in unexpected phase(%d)\n", phase); + result = FAILED; + } +} + +static void JNICALL +Callback_ClassFilePrepare(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) { + jvmtiPhase phase; + char *sig, *generic; + jvmtiError err; + + err = (*jvmti)->GetPhase(jvmti_env,&phase); + if (err != JVMTI_ERROR_NONE) { + printf("ClassPrepare event: GetPhase error: %s (%d)\n", TranslateError(err), err); + result = FAILED; + return; + } + + if (phase == JVMTI_PHASE_START || phase == JVMTI_PHASE_LIVE) { + + err = (*jvmti)->GetClassSignature(jvmti_env, klass, &sig, &generic); + + if (err != JVMTI_ERROR_NONE) { + printf("ClassPrepare event: GetClassSignature error: %s (%d)\n", TranslateError(err), err); + result = FAILED; + return; + } + + if (phase == JVMTI_PHASE_START) { + class_prepare_events_vm_start_count++; + if(strcmp(sig, EXPECTED_SIGNATURE) == 0) { + class_in_class_prepare_events_vm_start = JNI_TRUE; + } + } else { + if(strcmp(sig, EXPECTED_SIGNATURE) == 0) { + class_in_class_prepare_events_vm_live = JNI_TRUE; + } + } + + if (printdump == JNI_TRUE) { + printf(">>> ClassPrepare event: phase(%d), class signature %s\n", phase, sig == NULL ? "null": sig); + } + } else { + printf("ClassPrepare event: get event in unexpected phase(%d)\n", phase); + result = FAILED; + } +} + +static +jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { + jint res, size; + jvmtiCapabilities caps; + jvmtiEventCallbacks callbacks; + jvmtiError err; + + if (options != NULL) { + if (strstr(options, "with_early_vmstart") != NULL) { + with_early_vm_start_capability = JNI_TRUE; + } + if (strstr(options, "printdump") != NULL) { + printdump = JNI_TRUE; + } + } + + res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), + JVMTI_VERSION_9); + if (res != JNI_OK || jvmti == NULL) { + printf(" Error: wrong result of a valid call to GetEnv!\n"); + return JNI_ERR; + } + + if (with_early_vm_start_capability == JNI_TRUE) { + printf("Enabling following capability: can_generate_early_vmstart\n"); + memset(&caps, 0, sizeof(caps)); + caps.can_generate_early_vmstart = 1; + + err = (*jvmti)->AddCapabilities(jvmti, &caps); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in AddCapabilites: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + } + + size = (jint)sizeof(callbacks); + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.ClassLoad = Callback_ClassFileLoad; + callbacks.ClassPrepare = Callback_ClassFilePrepare; + + err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL); + + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + return JNI_OK; +} + +JNIEXPORT jint JNICALL +Java_MAAClassLoadPrepare_check(JNIEnv *env, jclass cls) { + jobject loader = NULL; + + if (jvmti == NULL) { + throw_exc(env, "JVMTI client was not properly loaded!\n"); + return FAILED; + } + + if (with_early_vm_start_capability == JNI_TRUE) { + /* + * Expecting that "java/util/Collections" class from java.base module is present in the + * ClassLoad and ClassPrepare events during VM Start phase when can_generate_early_vmstart + * capability is enabled. + * Expecting that ClassLoad and ClassPrepare events are sent in the VM early start phase + * when can_generate_early_vmstart is enabled(JDK-8165681). + */ + if (class_load_events_vm_start_count == 0) { + throw_exc(env, "Didn't get ClassLoad events in start phase!\n"); + return FAILED; + } + + printf("Expecting to find '%s' class in ClassLoad events during VM early start phase.\n", EXPECTED_SIGNATURE); + if (class_in_class_load_events_vm_start == JNI_FALSE) { + throw_exc(env, "Unable to find expected class in ClassLoad events during early start phase!\n"); + return FAILED; + } + + if (class_prepare_events_vm_start_count == 0) { + throw_exc(env, "Didn't get ClassPrepare events in start phase!\n"); + return FAILED; + } + + printf("Expecting to find '%s' class in ClassPrepare events during VM early start phase.\n", EXPECTED_SIGNATURE); + if (class_in_class_prepare_events_vm_start == JNI_FALSE) { + throw_exc(env, "Unable to find expected class in ClassPrepare events during early start phase!\n"); + return FAILED; + } + } else { + /* + * Expecting that "java/util/Collections" class from java.base module is not present in the + * ClassLoad and ClassPrepare events during VM Start phase when can_generate_early_vmstart + * capability is disabled. + */ + printf("Expecting that '%s' class is absent in ClassLoad events during normal VM start phase.\n", EXPECTED_SIGNATURE); + if (class_in_class_prepare_events_vm_start == JNI_TRUE) { + throw_exc(env, "Class is found in ClassLoad events during normal VM start phase!\n"); + return FAILED; + } + + printf("Expecting that '%s' class is absent in ClassPrepare events during normal VM start phase.\n", EXPECTED_SIGNATURE); + if (class_in_class_prepare_events_vm_start == JNI_TRUE) { + throw_exc(env, "Class is found in ClassPrepare events during normal VM start phase!\n"); + return FAILED; + } + } + + /* + * In any case, we not expect to see "java/util/Collections" class from java.base module + * in the ClassLoad and ClassPrepare events during VM Live phase. + */ + if (class_in_class_prepare_events_vm_live == JNI_TRUE) { + throw_exc(env, "Class is found in ClassLoad events during VM Live phase!\n"); + return FAILED; + } + + if (class_in_class_prepare_events_vm_live == JNI_TRUE) { + throw_exc(env, "Class is found in ClassPrepare events during VM Live phase!\n"); + return FAILED; + } + + return result; +} + +#ifdef __cplusplus +} +#endif diff --git a/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java new file mode 100644 index 00000000000..b8b76febb9c --- /dev/null +++ b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Verify ThreadStart JVMTI event with can_generate_early_vmstart capability + * @run main/othervm/native -agentlib:MAAThreadStart MAAThreadStart + */ + +public class MAAThreadStart { + + static { + try { + System.loadLibrary("MAAThreadStart"); + } catch (UnsatisfiedLinkError ule) { + System.err.println("Could not load MAAThreadStart library"); + System.err.println("java.library.path: " + + System.getProperty("java.library.path")); + throw ule; + } + } + + native static int check(); + + public static void main(String args[]) { + int status = check(); + if (status != 0) { + throw new RuntimeException("Non-zero status returned from the agent: " + status); + } + } +} diff --git a/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/libMAAThreadStart.c b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/libMAAThreadStart.c new file mode 100644 index 00000000000..ea346536e42 --- /dev/null +++ b/hotspot/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart/libMAAThreadStart.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include "jvmti.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef JNI_ENV_ARG + +#ifdef __cplusplus +#define JNI_ENV_ARG(x, y) y +#define JNI_ENV_PTR(x) x +#else +#define JNI_ENV_ARG(x,y) x, y +#define JNI_ENV_PTR(x) (*x) +#endif + +#endif + +#define TranslateError(err) "JVMTI error" + +#define PASSED 0 +#define FAILED 2 + +static const char *EXC_CNAME = "java/lang/Exception"; + +static jvmtiEnv *jvmti = NULL; +static jint result = PASSED; +static jboolean printdump = JNI_FALSE; + +static int thread_start_events_vm_start = 0; + +static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); + +JNIEXPORT +jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { + return JNI_VERSION_9; +} + +static +jint throw_exc(JNIEnv *env, char *msg) { + jclass exc_class = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, EXC_CNAME)); + + if (exc_class == NULL) { + printf("throw_exc: Error in FindClass(env, %s)\n", EXC_CNAME); + return -1; + } + return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg); +} + + +void JNICALL Callback_ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) { + jvmtiError err; + jvmtiPhase phase; + + err = (*jvmti)->GetPhase(jvmti_env,&phase); + if (err != JVMTI_ERROR_NONE) { + printf("ThreadStart event: GetPhase error: %s (%d)\n", TranslateError(err), err); + result = FAILED; + return; + } + + if (phase == JVMTI_PHASE_START) { + thread_start_events_vm_start++; + } + + if (printdump == JNI_TRUE) { + printf(">>> ThreadStart event: phase(%d)\n", phase); + } +} + +static +jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { + jint res, size; + jvmtiCapabilities caps; + jvmtiEventCallbacks callbacks; + jvmtiError err; + + if (options != NULL && strcmp(options, "printdump") == 0) { + printdump = JNI_TRUE; + } + + res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), + JVMTI_VERSION_9); + if (res != JNI_OK || jvmti == NULL) { + printf(" Error: wrong result of a valid call to GetEnv!\n"); + return JNI_ERR; + } + + printf("Enabling following capability: can_generate_early_vmstart\n"); + memset(&caps, 0, sizeof(caps)); + caps.can_generate_early_vmstart = 1; + + err = (*jvmti)->AddCapabilities(jvmti, &caps); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in AddCapabilites: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + size = (jint)sizeof(callbacks); + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.ThreadStart = Callback_ThreadStart; + + err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err); + return JNI_ERR; + } + + return JNI_OK; +} + +JNIEXPORT jint JNICALL +Java_MAAThreadStart_check(JNIEnv *env, jclass cls) { + jobject loader = NULL; + + if (jvmti == NULL) { + throw_exc(env, "JVMTI client was not properly loaded!\n"); + return FAILED; + } + + /* + * Expecting that ThreadStart events are sent during VM Start phase when + * can_generate_early_vmstart capability is enabled. + */ + if (thread_start_events_vm_start == 0) { + throw_exc(env, "Didn't get ThreadStart events in VM early start phase!\n"); + return FAILED; + } + + return result; +} + +#ifdef __cplusplus +} +#endif From e57692c64218b9959ca3a19327476861f0d3e4f1 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 21 Sep 2016 09:56:18 -0400 Subject: [PATCH 055/207] 8163969: Cyclic interface initialization causes JVM crash Fix interface initialization to follow spec: interface initializations do not set initialization state of interfaces that extend them. Reviewed-by: dholmes, acorn, lfoltan --- hotspot/src/share/vm/oops/instanceKlass.cpp | 94 ++++---- .../lambda-features/CyclicInterfaceInit.java | 80 +++++++ .../InterfaceInitializationStates.java | 202 ++++++++++++++++++ 3 files changed, 328 insertions(+), 48 deletions(-) create mode 100644 hotspot/test/runtime/lambda-features/CyclicInterfaceInit.java create mode 100644 hotspot/test/runtime/lambda-features/InterfaceInitializationStates.java diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index ea49b1baf85..1af90ceec69 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -517,7 +517,11 @@ bool InstanceKlass::link_class_or_fail(TRAPS) { bool InstanceKlass::link_class_impl( instanceKlassHandle this_k, bool throw_verifyerror, TRAPS) { - // check for error state + // check for error state. + // This is checking for the wrong state. If the state is initialization_error, + // then this class *was* linked. The CDS code does a try_link_class and uses + // initialization_error to mark classes to not include in the archive during + // DumpSharedSpaces. This should be removed when the CDS bug is fixed. if (this_k->is_in_error_state()) { ResourceMark rm(THREAD); THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(), @@ -670,36 +674,21 @@ void InstanceKlass::link_methods(TRAPS) { // Eagerly initialize superinterfaces that declare default methods (concrete instance: any access) void InstanceKlass::initialize_super_interfaces(instanceKlassHandle this_k, TRAPS) { - if (this_k->has_default_methods()) { - for (int i = 0; i < this_k->local_interfaces()->length(); ++i) { - Klass* iface = this_k->local_interfaces()->at(i); - InstanceKlass* ik = InstanceKlass::cast(iface); - if (ik->should_be_initialized()) { - if (ik->has_default_methods()) { - ik->initialize_super_interfaces(ik, THREAD); - } - // Only initialize() interfaces that "declare" concrete methods. - // has_default_methods drives searching superinterfaces since it - // means has_default_methods in its superinterface hierarchy - if (!HAS_PENDING_EXCEPTION && ik->declares_default_methods()) { - ik->initialize(THREAD); - } - if (HAS_PENDING_EXCEPTION) { - Handle e(THREAD, PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; - { - EXCEPTION_MARK; - // Locks object, set state, and notify all waiting threads - this_k->set_initialization_state_and_notify( - initialization_error, THREAD); + assert (this_k->has_default_methods(), "caller should have checked this"); + for (int i = 0; i < this_k->local_interfaces()->length(); ++i) { + Klass* iface = this_k->local_interfaces()->at(i); + InstanceKlass* ik = InstanceKlass::cast(iface); - // ignore any exception thrown, superclass initialization error is - // thrown below - CLEAR_PENDING_EXCEPTION; - } - THROW_OOP(e()); - } - } + // Initialization is depth first search ie. we start with top of the inheritance tree + // has_default_methods drives searching superinterfaces since it + // means has_default_methods in its superinterface hierarchy + if (ik->has_default_methods()) { + ik->initialize_super_interfaces(ik, CHECK); + } + + // Only initialize() interfaces that "declare" concrete methods. + if (ik->should_be_initialized() && ik->declares_default_methods()) { + ik->initialize(CHECK); } } } @@ -765,32 +754,36 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_k, TRAPS) { } // Step 7 - Klass* super_klass = this_k->super(); - if (super_klass != NULL && !this_k->is_interface() && super_klass->should_be_initialized()) { - super_klass->initialize(THREAD); + // Next, if C is a class rather than an interface, initialize it's super class and super + // interfaces. + if (!this_k->is_interface()) { + Klass* super_klass = this_k->super(); + if (super_klass != NULL && super_klass->should_be_initialized()) { + super_klass->initialize(THREAD); + } + // If C implements any interfaces that declares a non-abstract, non-static method, + // the initialization of C triggers initialization of its super interfaces. + // Only need to recurse if has_default_methods which includes declaring and + // inheriting default methods + if (!HAS_PENDING_EXCEPTION && this_k->has_default_methods()) { + this_k->initialize_super_interfaces(this_k, THREAD); + } + // If any exceptions, complete abruptly, throwing the same exception as above. if (HAS_PENDING_EXCEPTION) { Handle e(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; { EXCEPTION_MARK; - this_k->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads - CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, superclass initialization error is thrown below + // Locks object, set state, and notify all waiting threads + this_k->set_initialization_state_and_notify(initialization_error, THREAD); + CLEAR_PENDING_EXCEPTION; } DTRACE_CLASSINIT_PROBE_WAIT(super__failed, this_k(), -1,wait); THROW_OOP(e()); } } - // If C is an interface that declares a non-abstract, non-static method, - // the initialization of a class (not an interface) that implements C directly or - // indirectly. - // Recursively initialize any superinterfaces that declare default methods - // Only need to recurse if has_default_methods which includes declaring and - // inheriting default methods - if (!this_k->is_interface() && this_k->has_default_methods()) { - this_k->initialize_super_interfaces(this_k, CHECK); - } // Step 8 { @@ -852,10 +845,15 @@ void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_k, ClassState state, TRAPS) { oop init_lock = this_k->init_lock(); - ObjectLocker ol(init_lock, THREAD, init_lock != NULL); - this_k->set_init_state(state); - this_k->fence_and_clear_init_lock(); - ol.notify_all(CHECK); + if (init_lock != NULL) { + ObjectLocker ol(init_lock, THREAD); + this_k->set_init_state(state); + this_k->fence_and_clear_init_lock(); + ol.notify_all(CHECK); + } else { + assert(init_lock != NULL, "The initialization state should never be set twice"); + this_k->set_init_state(state); + } } // The embedded _implementor field can only record one implementor. diff --git a/hotspot/test/runtime/lambda-features/CyclicInterfaceInit.java b/hotspot/test/runtime/lambda-features/CyclicInterfaceInit.java new file mode 100644 index 00000000000..75fc5b03d95 --- /dev/null +++ b/hotspot/test/runtime/lambda-features/CyclicInterfaceInit.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8163969 + * @summary Interface initialization was crashing on this because the wrong class was getting + * initialization error. + * @run main CyclicInterfaceInit + */ +/** + * This snippet crashes with + * - Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13) + */ +public class CyclicInterfaceInit { + + interface Base { + static final Object CONST = new Target(){}.someMethod(); + + default void important() { + // Super interfaces with default methods get initialized (JLS 12.4.1) + } + } + + static boolean out(String c) { + System.out.println("initializing " + c); + return true; + } + + interface Target extends Base { + boolean v = CyclicInterfaceInit.out("Target"); + default Object someMethod() { + throw new RuntimeException(); + } + // Target can be fully initialized before initializating Base because Target doesn't + // initiate the initialization of Base. + } + + static class InnerBad implements Target {} + + public static void main(String[] args) { + try { + new Target() {}; // Creates inner class that causes initialization of super interfaces + } catch (ExceptionInInitializerError e) { + System.out.println("ExceptionInInitializerError thrown as expected"); + } + // Try again, InnerBad instantiation should throw NoClassdefFoundError + // because Base is marked erroneous due to previous exception during initialization + try { + InnerBad ig = new InnerBad(); + throw new RuntimeException("FAILED- initialization of InnerBad should throw NCDFE"); + } catch (NoClassDefFoundError e) { + System.out.println("NoClassDefFoundError thrown as expected"); + } + // Target is already initialized. + System.out.println("Target.v is " + Target.v); + // shouldn't throw any exceptions. + } +} diff --git a/hotspot/test/runtime/lambda-features/InterfaceInitializationStates.java b/hotspot/test/runtime/lambda-features/InterfaceInitializationStates.java new file mode 100644 index 00000000000..e43bb808160 --- /dev/null +++ b/hotspot/test/runtime/lambda-features/InterfaceInitializationStates.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8163969 + * @summary Test interface initialization states and when certain interfaces are initialized + * in the presence of initialization errors. + * @run main InterfaceInitializationStates + */ + +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; + +public class InterfaceInitializationStates { + + static List> cInitOrder = new ArrayList<>(); + + // K interface with a default method has an initialization error + interface K { + boolean v = InterfaceInitializationStates.out(K.class); + static final Object CONST = InterfaceInitializationStates.someMethod(); + default int method() { return 2; } + } + + // I is initialized when CONST is used, and doesn't trigger initialization of K, + // I also doesn't get an initialization error just because K has an initialization error. + interface I extends K { + boolean v = InterfaceInitializationStates.out(I.class); + static final Object CONST = InterfaceInitializationStates.someMethod(); + } + + // L can be fully initialized even though it extends an interface that has an + // initialization error + interface L extends K { + boolean v = InterfaceInitializationStates.out(L.class); + default void lx() {} + static void func() { + System.out.println("Calling function on interface with bad super interface."); + } + } + + // Another interface needing initialization. + // Initialization of this interface does not occur with ClassLIM because K throws + // an initialization error, so the interface initialization is abandoned + interface M { + boolean v = InterfaceInitializationStates.out(M.class); + default void mx() {} + } + + static class ClassLIM implements L, I, M { + boolean v = InterfaceInitializationStates.out(ClassLIM.class); + int callMethodInK() { return method(); } + static { + // Since interface initialization of K fails, this should never be called + System.out.println("Initializing C, but L is still good"); + L.func(); + } + } + + // Finally initialize M + static class ClassM implements M { + boolean v = InterfaceInitializationStates.out(ClassM.class); + } + + // Iunlinked is testing initialization like interface I, except interface I is linked when + // ClassLIM is linked. + // Iunlinked is not linked already when K gets an initialization error. Linking Iunlinked + // should succeed and not get NoClassDefFoundError because it does not depend on the + // initialization state of K for linking. There's bug now where it gets this error. + // See: https://bugs.openjdk.java.net/browse/JDK-8166203. + interface Iunlinked extends K { + boolean v = InterfaceInitializationStates.out(Iunlinked.class); + } + + // More tests. What happens if we use K for parameters and return types? + // K is a symbolic reference in the constant pool and the initialization error only + // matters when it's used. + interface Iparams { + boolean v = InterfaceInitializationStates.out(Iparams.class); + K the_k = null; + K m(K k); // abstract + default K method() { return new K(){}; } + } + + static class ClassIparams implements Iparams { + boolean v = InterfaceInitializationStates.out(ClassIparams.class); + public K m(K k) { return k; } + } + + public static void main(java.lang.String[] unused) { + // The rule this tests is the last sentence of JLS 12.4.1: + + // When a class is initialized, its superclasses are initialized (if they have not + // been previously initialized), as well as any superinterfaces (s8.1.5) that declare any + // default methods (s9.4.3) (if they have not been previously initialized). Initialization + // of an interface does not, of itself, cause initialization of any of its superinterfaces. + + // Trigger initialization. + // Now L is fully_initialized even though K should + // throw an error during initialization. + boolean v = L.v; + L.func(); + + try { + ClassLIM c = new ClassLIM(); // is K initialized, with a perfectly good L in the middle + // was bug: this used to succeed and be able to callMethodInK(). + throw new RuntimeException("FAIL exception not thrown for class"); + } catch (ExceptionInInitializerError e) { + System.out.println("ExceptionInInitializerError thrown as expected"); + } + + // Test that K already has initialization error so gets ClassNotFoundException because + // initialization was attempted with ClassLIM. + try { + Class.forName("InterfaceInitializationStates$K", true, InterfaceInitializationStates.class.getClassLoader()); + throw new RuntimeException("FAIL exception not thrown for forName(K)"); + } catch(ClassNotFoundException e) { + throw new RuntimeException("ClassNotFoundException should not be thrown"); + } catch(NoClassDefFoundError e) { + System.out.println("NoClassDefFoundError thrown as expected"); + } + + new ClassM(); + + // Initialize I, which doesn't cause K (super interface) to be initialized. + // Since the initialization of I does _not_ cause K to be initialized, it does + // not get NoClassDefFoundError because K is erroneous. + // But the initialization of I throws RuntimeException, so we expect + // ExceptionInInitializerError. + try { + Object ii = I.CONST; + throw new RuntimeException("FAIL exception not thrown for I's initialization"); + } catch (ExceptionInInitializerError e) { + System.out.println("ExceptionInInitializerError as expected"); + } + + // Initialize Iunlinked. This should not get NoClassDefFoundError because K + // (its super interface) is in initialization_error state. + // This is a bug. It does now. + try { + boolean bb = Iunlinked.v; + throw new RuntimeException("FAIL exception not thrown for Iunlinked initialization"); + } catch(NoClassDefFoundError e) { + System.out.println("NoClassDefFoundError thrown because of bug"); + } + + // This should be okay + boolean value = Iparams.v; + System.out.println("value is " + value); + + ClassIparams p = new ClassIparams(); + try { + // Now we get an error because K got an initialization_error + K kk = p.method(); + throw new RuntimeException("FAIL exception not thrown for calling method for K"); + } catch(NoClassDefFoundError e) { + System.out.println("NoClassDefFoundError thrown as expected"); + } + + // Check expected class initialization order + List> expectedCInitOrder = Arrays.asList(L.class, K.class, M.class, ClassM.class, + I.class, Iparams.class, + ClassIparams.class); + if (!cInitOrder.equals(expectedCInitOrder)) { + throw new RuntimeException( + String.format("Class initialization array %s not equal to expected array %s", + cInitOrder, expectedCInitOrder)); + } + } + + static boolean out(Class c) { + System.out.println("#: initializing " + c.getName()); + cInitOrder.add(c); + return true; + } + static Object someMethod() { + throw new RuntimeException(); + } +} From 371c29a6527d47ef62f0e0c23a64219da1f72d64 Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Wed, 21 Sep 2016 12:45:18 -0400 Subject: [PATCH 056/207] 8164852: Move slow tier1/tier2 runtime tests to later tiers Reviewed-by: gtriantafill, sla, mseledtsov --- hotspot/test/TEST.groups | 43 ++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index fc1eae68feb..74658bc86af 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -351,16 +351,29 @@ hotspot_fast_gc_gcold = \ hotspot_fast_runtime = \ runtime/ \ + -runtime/6626217/Test6626217.sh \ + -runtime/7100935 \ + -runtime/7158988/FieldMonitor.java \ + -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \ + -runtime/CommandLine/PrintGCApplicationConcurrentTime.java \ + -runtime/ConstantPool/IntfMethod.java \ + -runtime/ErrorHandling/CreateCoredumpOnCrash.java \ -runtime/ErrorHandling/ErrorHandler.java \ - -runtime/RedefineObject/TestRedefineObject.java \ - -runtime/MirrorFrame/Test8003720.java \ - -runtime/Metaspace/FragmentMetaspace.java \ - -runtime/Metaspace/FragmentMetaspaceSimple.java \ - -runtime/Thread/TestThreadDumpMonitorContention.java \ - -runtime/SharedArchiveFile/SharedBaseAddress.java \ + -runtime/logging/MonitorMismatchTest.java \ -runtime/memory/ReserveMemory.java \ -runtime/memory/RunUnitTestsConcurrently.java \ - -runtime/Unsafe/RangeCheck.java \ + -runtime/Metaspace/FragmentMetaspace.java \ + -runtime/Metaspace/FragmentMetaspaceSimple.java \ + -runtime/MirrorFrame/Test8003720.java \ + -runtime/modules/LoadUnloadModuleStress.java \ + -runtime/modules/ModuleStress/ExportModuleStressTest.java \ + -runtime/modules/ModuleStress/ModuleStressGC.java \ + -runtime/NMT \ + -runtime/RedefineObject/TestRedefineObject.java \ + -runtime/RedefineTests/RedefinePreviousVersions.java \ + -runtime/RedefineTests/RedefineRunningMethods.java \ + -runtime/RedefineTests/RedefineRunningMethodsWithBacktrace.java \ + -runtime/ReservedStack \ -runtime/SelectionResolution/AbstractMethodErrorTest.java \ -runtime/SelectionResolution/IllegalAccessErrorTest.java \ -runtime/SelectionResolution/InvokeInterfaceICCE.java \ @@ -372,14 +385,14 @@ hotspot_fast_runtime = \ -runtime/SelectionResolution/InvokeVirtualSuccessTest.java \ -runtime/SharedArchiveFile/CdsSameObjectAlignment.java \ -runtime/SharedArchiveFile/DefaultUseWithClient.java \ + -runtime/SharedArchiveFile/SharedBaseAddress.java \ -runtime/Thread/CancellableThreadTest.java \ - -runtime/7158988/FieldMonitor.java \ - -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \ + -runtime/Thread/TestThreadDumpMonitorContention.java \ + -runtime/Unsafe/RangeCheck.java \ sanity/ \ testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java hotspot_fast_serviceability = \ - sanity/ExecuteInternalVMTests.java \ serviceability/dcmd/compiler \ serviceability/logging @@ -398,6 +411,8 @@ hotspot_jprt = \ hotspot_runtime_tier2 = \ runtime/ \ serviceability/ \ + -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \ + -runtime/Thread/TestThreadDumpMonitorContention.java \ -:hotspot_fast_runtime \ -:hotspot_fast_serviceability \ -:hotspot_runtime_tier2_platform_agnostic @@ -405,6 +420,14 @@ hotspot_runtime_tier2 = \ hotspot_runtime_tier2_platform_agnostic = \ runtime/SelectionResolution \ -:hotspot_fast_runtime + +hotspot_runtime_tier3 = \ + runtime/ \ + serviceability/ \ + -:hotspot_fast_runtime \ + -:hotspot_fast_serviceability \ + -:hotspot_runtime_tier2_platform_agnostic \ + -:hotspot_runtime_tier2 hotspot_runtime_minimalvm = \ runtime/MinimalVM \ From dcde22fc999106135a79e88c3f3e125079a7fc7c Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Wed, 21 Sep 2016 12:53:16 -0700 Subject: [PATCH 057/207] 8161225: Assert failure in JVMTI GetNamedModule at JPLISAgent.c line: 792 Made the assert less restrictive. Reviewed-by: dholmes, dcubed, sspitsyn --- hotspot/src/share/vm/prims/jvmtiEnter.xsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmtiEnter.xsl b/hotspot/src/share/vm/prims/jvmtiEnter.xsl index bdb7915513d..3ce93d1f289 100644 --- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl +++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl @@ -487,8 +487,8 @@ static jvmtiError JNICALL if (trace_flags) { - log_trace(jvmti)("[-] %s %s", func_name, - JvmtiUtil::error_name(JVMTI_ERROR_WRONG_PHASE)); + log_trace(jvmti)("[-] %s %s(%d)", func_name, + JvmtiUtil::error_name(JVMTI_ERROR_WRONG_PHASE), JvmtiEnv::get_phase()); } From 3dad87645d36ac2c912f8e88a189cbea48c37baf Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 22 Sep 2016 08:57:37 +0200 Subject: [PATCH 058/207] 8166202: Tracefile gensrc cannot handle closed src dir in different location Reviewed-by: egahlin, dholmes, tbell --- hotspot/make/gensrc/GensrcJvmti.gmk | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hotspot/make/gensrc/GensrcJvmti.gmk b/hotspot/make/gensrc/GensrcJvmti.gmk index 25f569dc119..d5940bf2017 100644 --- a/hotspot/make/gensrc/GensrcJvmti.gmk +++ b/hotspot/make/gensrc/GensrcJvmti.gmk @@ -67,7 +67,8 @@ define SetupXslTransformBody $$($1_OUTPUT_DIR)/$1: $$($1_XML_FILE) $$($1_XSL_FILE) $$($1_DEPS) $$(BUILD_JVMTI_TOOLS) $$(call LogInfo, Generating $$(@F)) $$(call MakeDir, $$(@D)) - $$(call ExecuteWithLog, $$@, $$(TOOL_JVMTI_GEN) -IN $$($1_XML_FILE) -XSL $$($1_XSL_FILE) -OUT $$@ $$($1_ARGS)) + $$(call ExecuteWithLog, $$@, $$(TOOL_JVMTI_GEN) -IN $$($1_XML_FILE) \ + -XSL $$($1_XSL_FILE) -OUT $$@ $$($1_ARGS)) # jvmtiGen does not return error code properly on fail. # NOTE: We should really fix jvmtiGen.java instead. test -f $$@ @@ -134,8 +135,8 @@ TARGETS += $(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp TRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles TRACE_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/trace -# Append directories to search (might have been set by custom extensions) -TRACE_SEARCH_DIRS += $(TRACE_SRCDIR) +# Append list of XSL files to search (might have been set by custom extensions) +TRACE_XSL_FILES += $(wildcard $(TRACE_SRCDIR)/*.xsl) TRACE_XML ?= $(TRACE_SRCDIR)/trace.xml @@ -155,7 +156,7 @@ TRACE_DEPS += \ define SetupTraceGeneration $$(eval $$(call SetupXslTransform, $1, \ XML_FILE := $$(TRACE_XML), \ - XSL_FILE := $$(firstword $$(wildcard $$(addsuffix /$$(basename $1).xsl, $$(TRACE_SEARCH_DIRS)))), \ + XSL_FILE := $$(firstword $$(filter %/$$(basename $1).xsl, $$(TRACE_XSL_FILES))), \ OUTPUT_DIR := $$(TRACE_OUTPUTDIR), \ DEPS := $$(TRACE_DEPS), \ )) From abb5e00ccf4df7baba020e618384730aa73fbd67 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Thu, 22 Sep 2016 15:40:35 +0300 Subject: [PATCH 059/207] 8166483: gtest fmw should be updated to support null detection on SS >= 12u4 Reviewed-by: dholmes, kzhaldyb --- test/fmw/gtest/include/gtest/internal/gtest-port.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/fmw/gtest/include/gtest/internal/gtest-port.h b/test/fmw/gtest/include/gtest/internal/gtest-port.h index dc4fe0cb6b8..b772f4bed77 100644 --- a/test/fmw/gtest/include/gtest/internal/gtest-port.h +++ b/test/fmw/gtest/include/gtest/internal/gtest-port.h @@ -1586,12 +1586,13 @@ class ThreadLocal { GTEST_API_ size_t GetThreadCount(); // Passing non-POD classes through ellipsis (...) crashes the ARM -// compiler and generates a warning in Sun Studio. The Nokia Symbian +// compiler and generates a warning in Sun Studio before 12u4. The Nokia Symbian // and the IBM XL C/C++ compiler try to instantiate a copy constructor // for objects passed through ellipsis (...), failing for uncopyable // objects. We define this to ensure that only POD is passed through // ellipsis on these systems. -#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || \ + (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x5130) // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_ELLIPSIS_NEEDS_POD_ 1 From fadcca5e9a09054ebd506f5d1a2404417d42ce22 Mon Sep 17 00:00:00 2001 From: Jini George Date: Thu, 22 Sep 2016 15:42:40 +0300 Subject: [PATCH 060/207] 8166552: SA: Missed testcase for add default methods to InstanceKlass Add default methods to InstanceKlass to enable SA to inspect default methods Reviewed-by: dsamersoff, iklam --- .../sa/LingeredAppWithDefaultMethods.java | 55 ++++++ .../serviceability/sa/TestDefaultMethods.java | 157 ++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 hotspot/test/serviceability/sa/LingeredAppWithDefaultMethods.java create mode 100644 hotspot/test/serviceability/sa/TestDefaultMethods.java diff --git a/hotspot/test/serviceability/sa/LingeredAppWithDefaultMethods.java b/hotspot/test/serviceability/sa/LingeredAppWithDefaultMethods.java new file mode 100644 index 00000000000..83f45cbf51b --- /dev/null +++ b/hotspot/test/serviceability/sa/LingeredAppWithDefaultMethods.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.apps.LingeredApp; + +interface Language { + static final long nbrOfWords = 99999; + public abstract long getNbrOfWords(); + default boolean hasScript() { + return true; + } +} + +class ParselTongue implements Language { + public long getNbrOfWords() { + return nbrOfWords * 4; + } +} + +class SlytherinSpeak extends ParselTongue { + public boolean hasScript() { + return false; + } +} + +public class LingeredAppWithDefaultMethods extends LingeredApp { + + public static void main(String args[]) { + ParselTongue lang = new ParselTongue(); + SlytherinSpeak slang = new SlytherinSpeak(); + System.out.println(lang.hasScript() || slang.hasScript()); + + LingeredApp.main(args); + } + } diff --git a/hotspot/test/serviceability/sa/TestDefaultMethods.java b/hotspot/test/serviceability/sa/TestDefaultMethods.java new file mode 100644 index 00000000000..cebd833c809 --- /dev/null +++ b/hotspot/test/serviceability/sa/TestDefaultMethods.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; +import java.util.List; + +import sun.jvm.hotspot.HotSpotAgent; +import sun.jvm.hotspot.utilities.SystemDictionaryHelper; +import sun.jvm.hotspot.oops.InstanceKlass; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.oops.Method; +import sun.jvm.hotspot.utilities.MethodArray; + +import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.JDKToolFinder; +import jdk.test.lib.Platform; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Utils; +import jdk.test.lib.Asserts; + +/* + * @test + * @library /test/lib + * @requires os.family != "mac" + * @modules java.base/jdk.internal.misc + * jdk.hotspot.agent/sun.jvm.hotspot + * jdk.hotspot.agent/sun.jvm.hotspot.utilities + * jdk.hotspot.agent/sun.jvm.hotspot.oops + * jdk.hotspot.agent/sun.jvm.hotspot.debugger + * @run main/othervm TestDefaultMethods + */ + +public class TestDefaultMethods { + + private static LingeredAppWithDefaultMethods theApp = null; + + private static void printDefaultMethods(String pid, + String[] instanceKlassNames) { + HotSpotAgent agent = new HotSpotAgent(); + try { + agent.attach(Integer.parseInt(pid)); + } + catch (DebuggerException e) { + System.out.println(e.getMessage()); + System.err.println("Unable to connect to process ID: " + pid); + + agent.detach(); + e.printStackTrace(); + } + + for (String instanceKlassName : instanceKlassNames) { + InstanceKlass iKlass = SystemDictionaryHelper.findInstanceKlass(instanceKlassName); + MethodArray methods = iKlass.getMethods(); + MethodArray defaultMethods = iKlass.getDefaultMethods(); + for (int i = 0; i < methods.length(); i++) { + Method m = methods.at(i); + System.out.println("Method: " + m.getName().asString() + + " in instance klass: " + instanceKlassName); + } + if (defaultMethods != null) { + for (int j = 0; j < defaultMethods.length(); j++) { + Method dm = defaultMethods.at(j); + System.out.println("Default method: " + dm.getName().asString() + + " in instance klass: " + instanceKlassName); + } + } else { + System.out.println("No default methods in " + instanceKlassName); + } + + } + agent.detach(); + } + + private static void createAnotherToAttach( + String[] instanceKlassNames, + long lingeredAppPid) throws Exception { + + String[] toolArgs = { + "--add-modules=jdk.hotspot.agent", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED", + "TestDefaultMethods", + Long.toString(lingeredAppPid) + }; + + // Start a new process to attach to the lingered app + ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(toolArgs); + OutputAnalyzer SAOutput = ProcessTools.executeProcess(processBuilder); + SAOutput.shouldHaveExitValue(0); + System.out.println(SAOutput.getOutput()); + + SAOutput.shouldContain( + "Default method: hasScript in instance klass: " + instanceKlassNames[1]); + SAOutput.shouldContain( + "No default methods in " + instanceKlassNames[0]); + SAOutput.shouldContain( + "Method: hasScript in instance klass: " + instanceKlassNames[0]); + SAOutput.shouldContain( + "No default methods in " + instanceKlassNames[2]); + } + + public static void main (String... args) throws Exception { + + String[] instanceKlassNames = new String[] { + "Language", + "ParselTongue", + "SlytherinSpeak" + }; + + if (!Platform.shouldSAAttach()) { + System.out.println( + "SA attach not expected to work - test skipped."); + return; + } + + if (args == null || args.length == 0) { + try { + List vmArgs = new ArrayList(); + vmArgs.add("-XX:+UsePerfData"); + vmArgs.addAll(Utils.getVmOptions()); + + theApp = new LingeredAppWithDefaultMethods(); + LingeredApp.startApp(vmArgs, theApp); + createAnotherToAttach(instanceKlassNames, + theApp.getPid()); + } finally { + LingeredApp.stopApp(theApp); + } + } else { + printDefaultMethods(args[0], instanceKlassNames); + } + } +} From 200e2392783dba5a080dea0c39617d468e74cfbb Mon Sep 17 00:00:00 2001 From: Andrew Dinn Date: Thu, 22 Sep 2016 09:18:16 -0400 Subject: [PATCH 061/207] 8166433: AArch64: Fix for JDK-8163014 broke AArch64 build Reviewed-by: adinn, coleenp --- hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp index 91e32e94afa..76e0cbeabf8 100644 --- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp @@ -327,7 +327,7 @@ void InterpreterMacroAssembler::push_i(Register r) { void InterpreterMacroAssembler::push_l(Register r) { str(zr, pre(esp, -wordSize)); - str(r, pre(esp, -wordsize)); + str(r, pre(esp, - wordSize)); } void InterpreterMacroAssembler::pop_f(FloatRegister r) { From 362c2a8f6d4124c59eb7b3ac6e830c3109b6da0c Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Thu, 22 Sep 2016 10:24:25 -0700 Subject: [PATCH 062/207] 8166501: compilation error in stackwalk.cpp on some gccs Reviewed-by: coleenp --- hotspot/src/share/vm/prims/stackwalk.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/prims/stackwalk.cpp b/hotspot/src/share/vm/prims/stackwalk.cpp index 6821e6fc1ee..0948e50e8be 100644 --- a/hotspot/src/share/vm/prims/stackwalk.cpp +++ b/hotspot/src/share/vm/prims/stackwalk.cpp @@ -331,10 +331,12 @@ oop StackWalk::walk(Handle stackStream, jlong mode, assert (use_frames_array(mode), "Bad mode for get live frame"); RegisterMap regMap(jt, true); LiveFrameStream stream(jt, ®Map); - return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, CHECK_NULL); + return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, + start_index, frames_array, THREAD); } else { JavaFrameStream stream(jt, mode); - return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, CHECK_NULL); + return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, + start_index, frames_array, THREAD); } } From d2c144fb0f2043058e72498bf7a5830e90962a9b Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Thu, 22 Sep 2016 22:51:51 +0300 Subject: [PATCH 063/207] 8166549: fix incorrectly @ignore-d hotspot/compiler tests Reviewed-by: kvn, kzhaldyb --- .../compiler/codecache/stress/OverloadCompileQueueTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java b/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java index 95899878e81..c831ffc6782 100644 --- a/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java +++ b/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java @@ -29,7 +29,7 @@ * @modules java.base/jdk.internal.misc * java.management * - * @ignore 8071905 + * @ignore 8166554 * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission From 7fa5f5381599b12e2b8921dc507d3bee0cb6fa51 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Fri, 23 Sep 2016 09:14:29 +0300 Subject: [PATCH 064/207] 8165594: Bad rendering of Swing UI controls with Windows Classic L&F on HiDPI display Reviewed-by: serb, ssadetsky --- .../plaf/windows/WindowsIconFactory.java | 156 +++++++++----- .../swing/plaf/basic/BasicArrowButton.java | 42 ++++ .../classes/sun/swing/SwingUtilities2.java | 10 + .../8165594/WindowsClassicHiDPIIconsTest.java | 193 ++++++++++++++++++ 4 files changed, 348 insertions(+), 53 deletions(-) create mode 100644 jdk/test/javax/swing/plaf/windows/8165594/WindowsClassicHiDPIIconsTest.java diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java index 01de04d1dea..3d8b523a238 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java @@ -36,6 +36,7 @@ import static com.sun.java.swing.plaf.windows.TMSchema.*; import static com.sun.java.swing.plaf.windows.XPStyle.Skin; import sun.swing.MenuItemCheckIconFactory; +import sun.swing.SwingUtilities2; /** * Factory object that can vend Icons appropriate for the Windows {@literal L & F}. @@ -400,15 +401,24 @@ public class WindowsIconFactory implements Serializable // paint check if (model.isSelected()) { - g.drawLine(x+9, y+3, x+9, y+3); - g.drawLine(x+8, y+4, x+9, y+4); - g.drawLine(x+7, y+5, x+9, y+5); - g.drawLine(x+6, y+6, x+8, y+6); - g.drawLine(x+3, y+7, x+7, y+7); - g.drawLine(x+4, y+8, x+6, y+8); - g.drawLine(x+5, y+9, x+5, y+9); - g.drawLine(x+3, y+5, x+3, y+5); - g.drawLine(x+3, y+6, x+4, y+6); + if (SwingUtilities2.isScaledGraphics(g)) { + int[] xPoints = {3, 5, 9, 9, 5, 3}; + int[] yPoints = {5, 7, 3, 5, 9, 7}; + g.translate(x, y); + g.fillPolygon(xPoints, yPoints, 6); + g.drawPolygon(xPoints, yPoints, 6); + g.translate(-x, -y); + } else { + g.drawLine(x + 9, y + 3, x + 9, y + 3); + g.drawLine(x + 8, y + 4, x + 9, y + 4); + g.drawLine(x + 7, y + 5, x + 9, y + 5); + g.drawLine(x + 6, y + 6, x + 8, y + 6); + g.drawLine(x + 3, y + 7, x + 7, y + 7); + g.drawLine(x + 4, y + 8, x + 6, y + 8); + g.drawLine(x + 5, y + 9, x + 5, y + 9); + g.drawLine(x + 3, y + 5, x + 3, y + 5); + g.drawLine(x + 3, y + 6, x + 4, y + 6); + } } } } @@ -475,54 +485,94 @@ public class WindowsIconFactory implements Serializable g.fillRect(x+2, y+2, 8, 8); + boolean isScaledGraphics = SwingUtilities2.isScaledGraphics(g); + + if (isScaledGraphics) { + + Graphics2D g2d = (Graphics2D) g; + Stroke oldStroke = g2d.getStroke(); + g2d.setStroke(new BasicStroke(1.03f, BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND)); + Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + // outter left arc - g.setColor(UIManager.getColor("RadioButton.shadow")); - g.drawLine(x+4, y+0, x+7, y+0); - g.drawLine(x+2, y+1, x+3, y+1); - g.drawLine(x+8, y+1, x+9, y+1); - g.drawLine(x+1, y+2, x+1, y+3); - g.drawLine(x+0, y+4, x+0, y+7); - g.drawLine(x+1, y+8, x+1, y+9); + g.setColor(UIManager.getColor("RadioButton.shadow")); + g.drawArc(x, y, 11, 11, 45, 180); + // outter right arc + g.setColor(UIManager.getColor("RadioButton.highlight")); + g.drawArc(x, y, 11, 11, 45, -180); + // inner left arc + g.setColor(UIManager.getColor("RadioButton.darkShadow")); + g.drawArc(x + 1, y + 1, 9, 9, 45, 180); + // inner right arc + g.setColor(UIManager.getColor("RadioButton.light")); + g.drawArc(x + 1, y + 1, 9, 9, 45, -180); - // outter right arc - g.setColor(UIManager.getColor("RadioButton.highlight")); - g.drawLine(x+2, y+10, x+3, y+10); - g.drawLine(x+4, y+11, x+7, y+11); - g.drawLine(x+8, y+10, x+9, y+10); - g.drawLine(x+10, y+9, x+10, y+8); - g.drawLine(x+11, y+7, x+11, y+4); - g.drawLine(x+10, y+3, x+10, y+2); + g2d.setStroke(oldStroke); - - // inner left arc - g.setColor(UIManager.getColor("RadioButton.darkShadow")); - g.drawLine(x+4, y+1, x+7, y+1); - g.drawLine(x+2, y+2, x+3, y+2); - g.drawLine(x+8, y+2, x+9, y+2); - g.drawLine(x+2, y+3, x+2, y+3); - g.drawLine(x+1, y+4, x+1, y+7); - g.drawLine(x+2, y+8, x+2, y+8); - - - // inner right arc - g.setColor(UIManager.getColor("RadioButton.light")); - g.drawLine(x+2, y+9, x+3, y+9); - g.drawLine(x+4, y+10, x+7, y+10); - g.drawLine(x+8, y+9, x+9, y+9); - g.drawLine(x+9, y+8, x+9, y+8); - g.drawLine(x+10, y+7, x+10, y+4); - g.drawLine(x+9, y+3, x+9, y+3); - - - // indicate whether selected or not - if (model.isSelected()) { - if (model.isEnabled()) { - g.setColor(UIManager.getColor("RadioButton.foreground")); - } else { - g.setColor(UIManager.getColor("RadioButton.shadow")); + if (model.isSelected()) { + if (model.isEnabled()) { + g.setColor(UIManager.getColor("RadioButton.foreground")); + } else { + g.setColor(UIManager.getColor("RadioButton.shadow")); + } + g.fillOval(x + 3, y + 3, 5, 5); + } + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); + + } else { + + // outter left arc + g.setColor(UIManager.getColor("RadioButton.shadow")); + g.drawLine(x+4, y+0, x+7, y+0); + g.drawLine(x+2, y+1, x+3, y+1); + g.drawLine(x+8, y+1, x+9, y+1); + g.drawLine(x+1, y+2, x+1, y+3); + g.drawLine(x+0, y+4, x+0, y+7); + g.drawLine(x+1, y+8, x+1, y+9); + + // outter right arc + g.setColor(UIManager.getColor("RadioButton.highlight")); + g.drawLine(x+2, y+10, x+3, y+10); + g.drawLine(x+4, y+11, x+7, y+11); + g.drawLine(x+8, y+10, x+9, y+10); + g.drawLine(x+10, y+9, x+10, y+8); + g.drawLine(x+11, y+7, x+11, y+4); + g.drawLine(x+10, y+3, x+10, y+2); + + + // inner left arc + g.setColor(UIManager.getColor("RadioButton.darkShadow")); + g.drawLine(x+4, y+1, x+7, y+1); + g.drawLine(x+2, y+2, x+3, y+2); + g.drawLine(x+8, y+2, x+9, y+2); + g.drawLine(x+2, y+3, x+2, y+3); + g.drawLine(x+1, y+4, x+1, y+7); + g.drawLine(x+2, y+8, x+2, y+8); + + + // inner right arc + g.setColor(UIManager.getColor("RadioButton.light")); + g.drawLine(x+2, y+9, x+3, y+9); + g.drawLine(x+4, y+10, x+7, y+10); + g.drawLine(x+8, y+9, x+9, y+9); + g.drawLine(x+9, y+8, x+9, y+8); + g.drawLine(x+10, y+7, x+10, y+4); + g.drawLine(x+9, y+3, x+9, y+3); + + + // indicate whether selected or not + if (model.isSelected()) { + if (model.isEnabled()) { + g.setColor(UIManager.getColor("RadioButton.foreground")); + } else { + g.setColor(UIManager.getColor("RadioButton.shadow")); + } + g.fillRect(x+4, y+5, 4, 2); + g.fillRect(x+5, y+4, 2, 4); } - g.fillRect(x+4, y+5, 4, 2); - g.fillRect(x+5, y+4, 2, 4); } } } diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicArrowButton.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicArrowButton.java index ef06703baa8..33f155a3bd2 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicArrowButton.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicArrowButton.java @@ -27,9 +27,13 @@ package javax.swing.plaf.basic; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; import javax.swing.*; import javax.swing.plaf.UIResource; +import sun.swing.SwingUtilities2; /** * JButton object that draws a scaled Arrow in one of the cardinal directions. @@ -236,6 +240,16 @@ public class BasicArrowButton extends JButton implements SwingConstants */ public void paintTriangle(Graphics g, int x, int y, int size, int direction, boolean isEnabled) { + if (SwingUtilities2.isScaledGraphics(g)) { + paintScaledTriangle(g, x, y, size, direction, isEnabled); + } else { + paintUnscaledTriangle(g, x, y, size, direction, isEnabled); + } + } + + private void paintUnscaledTriangle(Graphics g, int x, int y, int size, + int direction, boolean isEnabled) + { Color oldColor = g.getColor(); int mid, i, j; @@ -309,4 +323,32 @@ public class BasicArrowButton extends JButton implements SwingConstants g.setColor(oldColor); } + private void paintScaledTriangle(Graphics g, double x, double y, double size, + int direction, boolean isEnabled) { + size = Math.max(size, 2); + Path2D.Double path = new Path2D.Double(); + path.moveTo(-size, size / 2); + path.lineTo(size, size / 2); + path.lineTo(0, -size / 2); + path.closePath(); + AffineTransform affineTransform = new AffineTransform(); + affineTransform.rotate(Math.PI * (direction - 1) / 4); + path.transform(affineTransform); + + Graphics2D g2d = (Graphics2D) g; + double tx = x + size / 2; + double ty = y + size / 2; + g2d.translate(tx, ty); + Color oldColor = g.getColor(); + if (!isEnabled) { + g2d.translate(1, 0); + g2d.setColor(highlight); + g2d.fill(path); + g2d.translate(-1, 0); + } + g2d.setColor(isEnabled ? darkShadow : shadow); + g2d.fill(path); + g2d.translate(-tx, -ty); + g2d.setColor(oldColor); + } } diff --git a/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java b/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java index 6f4c5f7045b..5119ab7a18d 100644 --- a/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java +++ b/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java @@ -31,6 +31,8 @@ import static java.awt.RenderingHints.*; import java.awt.event.*; import java.awt.font.*; import java.awt.geom.AffineTransform; +import static java.awt.geom.AffineTransform.TYPE_FLIP; +import static java.awt.geom.AffineTransform.TYPE_TRANSLATION; import java.awt.print.PrinterGraphics; import java.text.BreakIterator; import java.text.CharacterIterator; @@ -2036,6 +2038,14 @@ public class SwingUtilities2 { return path; } + public static boolean isScaledGraphics(Graphics g) { + if (g instanceof Graphics2D) { + AffineTransform tx = ((Graphics2D) g).getTransform(); + return (tx.getType() & ~(TYPE_TRANSLATION | TYPE_FLIP)) != 0; + } + return false; + } + /** * Used to listen to "blit" repaints in RepaintManager. */ diff --git a/jdk/test/javax/swing/plaf/windows/8165594/WindowsClassicHiDPIIconsTest.java b/jdk/test/javax/swing/plaf/windows/8165594/WindowsClassicHiDPIIconsTest.java new file mode 100644 index 00000000000..db4fb00b24d --- /dev/null +++ b/jdk/test/javax/swing/plaf/windows/8165594/WindowsClassicHiDPIIconsTest.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 8165594 + * @key headful + * @requires (os.family == "windows") + * @summary Bad rendering of Swing UI controls with Windows Classic L&F on HiDPI + * display + * @run main/manual/othervm -Dsun.java2d.uiScale=2 + * -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel + * WindowsClassicHiDPIIconsTest + */ + +public class WindowsClassicHiDPIIconsTest { + + private static volatile boolean testResult = false; + private static volatile CountDownLatch countDownLatch; + private static final String INSTRUCTIONS = "INSTRUCTIONS:\n" + + "Check that the icons are painted smoothly on Swing UI controls:\n" + + " - JRadioButton\n" + + " - JCheckBox\n" + + " - JComboBox\n" + + " - JScrollPane (vertical and horizontal scroll bars)\n" + + "\n" + + "If so, press PASS, else press FAIL.\n"; + + public static void main(String args[]) throws Exception { + countDownLatch = new CountDownLatch(1); + + SwingUtilities.invokeLater(WindowsClassicHiDPIIconsTest::createUI); + countDownLatch.await(15, TimeUnit.MINUTES); + + if (!testResult) { + throw new RuntimeException("Test fails!"); + } + } + + private static void createUI() { + + final JFrame mainFrame = new JFrame("Windows Classic L&F icons test"); + GridBagLayout layout = new GridBagLayout(); + JPanel mainControlPanel = new JPanel(layout); + JPanel resultButtonPanel = new JPanel(layout); + + GridBagConstraints gbc = new GridBagConstraints(); + + + JPanel testPanel = createJPanel(); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.HORIZONTAL; + mainControlPanel.add(testPanel, gbc); + + JTextArea instructionTextArea = new JTextArea(); + instructionTextArea.setText(INSTRUCTIONS); + instructionTextArea.setEditable(false); + instructionTextArea.setBackground(Color.white); + + gbc.gridx = 0; + gbc.gridy = 1; + gbc.fill = GridBagConstraints.HORIZONTAL; + mainControlPanel.add(instructionTextArea, gbc); + + JButton passButton = new JButton("Pass"); + passButton.setActionCommand("Pass"); + passButton.addActionListener((ActionEvent e) -> { + testResult = true; + mainFrame.dispose(); + countDownLatch.countDown(); + + }); + + JButton failButton = new JButton("Fail"); + failButton.setActionCommand("Fail"); + failButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mainFrame.dispose(); + countDownLatch.countDown(); + } + }); + + gbc.gridx = 0; + gbc.gridy = 0; + resultButtonPanel.add(passButton, gbc); + + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 2; + mainControlPanel.add(resultButtonPanel, gbc); + + mainFrame.add(mainControlPanel); + mainFrame.pack(); + + mainFrame.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + mainFrame.dispose(); + countDownLatch.countDown(); + } + }); + mainFrame.setVisible(true); + } + + private static JPanel createJPanel() { + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + + JPanel iconPanel = new JPanel(new FlowLayout()); + JRadioButton radioButton = new JRadioButton(); + radioButton.setSelected(false); + iconPanel.add(radioButton); + radioButton = new JRadioButton(); + radioButton.setSelected(true); + iconPanel.add(radioButton); + panel.add(iconPanel); + + iconPanel = new JPanel(new FlowLayout()); + JCheckBox checkBox = new JCheckBox(); + checkBox.setSelected(false); + iconPanel.add(checkBox); + checkBox = new JCheckBox(); + checkBox.setSelected(true); + iconPanel.add(checkBox); + panel.add(iconPanel); + + iconPanel = new JPanel(new FlowLayout()); + JComboBox comboBox = new JComboBox(new String[]{"111", "222"}); + iconPanel.add(comboBox); + panel.add(iconPanel); + + iconPanel = new JPanel(new FlowLayout()); + JTextArea textArea = new JTextArea(3, 7); + textArea.setText("AAA"); + JScrollPane scrollPane = new JScrollPane(textArea); + scrollPane.setHorizontalScrollBarPolicy( + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); + scrollPane.setVerticalScrollBarPolicy( + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + iconPanel.add(scrollPane); + panel.add(iconPanel); + + return panel; + } +} From 0ee1f71b81b80bd61811ee3613ee043e06315ca2 Mon Sep 17 00:00:00 2001 From: Semyon Sadetsky Date: Fri, 23 Sep 2016 10:36:32 +0300 Subject: [PATCH 065/207] 8161910: [PIT] regression: HW/LW mixing seems broken on Unity Reviewed-by: azvegint --- .../unix/classes/sun/awt/X11/XDecoratedPeer.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java index 66fc0272279..a3f2ae535ca 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java @@ -325,7 +325,8 @@ abstract class XDecoratedPeer extends XWindowPeer { if (!isEmbedded() && !isTargetUndecorated()) { lastKnownInsets.put(getClass(), in); } - if (!in.equals(dimensions.getInsets())) { + if (!in.equals(dimensions.getInsets()) || + !dimensions.isClientSizeSet()) { handleCorrectInsets(in); } insets_corrected = true; @@ -374,6 +375,9 @@ abstract class XDecoratedPeer extends XWindowPeer { } else { /* reparented to WM frame, figure out our insets */ setReparented(true); insets_corrected = false; + if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM) { + return; + } // Check if we have insets provided by the WM Insets correctWM = getWMSetInsets(null); @@ -405,7 +409,7 @@ abstract class XDecoratedPeer extends XWindowPeer { } } - if (correctWM != null && XWM.getWMID() != XWM.UNITY_COMPIZ_WM) { + if (correctWM != null) { handleCorrectInsets(correctWM); } } From ec6f109b23d5c3680a3ca50f6c36dda4d30ec255 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Sun, 25 Sep 2016 02:55:18 +0300 Subject: [PATCH 066/207] 8166288: Au file format can be validated better Reviewed-by: amenkov --- .../com/sun/media/sound/AuFileReader.java | 19 +++++- .../com/sun/media/sound/SunFileReader.java | 6 +- .../AudioFileReader/ReadersExceptions.java | 59 +++++++++++++++++-- .../AudioFileReader/RepeatedFormatReader.java | 4 +- 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java index 097b64b4746..8ca5e796f04 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java @@ -44,7 +44,7 @@ import javax.sound.sampled.UnsupportedAudioFileException; public final class AuFileReader extends SunFileReader { @Override - public StandardFileFormat getAudioFileFormatImpl(final InputStream stream) + StandardFileFormat getAudioFileFormatImpl(final InputStream stream) throws UnsupportedAudioFileException, IOException { final DataInputStream dis = new DataInputStream(stream); final int magic = dis.readInt(); @@ -55,9 +55,15 @@ public final class AuFileReader extends SunFileReader { } final int headerSize = dis.readInt(); + if (headerSize < AuFileFormat.AU_HEADERSIZE) { + throw new UnsupportedAudioFileException("Invalid header size"); + } final long /* unsigned int */ dataSize = dis.readInt() & 0xffffffffL; final int auType = dis.readInt(); final int sampleRate = dis.readInt(); + if (sampleRate <= 0) { + throw new UnsupportedAudioFileException("Invalid sample rate"); + } final int channels = dis.readInt(); if (channels <= 0) { throw new UnsupportedAudioFileException("Invalid number of channels"); @@ -119,10 +125,19 @@ public final class AuFileReader extends SunFileReader { // unsupported filetype, throw exception throw new UnsupportedAudioFileException("not a valid AU file"); } - // now seek past the header + + // Skip the variable-length annotation field. The content of this field + // is currently undefined by AU specification and is unsupported by + // JavaSound, so seek past the header dis.skipBytes(headerSize - AuFileFormat.AU_HEADERSIZE); + // Even if the sampleSizeInBits and channels are supported we can get an + // unsupported frameSize because of overflow final int frameSize = calculatePCMFrameSize(sampleSizeInBits, channels); + if (frameSize <= 0) { + throw new UnsupportedAudioFileException("Invalid frame size"); + } + //$$fb 2002-11-02: fix for 4629669: AU file reader: problems with empty files //$$fb 2003-10-20: fix for 4940459: AudioInputStream.getFrameLength() returns 0 instead of NOT_SPECIFIED long frameLength = AudioSystem.NOT_SPECIFIED; diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunFileReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunFileReader.java index 01307d59514..7553353153a 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunFileReader.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunFileReader.java @@ -252,6 +252,10 @@ abstract class SunFileReader extends AudioFileReader { * @return the size of a PCM frame in bytes. */ static final int calculatePCMFrameSize(int sampleSizeInBits, int channels) { - return ((sampleSizeInBits + 7) / 8) * channels; + try { + return Math.multiplyExact((sampleSizeInBits + 7) / 8, channels); + } catch (final ArithmeticException ignored) { + return 0; + } } } diff --git a/jdk/test/javax/sound/sampled/spi/AudioFileReader/ReadersExceptions.java b/jdk/test/javax/sound/sampled/spi/AudioFileReader/ReadersExceptions.java index 604c703423a..39bd757cd77 100644 --- a/jdk/test/javax/sound/sampled/spi/AudioFileReader/ReadersExceptions.java +++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/ReadersExceptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,11 +74,56 @@ public final class ReadersExceptions { // empty channels static byte[] wrongAUCh = {0x2e, 0x73, 0x6e, 0x64,//AiffFileFormat.AU_SUN_MAGIC - 0, 0, 0, 0, // headerSize + 0, 0, 0, 24, // headerSize + 0, 0, 0, 0, // dataSize + 0, 0, 0, 1, // encoding_local AuFileFormat.AU_ULAW_8 + 0, 0, 0, 1, // sampleRate + 0, 0, 0, 0 // channels + }; + // empty sample rate + static byte[] wrongAUSR = + {0x2e, 0x73, 0x6e, 0x64,//AiffFileFormat.AU_SUN_MAGIC + 0, 0, 0, 24, // headerSize 0, 0, 0, 0, // dataSize 0, 0, 0, 1, // encoding_local AuFileFormat.AU_ULAW_8 0, 0, 0, 0, // sampleRate - 0, 0, 0, 0 // channels + 0, 0, 0, 1 // channels + }; + // empty header size + static byte[] wrongAUEmptyHeader = + {0x2e, 0x73, 0x6e, 0x64,//AiffFileFormat.AU_SUN_MAGIC + 0, 0, 0, 0, // headerSize + 0, 0, 0, 0, // dataSize + 0, 0, 0, 1, // encoding_local AuFileFormat.AU_ULAW_8 + 0, 0, 0, 1, // sampleRate + 0, 0, 0, 1 // channels + }; + // small header size + static byte[] wrongAUSmallHeader = + {0x2e, 0x73, 0x6e, 0x64,//AiffFileFormat.AU_SUN_MAGIC + 0, 0, 0, 7, // headerSize + 0, 0, 0, 0, // dataSize + 0, 0, 0, 1, // encoding_local AuFileFormat.AU_ULAW_8 + 0, 0, 0, 1, // sampleRate + 0, 0, 0, 1 // channels + }; + // frame size overflow, when result negative + static byte[] wrongAUFrameSizeOverflowNegativeResult = + {0x2e, 0x73, 0x6e, 0x64,//AiffFileFormat.AU_SUN_MAGIC + 0, 0, 0, 24, // headerSize + 0, 0, 0, 0, // dataSize + 0, 0, 0, 5, // encoding_local AuFileFormat.AU_LINEAR_32 + 0, 0, 0, 1, // sampleRate + 0x7F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF // channels + }; + // frame size overflow, when result positive + static byte[] wrongAUFrameSizeOverflowPositiveResult = + {0x2e, 0x73, 0x6e, 0x64,//AiffFileFormat.AU_SUN_MAGIC + 0, 0, 0, 24, // headerSize + 0, 0, 0, 0, // dataSize + 0, 0, 0, 4, // encoding_local AuFileFormat.AU_LINEAR_24 + 0, 0, 0, 1, // sampleRate + 0x7F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF // channels }; // empty channels static byte[] wrongWAVCh = @@ -113,8 +158,12 @@ public final class ReadersExceptions { 0, 0, 0, 0, // dataLength }; - static byte[][] data = {wrongAIFFCh, wrongAIFFSSL, wrongAIFFSSH, wrongAUCh, - wrongWAVCh, wrongWAVSSB}; + static byte[][] data = { + wrongAIFFCh, wrongAIFFSSL, wrongAIFFSSH, wrongAUCh, wrongAUSR, + wrongAUEmptyHeader, wrongAUSmallHeader, + wrongAUFrameSizeOverflowNegativeResult, + wrongAUFrameSizeOverflowPositiveResult, wrongWAVCh, wrongWAVSSB + }; public static void main(final String[] args) throws IOException { for (final byte[] bytes : data) { diff --git a/jdk/test/javax/sound/sampled/spi/AudioFileReader/RepeatedFormatReader.java b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RepeatedFormatReader.java index 2ac37e8490d..f349c8a1ba1 100644 --- a/jdk/test/javax/sound/sampled/spi/AudioFileReader/RepeatedFormatReader.java +++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RepeatedFormatReader.java @@ -45,10 +45,10 @@ public final class RepeatedFormatReader { }; private static byte[] headerAU = {0x2e, 0x73, 0x6e, 0x64, // AU_SUN_MAGIC - 0, 0, 0, 0, // headerSize + 0, 0, 0, 24, // headerSize 0, 0, 0, 0, // dataSize 0, 0, 0, 1, // encoding - 0, 0, 0, 0, // sampleRate + 0, 0, 0, 1, // sampleRate 0, 0, 0, 1 // channels }; From fa280894b374641031358d38819067a4c1efc4a8 Mon Sep 17 00:00:00 2001 From: Rajeev Chamyal Date: Mon, 26 Sep 2016 12:33:40 +0530 Subject: [PATCH 067/207] 8149371: multi-res. image: -Dsun.java2d.uiScale does not work for Window icons (some ambiguity for Window.setIconImages()?) Reviewed-by: serb, alexsch --- .../share/classes/java/awt/Window.java | 4 + .../share/classes/sun/awt/SunToolkit.java | 12 +- .../classes/sun/awt/windows/WWindowPeer.java | 7 +- .../native/libawt/windows/awt_Window.cpp | 50 ++++- .../MultiResolutionIcon/MultiResIconTest.java | 198 ++++++++++++++++++ 5 files changed, 263 insertions(+), 8 deletions(-) create mode 100644 jdk/test/java/awt/image/multiresolution/MultiResolutionIcon/MultiResIconTest.java diff --git a/jdk/src/java.desktop/share/classes/java/awt/Window.java b/jdk/src/java.desktop/share/classes/java/awt/Window.java index 71fc98009b3..ed7d63ae154 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Window.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Window.java @@ -678,6 +678,10 @@ public class Window extends Container implements Accessible { * Depending on the platform capabilities one or several images * of different dimensions will be used as the window's icon. *

+ * The {@code icons} list can contain {@code MultiResolutionImage} images also. + * Suitable image depending on screen resolution is extracted from + * base {@code MultiResolutionImage} image and added to the icons list + * while base resolution image is removed from list. * The {@code icons} list is scanned for the images of most * appropriate dimensions from the beginning. If the list contains * several images of the same size, the first will be used. diff --git a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java index c017454ec0f..054c3edf825 100644 --- a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -46,6 +46,7 @@ import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.security.AccessController; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.Locale; @@ -887,12 +888,21 @@ public abstract class SunToolkit extends Toolkit if (width == 0 || height == 0) { return null; } + java.util.List multiResAndnormalImages = new ArrayList<>(imageList.size()); + for (Image image : imageList) { + if ((image instanceof MultiResolutionImage)) { + Image im = ((MultiResolutionImage) image).getResolutionVariant(width, height); + multiResAndnormalImages.add(im); + } else { + multiResAndnormalImages.add(image); + } + } Image bestImage = null; int bestWidth = 0; int bestHeight = 0; double bestSimilarity = 3; //Impossibly high value double bestScaleFactor = 0; - for (Iterator i = imageList.iterator();i.hasNext();) { + for (Iterator i = multiResAndnormalImages.iterator();i.hasNext();) { //Iterate imageList looking for best matching image. //'Similarity' measure is defined as good scale factor and small insets. //best possible similarity is 0 (no scale, no insets). diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java index a776c741174..3aaca2b033c 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java @@ -34,7 +34,7 @@ import java.beans.*; import java.util.*; import java.util.List; import sun.util.logging.PlatformLogger; - +import java.awt.geom.AffineTransform; import sun.awt.*; import sun.java2d.pipe.Region; @@ -391,6 +391,11 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, int h = getSysIconHeight(); int smw = getSysSmIconWidth(); int smh = getSysSmIconHeight(); + AffineTransform tx = getGraphicsConfiguration().getDefaultTransform(); + w = Region.clipScale(w, tx.getScaleX()); + h = Region.clipScale(h, tx.getScaleY()); + smw = Region.clipScale(smw, tx.getScaleX()); + smh = Region.clipScale(smh, tx.getScaleY()); DataBufferInt iconData = SunToolkit.getScaledIconData(imageList, w, h); DataBufferInt iconSmData = SunToolkit.getScaledIconData(imageList, diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp index 6ca1641655d..36501fdf0fd 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp @@ -46,11 +46,16 @@ #include "sun_awt_windows_WCanvasPeer.h" #include - +#include #if !defined(__int3264) typedef __int32 LONG_PTR; #endif // __int3264 +#if defined(_MSC_VER) && _MSC_VER >= 1800 +# define ROUND_TO_INT(num) ((int) round(num)) +#else +# define ROUND_TO_INT(num) ((int) floor((num) + 0.5)) +#endif // Used for Swing's Menu/Tooltip animation Support const int UNSPECIFIED = 0; const int TOOLTIP = 1; @@ -3097,7 +3102,7 @@ void AwtWindow::_GetNativeWindowSize(void* param) { env->DeleteGlobalRef(self); } - +extern "C" int getSystemMetricValue(int msgType); extern "C" { /* @@ -3407,7 +3412,7 @@ Java_sun_awt_windows_WWindowPeer_getSysIconHeight(JNIEnv *env, jclass self) { TRY; - return ::GetSystemMetrics(SM_CYICON); + return getSystemMetricValue(SM_CYICON); CATCH_BAD_ALLOC_RET(0); } @@ -3422,7 +3427,7 @@ Java_sun_awt_windows_WWindowPeer_getSysIconWidth(JNIEnv *env, jclass self) { TRY; - return ::GetSystemMetrics(SM_CXICON); + return getSystemMetricValue(SM_CXICON); CATCH_BAD_ALLOC_RET(0); } @@ -3437,7 +3442,7 @@ Java_sun_awt_windows_WWindowPeer_getSysSmIconHeight(JNIEnv *env, jclass self) { TRY; - return ::GetSystemMetrics(SM_CYSMICON); + return getSystemMetricValue(SM_CYSMICON); CATCH_BAD_ALLOC_RET(0); } @@ -3452,11 +3457,44 @@ Java_sun_awt_windows_WWindowPeer_getSysSmIconWidth(JNIEnv *env, jclass self) { TRY; - return ::GetSystemMetrics(SM_CXSMICON); + return getSystemMetricValue(SM_CXSMICON); CATCH_BAD_ALLOC_RET(0); } +int getSystemMetricValue(int msgType) { + int value = 1; + int logPixels = LOGPIXELSX; + switch (msgType) { + case SM_CXICON: + value = ::GetSystemMetrics(SM_CXICON); + break; + case SM_CYICON: + value = ::GetSystemMetrics(SM_CYICON); + logPixels = LOGPIXELSY; + break; + case SM_CXSMICON: + value = ::GetSystemMetrics(SM_CXSMICON); + break; + case SM_CYSMICON: + value = ::GetSystemMetrics(SM_CYSMICON); + logPixels = LOGPIXELSY; + break; + } + static int dpi = -1; + if (dpi == -1) { + HWND hWnd = ::GetDesktopWindow(); + HDC hDC = ::GetDC(hWnd); + dpi = GetDeviceCaps(hDC, logPixels); + ::ReleaseDC(hWnd, hDC); + } + if(dpi != 0 && dpi != 96) { + float invScaleX = 96.0f / dpi; + value = (int) ROUND_TO_INT(value * invScaleX); + } + return value; +} + /* * Class: sun_awt_windows_WWindowPeer * Method: setIconImagesData diff --git a/jdk/test/java/awt/image/multiresolution/MultiResolutionIcon/MultiResIconTest.java b/jdk/test/java/awt/image/multiresolution/MultiResolutionIcon/MultiResIconTest.java new file mode 100644 index 00000000000..f2486a13b27 --- /dev/null +++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionIcon/MultiResIconTest.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @key headful + * @bug 8149371 + * @summary multi-res. image: -Dsun.java2d.uiScale does not work for Window + * icons (some ambiguity for Window.setIconImages()?) + * @run main/othervm/manual -Dsun.java2d.uiScale=2 MultiResIconTest + */ +import java.awt.Color; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BaseMultiResolutionImage; +import java.awt.image.BufferedImage; +import java.util.concurrent.CountDownLatch; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +public class MultiResIconTest { + + private static GridBagLayout layout; + private static JPanel mainControlPanel; + private static JPanel resultButtonPanel; + private static JLabel instructionText; + private static JButton passButton; + private static JButton failButton; + private static JDialog f; + private static CountDownLatch latch; + private static TestFrame frame; + + private static BufferedImage generateImage(int x, Color c) { + + BufferedImage img = new BufferedImage(x, x, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + g.setColor(c); + g.fillRect(0, 0, x, x); + g.setColor(Color.WHITE); + g.fillRect(x / 3, x / 3, x / 3, x / 3); + return img; + } + + public MultiResIconTest() { + try { + latch = new CountDownLatch(1); + createUI(); + latch.await(); + } catch (Exception ex) { + } + } + + private static void createUI() throws Exception { + SwingUtilities.invokeAndWait(() -> { + frame = new TestFrame(); + f = new JDialog(frame); + f.setTitle("Instruction Dialog"); + layout = new GridBagLayout(); + mainControlPanel = new JPanel(layout); + resultButtonPanel = new JPanel(layout); + GridBagConstraints gbc = new GridBagConstraints(); + String instructions + = " INSTRUCTIONS:

" + + "1) Test frame title icon and frame color should be green." + + "
" + + "2) Test frame task bar icon should be blue
" + + "3) If color are same as mentioned in 1 and 2 press pass
" + + " else press fail.

"; + + instructionText = new JLabel(); + instructionText.setText(instructions); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.HORIZONTAL; + mainControlPanel.add(instructionText, gbc); + passButton = new JButton("Pass"); + passButton.setActionCommand("Pass"); + passButton.addActionListener((ActionEvent e) -> { + latch.countDown(); + f.dispose(); + frame.dispose(); + }); + failButton = new JButton("Fail"); + failButton.setActionCommand("Fail"); + failButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + latch.countDown(); + f.dispose(); + frame.dispose(); + throw new RuntimeException("Test Failed"); + } + }); + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(passButton, gbc); + gbc.gridx = 2; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 1; + mainControlPanel.add(resultButtonPanel, gbc); + + f.add(mainControlPanel); + f.setSize(400, 200); + f.setLocationRelativeTo(null); + f.setVisible(true); + + f.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + latch.countDown(); + f.dispose(); + frame.dispose(); + } + }); + }); + } + + private static class TestFrame extends JFrame { + + private static final int W = 200; + + private static final BaseMultiResolutionImage IMG + = new BaseMultiResolutionImage( + new BufferedImage[]{generateImage(W, Color.RED), + generateImage(2 * W, Color.GREEN), + generateImage(4 * W, Color.BLUE)}); + + private static final BaseMultiResolutionImage ICON + = new BaseMultiResolutionImage( + new BufferedImage[]{generateImage(16, Color.RED), + generateImage(32, Color.GREEN), + generateImage(64, Color.BLUE), + generateImage(128, Color.BLACK), + generateImage(256, Color.GRAY)}); + + public TestFrame() { + createUI(); + } + + private void createUI() { + setTitle("Test Frame"); + setIconImage(ICON); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + dispose(); + } + }); + setSize(W, W); + setLocation(50, 50); + setResizable(false); + setVisible(true); + } + + @Override + public void paint(Graphics gr) { + gr.drawImage(IMG, 0, 0, this); + } + } + + public static void main(String[] args) { + new MultiResIconTest(); + } +} + From 8d81ec63b2bafc431cbb8572a3e45e76580ab46f Mon Sep 17 00:00:00 2001 From: Semyon Sadetsky Date: Mon, 26 Sep 2016 11:59:46 +0300 Subject: [PATCH 068/207] 8154043: Fields not reachable anymore by tab-key, because of new tabbing behaviour of radio button groups Reviewed-by: alexsch --- .../swing/LayoutFocusTraversalPolicy.java | 29 +++- .../swing/plaf/basic/BasicRadioButtonUI.java | 18 +- .../ButtonGroupLayoutTraversalTest.java | 158 ++++++++++++++++++ .../JRadioButton/8033699/bug8033699.java | 48 +++--- 4 files changed, 212 insertions(+), 41 deletions(-) create mode 100644 jdk/test/java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayoutTraversalTest.java diff --git a/jdk/src/java.desktop/share/classes/javax/swing/LayoutFocusTraversalPolicy.java b/jdk/src/java.desktop/share/classes/javax/swing/LayoutFocusTraversalPolicy.java index 3a635a5423a..c976af640ee 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/LayoutFocusTraversalPolicy.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/LayoutFocusTraversalPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,9 @@ package javax.swing; import java.awt.Component; import java.awt.Container; -import java.awt.ComponentOrientation; import java.util.Comparator; import java.io.*; +import java.util.Enumeration; import sun.awt.SunToolkit; @@ -236,6 +236,31 @@ public class LayoutFocusTraversalPolicy extends SortingFocusTraversalPolicy JComboBox box = (JComboBox)aComponent; return box.getUI().isFocusTraversable(box); } else if (aComponent instanceof JComponent) { + if (SunToolkit.isInstanceOf(aComponent, + "javax.swing.JToggleButton")) { + JToggleButton.ToggleButtonModel model = + (JToggleButton.ToggleButtonModel) ((JToggleButton) + aComponent).getModel(); + if (model != null) { + ButtonGroup group = model.getGroup(); + if (group != null) { + Enumeration elements = + group.getElements(); + int idx = 0; + while (elements.hasMoreElements()) { + AbstractButton member = elements.nextElement(); + if (member.isVisible() && member.isDisplayable() && + member.isEnabled() && member.isFocusable()) { + if (member == aComponent) { + return idx == 0; + } + idx++; + } + } + } + } + } + JComponent jComponent = (JComponent)aComponent; InputMap inputMap = jComponent.getInputMap(JComponent.WHEN_FOCUSED, false); diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java index 83e5e7af614..03ed97d1a4f 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -438,21 +438,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI // Check if the next object to gain focus belongs // to the button group or not Component getFocusTransferBaseComponent(boolean next){ - Component focusBaseComp = activeBtn; - Container container = focusBaseComp.getFocusCycleRootAncestor(); - if (container != null) { - FocusTraversalPolicy policy = container.getFocusTraversalPolicy(); - Component comp = next ? policy.getComponentAfter(container, activeBtn) - : policy.getComponentBefore(container, activeBtn); - - // If next component in the button group, use last/first button as base focus - // otherwise, use the activeBtn as the base focus - if (containsInGroup(comp)) { - focusBaseComp = next ? lastBtn : firstBtn; - } - } - - return focusBaseComp; + return firstBtn; } boolean getButtonGroupInfo() { diff --git a/jdk/test/java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayoutTraversalTest.java b/jdk/test/java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayoutTraversalTest.java new file mode 100644 index 00000000000..faabfce401c --- /dev/null +++ b/jdk/test/java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayoutTraversalTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8154043 + @summary Fields not reachable anymore by tab-key, because of new tabbing + behaviour of radio button groups. + @run main ButtonGroupLayoutTraversalTest +*/ + +import javax.swing.*; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; + +public class ButtonGroupLayoutTraversalTest { + static int nx = 3; + static int ny = 3; + + static int focusCnt[] = new int[nx * ny]; + private static JFrame window; + + + public static void main(String[] args) throws Exception { + + SwingUtilities.invokeAndWait(()->initLayout(nx, ny)); + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(200); + + + for(int i = 0; i < nx * ny - nx * ny / 2 - 1; i++) { + robot.keyPress(KeyEvent.VK_RIGHT); + robot.keyRelease(KeyEvent.VK_RIGHT); + } + + for(int i = 0; i < nx * ny / 2; i++) { + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + } + + robot.waitForIdle(); + robot.delay(200); + + for(int i = 0; i < nx * ny; i++) { + if(focusCnt[i] < 1) { + SwingUtilities.invokeLater(window::dispose); + throw new RuntimeException("Component " + i + + " is not reachable in the forward focus cycle"); + } else if (focusCnt[i] > 1) { + SwingUtilities.invokeLater(window::dispose); + throw new RuntimeException("Component " + i + + " got focus more than once in the forward focus cycle"); + } + } + + for(int i = 0; i < nx * ny / 2; i++) { + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_SHIFT); + } + + for(int i = 0; i < nx * ny - nx * ny / 2 - 1; i++) { + robot.keyPress(KeyEvent.VK_LEFT); + robot.keyRelease(KeyEvent.VK_LEFT); + } + + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_SHIFT); + + robot.waitForIdle(); + robot.delay(200); + + for(int i = 0; i < nx * ny; i++) { + if(focusCnt[i] < 2) { + SwingUtilities.invokeLater(window::dispose); + throw new RuntimeException("Component " + i + + " is not reachable in the backward focus cycle"); + } else if (focusCnt[i] > 2) { + SwingUtilities.invokeLater(window::dispose); + throw new RuntimeException("Component " + i + + " got focus more than once in the backward focus cycle"); + } + } + + SwingUtilities.invokeLater(window::dispose); + } + + public static void initLayout(int nx, int ny) + { + window = new JFrame("Test"); + window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + JPanel rootPanel = new JPanel(); + rootPanel.setLayout(new BorderLayout()); + JPanel formPanel = new JPanel(new GridLayout(nx, ny)); + formPanel.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); + formPanel.setFocusCycleRoot(true); + ButtonGroup radioButtonGroup = new ButtonGroup(); + for(int i = 0; i < nx * ny; i++) { + JToggleButton comp; + if(i % 2 == 0) { + comp = new JRadioButton("Grouped component"); + radioButtonGroup.add(comp); + } else { + comp = new JRadioButton("Single component"); + } + formPanel.add(comp); + int fi = i; + comp.setBackground(Color.red); + comp.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + focusCnt[fi]++; + if( focusCnt[fi] == 1) { + ((JComponent) e.getSource()) + .setBackground(Color.yellow); + } else if(focusCnt[fi] == 2) { + ((JComponent) e.getSource()) + .setBackground(Color.green); + } else { + ((JComponent) e.getSource()) + .setBackground(Color.red); + } + } + }); + } + rootPanel.add(formPanel, BorderLayout.CENTER); + window.add(rootPanel); + window.pack(); + window.setVisible(true); + } +} diff --git a/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java b/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java index 681bb925290..4b95dc92bb3 100644 --- a/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java +++ b/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ * @key headful * @library ../../regtesthelpers * @build Util - * @bug 8033699 + * @bug 8033699 8154043 * @summary Incorrect radio button behavior when pressing tab key * @author Vivi An * @run main bug8033699 @@ -135,6 +135,7 @@ public class bug8033699 { private static void runTest1() throws Exception{ hitKey(robot, KeyEvent.VK_TAB); hitKey(robot, KeyEvent.VK_TAB); + hitKey(robot, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { public void run() { @@ -161,13 +162,14 @@ public class bug8033699 { // Non-Grouped Radio button and Group Radio button as a single component when traversing through shift-tab key private static void runTest3() throws Exception{ + hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { public void run() { - if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { System.out.println("Radio button Group/Non Grouped Radio Button SHIFT-Tab Key Test failed"); - throw new RuntimeException("Focus is not on Radio Button C as Expected"); + throw new RuntimeException("Focus is not on Radio Button A as Expected"); } } }); @@ -175,39 +177,39 @@ public class bug8033699 { // Using arrow key to move focus in radio button group private static void runTest4() throws Exception{ - hitKey(robot, KeyEvent.VK_UP); - hitKey(robot, KeyEvent.VK_LEFT); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { - System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed"); - throw new RuntimeException("Focus is not on Radio Button A as Expected"); - } - } - }); - } - - private static void runTest5() throws Exception{ hitKey(robot, KeyEvent.VK_DOWN); hitKey(robot, KeyEvent.VK_RIGHT); SwingUtilities.invokeAndWait(new Runnable() { public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { - System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed"); + System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed"); throw new RuntimeException("Focus is not on Radio Button C as Expected"); } } }); } + private static void runTest5() throws Exception{ + hitKey(robot, KeyEvent.VK_UP); + hitKey(robot, KeyEvent.VK_LEFT); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { + System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed"); + throw new RuntimeException("Focus is not on Radio Button A as Expected"); + } + } + }); + } + private static void runTest6() throws Exception{ - hitKey(robot, KeyEvent.VK_DOWN); - hitKey(robot, KeyEvent.VK_DOWN); + hitKey(robot, KeyEvent.VK_UP); + hitKey(robot, KeyEvent.VK_UP); SwingUtilities.invokeAndWait(new Runnable() { public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn2) { System.out.println("Radio button Group Circle Back To First Button Test"); - throw new RuntimeException("Focus is not on Radio Button A as Expected"); + throw new RuntimeException("Focus is not on Radio Button B as Expected"); } } }); @@ -229,9 +231,9 @@ public class bug8033699 { hitKey(robot, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { public void run() { - if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { System.out.println("Separate Component added in button group layout"); - throw new RuntimeException("Focus is not on Radio Button C as Expected"); + throw new RuntimeException("Focus is not on Radio Button Single as Expected"); } } }); From e319d259e6ba3616dd0b487c4e054e53655d736c Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Mon, 26 Sep 2016 14:47:41 +0530 Subject: [PATCH 069/207] 8165947: One more page printed before the test page with OpenJDK 8166259: One more banner page printed before the test page Reviewed-by: prr, jdv --- .../classes/sun/print/RasterPrinterJob.java | 22 ++- .../TestCheckSystemDefaultBannerOption.java | 172 ++++++++++++++++++ 2 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 jdk/test/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java diff --git a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java index 0a5e99c0bd5..4988a20cc68 100644 --- a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java +++ b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java @@ -1282,12 +1282,6 @@ public abstract class RasterPrinterJob extends PrinterJob { JobSheets jobSheets = (JobSheets)attributes.get(JobSheets.class); if (jobSheets != null) { noJobSheet = jobSheets == JobSheets.NONE; - } else { - JobSheets js = (JobSheets)getPrintService(). - getDefaultAttributeValue(JobSheets.class); - if (js != null && js.equals(JobSheets.NONE)) { - noJobSheet = true; - } } JobName jobName = (JobName)attributes.get(JobName.class); @@ -1487,6 +1481,22 @@ public abstract class RasterPrinterJob extends PrinterJob { throw new PrinterException("Printer is not accepting job."); } + /* + * Check the default job-sheet value on underlying platform. If IPP + * reports job-sheets=none, then honour that and modify noJobSheet since + * by default, noJobSheet is false which mean jdk will print banner page. + * This is because if "attributes" is null (if user directly calls print() + * without specifying any attributes and without showing printdialog) then + * setAttribute will return without changing noJobSheet value. + * Also, we do this before setAttributes() call so as to allow the user + * to override this via explicitly adding JobSheets attributes to + * PrintRequestAttributeSet while calling print(attributes) + */ + JobSheets js = (JobSheets)psvc.getDefaultAttributeValue(JobSheets.class); + if (js != null && js.equals(JobSheets.NONE)) { + noJobSheet = true; + } + if ((psvc instanceof SunPrinterJobService) && ((SunPrinterJobService)psvc).usesClass(getClass())) { setAttributes(attributes); diff --git a/jdk/test/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java b/jdk/test/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java new file mode 100644 index 00000000000..b8e43196c20 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8165947 + * @summary Verifies System default banner page option is honoured by jdk + * @requires (os.family == "linux" | os.family == "solaris") + * @run main/manual TestCheckSystemDefaultBannerOption + */ +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import static java.awt.print.Printable.NO_SUCH_PAGE; +import static java.awt.print.Printable.PAGE_EXISTS; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.print.attribute.standard.JobSheets; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + + +public class TestCheckSystemDefaultBannerOption implements Printable { + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static boolean noJobSheet = false; + private static PrinterJob job = null; + + public static void main (String[] args) throws Exception { + + job = PrinterJob.getPrinterJob(); + if (job.getPrintService() == null) { + System.out.println("No printers. Test cannot continue"); + return; + } + // check system default banner option and let user know what to expect + JobSheets js = (JobSheets)job.getPrintService(). + getDefaultAttributeValue(JobSheets.class); + if (js != null && js.equals(JobSheets.NONE)) { + noJobSheet = true; + } + SwingUtilities.invokeAndWait(() -> { + doTest(TestCheckSystemDefaultBannerOption::printTest); + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + String banner = noJobSheet ? "Banner page" : " No Banner page"; + throw new RuntimeException(banner + " is printed"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + private static void printTest() { + job.setPrintable(new TestCheckSystemDefaultBannerOption()); + try { + job.print(); + } catch (PrinterException e) { + e.printStackTrace(); + } + } + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String banner = null; + if (noJobSheet) { + banner = "No Banner page"; + } else { + banner = "Banner page"; + } + String description + = " A testpage will be sent to printer. \n" + + " Please check if " + banner + " is printed \n" + + " along with testpage.\n " + + " If " + banner + " is printed, press PASS else press FAIL"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + } + + @Override + public int print(Graphics g, PageFormat pf, int pi) + throws PrinterException { + System.out.println("pi = " + pi); + g.drawString("Testing", 100, 100); + if (pi == 1) + return NO_SUCH_PAGE; + return PAGE_EXISTS; + } +} From b74da55b154d49ac5e3618570fc56f55a4e0ebb7 Mon Sep 17 00:00:00 2001 From: Semyon Sadetsky Date: Mon, 26 Sep 2016 13:15:37 +0300 Subject: [PATCH 070/207] 8155753: Removing a monitor in the OS dispaly configuration causes assertion fails under Windows if D3D is on Reviewed-by: vadim, serb --- .../sun/java2d/opengl/CGLGraphicsConfig.java | 15 +- .../pipe/hw/AccelDeviceEventListener.java | 59 ------ .../pipe/hw/AccelDeviceEventNotifier.java | 169 ------------------ .../java2d/pipe/hw/AccelGraphicsConfig.java | 24 +-- .../sun/java2d/opengl/GLXGraphicsConfig.java | 15 +- .../sun/java2d/d3d/D3DGraphicsConfig.java | 15 +- .../sun/java2d/opengl/WGLGraphicsConfig.java | 36 +--- .../native/libawt/java2d/d3d/D3DContext.cpp | 8 +- .../native/libawt/java2d/d3d/D3DContext.h | 8 +- .../libawt/java2d/d3d/D3DPipelineManager.cpp | 37 +--- .../libawt/java2d/d3d/D3DPipelineManager.h | 7 +- .../java2d/pipe/hw/RSLAPITest/RSLAPITest.java | 11 -- 12 files changed, 11 insertions(+), 393 deletions(-) delete mode 100644 jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventListener.java delete mode 100644 jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java diff --git a/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java b/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java index 0e766e4e2be..78faf0a8f7b 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java +++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,8 +56,6 @@ import sun.java2d.pipe.hw.AccelTypedVolatileImage; import sun.java2d.pipe.hw.ContextCapabilities; import static sun.java2d.opengl.OGLSurfaceData.*; import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; -import sun.java2d.pipe.hw.AccelDeviceEventListener; -import sun.java2d.pipe.hw.AccelDeviceEventNotifier; import sun.lwawt.LWComponentPeer; import sun.lwawt.macosx.CPlatformView; @@ -407,17 +405,6 @@ public final class CGLGraphicsConfig extends CGraphicsConfig return oglCaps; } - @Override - public void addDeviceEventListener(AccelDeviceEventListener l) { - int displayID = getDevice().getCGDisplayID(); - AccelDeviceEventNotifier.addListener(l, displayID); - } - - @Override - public void removeDeviceEventListener(AccelDeviceEventListener l) { - AccelDeviceEventNotifier.removeListener(l); - } - @Override public int getMaxTextureWidth() { return Math.max(maxTextureSize / getDevice().getScaleFactor(), diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventListener.java b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventListener.java deleted file mode 100644 index 947b46871c8..00000000000 --- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventListener.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. - * 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 sun.java2d.pipe.hw; - -/** - * An interface for receiving notifications about imminent accelerated device's - * events. Upon receiving such event appropriate actions can be taken (for - * example, resources associated with the device can be freed). - */ -public interface AccelDeviceEventListener { - /** - * Called when the device is about to be reset. - * - * One must release all native resources associated with the device which - * prevent the device from being reset (such as Default Pool resources for - * the D3D pipeline). - * - * It is safe to remove the listener while in the call back. - * - * Note: this method is called on the rendering thread, - * do not call into user code, do not take RQ lock! - */ - public void onDeviceReset(); - - /** - * Called when the device is about to be disposed of. - * - * One must release all native resources associated with the device. - * - * It is safe to remove the listener while in the call back. - * - * Note: this method is called on the rendering thread, - * do not call into user code, do not take RQ lock! - */ - public void onDeviceDispose(); -} diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java deleted file mode 100644 index 9cca142c48f..00000000000 --- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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 - * 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 sun.java2d.pipe.hw; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.lang.annotation.Native; - - -/** - * This class is used to notify listeners about accelerated device's - * events such as device reset or dispose that are about to occur. - */ -public class AccelDeviceEventNotifier { - - private static AccelDeviceEventNotifier theInstance; - - /** - * A device is about to be reset. The listeners have to release all - * resources associated with the device which are required for the device - * to be reset. - */ - @Native public static final int DEVICE_RESET = 0; - - /** - * A device is about to be disposed. The listeners have to release all - * resources associated with the device. - */ - @Native public static final int DEVICE_DISPOSED = 1; - - private final Map listeners; - - private AccelDeviceEventNotifier() { - listeners = Collections.synchronizedMap( - new HashMap(1)); - } - - /** - * Returns a singleton of AccelDeviceEventNotifier if it exists. If the - * passed boolean is false and singleton doesn't exist yet, null is - * returned. If the passed boolean is {@code true} and singleton doesn't - * exist it will be created and returned. - * - * @param create whether to create a singleton instance if doesn't yet - * exist - * @return a singleton instance or null - */ - private static synchronized - AccelDeviceEventNotifier getInstance(boolean create) - { - if (theInstance == null && create) { - theInstance = new AccelDeviceEventNotifier(); - } - return theInstance; - } - - /** - * Called to indicate that a device event had occurred. - * If a singleton exists, the listeners (those associated with - * the device) will be notified. - * - * @param screen a screen number of the device which is a source of - * the event - * @param eventType a type of the event - * @see #DEVICE_DISPOSED - * @see #DEVICE_RESET - */ - public static final void eventOccured(int screen, int eventType) { - AccelDeviceEventNotifier notifier = getInstance(false); - if (notifier != null) { - notifier.notifyListeners(eventType, screen); - } - } - - /** - * Adds the listener associated with a device on particular screen. - * - * Note: the listener must be removed as otherwise it will forever - * be referenced by the notifier. - * - * @param l the listener - * @param screen the screen number indicating which device the listener is - * interested in. - */ - public static final void addListener(AccelDeviceEventListener l,int screen){ - getInstance(true).add(l, screen); - } - - /** - * Removes the listener. - * - * @param l the listener - */ - public static final void removeListener(AccelDeviceEventListener l) { - getInstance(true).remove(l); - } - - private final void add(AccelDeviceEventListener theListener, int screen) { - listeners.put(theListener, screen); - } - private final void remove(AccelDeviceEventListener theListener) { - listeners.remove(theListener); - } - - /** - * Notifies the listeners associated with the screen's device about the - * event. - * - * Implementation note: the current list of listeners is first duplicated - * which allows the listeners to remove themselves during the iteration. - * - * @param screen a screen number with which the device which is a source of - * the event is associated with - * @param deviceEventType a type of the event - * @see #DEVICE_DISPOSED - * @see #DEVICE_RESET - */ - private final void notifyListeners(int deviceEventType, int screen) { - HashMap listClone; - Set cloneSet; - - synchronized(listeners) { - listClone = - new HashMap(listeners); - } - - cloneSet = listClone.keySet(); - Iterator itr = cloneSet.iterator(); - while (itr.hasNext()) { - AccelDeviceEventListener current = itr.next(); - Integer i = listClone.get(current); - // only notify listeners which are interested in this device - if (i != null && i.intValue() != screen) { - continue; - } - if (deviceEventType == DEVICE_RESET) { - current.onDeviceReset(); - } else if (deviceEventType == DEVICE_DISPOSED) { - current.onDeviceDispose(); - } - } - } -} diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelGraphicsConfig.java b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelGraphicsConfig.java index 50712319180..174fbb6fff8 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelGraphicsConfig.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/hw/AccelGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,26 +70,4 @@ public interface AccelGraphicsConfig extends BufferedContextProvider { * @see ContextCapabilities */ public ContextCapabilities getContextCapabilities(); - - /** - * Adds an {@code AccelDeviceEventListener} to listen to accelerated - * device's (which is associated with this {@code AccelGraphicsConfig}) - * events. - * - * Note: a hard link to the listener may be kept so it must be explicitly - * removed via {@link #removeDeviceEventListener}. - * - * @param l the listener - * @see AccelDeviceEventListener - */ - public void addDeviceEventListener(AccelDeviceEventListener l); - - /** - * Removes an {@code AccelDeviceEventListener} from the list of listeners - * for this device's events. - * - * @param l the listener - * @see AccelDeviceEventListener - */ - public void removeDeviceEventListener(AccelDeviceEventListener l); } diff --git a/jdk/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java b/jdk/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java index 660a71125b3..6af8e91dff0 100644 --- a/jdk/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java +++ b/jdk/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ package sun.java2d.opengl; import java.awt.AWTException; import java.awt.BufferCapabilities; -import java.awt.BufferCapabilities.FlipContents; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; @@ -59,8 +58,6 @@ import static sun.java2d.opengl.OGLSurfaceData.*; import static sun.java2d.opengl.OGLContext.*; import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; import sun.java2d.opengl.GLXSurfaceData.GLXVSyncOffScreenSurfaceData; -import sun.java2d.pipe.hw.AccelDeviceEventListener; -import sun.java2d.pipe.hw.AccelDeviceEventNotifier; public class GLXGraphicsConfig extends X11GraphicsConfig @@ -426,14 +423,4 @@ public class GLXGraphicsConfig public ContextCapabilities getContextCapabilities() { return oglCaps; } - - @Override - public void addDeviceEventListener(AccelDeviceEventListener l) { - AccelDeviceEventNotifier.addListener(l, screen.getScreen()); - } - - @Override - public void removeDeviceEventListener(AccelDeviceEventListener l) { - AccelDeviceEventNotifier.removeListener(l); - } } diff --git a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsConfig.java b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsConfig.java index 368b43dbb7c..a6583027e66 100644 --- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsConfig.java +++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ package sun.java2d.d3d; import java.awt.AWTException; import java.awt.BufferCapabilities; -import java.awt.BufferCapabilities.FlipContents; import java.awt.Component; import java.awt.Graphics; import java.awt.ImageCapabilities; @@ -43,14 +42,12 @@ import sun.awt.image.SurfaceManager; import sun.awt.windows.WComponentPeer; import sun.java2d.Surface; import sun.java2d.SurfaceData; -import sun.java2d.pipe.hw.AccelDeviceEventNotifier; import sun.java2d.pipe.hw.AccelTypedVolatileImage; import sun.java2d.pipe.hw.AccelGraphicsConfig; import sun.java2d.pipe.hw.AccelSurface; import sun.java2d.pipe.hw.ContextCapabilities; import static sun.java2d.pipe.hw.AccelSurface.*; import static sun.java2d.d3d.D3DContext.D3DContextCaps.*; -import sun.java2d.pipe.hw.AccelDeviceEventListener; public class D3DGraphicsConfig extends Win32GraphicsConfig @@ -315,14 +312,4 @@ public class D3DGraphicsConfig public ContextCapabilities getContextCapabilities() { return device.getContextCapabilities(); } - - @Override - public void addDeviceEventListener(AccelDeviceEventListener l) { - AccelDeviceEventNotifier.addListener(l, device.getScreen()); - } - - @Override - public void removeDeviceEventListener(AccelDeviceEventListener l) { - AccelDeviceEventNotifier.removeListener(l); - } } diff --git a/jdk/src/java.desktop/windows/classes/sun/java2d/opengl/WGLGraphicsConfig.java b/jdk/src/java.desktop/windows/classes/sun/java2d/opengl/WGLGraphicsConfig.java index 1e78384130c..f2c5e4f4497 100644 --- a/jdk/src/java.desktop/windows/classes/sun/java2d/opengl/WGLGraphicsConfig.java +++ b/jdk/src/java.desktop/windows/classes/sun/java2d/opengl/WGLGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,8 +54,6 @@ import sun.java2d.pipe.hw.ContextCapabilities; import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; import static sun.java2d.opengl.WGLSurfaceData.*; import sun.java2d.opengl.OGLContext.OGLContextCaps; -import sun.java2d.pipe.hw.AccelDeviceEventListener; -import sun.java2d.pipe.hw.AccelDeviceEventNotifier; import sun.java2d.windows.GDIWindowSurfaceData; public class WGLGraphicsConfig @@ -92,8 +90,7 @@ public class WGLGraphicsConfig // add a record to the Disposer so that we destroy the native // WGLGraphicsConfigInfo data when this object goes away Disposer.addRecord(disposerReferent, - new WGLGCDisposerRecord(pConfigInfo, - device.getScreen())); + new WGLGCDisposerRecord(pConfigInfo)); } public Object getProxyKey() { @@ -198,27 +195,10 @@ public class WGLGraphicsConfig private static class WGLGCDisposerRecord implements DisposerRecord { private long pCfgInfo; - private int screen; - public WGLGCDisposerRecord(long pCfgInfo, int screen) { + public WGLGCDisposerRecord(long pCfgInfo) { this.pCfgInfo = pCfgInfo; } public void dispose() { - OGLRenderQueue rq = OGLRenderQueue.getInstance(); - rq.lock(); - try { - rq.flushAndInvokeNow(new Runnable() { - public void run() { - AccelDeviceEventNotifier. - eventOccured(screen, - AccelDeviceEventNotifier.DEVICE_RESET); - AccelDeviceEventNotifier. - eventOccured(screen, - AccelDeviceEventNotifier.DEVICE_DISPOSED); - } - }); - } finally { - rq.unlock(); - } if (pCfgInfo != 0) { OGLRenderQueue.disposeGraphicsConfig(pCfgInfo); pCfgInfo = 0; @@ -455,14 +435,4 @@ public class WGLGraphicsConfig public ContextCapabilities getContextCapabilities() { return oglCaps; } - - @Override - public void addDeviceEventListener(AccelDeviceEventListener l) { - AccelDeviceEventNotifier.addListener(l, screen.getScreen()); - } - - @Override - public void removeDeviceEventListener(AccelDeviceEventListener l) { - AccelDeviceEventNotifier.removeListener(l); - } } diff --git a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp index 8722d549bad..a847b838265 100644 --- a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -253,9 +253,6 @@ void D3DContext::ReleaseDefPoolResources() EndScene(); - D3DPipelineManager::NotifyAdapterEventListeners(devCaps.AdapterOrdinal, - DEVICE_RESET); - contextCaps = CAPS_EMPTY; SAFE_RELEASE(pSyncQuery); @@ -292,9 +289,6 @@ void D3DContext::ReleaseContextResources() ReleaseDefPoolResources(); - D3DPipelineManager::NotifyAdapterEventListeners(devCaps.AdapterOrdinal, - DEVICE_DISPOSED); - // dispose shader lists ShaderList_Dispose(&convolvePrograms); ShaderList_Dispose(&rescalePrograms); diff --git a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.h b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.h index 48defe17b47..a9f89037686 100644 --- a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.h +++ b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ #include "sun_java2d_pipe_BufferedContext.h" #include "sun_java2d_d3d_D3DContext_D3DContextCaps.h" #include "sun_java2d_d3d_D3DSurfaceData.h" -#include "sun_java2d_pipe_hw_AccelDeviceEventNotifier.h" #include "ShaderList.h" #include "D3DPipeline.h" @@ -413,9 +412,4 @@ private: #define CAPS_PS30 \ sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_PS30 -#define DEVICE_RESET \ - sun_java2d_pipe_hw_AccelDeviceEventNotifier_DEVICE_RESET -#define DEVICE_DISPOSED \ - sun_java2d_pipe_hw_AccelDeviceEventNotifier_DEVICE_DISPOSED - #endif // D3DCONTEXT_H diff --git a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.cpp b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.cpp index 11792b1c705..6b20759e393 100644 --- a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,41 +173,6 @@ HRESULT D3DPipelineManager::ReleaseAdapters() return S_OK; } -// static -void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter, - jint eventType) -{ - HMONITOR hMon; - int gdiScreen; - D3DPipelineManager *pMgr; - - // fix for 6946559: if d3d preloading fails jmv may be NULL - if (jvm == NULL) { - return; - } - - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - RETURN_IF_NULL(env); - - pMgr = D3DPipelineManager::GetInstance(); - RETURN_IF_NULL(pMgr); - hMon = pMgr->pd3d9->GetAdapterMonitor(adapter); - - /* - * If we don't have devices initialized yet, no sense to clear them. - */ - if (!Devices::GetInstance()){ - return; - } - - gdiScreen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hMon); - - JNU_CallStaticMethodByName(env, NULL, - "sun/java2d/pipe/hw/AccelDeviceEventNotifier", - "eventOccured", "(II)V", - gdiScreen, eventType); -} - UINT D3DPipelineManager::GetAdapterOrdinalForScreen(jint gdiScreen) { HMONITOR mHnd = AwtWin32GraphicsDevice::GetMonitor(gdiScreen); diff --git a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.h b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.h index 3d7227fab28..5676b71ad1a 100644 --- a/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.h +++ b/jdk/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,11 +78,6 @@ public: // these may differ depending on which display is primary UINT GetAdapterOrdinalForScreen(jint gdiScreen); - // notifies adapter event listeners by calling - // AccelDeviceEventNotifier.eventOccured() - static - void NotifyAdapterEventListeners(UINT adapter, jint eventType); - private: D3DPipelineManager(void); ~D3DPipelineManager(void); diff --git a/jdk/test/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java b/jdk/test/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java index 25c6b0be5c0..18a23ed42bd 100644 --- a/jdk/test/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java +++ b/jdk/test/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java @@ -47,7 +47,6 @@ import sun.java2d.DestSurfaceProvider; import sun.java2d.Surface; import sun.java2d.pipe.BufferedContext; import sun.java2d.pipe.RenderQueue; -import sun.java2d.pipe.hw.AccelDeviceEventListener; import sun.java2d.pipe.hw.AccelGraphicsConfig; import sun.java2d.pipe.hw.AccelSurface; import static java.awt.Transparency.*; @@ -254,16 +253,6 @@ public class RSLAPITest { private static void testContext(final AccelGraphicsConfig agc) { BufferedContext c = agc.getContext(); - final AccelDeviceEventListener l = new AccelDeviceEventListener() { - public void onDeviceDispose() { - System.out.println("onDeviceDispose invoked"); - agc.removeDeviceEventListener(this); - } - public void onDeviceReset() { - System.out.println("onDeviceReset invoked"); - } - }; - agc.addDeviceEventListener(l); RenderQueue rq = c.getRenderQueue(); rq.lock(); From 7a9ceeb8ef484d38fd7daefbf0d9c5891b1f86a9 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 26 Sep 2016 14:38:35 -0400 Subject: [PATCH 071/207] 8166663: Simplify oops_on_card_seq_iterate_careful Remove unnecessary parameter, change return value. Reviewed-by: tschatzl, mgerdin --- hotspot/src/share/vm/gc/g1/g1RemSet.cpp | 16 ++++--- hotspot/src/share/vm/gc/g1/heapRegion.cpp | 51 ++++++++++------------- hotspot/src/share/vm/gc/g1/heapRegion.hpp | 21 +++++----- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp index 4e4bb9904cf..ccb8fbdd2fd 100644 --- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp @@ -668,20 +668,18 @@ bool G1RemSet::refine_card(jbyte* card_ptr, // fail arbitrarily). We tell the iteration code to perform this // filtering when it has been determined that there has been an actual // allocation in this region and making it safe to check the young type. - bool filter_young = true; - HeapWord* stop_point = + bool card_processed = r->oops_on_card_seq_iterate_careful(dirtyRegion, &filter_then_update_rs_oop_cl, - filter_young, card_ptr); - // If stop_point is non-null, then we encountered an unallocated region - // (perhaps the unfilled portion of a TLAB.) For now, we'll dirty the - // card and re-enqueue: if we put off the card until a GC pause, then the - // unallocated portion will be filled in. Alternatively, we might try - // the full complexity of the technique used in "regular" precleaning. - if (stop_point != NULL) { + // If unable to process the card then we encountered an unparsable + // part of the heap (e.g. a partially allocated object). Redirty + // and re-enqueue: if we put off the card until a GC pause, then the + // allocation will have completed. + if (!card_processed) { + assert(!_g1->is_gc_active(), "Unparsable heap during GC"); // The card might have gotten re-dirtied and re-enqueued while we // worked. (In fact, it's pretty likely.) if (*card_ptr != CardTableModRefBS::dirty_card_val()) { diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.cpp b/hotspot/src/share/vm/gc/g1/heapRegion.cpp index 6944bcf0c44..f2df4a3c5b8 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp @@ -352,19 +352,10 @@ void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark, _prev_marked_bytes = marked_bytes; } -HeapWord* -HeapRegion:: -oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl, - bool filter_young, - jbyte* card_ptr) { - // Currently, we should only have to clean the card if filter_young - // is true and vice versa. - if (filter_young) { - assert(card_ptr != NULL, "pre-condition"); - } else { - assert(card_ptr == NULL, "pre-condition"); - } +bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, + FilterOutOfRegionClosure* cl, + jbyte* card_ptr) { + assert(card_ptr != NULL, "pre-condition"); G1CollectedHeap* g1h = G1CollectedHeap::heap(); // If we're within a stop-world GC, then we might look at a card in a @@ -375,7 +366,9 @@ oops_on_card_seq_iterate_careful(MemRegion mr, } else { mr = mr.intersection(used_region()); } - if (mr.is_empty()) return NULL; + if (mr.is_empty()) { + return true; + } // Otherwise, find the obj that extends onto mr.start(). // The intersection of the incoming mr (for the card) and the @@ -384,27 +377,21 @@ oops_on_card_seq_iterate_careful(MemRegion mr, // G1CollectedHeap.cpp that allocates a new region sets the // is_young tag on the region before allocating. Thus we // safely know if this region is young. - if (is_young() && filter_young) { - return NULL; + if (is_young()) { + return true; } - assert(!is_young(), "check value of filter_young"); - // We can only clean the card here, after we make the decision that - // the card is not young. And we only clean the card if we have been - // asked to (i.e., card_ptr != NULL). - if (card_ptr != NULL) { - *card_ptr = CardTableModRefBS::clean_card_val(); - // We must complete this write before we do any of the reads below. - OrderAccess::storeload(); - } + // the card is not young. + *card_ptr = CardTableModRefBS::clean_card_val(); + // We must complete this write before we do any of the reads below. + OrderAccess::storeload(); // Cache the boundaries of the memory region in some const locals HeapWord* const start = mr.start(); HeapWord* const end = mr.end(); - // We used to use "block_start_careful" here. But we're actually happy - // to update the BOT while we do this... + // Update BOT as needed while finding start of (potential) object. HeapWord* cur = block_start(start); assert(cur <= start, "Postcondition"); @@ -416,7 +403,9 @@ oops_on_card_seq_iterate_careful(MemRegion mr, obj = oop(cur); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. - return cur; + assert(!g1h->is_gc_active(), + "Unparsable heap during GC at " PTR_FORMAT, p2i(cur)); + return false; } // Otherwise... next = cur + block_size(cur); @@ -433,7 +422,9 @@ oops_on_card_seq_iterate_careful(MemRegion mr, assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant"); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. - return cur; + assert(!g1h->is_gc_active(), + "Unparsable heap during GC at " PTR_FORMAT, p2i(cur)); + return false; } // Advance the current pointer. "obj" still points to the object to iterate. @@ -452,7 +443,7 @@ oops_on_card_seq_iterate_careful(MemRegion mr, } } while (cur < end); - return NULL; + return true; } // Code roots support diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.hpp b/hotspot/src/share/vm/gc/g1/heapRegion.hpp index 9542b9ffb11..7f4de70b597 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp @@ -653,16 +653,17 @@ class HeapRegion: public G1ContiguousSpace { } } - // filter_young: if true and the region is a young region then we - // skip the iteration. - // card_ptr: if not NULL, and we decide that the card is not young - // and we iterate over it, we'll clean the card before we start the - // iteration. - HeapWord* - oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl, - bool filter_young, - jbyte* card_ptr); + // Iterate over the card in the card designated by card_ptr, + // applying cl to all references in the region. + // mr: the memory region covered by the card. + // card_ptr: if we decide that the card is not young and we iterate + // over it, we'll clean the card before we start the iteration. + // Returns true if card was successfully processed, false if an + // unparsable part of the heap was encountered, which should only + // happen when invoked concurrently with the mutator. + bool oops_on_card_seq_iterate_careful(MemRegion mr, + FilterOutOfRegionClosure* cl, + jbyte* card_ptr); size_t recorded_rs_length() const { return _recorded_rs_length; } double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; } From e36aa5f9d0fcdade97494e0d08404dd00635746a Mon Sep 17 00:00:00 2001 From: Frederic Parain Date: Mon, 26 Sep 2016 15:56:39 -0400 Subject: [PATCH 072/207] 8146546: assert(fr->safe_for_sender(thread)) failed: Safety check Reviewed-by: dcubed, gziemski, dlong --- hotspot/src/os/windows/vm/os_windows.cpp | 6 ++++-- hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp | 6 ++++-- hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 6 ++++-- hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 3b075455d92..5af74d3668f 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -2366,7 +2366,9 @@ bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, if (Interpreter::contains(pc)) { *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); if (!fr->is_first_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. *fr = fr->java_sender(); } } else { @@ -2383,7 +2385,7 @@ bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, // has been pushed on the stack *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp())); if (!fr->is_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // See java_sender() comment above. *fr = fr->java_sender(); } } diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp index 6e3de2d6f9e..d9d8da7395a 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp @@ -378,7 +378,9 @@ bool os::Bsd::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* u // method returns the Java sender of the current frame. *fr = os::fetch_frame_from_ucontext(thread, uc); if (!fr->is_first_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. *fr = fr->java_sender(); } } else { @@ -395,7 +397,7 @@ bool os::Bsd::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* u // has been pushed on the stack *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp())); if (!fr->is_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // See java_sender() comment above. *fr = fr->java_sender(); } } 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 e7566c7d4af..0bf4b8db7fc 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 @@ -191,7 +191,9 @@ bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* // method returns the Java sender of the current frame. *fr = os::fetch_frame_from_ucontext(thread, uc); if (!fr->is_first_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. *fr = fr->java_sender(); } } else { @@ -209,8 +211,8 @@ bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* intptr_t* sp = os::Linux::ucontext_get_sp(uc); *fr = frame(sp + 1, fp, (address)*sp); if (!fr->is_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); assert(!fr->is_first_frame(), "Safety check"); + // See java_sender() comment above. *fr = fr->java_sender(); } } diff --git a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index bc79053f81d..530f7033df9 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -255,7 +255,9 @@ bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_ // method returns the Java sender of the current frame. *fr = os::fetch_frame_from_ucontext(thread, uc); if (!fr->is_first_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. *fr = fr->java_sender(); } } else { @@ -273,7 +275,7 @@ bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_ intptr_t* sp = os::Solaris::ucontext_get_sp(uc); *fr = frame(sp + 1, fp, (address)*sp); if (!fr->is_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // See java_sender() comment above. *fr = fr->java_sender(); } } From 7487c5739967b1bd09f0a0c924d7db4ff69569b3 Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Mon, 26 Sep 2016 17:49:01 +0300 Subject: [PATCH 073/207] 8159818: Convert IHOP_test to GTest Reviewed-by: tschatzl, iignatyev --- hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp | 117 -------------- hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp | 9 +- .../share/vm/utilities/internalVMTests.cpp | 1 - .../test/native/gc/g1/test_g1IHOPControl.cpp | 149 ++++++++++++++++++ 4 files changed, 150 insertions(+), 126 deletions(-) create mode 100644 hotspot/test/native/gc/g1/test_g1IHOPControl.cpp diff --git a/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp b/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp index 996a68ae39c..9b74d50a085 100644 --- a/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp +++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp @@ -81,47 +81,6 @@ G1StaticIHOPControl::G1StaticIHOPControl(double ihop_percent) : _last_marking_length_s(0.0) { } -#ifndef PRODUCT -static void test_update(G1IHOPControl* ctrl, double alloc_time, size_t alloc_amount, size_t young_size, double mark_time) { - for (int i = 0; i < 100; i++) { - ctrl->update_allocation_info(alloc_time, alloc_amount, young_size); - ctrl->update_marking_length(mark_time); - } -} - -void G1StaticIHOPControl::test() { - size_t const initial_ihop = 45; - - G1StaticIHOPControl ctrl(initial_ihop); - ctrl.update_target_occupancy(100); - - size_t threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == initial_ihop, - "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold); - - ctrl.update_allocation_info(100.0, 100, 100); - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == initial_ihop, - "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold); - - ctrl.update_marking_length(1000.0); - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == initial_ihop, - "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold); - - // Whatever we pass, the IHOP value must stay the same. - test_update(&ctrl, 2, 10, 10, 3); - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == initial_ihop, - "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold); - - test_update(&ctrl, 12, 10, 10, 3); - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == initial_ihop, - "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold); -} -#endif - G1AdaptiveIHOPControl::G1AdaptiveIHOPControl(double ihop_percent, G1Predictions const* predictor, size_t heap_reserve_percent, @@ -224,79 +183,3 @@ void G1AdaptiveIHOPControl::send_trace_event(G1NewTracer* tracer) { _predictor->get_new_prediction(&_marking_times_s), have_enough_data_for_prediction()); } - -#ifndef PRODUCT -void G1AdaptiveIHOPControl::test() { - size_t const initial_threshold = 45; - size_t const young_size = 10; - size_t const target_size = 100; - - // The final IHOP value is always - // target_size - (young_size + alloc_amount/alloc_time * marking_time) - - G1Predictions pred(0.95); - G1AdaptiveIHOPControl ctrl(initial_threshold, &pred, 0, 0); - ctrl.update_target_occupancy(target_size); - - // First "load". - size_t const alloc_time1 = 2; - size_t const alloc_amount1 = 10; - size_t const marking_time1 = 2; - size_t const settled_ihop1 = target_size - (young_size + alloc_amount1/alloc_time1 * marking_time1); - - size_t threshold; - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == initial_threshold, - "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_threshold, threshold); - for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) { - ctrl.update_allocation_info(alloc_time1, alloc_amount1, young_size); - ctrl.update_marking_length(marking_time1); - // Not enough data yet. - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == initial_threshold, - "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_threshold, threshold); - } - - test_update(&ctrl, alloc_time1, alloc_amount1, young_size, marking_time1); - - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold == settled_ihop1, - "Expected IHOP threshold to settle at " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop1, threshold); - - // Second "load". A bit higher allocation rate. - size_t const alloc_time2 = 2; - size_t const alloc_amount2 = 30; - size_t const marking_time2 = 2; - size_t const settled_ihop2 = target_size - (young_size + alloc_amount2/alloc_time2 * marking_time2); - - test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2); - - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold < settled_ihop1, - "Expected IHOP threshold to settle at a value lower than " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop1, threshold); - - // Third "load". Very high (impossible) allocation rate. - size_t const alloc_time3 = 1; - size_t const alloc_amount3 = 50; - size_t const marking_time3 = 2; - size_t const settled_ihop3 = 0; - - test_update(&ctrl, alloc_time3, alloc_amount3, young_size, marking_time3); - threshold = ctrl.get_conc_mark_start_threshold(); - - assert(threshold == settled_ihop3, - "Expected IHOP threshold to settle at " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop3, threshold); - - // And back to some arbitrary value. - test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2); - - threshold = ctrl.get_conc_mark_start_threshold(); - assert(threshold > settled_ihop3, - "Expected IHOP threshold to settle at value larger than " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop3, threshold); -} - -void IHOP_test() { - G1StaticIHOPControl::test(); - G1AdaptiveIHOPControl::test(); -} -#endif diff --git a/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp b/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp index 300884b6c2f..c8018949b39 100644 --- a/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp +++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,10 +99,6 @@ class G1StaticIHOPControl : public G1IHOPControl { assert(marking_length_s > 0.0, "Marking length must be larger than zero but is %.3f", marking_length_s); _last_marking_length_s = marking_length_s; } - -#ifndef PRODUCT - static void test(); -#endif }; // This algorithm tries to return a concurrent mark starting occupancy value that @@ -148,9 +144,6 @@ class G1AdaptiveIHOPControl : public G1IHOPControl { virtual void print(); virtual void send_trace_event(G1NewTracer* tracer); -#ifndef PRODUCT - static void test(); -#endif }; #endif // SHARE_VM_GC_G1_G1IHOPCONTROL_HPP diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index f37c9dfc690..718da1d0452 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -86,7 +86,6 @@ void InternalVMTests::run() { run_unit_test(TestBufferingOopClosure_test); if (UseG1GC) { run_unit_test(FreeRegionList_test); - run_unit_test(IHOP_test); } run_unit_test(WorkerDataArray_test); run_unit_test(ParallelCompact_test); diff --git a/hotspot/test/native/gc/g1/test_g1IHOPControl.cpp b/hotspot/test/native/gc/g1/test_g1IHOPControl.cpp new file mode 100644 index 00000000000..082b0886bf9 --- /dev/null +++ b/hotspot/test/native/gc/g1/test_g1IHOPControl.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1IHOPControl.hpp" +#include "gc/g1/g1Predictions.hpp" +#include "unittest.hpp" + +static void test_update(G1IHOPControl* ctrl, double alloc_time, + size_t alloc_amount, size_t young_size, + double mark_time) { + for (int i = 0; i < 100; i++) { + ctrl->update_allocation_info(alloc_time, alloc_amount, young_size); + ctrl->update_marking_length(mark_time); + } +} + +// @requires UseG1GC +TEST_VM(G1StaticIHOPControl, simple) { + // Test requires G1 + if (!UseG1GC) { + return; + } + + const size_t initial_ihop = 45; + + G1StaticIHOPControl ctrl(initial_ihop); + ctrl.update_target_occupancy(100); + + size_t threshold = ctrl.get_conc_mark_start_threshold(); + EXPECT_EQ(initial_ihop, threshold); + + ctrl.update_allocation_info(100.0, 100, 100); + threshold = ctrl.get_conc_mark_start_threshold(); + EXPECT_EQ(initial_ihop, threshold); + + ctrl.update_marking_length(1000.0); + threshold = ctrl.get_conc_mark_start_threshold(); + EXPECT_EQ(initial_ihop, threshold); + + // Whatever we pass, the IHOP value must stay the same. + test_update(&ctrl, 2, 10, 10, 3); + threshold = ctrl.get_conc_mark_start_threshold(); + + EXPECT_EQ(initial_ihop, threshold); + + test_update(&ctrl, 12, 10, 10, 3); + threshold = ctrl.get_conc_mark_start_threshold(); + + EXPECT_EQ(initial_ihop, threshold); +} + +// @requires UseG1GC +TEST_VM(G1AdaptiveIHOPControl, simple) { + // Test requires G1 + if (!UseG1GC) { + return; + } + + const size_t initial_threshold = 45; + const size_t young_size = 10; + const size_t target_size = 100; + + // The final IHOP value is always + // target_size - (young_size + alloc_amount/alloc_time * marking_time) + + G1Predictions pred(0.95); + G1AdaptiveIHOPControl ctrl(initial_threshold, &pred, 0, 0); + ctrl.update_target_occupancy(target_size); + + // First "load". + const size_t alloc_time1 = 2; + const size_t alloc_amount1 = 10; + const size_t marking_time1 = 2; + const size_t settled_ihop1 = target_size + - (young_size + alloc_amount1 / alloc_time1 * marking_time1); + + size_t threshold; + threshold = ctrl.get_conc_mark_start_threshold(); + + EXPECT_EQ(initial_threshold, threshold); + + for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) { + ctrl.update_allocation_info(alloc_time1, alloc_amount1, young_size); + ctrl.update_marking_length(marking_time1); + // Not enough data yet. + threshold = ctrl.get_conc_mark_start_threshold(); + + ASSERT_EQ(initial_threshold, threshold) << "on step " << i; + } + + test_update(&ctrl, alloc_time1, alloc_amount1, young_size, marking_time1); + + threshold = ctrl.get_conc_mark_start_threshold(); + + EXPECT_EQ(settled_ihop1, threshold); + + // Second "load". A bit higher allocation rate. + const size_t alloc_time2 = 2; + const size_t alloc_amount2 = 30; + const size_t marking_time2 = 2; + const size_t settled_ihop2 = target_size + - (young_size + alloc_amount2 / alloc_time2 * marking_time2); + + test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2); + + threshold = ctrl.get_conc_mark_start_threshold(); + + EXPECT_LT(threshold, settled_ihop1); + + // Third "load". Very high (impossible) allocation rate. + const size_t alloc_time3 = 1; + const size_t alloc_amount3 = 50; + const size_t marking_time3 = 2; + const size_t settled_ihop3 = 0; + + test_update(&ctrl, alloc_time3, alloc_amount3, young_size, marking_time3); + threshold = ctrl.get_conc_mark_start_threshold(); + + EXPECT_EQ(settled_ihop3, threshold); + + // And back to some arbitrary value. + test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2); + + threshold = ctrl.get_conc_mark_start_threshold(); + + EXPECT_GT(threshold, settled_ihop3); +} From 12a0e42ed245aa31a35acb8334cfb38d95814dbb Mon Sep 17 00:00:00 2001 From: Semyon Sadetsky Date: Tue, 27 Sep 2016 09:55:45 +0300 Subject: [PATCH 074/207] 8160160: The menu displayed nothing with the option"-server -d64 -Xmixed -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel" Reviewed-by: alexsch, serb --- .../sun/java/swing/plaf/gtk/GTKEngine.java | 9 ++++--- .../sun/java/swing/plaf/gtk/GTKPainter.java | 27 +++++++++++++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java index 940b0107a93..7bb07cce215 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java @@ -586,8 +586,8 @@ class GTKEngine { * Convenience method that delegates to finishPainting() with * caching enabled. */ - public void finishPainting() { - finishPainting(true); + public BufferedImage finishPainting() { + return finishPainting(true); } /** @@ -595,7 +595,7 @@ class GTKEngine { * BufferedImage from the offscreen buffer, (optionally) cache it, * and paint it. */ - public void finishPainting(boolean useCache) { + public BufferedImage finishPainting(boolean useCache) { DataBufferInt dataBuffer = new DataBufferInt(w0 * h0); // Note that stealData() requires a markDirty() afterwards // since we modify the data in it. @@ -609,11 +609,12 @@ class GTKEngine { dataBuffer, w0, h0, w0, bands, null); ColorModel cm = COLOR_MODELS[transparency - 1]; - Image img = new BufferedImage(cm, raster, false, null); + BufferedImage img = new BufferedImage(cm, raster, false, null); if (useCache) { cache.setImage(getClass(), null, w0, h0, cacheArgs, img); } graphics.drawImage(img, x0, y0, null); + return img; } /** diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java index 94408916d8f..2dade4d67a4 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java @@ -24,6 +24,8 @@ */ package com.sun.java.swing.plaf.gtk; +import sun.awt.ModalExclude; +import sun.awt.SunToolkit; import sun.awt.UNIXToolkit; import javax.swing.plaf.synth.*; @@ -36,6 +38,7 @@ import com.sun.java.swing.plaf.gtk.GTKConstants.ExpanderStyle; import com.sun.java.swing.plaf.gtk.GTKConstants.Orientation; import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType; import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType; +import java.awt.image.BufferedImage; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -567,8 +570,10 @@ class GTKPainter extends SynthPainter { Region id = context.getRegion(); int gtkState = GTKLookAndFeel.synthStateToGTKState( id, context.getComponentState()); + boolean isHW = SunToolkit.getHeavyweightComponent( + context.getComponent()) instanceof ModalExclude; synchronized (UNIXToolkit.GTK_LOCK) { - if (ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState)) { + if (ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, isHW)) { return; } ENGINE.startPainting(g, x, y, w, h, id, gtkState); @@ -581,7 +586,25 @@ class GTKPainter extends SynthPainter { style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND), x + insets.left, y + insets.top, w - insets.left - insets.right, h - insets.top - insets.bottom); - ENGINE.finishPainting(); + BufferedImage img = ENGINE.finishPainting(); + if(!isHW) { + int border = img.getRGB(0, h / 2); + if (img != null && border == img.getRGB(w / 2, h / 2)) { + // fix no menu borders in Adwaita theme + Graphics g2 = img.getGraphics(); + Color c = new Color(border); + g2.setColor(new Color(Math.max((int) (c.getRed() * 0.8), 0), + Math.max((int) (c.getGreen() * 0.8), 0), + Math.max((int) (c.getBlue() * 0.8), 0))); + g2.drawLine(0, 0, w - 1, 0); + g2.drawLine(w - 1, 0, w - 1, h - 1); + g2.drawLine(0, h - 1, 0, 1); + g2.setColor(c.darker()); + g2.drawLine(w - 1, h - 1, 0, h - 1); + g2.dispose(); + g.drawImage(img, x, y, null); + } + } } } From e6c9f4d18d18806f50b622cfa8bccf5651af3ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Tue, 27 Sep 2016 16:43:59 -0400 Subject: [PATCH 075/207] 8165857: CMS _overflow_list is missing volatile specifiers Change _overflow_list from "oop" to "oopDesc* volatile", both CMS and ParNew. Reviewed-by: kbarrett, tschatzl --- hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp | 2 +- hotspot/src/share/vm/gc/cms/parNewGeneration.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp index a5b7f9157b2..8a9d2b8ded3 100644 --- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp @@ -540,7 +540,7 @@ class CMSCollector: public CHeapObj { // Overflow list of grey objects, threaded through mark-word // Manipulated with CAS in the parallel/multi-threaded case. - oop _overflow_list; + oopDesc* volatile _overflow_list; // The following array-pair keeps track of mark words // displaced for accommodating overflow list above. // This code will likely be revisited under RFE#4922830. diff --git a/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp b/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp index 94ec916357c..0576e05cebd 100644 --- a/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp +++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -323,7 +323,7 @@ class ParNewGeneration: public DefNewGeneration { // A list of from-space images of to-be-scanned objects, threaded through // klass-pointers (klass information already copied to the forwarded // image.) Manipulated with CAS. - oop _overflow_list; + oopDesc* volatile _overflow_list; NOT_PRODUCT(ssize_t _num_par_pushes;) // This closure is used by the reference processor to filter out From 9de81c383a50300ef4cc8f5b8d79c414111131b7 Mon Sep 17 00:00:00 2001 From: Sharath Ballal Date: Wed, 28 Sep 2016 11:58:56 +0530 Subject: [PATCH 076/207] 8165537: runtime/SharedArchiveFile/SASymbolTableTest.java fails with NullPointerException Modify SASymbolTableTest.java to attach to LingeredApp and also handle the case where SymbolTable is not created. Reviewed-by: dsamersoff, mseledtsov, iklam --- .../SharedArchiveFile/SASymbolTableTest.java | 86 +++++++++---------- .../SASymbolTableTestAgent.java | 48 ++++++----- .../SASymbolTableTestAttachee.java | 38 -------- 3 files changed, 68 insertions(+), 104 deletions(-) delete mode 100644 hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAttachee.java diff --git a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java index 65cb422adad..14603a5f1c6 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java +++ b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java @@ -34,14 +34,17 @@ * jdk.hotspot.agent/sun.jvm.hotspot.runtime * jdk.hotspot.agent/sun.jvm.hotspot.tools * java.management - * @build SASymbolTableTestAgent SASymbolTableTestAttachee + * @build SASymbolTableTestAgent * @run main SASymbolTableTest */ +import java.util.Arrays; +import java.util.List; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.JDKToolFinder; import jdk.test.lib.Platform; +import jdk.test.lib.apps.LingeredApp; /* * The purpose of this test is to validate that we can use SA to @@ -53,6 +56,7 @@ import jdk.test.lib.Platform; */ public class SASymbolTableTest { static String jsaName = "./SASymbolTableTest.jsa"; + private static LingeredApp theApp = null; public static void main(String[] args) throws Exception { if (!Platform.shouldSAAttach()) { @@ -78,50 +82,44 @@ public class SASymbolTableTest { private static void run(boolean useArchive) throws Exception { String flag = useArchive ? "auto" : "off"; - // (1) Launch the attachee process - ProcessBuilder attachee = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", - "-XX:SharedArchiveFile=" + jsaName, - "-Xshare:" + flag, - "-showversion", // so we can see "sharing" in the output - "SASymbolTableTestAttachee"); + try { + // (1) Launch the attachee process + System.out.println("Starting LingeredApp"); + List vmOpts = Arrays.asList( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + jsaName, + "-Xshare:" + flag, + "-showversion"); // so we can see "sharing" in the output - final Process p = attachee.start(); + theApp = LingeredApp.startApp(vmOpts); - // (2) Launch the agent process - long pid = p.getPid(); - System.out.println("Attaching agent " + pid); - ProcessBuilder tool = ProcessTools.createJavaProcessBuilder( - "--add-modules=jdk.hotspot.agent", - "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED", - "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED", - "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED", - "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED", - "SASymbolTableTestAgent", - Long.toString(pid)); - OutputAnalyzer output = ProcessTools.executeProcess(tool); - System.out.println(output.getOutput()); - output.shouldHaveExitValue(0); - - Thread t = new Thread() { - public void run() { - try { - OutputAnalyzer output = new OutputAnalyzer(p); - System.out.println("STDOUT["); - System.out.print(output.getStdout()); - System.out.println("]"); - System.out.println("STDERR["); - System.out.print(output.getStderr()); - System.out.println("]"); - } catch (Throwable t) { - t.printStackTrace(); - } - } - }; - t.start(); - - Thread.sleep(2 * 1000); - p.destroy(); - t.join(); + // (2) Launch the agent process + long pid = theApp.getPid(); + System.out.println("Attaching agent to " + pid ); + ProcessBuilder tool = ProcessTools.createJavaProcessBuilder( + "--add-modules=jdk.hotspot.agent", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED", + "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED", + "SASymbolTableTestAgent", + Long.toString(pid)); + OutputAnalyzer output = ProcessTools.executeProcess(tool); + System.out.println("STDOUT["); + System.out.println(output.getOutput()); + if (output.getStdout().contains("connected too early")) { + System.out.println("SymbolTable not created by VM - test skipped"); + return; + } + System.out.println("]"); + System.out.println("STDERR["); + System.out.print(output.getStderr()); + System.out.println("]"); + output.shouldHaveExitValue(0); + } catch (Exception ex) { + throw new RuntimeException("Test ERROR " + ex, ex); + } finally { + LingeredApp.stopApp(theApp); + } } } diff --git a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAgent.java b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAgent.java index 4c5193fbcc4..6be0e86976f 100644 --- a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAgent.java +++ b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAgent.java @@ -112,31 +112,35 @@ public class SASymbolTableTestAgent extends Tool { public void run() { System.out.println("SASymbolTableTestAgent: starting"); - VM vm = VM.getVM(); - SymbolTable table = vm.getSymbolTable(); + try { + VM vm = VM.getVM(); + SymbolTable table = vm.getSymbolTable(); - // (a) These are names that are likely to exist in the symbol table - // of a JVM after start-up. They were taken from vmSymbols.hpp - // during the middle of JDK9 development. - // - // The purpose is not to check that each name must exist (a future - // version of JDK may not preload some of the classes). - // - // The purpose of this loops is to ensure that we check a lot of symbols, - // so we will (most likely) hit on both VALUE_ONLY_BUCKET_TYPE and normal bucket type - // in CompactHashTable.probe(). - for (String n : commonNames) { - Symbol s = table.probe(n); - System.out.format("%-40s = %s\n", n, s); - } + // (a) These are names that are likely to exist in the symbol table + // of a JVM after start-up. They were taken from vmSymbols.hpp + // during the middle of JDK9 development. + // + // The purpose is not to check that each name must exist (a future + // version of JDK may not preload some of the classes). + // + // The purpose of this loops is to ensure that we check a lot of symbols, + // so we will (most likely) hit on both VALUE_ONLY_BUCKET_TYPE and normal bucket type + // in CompactHashTable.probe(). + for (String n : commonNames) { + Symbol s = table.probe(n); + System.out.format("%-40s = %s\n", n, s); + } - System.out.println("======================================================================"); + System.out.println("======================================================================"); - // (b) Also test a few strings that are known to not exist in the table. This will - // both the compact table (if it exists) and the regular table to be walked. - for (String n : badNames) { - Symbol s = table.probe(n); - System.out.format("%-40s = %s\n", n, s); + // (b) Also test a few strings that are known to not exist in the table. This will + // both the compact table (if it exists) and the regular table to be walked. + for (String n : badNames) { + Symbol s = table.probe(n); + System.out.format("%-40s = %s\n", n, s); + } + } catch (NullPointerException e) { + System.out.println("connected too early -- please try again"); } } } diff --git a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAttachee.java b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAttachee.java deleted file mode 100644 index e08d1a55bf5..00000000000 --- a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTestAttachee.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * This class is launched in a sub-process by the main test, - * SASymbolTableTest.java. - * - * This class does nothing in particular. It just sleeps for 120 - * seconds so SASymbolTableTestAgent can have a chance to examine its - * SymbolTable. This process should be killed by the parent process - * after SASymbolTableTestAgent has completed testing. - */ -public class SASymbolTableTestAttachee { - public static void main(String args[]) throws Throwable { - System.out.println("SASymbolTableTestAttachee: sleeping to wait for SA tool to attach ..."); - Thread.sleep(120 * 1000); - } -} From a4676806a83ef2201725382d8bd49d261229c898 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 27 Sep 2016 15:45:44 +0200 Subject: [PATCH 077/207] 8166777: [ppc] port "8164086: Checked JNI pending exception check should be cleared" Reviewed-by: fparain, dholmes --- hotspot/src/cpu/ppc/vm/assembler_ppc.hpp | 3 +++ hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp | 3 +++ hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp | 5 +++++ hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp | 6 ++++++ 4 files changed, 17 insertions(+) diff --git a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp index d96f1635e17..9c684e4aca2 100644 --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp @@ -1575,6 +1575,9 @@ class Assembler : public AbstractAssembler { inline void stdu( Register d, int si16, Register s1); inline void stdux(Register s, Register a, Register b); + inline void st_ptr(Register d, int si16, Register s1); + DEBUG_ONLY(inline void st_ptr(Register d, ByteSize b, Register s1);) + // PPC 1, section 3.3.13 Move To/From System Register Instructions inline void mtlr( Register s1); inline void mflr( Register d); diff --git a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp index ef129efeefe..f46f47dc311 100644 --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp @@ -349,6 +349,9 @@ inline void Assembler::stdx( Register d, Register s1, Register s2) { emit_int32( inline void Assembler::stdu( Register d, int si16, Register s1) { emit_int32(STDU_OPCODE | rs(d) | ds(si16) | rta0mem(s1));} inline void Assembler::stdux(Register s, Register a, Register b) { emit_int32(STDUX_OPCODE| rs(s) | rta0mem(a) | rb(b));} +inline void Assembler::st_ptr(Register d, int b, Register s1) { std(d, b, s1); } +DEBUG_ONLY(inline void Assembler::st_ptr(Register d, ByteSize b, Register s1) { std(d, in_bytes(b), s1); }) + // PPC 1, section 3.3.13 Move To/From System Register Instructions inline void Assembler::mtlr( Register s1) { emit_int32(MTLR_OPCODE | rs(s1)); } inline void Assembler::mflr( Register d ) { emit_int32(MFLR_OPCODE | rt(d)); } diff --git a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp index 609420a675b..5044e80a0a9 100644 --- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp @@ -2489,6 +2489,11 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, __ verify_oop(R3_RET); } + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ load_const_optimized(R0, 0L); + __ st_ptr(R0, JavaThread::pending_jni_exception_check_fn_offset(), R16_thread); + } // Reset handle block. // -------------------------------------------------------------------------- diff --git a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp index c37887fd9cf..959ee898504 100644 --- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp @@ -1544,6 +1544,12 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { __ fence(); } + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ load_const_optimized(R0, 0L); + __ st_ptr(R0, JavaThread::pending_jni_exception_check_fn_offset(), R16_thread); + } + __ reset_last_Java_frame(); // Jvmdi/jvmpi support. Whether we've got an exception pending or From 26559c033b138f937fd5bd4595ab34afa83668fe Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 27 Sep 2016 10:47:08 +0200 Subject: [PATCH 078/207] 8166765: [ppc] Port "8163014: Mysterious/wrong value for long frame local variable on 64-bit" Reviewed-by: mockner --- hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp index 70544e9366a..95234115319 100644 --- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp +++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp @@ -261,6 +261,9 @@ void InterpreterMacroAssembler::push_ptr(Register r) { } void InterpreterMacroAssembler::push_l(Register r) { + // Clear unused slot. + load_const_optimized(R0, 0L); + std(R0, 0, R15_esp); std(r, - Interpreter::stackElementSize, R15_esp); addi(R15_esp, R15_esp, - 2 * Interpreter::stackElementSize ); } From 538b312a6093ffc6bd7e5bd8d26c6eda58a02b89 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Tue, 27 Sep 2016 17:15:02 +0300 Subject: [PATCH 079/207] 8165829: Android Studio 2.x crashes with NPE at sun.lwawt.macosx.CAccessibility.getAccessibleIndexInParent Reviewed-by: serb, ptbrunet --- .../sun/lwawt/macosx/CAccessibility.java | 21 +++++++++++++------ .../awt/JavaComponentAccessibility.m | 8 +++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java index 3307e5b0e86..e8bfd053bfc 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java @@ -86,6 +86,15 @@ class CAccessibility implements PropertyChangeListener { return null; } + static T invokeAndWait(final Callable callable, final Component c, final T defValue) { + T value = null; + try { + value = LWCToolkit.invokeAndWait(callable, c); + } catch (final Exception e) { e.printStackTrace(); } + + return value != null ? value : defValue; + } + static void invokeLater(final Runnable runnable, final Component c) { try { LWCToolkit.invokeLater(runnable, c); @@ -181,7 +190,7 @@ class CAccessibility implements PropertyChangeListener { return as.isAccessibleChildSelected(index); } - }, c); + }, c, false); } public static AccessibleStateSet getAccessibleStateSet(final AccessibleContext ac, final Component c) { @@ -203,7 +212,7 @@ class CAccessibility implements PropertyChangeListener { if (ass == null) return null; return ass.contains(as); } - }, c); + }, c, false); } static String getAccessibleRoleFor(final Accessible a) { @@ -248,7 +257,7 @@ class CAccessibility implements PropertyChangeListener { public Integer call() throws Exception { return at.getCharCount(); } - }, c); + }, c, 0); } // Accessibility Threadsafety for JavaComponentAccessibility.m @@ -273,7 +282,7 @@ class CAccessibility implements PropertyChangeListener { if (ac == null) return null; return ac.getAccessibleIndexInParent(); } - }, c); + }, c, -1); } public static AccessibleComponent getAccessibleComponent(final Accessible a, final Component c) { @@ -369,7 +378,7 @@ class CAccessibility implements PropertyChangeListener { return aComp.isFocusTraversable(); } - }, c); + }, c, false); } public static Accessible accessibilityHitTest(final Container parent, final float hitPointX, final float hitPointY) { @@ -428,7 +437,7 @@ class CAccessibility implements PropertyChangeListener { return aComp.isEnabled(); } - }, c); + }, c, false); } // KCH - can we make this a postEvent instead? diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m index f716abf7055..ad2fce0e55b 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m @@ -323,11 +323,15 @@ static NSObject *sAttributeNamesLOCK = nil; + (JavaComponentAccessibility *)createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view { + JavaComponentAccessibility *ret = nil; jobject jcomponent = [(AWTView *)view awtComponent:env]; jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent); - NSString *javaRole = getJavaRole(env, jaccessible, jcomponent); + if (index >= 0) { + NSString *javaRole = getJavaRole(env, jaccessible, jcomponent); + ret = [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view]; + } (*env)->DeleteLocalRef(env, jcomponent); - return [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view]; + return ret; } + (JavaComponentAccessibility *) createWithAccessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view From 623a0bf34af19ef5400207c70e90829a9fb6dec4 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Tue, 27 Sep 2016 14:12:48 -0700 Subject: [PATCH 080/207] 8162531: solaris.fontconfig.properties needs updating Reviewed-by: serb, vadim, okutsu --- .../fontconfig/solaris.fontconfig.properties | 961 ++++++++---------- 1 file changed, 424 insertions(+), 537 deletions(-) diff --git a/jdk/make/data/fontconfig/solaris.fontconfig.properties b/jdk/make/data/fontconfig/solaris.fontconfig.properties index e1617fadd73..bbd68b5024d 100644 --- a/jdk/make/data/fontconfig/solaris.fontconfig.properties +++ b/jdk/make/data/fontconfig/solaris.fontconfig.properties @@ -1,6 +1,6 @@ # -# -# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. +# +# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -30,602 +30,489 @@ version=1 # Component Font Mappings -allfonts.chinese-gb2312=-monotype-song-medium-r-normal--*-%d-*-*-m-*-gb2312.1980-0 -allfonts.chinese-gbk=-sun-song-medium-r-normal--*-%d-*-*-c-*-gbk-0 -allfonts.chinese-gb18030-0=-fangzheng-song-medium-r-normal--*-%d-*-*-m-*-gb18030.2000-0 -allfonts.chinese-gb18030-1=-fangzheng-song-medium-r-normal--*-%d-*-*-m-*-gb18030.2000-1 -allfonts.chinese-cns11643-1=-Hanyi-Ming-Medium-r-normal--*-%d-*-*-m-*-cns11643-1 -allfonts.chinese-cns11643-2=-Hanyi-Ming-Medium-r-normal--*-%d-*-*-m-*-cns11643-2 -allfonts.chinese-cns11643-3=-Hanyi-Ming-Medium-r-normal--*-%d-*-*-m-*-cns11643-3 -allfonts.chinese-big5=-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1 -allfonts.chinese-hkscs=-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-hkscs-1 -allfonts.dingbats=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific -allfonts.japanese-x0212=-ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0 -allfonts.korean=-hanyang-kodig-medium-r-normal--*-%d-*-*-m-*-ksc5601.1987-0 -allfonts.korean-johab=-hanyang-kodig-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3 +allfonts.chinese-gb2312=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-gbk=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-gb18030-0=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-gb18030-1=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-cns11643-1=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-cns11643-2=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-cns11643-3=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-big5=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.chinese-hkscs=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.dingbats=-microsoft-wingdings-medium-r-normal--*-%d-*-*-p-*-adobe-fontspecific +allfonts.japanese-x0212=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.korean=-hanyang-gothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +allfonts.korean-johab=-hanyang-gothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 allfonts.lucida=-b&h-lucidasans-medium-r-normal-sans-*-%d-*-*-p-*-iso8859-1 -allfonts.symbol=-*-symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific +allfonts.symbol=-monotype-symbol-medium-r-normal--*-%d-*-*-p-*-adobe-symbol +allfonts.bengali=-misc-lohit bengali-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.gujarati=-misc-lohit gujarati-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.hindi=-misc-lohit hindi-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.kannada=-misc-lohit kannada-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.malayalam=-misc-lohit malayalam-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.marathi=-misc-lohit marathi-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.tamil=-misc-lohit tamil-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.telugu=-misc-lohit telugu-medium-r-normal--0-0-0-0-p-0-iso10646-1 +allfonts.dejavusans=-misc-dejavu sans-medium-r-normal--0-0-0-0-p-0-iso10646-1 -serif.plain.arabic=-monotype-naskh-medium-r-normal--*-%d-*-*-p-*-iso8859-6 -serif.plain.cyrillic-iso8859-5=-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-5 -serif.plain.cyrillic-cp1251=-monotype-times-regular-r-normal--*-%d-*-*-p-*-ansi-1251 -serif.plain.cyrillic-koi8-r=-monotype-times-regular-r-normal--*-%d-*-*-p-*-koi8-r -serif.plain.greek=-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-7 -serif.plain.hebrew=-monotype-timesnewroman-medium-r-normal--*-%d-*-*-p-*-iso8859-8 -serif.plain.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -serif.plain.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -serif.plain.latin-1=-monotype-times new roman-regular-r---*-%d-*-*-p-*-iso8859-1 -serif.plain.latin-2=-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-2 -serif.plain.latin-5=-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-9 -serif.plain.latin-7=-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-13 -serif.plain.latin-9=-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-15 -serif.plain.thai=-monotype-angsa-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0 +serif.plain.arabic=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.cyrillic-iso8859-5=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.cyrillic-cp1251=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.cyrillic-koi8-r=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.greek=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.hebrew=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.plain.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.plain.latin-1=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.latin-2=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.latin-5=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.latin-7=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.latin-9=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.plain.thai=-monotype-angsana new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 -serif.bold.arabic=-monotype-naskh-bold-r-normal--*-%d-*-*-p-*-iso8859-6 -serif.bold.cyrillic-iso8859-5=-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-5 -serif.bold.cyrillic-cp1251=-monotype-times-bold-r-normal--*-%d-*-*-p-*-ansi-1251 -serif.bold.cyrillic-koi8-r=-monotype-times-bold-r-normal--*-%d-*-*-p-*-koi8-r -serif.bold.greek=-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-7 -serif.bold.hebrew=-monotype-timesnewroman-bold-r-normal-bold-*-%d-*-*-p-*-iso8859-8 -serif.bold.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -serif.bold.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -serif.bold.latin-1=-monotype-times new roman-bold-r---*-%d-*-*-p-*-iso8859-1 -serif.bold.latin-2=-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-2 -serif.bold.latin-5=-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-9 -serif.bold.latin-7=-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-13 -serif.bold.latin-9=-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-15 -serif.bold.thai=-monotype-angsab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0 +serif.bold.arabic=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.cyrillic-iso8859-5=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.cyrillic-cp1251=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.cyrillic-koi8-r=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.greek=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.hebrew=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.bold.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.bold.latin-1=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.latin-2=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.latin-5=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.latin-7=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.latin-9=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bold.thai=-monotype-angsana new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 -serif.italic.arabic=-monotype-naskh-medium-r-normal--*-%d-*-*-p-*-iso8859-6 -serif.italic.cyrillic-iso8859-5=-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-5 -serif.italic.cyrillic-cp1251=-monotype-times-regular-i-normal--*-%d-*-*-p-*-ansi-1251 -serif.italic.cyrillic-koi8-r=-monotype-times-regular-i-normal--*-%d-*-*-p-*-koi8-r -serif.italic.greek=-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-7 -serif.italic.hebrew=-monotype-timesnewroman-medium-i-normal-italic-*-%d-*-*-p-*-iso8859-8 -serif.italic.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -serif.italic.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -serif.italic.latin-1=-monotype-times new roman-regular-i---*-%d-*-*-p-*-iso8859-1 -serif.italic.latin-2=-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-2 -serif.italic.latin-5=-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-9 -serif.italic.latin-7=-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-13 -serif.italic.latin-9=-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-15 -serif.italic.thai=-monotype-angsai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0 +serif.italic.arabic=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.cyrillic-iso8859-5=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.cyrillic-cp1251=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.cyrillic-koi8-r=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.greek=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.hebrew=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.italic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.italic.latin-1=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.latin-2=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.latin-5=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.latin-7=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.latin-9=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.italic.thai=-monotype-angsana new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 -serif.bolditalic.arabic=-monotype-naskh-bold-r-normal--*-%d-*-*-p-*-iso8859-6 -serif.bolditalic.cyrillic-iso8859-5=-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-5 -serif.bolditalic.cyrillic-cp1251=-monotype-times-bold-i-normal--*-%d-*-*-p-*-ansi-1251 -serif.bolditalic.cyrillic-koi8-r=-monotype-times-bold-i-normal--*-%d-*-*-p-*-koi8-r -serif.bolditalic.greek=-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-7 -serif.bolditalic.hebrew=-monotype-timesnewroman-bold-i-normal-bolditalic-*-%d-*-*-p-*-iso8859-8 -serif.bolditalic.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -serif.bolditalic.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -serif.bolditalic.latin-1=-monotype-times new roman-bold-i---*-%d-*-*-p-*-iso8859-1 -serif.bolditalic.latin-2=-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-2 -serif.bolditalic.latin-5=-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-9 -serif.bolditalic.latin-7=-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-13 -serif.bolditalic.latin-9=-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-15 -serif.bolditalic.thai=-monotype-angsaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0 +serif.bolditalic.arabic=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.cyrillic-iso8859-5=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.cyrillic-cp1251=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.cyrillic-koi8-r=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.greek=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.hebrew=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.bolditalic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +serif.bolditalic.latin-1=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.latin-2=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.latin-5=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.latin-7=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.latin-9=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +serif.bolditalic.thai=-monotype-angsana new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 -sansserif.plain.arabic=-monotype-naskh-medium-r-normal--*-%d-*-*-p-*-iso8859-6 -sansserif.plain.cyrillic-iso8859-5=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-5 -sansserif.plain.cyrillic-cp1251=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-ansi-1251 -sansserif.plain.cyrillic-koi8-r=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-koi8-r -sansserif.plain.greek=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-7 -sansserif.plain.hebrew=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso8859-8 -sansserif.plain.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -sansserif.plain.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -sansserif.plain.latin-1=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-1 -sansserif.plain.latin-2=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-2 -sansserif.plain.latin-5=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-9 -sansserif.plain.latin-7=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-13 -sansserif.plain.latin-9=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-15 -sansserif.plain.thai=-monotype-browa-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0 +sansserif.plain.arabic=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.cyrillic-iso8859-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.cyrillic-cp1251=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.cyrillic-koi8-r=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.greek=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.hebrew=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.plain.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.plain.latin-1=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.latin-2=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.latin-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.latin-7=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.latin-9=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.plain.thai=-monotype-browallia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 -sansserif.bold.arabic=-monotype-naskh-bold-r-normal--*-%d-*-*-p-*-iso8859-6 -sansserif.bold.cyrillic-iso8859-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-5 -sansserif.bold.cyrillic-cp1251=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-ansi-1251 -sansserif.bold.cyrillic-koi8-r=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-koi8-r -sansserif.bold.greek=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-7 -sansserif.bold.hebrew=-monotype-arial-bold-r-normal-Bold-*-%d-*-*-p-*-iso8859-8 -sansserif.bold.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -sansserif.bold.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -sansserif.bold.latin-1=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-1 -sansserif.bold.latin-2=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-2 -sansserif.bold.latin-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-9 -sansserif.bold.latin-7=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-13 -sansserif.bold.latin-9=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-15 -sansserif.bold.thai=-monotype-browab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0 +sansserif.bold.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.cyrillic-iso8859-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.cyrillic-cp1251=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.cyrillic-koi8-r=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.greek=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.hebrew=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.bold.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.bold.latin-1=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.latin-2=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.latin-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.latin-7=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.latin-9=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bold.thai=-monotype-browallia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 -sansserif.italic.arabic=-monotype-naskh-medium-r-normal--*-%d-*-*-p-*-iso8859-6 -sansserif.italic.cyrillic-iso8859-5=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-5 -sansserif.italic.cyrillic-cp1251=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-ansi-1251 -sansserif.italic.cyrillic-koi8-r=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-koi8-r -sansserif.italic.greek=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-7 -sansserif.italic.hebrew=-monotype-arial-medium-i-normal-Italic-*-%d-*-*-p-*-iso8859-8 -sansserif.italic.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -sansserif.italic.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -sansserif.italic.latin-1=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-1 -sansserif.italic.latin-2=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-2 -sansserif.italic.latin-5=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-9 -sansserif.italic.latin-7=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-13 -sansserif.italic.latin-9=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-15 -sansserif.italic.thai=-monotype-browai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0 +sansserif.italic.arabic=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.cyrillic-iso8859-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.cyrillic-cp1251=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.cyrillic-koi8-r=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.greek=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.hebrew=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.italic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.italic.latin-1=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.latin-2=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.latin-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.latin-7=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.latin-9=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.italic.thai=-monotype-browallia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 -sansserif.bolditalic.arabic=-monotype-naskh-bold-r-normal--*-%d-*-*-p-*-iso8859-6 -sansserif.bolditalic.cyrillic-iso8859-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-5 -sansserif.bolditalic.cyrillic-cp1251=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-ansi-1251 -sansserif.bolditalic.cyrillic-koi8-r=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-koi8-r -sansserif.bolditalic.greek=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-7 -sansserif.bolditalic.hebrew=-monotype-arial-bold-i-normal-BoldItalic-*-%d-*-*-p-*-iso8859-8 -sansserif.bolditalic.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -sansserif.bolditalic.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -sansserif.bolditalic.latin-1=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-1 -sansserif.bolditalic.latin-2=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-2 -sansserif.bolditalic.latin-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-9 -sansserif.bolditalic.latin-7=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-13 -sansserif.bolditalic.latin-9=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-15 -sansserif.bolditalic.thai=-monotype-browaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0 +sansserif.bolditalic.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.cyrillic-iso8859-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.cyrillic-cp1251=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.cyrillic-koi8-r=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.greek=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.hebrew=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.bolditalic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +sansserif.bolditalic.latin-1=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.latin-2=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.latin-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.latin-7=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.latin-9=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +sansserif.bolditalic.thai=-monotype-browallia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 -monospaced.plain.arabic=-monotype-akhbar-medium-r-normal--*-%d-*-*-p-*-iso8859-6 -monospaced.plain.cyrillic-iso8859-5=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-5 -monospaced.plain.cyrillic-cp1251=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-ansi-1251 -monospaced.plain.cyrillic-koi8-r=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-koi8-r -monospaced.plain.greek=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-7 -monospaced.plain.hebrew=-monotype-couriernew-medium-r-normal--*-%d-*-*-m-*-iso8859-8 -monospaced.plain.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -monospaced.plain.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -monospaced.plain.latin-1=-monotype-courier new-regular-r---*-%d-*-*-m-*-iso8859-1 -monospaced.plain.latin-2=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-2 -monospaced.plain.latin-5=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-9 -monospaced.plain.latin-7=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-13 -monospaced.plain.latin-9=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-15 -monospaced.plain.thai=-monotype-cordia-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0 +monospaced.plain.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.cyrillic-iso8859-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.cyrillic-cp1251=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.cyrillic-koi8-r=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.greek=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.hebrew=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.plain.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.plain.latin-1=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.latin-2=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.latin-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.latin-7=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.latin-9=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.plain.thai=-monotype-cordia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 -monospaced.bold.arabic=-monotype-akhbar-bold-r-normal--*-%d-*-*-p-*-iso8859-6 -monospaced.bold.cyrillic-iso8859-5=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-5 -monospaced.bold.cyrillic-cp1251=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-ansi-1251 -monospaced.bold.cyrillic-koi8-r=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-koi8-r -monospaced.bold.greek=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-7 -monospaced.bold.hebrew=-monotype-couriernew-bold-r-normal-Bold-*-%d-*-*-m-*-iso8859-8 -monospaced.bold.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -monospaced.bold.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -monospaced.bold.latin-1=-monotype-courier new-bold-r---*-%d-*-*-m-*-iso8859-1 -monospaced.bold.latin-2=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-2 -monospaced.bold.latin-5=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-9 -monospaced.bold.latin-7=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-13 -monospaced.bold.latin-9=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-15 -monospaced.bold.thai=-monotype-cordiab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0 +monospaced.bold.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.cyrillic-iso8859-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.cyrillic-cp1251=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.cyrillic-koi8-r=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.greek=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.hebrew=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.bold.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.bold.latin-1=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.latin-2=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.latin-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.latin-7=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.latin-9=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bold.thai=-monotype-cordia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 -monospaced.italic.arabic=-monotype-akhbar-medium-r-normal--*-%d-*-*-p-*-iso8859-6 -monospaced.italic.cyrillic-iso8859-5=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-5 -monospaced.italic.cyrillic-cp1251=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-ansi-1251 -monospaced.italic.cyrillic-koi8-r=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-koi8-r -monospaced.italic.greek=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-7 -monospaced.italic.hebrew=-monotype-couriernew-medium-i-normal-Italic-*-%d-*-*-m-*-iso8859-8 -monospaced.italic.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -monospaced.italic.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -monospaced.italic.latin-1=-monotype-courier new-regular-i---*-%d-*-*-m-*-iso8859-1 -monospaced.italic.latin-2=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-2 -monospaced.italic.latin-5=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-9 -monospaced.italic.latin-7=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-13 -monospaced.italic.latin-9=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-15 -monospaced.italic.thai=-monotype-cordiai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0 +monospaced.italic.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.cyrillic-iso8859-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.cyrillic-cp1251=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.cyrillic-koi8-r=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.greek=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.hebrew=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.italic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.italic.latin-1=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.latin-2=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.latin-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.latin-7=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.latin-9=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.italic.thai=-monotype-cordia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 -monospaced.bolditalic.arabic=-monotype-akhbar-bold-r-normal--*-%d-*-*-p-*-iso8859-6 -monospaced.bolditalic.cyrillic-iso8859-5=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-5 -monospaced.bolditalic.cyrillic-cp1251=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-ansi-1251 -monospaced.bolditalic.cyrillic-koi8-r=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-koi8-r -monospaced.bolditalic.greek=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-7 -monospaced.bolditalic.hebrew=-monotype-couriernew-bold-i-normal-BoldItalic-*-%d-*-*-m-*-iso8859-8 -monospaced.bolditalic.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -monospaced.bolditalic.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -monospaced.bolditalic.latin-1=-monotype-courier new-bold-i---*-%d-*-*-m-*-iso8859-1 -monospaced.bolditalic.latin-2=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-2 -monospaced.bolditalic.latin-5=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-9 -monospaced.bolditalic.latin-7=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-13 -monospaced.bolditalic.latin-9=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-15 -monospaced.bolditalic.thai=-monotype-cordiaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0 +monospaced.bolditalic.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.cyrillic-iso8859-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.cyrillic-cp1251=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.cyrillic-koi8-r=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.greek=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.hebrew=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.bolditalic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +monospaced.bolditalic.latin-1=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.latin-2=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.latin-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.latin-7=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.latin-9=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +monospaced.bolditalic.thai=-monotype-cordia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 -dialog.plain.arabic=-monotype-shayyal-medium-r-normal--*-%d-*-*-m-*-iso8859-6 -dialog.plain.cyrillic-iso8859-5=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-5 -dialog.plain.cyrillic-cp1251=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-ansi-1251 -dialog.plain.cyrillic-koi8-r=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-koi8-r -dialog.plain.greek=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-7 -dialog.plain.hebrew=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso8859-8 -dialog.plain.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialog.plain.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -dialog.plain.latin-1=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-1 -dialog.plain.latin-2=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-2 -dialog.plain.latin-5=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-9 -dialog.plain.latin-7=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-13 -dialog.plain.latin-9=-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-15 -dialog.plain.thai=-monotype-browa-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0 +dialog.plain.arabic=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.cyrillic-iso8859-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.cyrillic-cp1251=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.cyrillic-koi8-r=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.greek=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.hebrew=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.plain.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.plain.latin-1=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.latin-2=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.latin-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.latin-7=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.latin-9=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.plain.thai=-monotype-browallia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 -dialog.bold.arabic=-monotype-shayyal-bold-r-normal--*-%d-*-*-m-*-iso8859-6 -dialog.bold.cyrillic-iso8859-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-5 -dialog.bold.cyrillic-cp1251=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-ansi-1251 -dialog.bold.cyrillic-koi8-r=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-koi8-r -dialog.bold.greek=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-7 -dialog.bold.hebrew=-monotype-arial-bold-r-normal-Bold-*-%d-*-*-p-*-iso8859-8 -dialog.bold.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialog.bold.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -dialog.bold.latin-1=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-1 -dialog.bold.latin-2=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-2 -dialog.bold.latin-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-9 -dialog.bold.latin-7=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-13 -dialog.bold.latin-9=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-15 -dialog.bold.thai=-monotype-browab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0 +dialog.bold.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.cyrillic-iso8859-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.cyrillic-cp1251=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.cyrillic-koi8-r=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.greek=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.hebrew=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.bold.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.bold.latin-1=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.latin-2=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.latin-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.latin-7=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.latin-9=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bold.thai=-monotype-browallia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 -dialog.italic.arabic=-monotype-shayyal-medium-r-normal--*-%d-*-*-m-*-iso8859-6 -dialog.italic.cyrillic-iso8859-5=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-5 -dialog.italic.cyrillic-cp1251=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-ansi-1251 -dialog.italic.cyrillic-koi8-r=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-koi8-r -dialog.italic.greek=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-7 -dialog.italic.hebrew=-monotype-arial-medium-i-normal-Italic-*-%d-*-*-p-*-iso8859-8 -dialog.italic.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialog.italic.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -dialog.italic.latin-1=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-1 -dialog.italic.latin-2=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-2 -dialog.italic.latin-5=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-9 -dialog.italic.latin-7=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-13 -dialog.italic.latin-9=-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-15 -dialog.italic.thai=-monotype-browai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0 +dialog.italic.arabic=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.cyrillic-iso8859-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.cyrillic-cp1251=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.cyrillic-koi8-r=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.greek=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.hebrew=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.italic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.italic.latin-1=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.latin-2=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.latin-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.latin-7=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.latin-9=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.italic.thai=-monotype-browallia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 -dialog.bolditalic.arabic=-monotype-shayyal-bold-r-normal--*-%d-*-*-m-*-iso8859-6 -dialog.bolditalic.cyrillic-iso8859-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-5 -dialog.bolditalic.cyrillic-cp1251=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-ansi-1251 -dialog.bolditalic.cyrillic-koi8-r=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-koi8-r -dialog.bolditalic.greek=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-7 -dialog.bolditalic.hebrew=-monotype-arial-bold-i-normal-BoldItalic-*-%d-*-*-p-*-iso8859-8 -dialog.bolditalic.japanese-x0201=-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialog.bolditalic.japanese-x0208=-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0 -dialog.bolditalic.latin-1=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-1 -dialog.bolditalic.latin-2=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-2 -dialog.bolditalic.latin-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-9 -dialog.bolditalic.latin-7=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-13 -dialog.bolditalic.latin-9=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-15 -dialog.bolditalic.thai=-monotype-browaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0 +dialog.bolditalic.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.cyrillic-iso8859-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.cyrillic-cp1251=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.cyrillic-koi8-r=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.greek=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.hebrew=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.bolditalic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialog.bolditalic.latin-1=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.latin-2=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.latin-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.latin-7=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.latin-9=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialog.bolditalic.thai=-monotype-browallia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 -dialoginput.plain.arabic=-monotype-shayyal-medium-r-normal--*-%d-*-*-m-*-iso8859-6 -dialoginput.plain.cyrillic-iso8859-5=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-5 -dialoginput.plain.cyrillic-cp1251=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-ansi-1251 -dialoginput.plain.cyrillic-koi8-r=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-koi8-r -dialoginput.plain.greek=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-7 -dialoginput.plain.hebrew=-monotype-couriernew-medium-r-normal--*-%d-*-*-m-*-iso8859-8 -dialoginput.plain.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialoginput.plain.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -dialoginput.plain.latin-1=-monotype-courier new-regular-r---*-%d-*-*-m-*-iso8859-1 -dialoginput.plain.latin-2=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-2 -dialoginput.plain.latin-5=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-9 -dialoginput.plain.latin-7=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-13 -dialoginput.plain.latin-9=-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-15 -dialoginput.plain.thai=-monotype-cordia-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0 +dialoginput.plain.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.cyrillic-iso8859-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.cyrillic-cp1251=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.cyrillic-koi8-r=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.greek=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.hebrew=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.plain.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.plain.latin-1=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.latin-2=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.latin-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.latin-7=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.latin-9=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.plain.thai=-monotype-cordia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 -dialoginput.bold.arabic=-monotype-shayyal-bold-r-normal--*-%d-*-*-m-*-iso8859-6 -dialoginput.bold.cyrillic-iso8859-5=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-5 -dialoginput.bold.cyrillic-cp1251=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-ansi-1251 -dialoginput.bold.cyrillic-koi8-r=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-koi8-r -dialoginput.bold.greek=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-7 -dialoginput.bold.hebrew=-monotype-couriernew-bold-r-normal-Bold-*-%d-*-*-m-*-iso8859-8 -dialoginput.bold.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialoginput.bold.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -dialoginput.bold.latin-1=-monotype-courier new-bold-r---*-%d-*-*-m-*-iso8859-1 -dialoginput.bold.latin-2=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-2 -dialoginput.bold.latin-5=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-9 -dialoginput.bold.latin-7=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-13 -dialoginput.bold.latin-9=-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-15 -dialoginput.bold.thai=-monotype-cordiab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0 +dialoginput.bold.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.cyrillic-iso8859-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.cyrillic-cp1251=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.cyrillic-koi8-r=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.greek=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.hebrew=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.bold.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.bold.latin-1=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.latin-2=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.latin-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.latin-7=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.latin-9=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bold.thai=-monotype-cordia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 -dialoginput.italic.arabic=-monotype-shayyal-medium-r-normal--*-%d-*-*-m-*-iso8859-6 -dialoginput.italic.cyrillic-iso8859-5=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-5 -dialoginput.italic.cyrillic-cp1251=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-ansi-1251 -dialoginput.italic.cyrillic-koi8-r=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-koi8-r -dialoginput.italic.greek=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-7 -dialoginput.italic.hebrew=-monotype-couriernew-medium-i-normal-Italic-*-%d-*-*-m-*-iso8859-8 -dialoginput.italic.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialoginput.italic.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -dialoginput.italic.latin-1=-monotype-courier new-regular-i---*-%d-*-*-m-*-iso8859-1 -dialoginput.italic.latin-2=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-2 -dialoginput.italic.latin-5=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-9 -dialoginput.italic.latin-7=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-13 -dialoginput.italic.latin-9=-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-15 -dialoginput.italic.thai=-monotype-cordiai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0 +dialoginput.italic.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.cyrillic-iso8859-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.cyrillic-cp1251=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.cyrillic-koi8-r=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.greek=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.hebrew=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.italic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.italic.latin-1=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.latin-2=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.latin-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.latin-7=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.latin-9=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.italic.thai=-monotype-cordia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 -dialoginput.bolditalic.arabic=-monotype-shayyal-bold-r-normal--*-%d-*-*-m-*-iso8859-6 -dialoginput.bolditalic.cyrillic-iso8859-5=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-5 -dialoginput.bolditalic.cyrillic-cp1251=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-ansi-1251 -dialoginput.bolditalic.cyrillic-koi8-r=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-koi8-r -dialoginput.bolditalic.greek=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-7 -dialoginput.bolditalic.hebrew=-monotype-couriernew-bold-i-normal-BoldItalic-*-%d-*-*-m-*-iso8859-8 -dialoginput.bolditalic.japanese-x0201=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0 -dialoginput.bolditalic.japanese-x0208=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0 -dialoginput.bolditalic.latin-1=-monotype-courier new-bold-i---*-%d-*-*-m-*-iso8859-1 -dialoginput.bolditalic.latin-2=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-2 -dialoginput.bolditalic.latin-5=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-9 -dialoginput.bolditalic.latin-7=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-13 -dialoginput.bolditalic.latin-9=-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-15 -dialoginput.bolditalic.thai=-monotype-cordiaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0 +dialoginput.bolditalic.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.cyrillic-iso8859-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.cyrillic-cp1251=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.cyrillic-koi8-r=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.greek=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.hebrew=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.bolditalic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +dialoginput.bolditalic.latin-1=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.latin-2=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.latin-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.latin-7=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.latin-9=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +dialoginput.bolditalic.thai=-monotype-cordia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 # Search Sequences -sequence.allfonts=latin-1,dingbats,symbol +sequence.allfonts=latin-1 -sequence.allfonts.Big5=latin-1,chinese-big5,dingbats,symbol +sequence.allfonts.Big5=latin-1,chinese-big5 -sequence.allfonts.Big5-HKSCS-2001=latin-1,chinese-big5,chinese-hkscs,dingbats,symbol +sequence.allfonts.Big5-HKSCS-2001=latin-1,chinese-big5,chinese-hkscs -sequence.allfonts.windows-1251=cyrillic-cp1251,latin-1,dingbats,symbol +sequence.allfonts.windows-1251=cyrillic-cp1251,latin-1 -sequence.allfonts.GB2312=latin-1,chinese-gbk,chinese-gb2312,dingbats,symbol +sequence.allfonts.GB2312=latin-1,chinese-gb2312 -sequence.allfonts.x-eucJP-Open=latin-1,japanese-x0201,japanese-x0208,japanese-x0212,dingbats,symbol +sequence.allfonts.x-eucJP-Open=latin-1,japanese-x0201,japanese-x0208,japanese-x0212 -sequence.allfonts.EUC-KR=latin-1,korean,dingbats,symbol +sequence.allfonts.EUC-KR=latin-1,korean -sequence.allfonts.x-EUC-TW=latin-1,chinese-cns11643-1,chinese-cns11643-2,chinese-cns11643-3,dingbats,symbol +sequence.allfonts.x-EUC-TW=latin-1,chinese-cns11643-1,chinese-cns11643-2,chinese-cns11643-3 -sequence.allfonts.GBK=latin-1,chinese-gbk,dingbats,symbol +sequence.allfonts.GBK=latin-1,chinese-gbk -sequence.allfonts.GB18030=latin-1,chinese-gb18030-0,chinese-gb18030-1,dingbats,symbol +sequence.allfonts.GB18030=latin-1,chinese-gb18030-0,chinese-gb18030-1 -sequence.allfonts.ISO-8859-2=latin-2,latin-1,dingbats,symbol +sequence.allfonts.ISO-8859-2=latin-2,latin-1 -sequence.allfonts.ISO-8859-5=cyrillic-iso8859-5,latin-1,dingbats,symbol +sequence.allfonts.ISO-8859-5=cyrillic-iso8859-5,latin-1 -sequence.allfonts.ISO-8859-6=arabic,latin-1,dingbats,symbol +sequence.allfonts.ISO-8859-6=arabic,latin-1 -sequence.allfonts.ISO-8859-7=latin-1,greek,dingbats,symbol +sequence.allfonts.ISO-8859-7=latin-1,greek -sequence.allfonts.ISO-8859-8=latin-1,hebrew,dingbats,symbol +sequence.allfonts.ISO-8859-8=latin-1,hebrew -sequence.allfonts.ISO-8859-9=latin-5,latin-1,dingbats,symbol +sequence.allfonts.ISO-8859-9=latin-5,latin-1 -sequence.allfonts.ISO-8859-13=latin-7,latin-1,dingbats,symbol +sequence.allfonts.ISO-8859-13=latin-7,latin-1 -sequence.allfonts.ISO-8859-15=latin-9,dingbats,symbol +sequence.allfonts.ISO-8859-15=latin-9 -sequence.allfonts.KOI8-R=cyrillic-koi8-r,latin-1,dingbats,symbol +sequence.allfonts.KOI8-R=cyrillic-koi8-r,latin-1 -sequence.allfonts.x-PCK=latin-1,japanese-x0201,japanese-x0208,japanese-x0212,dingbats,symbol +sequence.allfonts.x-PCK=latin-1,japanese-x0201,japanese-x0208,japanese-x0212 -sequence.allfonts.TIS-620=latin-1,thai,dingbats,symbol +sequence.allfonts.TIS-620=latin-1,thai -sequence.allfonts.UTF-8=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ - japanese-x0201,japanese-x0208,japanese-x0212,korean-johab,\ - chinese-gb2312,chinese-big5,dingbats,symbol +sequence.allfonts.UTF-8=latin-1 +sequence.allfonts.UTF-8.en=latin-1 +sequence.allfonts.UTF-8.hi=latin-1,hindi +sequence.allfonts.UTF-8.be=latin-1,bengali +sequence.allfonts.UTF-8.te=latin-1,telugu +sequence.allfonts.UTF-8.mr=latin-1,marathi +sequence.allfonts.UTF-8.ta=latin-1,tamil +sequence.allfonts.UTF-8.gu=latin-1,gujarati +sequence.allfonts.UTF-8.kn=latin-1,kannada +sequence.allfonts.UTF-8.ma=latin-1,malayalam -sequence.allfonts.UTF-8.hi=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ - japanese-x0201,japanese-x0208,japanese-x0212,korean-johab,\ - chinese-gb2312,chinese-big5,thai,dingbats,symbol +sequence.allfonts.UTF-8.ko=latin-1,korean-johab,japanese-x0201,japanese-x0208,japanese-x0212 -sequence.allfonts.UTF-8.ko=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ - korean-johab,japanese-x0201,japanese-x0208,japanese-x0212,\ - chinese-gb2312,chinese-big5,dingbats,symbol +sequence.allfonts.UTF-8.th=latin-1,thai -sequence.allfonts.UTF-8.th=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ - thai,chinese-gb2312,chinese-big5,japanese-x0201,japanese-x0208,japanese-x0212,\ - korean-johab,dingbats,symbol +sequence.allfonts.UTF-8.zh.CN=latin-1,chinese-gb18030-0,chinese-gb18030-1,chinese-big5,chinese-hkscs -sequence.allfonts.UTF-8.zh.CN=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ - chinese-gb18030-0,chinese-gb18030-1,chinese-big5,chinese-hkscs,\ - japanese-x0201,japanese-x0208,japanese-x0212,korean-johab,thai,dingbats,symbol +sequence.allfonts.UTF-8.zh.HK=latin-1,chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1 -sequence.allfonts.UTF-8.zh.HK=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ - chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1,\ - japanese-x0201,japanese-x0208,japanese-x0212,korean-johab,thai,dingbats,symbol - -sequence.allfonts.UTF-8.zh.TW=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ - chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1,\ - japanese-x0201,japanese-x0208,japanese-x0212,korean-johab,thai,dingbats,symbol +sequence.allfonts.UTF-8.zh.TW=latin-1,chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1 # the fallback sequence omits the following character subsets: -# - latin-1, latin-2, latin-5, latin-7, latin-9: characters covered by lucida -# - cyrillic-cp1251, cyrillic-iso8859-5, cyrillic-koi8-r: characters covered by lucida -# - arabic, devanagari, greek, hebrew, thai: characters covered by lucida -# - chinese-cns11643-1, chinese-cns11643-2, chinese-cns11643-3, chinese-hkscs: same file as chinese-big5 -# - chinese-gbk, chinese-gb18030-1: same file as chinese-gb18030-0 +# - chinese: all same file : just use chinese-gb18030-0 # - japanese-x0208: same files as japanese-x0201 # - japanese-x0212: same files as japanese-x0201 # - korean: same file as korean-johab -# - dingbats, symbol: included in all core sequences -sequence.fallback=lucida,\ - chinese-big5,chinese-gb2312,chinese-gb18030-0,\ - japanese-x0201,korean-johab - -# Exclusion Ranges - -exclusion.chinese-cns11643-2=0390-03d6,2200-22ef,2701-27be -exclusion.chinese-cns11643-3=0390-03d6,2200-22ef,2701-27be +sequence.fallback=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ + arabic,hebrew,thai,lucida,\ + chinese-gb18030-0,\ + japanese-x0201,korean-johab,\ + hindi,bengali,telugu,marathi,tamil,gujarati,kannada,malayalam,\ + dejavusans,dingbats,symbol # Font File Names -filename.-*-symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific=/usr/openwin/lib/X11/fonts/TrueType/Symbol.ttf +filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arial.ttf +filename.-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/ariali.ttf +filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialb.ttf +filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbi.ttf +filename.-monotype-courier_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cour.ttf +filename.-monotype-courier_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/couri.ttf +filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courb.ttf +filename.-monotype-courier_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbi.ttf +filename.-monotype-times_new_roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/times.ttf +filename.-monotype-times_new_roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesi.ttf +filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesb.ttf +filename.-monotype-times_new_roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbi.ttf + +filename.-monotype-angsana_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsa.ttf +filename.-monotype-angsana_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsai.ttf +filename.-monotype-angsana_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsab.ttf +filename.-monotype-angsana_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsaz.ttf +filename.-monotype-browallia_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browa.ttf +filename.-monotype-browallia_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browai.ttf +filename.-monotype-browallia_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browab.ttf +filename.-monotype-browallia_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browaz.ttf +filename.-monotype-cordia_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordia.ttf +filename.-monotype-cordia_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordiai.ttf +filename.-monotype-cordia_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordiab.ttf +filename.-monotype-cordia_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordiaz.ttf + +filename.-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/ipafont/ipag.otf +filename.-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/ipafont/ipam.otf +filename.-hanyang-gothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/hanyang/h2gtrm.ttf +filename.-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/arphic/uming.ttf +filename.-monotype-symbol-medium-r-normal--*-%d-*-*-p-*-adobe-symbol=/usr/share/fonts/TrueType/core/symbol.ttf +filename.-microsoft-wingdings-medium-r-normal--*-%d-*-*-p-*-adobe-fontspecific=/usr/share/fonts/TrueType/core/wingdings.ttf filename.-b&h-lucidasans-medium-r-normal-sans-*-%d-*-*-p-*-iso8859-1=$JRE_LIB_FONTS/LucidaSansRegular.ttf -filename.-fangzheng-song-medium-r-normal--*-%d-*-*-m-*-gb18030.2000-0=/usr/openwin/lib/locale/zh_CN.GB18030/X11/fonts/TrueType/songti.ttf -filename.-fangzheng-song-medium-r-normal--*-%d-*-*-m-*-gb18030.2000-1=/usr/openwin/lib/locale/zh_CN.GB18030/X11/fonts/TrueType/songti.ttf -filename.-hanyang-kodig-medium-r-normal--*-%d-*-*-m-*-ksc5601.1987-0=/usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType/h2gtrm.ttf -filename.-hanyang-kodig-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3=/usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType/h2gtrm.ttf -filename.-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1=/usr/openwin/lib/locale/zh_TW.BIG5/X11/fonts/TT/ming.ttf -filename.-Hanyi-Ming-Medium-r-normal--*-%d-*-*-m-*-cns11643-1=/usr/openwin/lib/locale/zh_TW.BIG5/X11/fonts/TT/ming.ttf -filename.-Hanyi-Ming-Medium-r-normal--*-%d-*-*-m-*-cns11643-2=/usr/openwin/lib/locale/zh_TW.BIG5/X11/fonts/TT/ming.ttf -filename.-Hanyi-Ming-Medium-r-normal--*-%d-*-*-m-*-cns11643-3=/usr/openwin/lib/locale/zh_TW.BIG5/X11/fonts/TT/ming.ttf -filename.-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-hkscs-1=/usr/openwin/lib/locale/zh_TW.BIG5/X11/fonts/TT/ming.ttf -filename.-monotype-akhbar-bold-r-normal--*-%d-*-*-p-*-iso8859-6=/usr/openwin/lib/locale/ar/X11/fonts/TrueType/AKHBARBD.ttf -filename.-monotype-akhbar-medium-r-normal--*-%d-*-*-p-*-iso8859-6=/usr/openwin/lib/locale/ar/X11/fonts/TrueType/AKHBARMT.ttf -filename.-monotype-angsa-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/angsa.ttf -filename.-monotype-angsab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/angsab.ttf -filename.-monotype-angsai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/angsai.ttf -filename.-monotype-angsaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/angsaz.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/Arial-BoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBoldItalic.ttf -filename.-monotype-arial-bold-i-normal-BoldItalic-*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/arialbih.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/Arial-Bold.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-bold-r-normal-Bold-*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/arialb_h.ttf -filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialBold.ttf -filename.-monotype-arial-medium-i-normal-Italic-*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/ariali_h.ttf -filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/arial__h.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/Arial-Italic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-i-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialItalic.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/Arial.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-arial-regular-r-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/ArialRegular.ttf -filename.-monotype-browa-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/browa.ttf -filename.-monotype-browab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/browab.ttf -filename.-monotype-browai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/browai.ttf -filename.-monotype-browaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/browaz.ttf -filename.-monotype-cordia-medium-r-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/cordia.ttf -filename.-monotype-cordiab-bold-r-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/cordiab.ttf -filename.-monotype-cordiai-medium-i-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/cordiai.ttf -filename.-monotype-cordiaz-bold-i-normal--*-%d-*-*-m-*-tis620.2533-0=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType/cordiaz.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-i-normal--*-%d-*-*-m-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBoldItalic.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-bold-r-normal--*-%d-*-*-m-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierBold.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-i-normal--*-%d-*-*-m-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierItalic.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier-regular-r-normal--*-%d-*-*-m-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/CourierRegular.ttf -filename.-monotype-courier_new-bold-i---*-%d-*-*-m-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/CourierNew-BoldItalic.ttf -filename.-monotype-courier_new-bold-r---*-%d-*-*-m-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/CourierNew-Bold.ttf -filename.-monotype-courier_new-regular-i---*-%d-*-*-m-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/CourierNew-Italic.ttf -filename.-monotype-courier_new-regular-r---*-%d-*-*-m-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/CourierNew.ttf -filename.-monotype-couriernew-bold-i-normal-BoldItalic-*-%d-*-*-m-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/courbi_h.ttf -filename.-monotype-couriernew-bold-r-normal-Bold-*-%d-*-*-m-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/courb__h.ttf -filename.-monotype-couriernew-medium-i-normal-Italic-*-%d-*-*-m-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/couri__h.ttf -filename.-monotype-couriernew-medium-r-normal--*-%d-*-*-m-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/cour___h.ttf -filename.-monotype-naskh-bold-r-normal--*-%d-*-*-p-*-iso8859-6=/usr/openwin/lib/locale/ar/X11/fonts/TrueType/NASKHBD.ttf -filename.-monotype-naskh-medium-r-normal--*-%d-*-*-p-*-iso8859-6=/usr/openwin/lib/locale/ar/X11/fonts/TrueType/NASKHMT.ttf -filename.-monotype-shayyal-bold-r-normal--*-%d-*-*-m-*-iso8859-6=/usr/openwin/lib/locale/ar/X11/fonts/TrueType/SHAYBD.ttf -filename.-monotype-shayyal-medium-r-normal--*-%d-*-*-m-*-iso8859-6=/usr/openwin/lib/locale/ar/X11/fonts/TrueType/SHAYMT.ttf -filename.-monotype-song-medium-r-normal--*-%d-*-*-m-*-gb2312.1980-0=/usr/openwin/lib/locale/zh/X11/fonts/TrueType/msgbl.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBoldItalic.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesBold.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesItalic.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-ansi-1251=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-13=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-15=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-2=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-5=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-7=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-9=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times-regular-r-normal--*-%d-*-*-p-*-koi8-r=/usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType/TimesRegular.ttf -filename.-monotype-times_new_roman-bold-i---*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/TimesNewRoman-BoldItalic.ttf -filename.-monotype-times_new_roman-bold-r---*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/TimesNewRoman-Bold.ttf -filename.-monotype-times_new_roman-regular-i---*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/TimesNewRoman-Italic.ttf -filename.-monotype-times_new_roman-regular-r---*-%d-*-*-p-*-iso8859-1=/usr/openwin/lib/X11/fonts/TrueType/TimesNewRoman.ttf -filename.-monotype-timesnewroman-bold-i-normal-bolditalic-*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/timesbih.ttf -filename.-monotype-timesnewroman-bold-r-normal-bold-*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/timesb_h.ttf -filename.-monotype-timesnewroman-medium-i-normal-italic-*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/timesi_h.ttf -filename.-monotype-timesnewroman-medium-r-normal--*-%d-*-*-p-*-iso8859-8=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType/times__h.ttf -filename.-ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0=/usr/openwin/lib/locale/ja/X11/fonts/TT/hgmlsun.ttf -filename.-ricoh-hg_gothic_b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0=/usr/openwin/lib/locale/ja/X11/fonts/TT/hggbsun.ttf -filename.-ricoh-hg_gothic_b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0=/usr/openwin/lib/locale/ja/X11/fonts/TT/hggbsun.ttf -filename.-ricoh-hg_mincho_l-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0=/usr/openwin/lib/locale/ja/X11/fonts/TT/hgmlsun.ttf -filename.-ricoh-hg_mincho_l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0=/usr/openwin/lib/locale/ja/X11/fonts/TT/hgmlsun.ttf -filename.-sun-song-medium-r-normal--*-%d-*-*-c-*-gbk-0=/usr/openwin/lib/locale/zh_CN.GB18030/X11/fonts/TrueType/songti.ttf -filename.-urw-itc_zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific=/usr/openwin/lib/X11/fonts/TrueType/MonotypeSorts.ttf +filename.-misc-lohit_bengali-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Bengali.ttf +filename.-misc-lohit_gujarati-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Gujarati.ttf +filename.-misc-lohit_hindi-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Hindi.ttf +filename.-misc-lohit_kannada-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Kannada.ttf +filename.-misc-lohit_malayalam-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Malayalam.ttf +filename.-misc-lohit_marathi-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Marathi.ttf +filename.-misc-lohit_tamil-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Tamil.ttf +filename.-misc-lohit_telugu-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Telugu.ttf +filename.-misc-dejavu_sans-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/dejavu/DejaVuSans.ttf # AWT X11 font paths -awtfontpath.latin-1=/usr/openwin/lib/X11/fonts/TrueType -awtfontpath.latin-2=/usr/openwin/lib/locale/iso_8859_2/X11/fonts/TrueType -awtfontpath.latin-5=/usr/openwin/lib/locale/iso_8859_9/X11/fonts/TrueType -awtfontpath.latin-7=/usr/openwin/lib/locale/iso_8859_13/X11/fonts/TrueType -awtfontpath.latin-9=/usr/openwin/lib/locale/iso_8859_15/X11/fonts/TrueType -awtfontpath.hebrew=/usr/openwin/lib/locale/iso_8859_8/X11/fonts/TrueType -awtfontpath.arabic=/usr/openwin/lib/locale/ar/X11/fonts/TrueType -awtfontpath.thai=/usr/openwin/lib/locale/th_TH/X11/fonts/TrueType -awtfontpath.greek=/usr/openwin/lib/locale/iso_8859_7/X11/fonts/TrueType -awtfontpath.cyrillic-iso8859-5=/usr/openwin/lib/locale/iso_8859_5/X11/fonts/TrueType -awtfontpath.cyrillic-cp1251=/usr/openwin/lib/locale/ru.ansi-1251/X11/fonts/TrueType -awtfontpath.cyrillic-koi8-r=/usr/openwin/lib/locale/KOI8-R/X11/fonts/TrueType -awtfontpath.korean=/usr/openwin/lib/locale/ko/X11/fonts/TrueType -awtfontpath.korean-johab=/usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType -awtfontpath.japanese-x0201=/usr/openwin/lib/locale/ja/X11/fonts/TT -awtfontpath.japanese-x0208=/usr/openwin/lib/locale/ja/X11/fonts/TT -awtfontpath.japanese-x0212=/usr/openwin/lib/locale/ja/X11/fonts/TT -awtfontpath.chinese-gbk=/usr/openwin/lib/locale/zh.GBK/X11/fonts/TrueType -awtfontpath.chinese-cns11643-1=/usr/openwin/lib/locale/zh_TW/X11/fonts/TrueType -awtfontpath.chinese-cns11643-2=/usr/openwin/lib/locale/zh_TW/X11/fonts/TrueType -awtfontpath.chinese-cns11643-3=/usr/openwin/lib/locale/zh_TW/X11/fonts/TrueType -awtfontpath.chinese-big5=/usr/openwin/lib/locale/zh_TW.BIG5/X11/fonts/TT -awtfontpath.chinese-gb2312=/usr/openwin/lib/locale/zh/X11/fonts/TrueType -awtfontpath.chinese-gb18030-0=/usr/openwin/lib/locale/zh_CN.GB18030/X11/fonts/TrueType -awtfontpath.chinese-gb18030-1=/usr/openwin/lib/locale/zh_CN.GB18030/X11/fonts/TrueType -awtfontpath.chinese-hkscs=/usr/openwin/lib/locale/zh_HK.BIG5HK/X11/fonts/TT +awtfontpath.latin-1=/usr/share/fonts/TrueType/core +awtfontpath.latin-2=/usr/share/fonts/TrueType/core +awtfontpath.latin-5=/usr/share/fonts/TrueType/core +awtfontpath.latin-7=/usr/share/fonts/TrueType/core +awtfontpath.latin-9=/usr/share/fonts/TrueType/core +awtfontpath.hebrew=/usr/share/fonts/TrueType/core +awtfontpath.arabic=/usr/share/fonts/TrueType/core +awtfontpath.thai=/usr/share/fonts/TrueType/core +awtfontpath.greek=/usr/share/fonts/TrueType/core +awtfontpath.cyrillic-iso8859-5=/usr/share/fonts/TrueType/core +awtfontpath.cyrillic-cp1251=/usr/share/fonts/TrueType/core +awtfontpath.cyrillic-koi8-r=/usr/share/fonts/TrueType/core +awtfontpath.korean=/usr/share/fonts/TrueType/hanyang +awtfontpath.korean-johab=/usr/share/fonts/TrueType/hanyang +awtfontpath.japanese-x0201=/usr/share/fonts/TrueType/ipafont +awtfontpath.japanese-x0208=/usr/share/fonts/TrueType/ipafont +awtfontpath.japanese-x0212=/usr/share/fonts/TrueType/ipafont +awtfontpath.chinese-gbk=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-cns11643-1=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-cns11643-2=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-cns11643-3=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-big5=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-gb2312=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-gb18030-0=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-gb18030-1=/usr/share/fonts/TrueType/arphic +awtfontpath.chinese-hkscs=/usr/share/fonts/TrueType/arphic +awtfontpath.bengali=/usr/share/fonts/TrueType/lohit +awtfontpath.gujarati=/usr/share/fonts/TrueType/lohit +awtfontpath.hindi=/usr/share/fonts/TrueType/lohit +awtfontpath.kannada=/usr/share/fonts/TrueType/lohit +awtfontpath.malayalam=/usr/share/fonts/TrueType/lohit +awtfontpath.marathi=/usr/share/fonts/TrueType/lohit +awtfontpath.tamil=/usr/share/fonts/TrueType/lohit +awtfontpath.telugu=/usr/share/fonts/TrueType/lohit +awtfontpath.dejavusans=/usr/share/fonts/TrueType/dejavu # Appended Font Path - - From f0cac034bd52cb8344876694ff68f4bcb09e05ad Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Wed, 28 Sep 2016 03:40:45 +0300 Subject: [PATCH 081/207] 8164536: enableSuddenTermination() - Not throws SecurityException if a security manager exists and it will not allow the caller to invoke System.exit Reviewed-by: serb, ssadetsky --- .../share/classes/java/awt/Desktop.java | 65 ++++++++++++------- .../share/classes/java/awt/Taskbar.java | 53 +++++++-------- 2 files changed, 68 insertions(+), 50 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/java/awt/Desktop.java b/jdk/src/java.desktop/share/classes/java/awt/Desktop.java index f738fd78203..fac3def4de0 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Desktop.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Desktop.java @@ -271,6 +271,14 @@ public class Desktop { } } + private void checkEventsProcessingPermission() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new RuntimePermission( + "canProcessApplicationEvents")); + } + } + /** * Returns the {@code Desktop} instance of the current * desktop context. On some platforms the Desktop API may not be @@ -662,7 +670,7 @@ public class Desktop { * * @throws SecurityException if a security manager exists and it * denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} + * {@code RuntimePermission("canProcessApplicationEvents")} * permission * * @see java.awt.desktop.AppForegroundListener @@ -674,7 +682,7 @@ public class Desktop { * @since 9 */ public void addAppEventListener(final SystemEventListener listener) { - checkAWTPermission(); + checkEventsProcessingPermission(); peer.addAppEventListener(listener); } @@ -689,7 +697,7 @@ public class Desktop { * * @throws SecurityException if a security manager exists and it * denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} + * {@code RuntimePermission("canProcessApplicationEvents")} * permission * * @see java.awt.desktop.AppForegroundListener @@ -701,7 +709,7 @@ public class Desktop { * @since 9 */ public void removeAppEventListener(final SystemEventListener listener) { - checkAWTPermission(); + checkEventsProcessingPermission(); peer.removeAppEventListener(listener); } @@ -716,7 +724,7 @@ public class Desktop { * * @throws SecurityException if a security manager exists and it * denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} + * {@code RuntimePermission("canProcessApplicationEvents")} * permission * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_ABOUT} action @@ -724,7 +732,7 @@ public class Desktop { * @since 9 */ public void setAboutHandler(final AboutHandler aboutHandler) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkActionSupport(Action.APP_ABOUT); peer.setAboutHandler(aboutHandler); } @@ -741,14 +749,13 @@ public class Desktop { * * @throws SecurityException if a security manager exists and it * denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} - * permission + * {@code RuntimePermission("canProcessApplicationEvents")} permission * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_PREFERENCES} action * @since 9 */ public void setPreferencesHandler(final PreferencesHandler preferencesHandler) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkActionSupport(Action.APP_PREFERENCES); peer.setPreferencesHandler(preferencesHandler); } @@ -770,7 +777,7 @@ public class Desktop { * @throws SecurityException if a security manager exists and its * {@link java.lang.SecurityManager#checkRead(java.lang.String)} * method denies read access to the files, or it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} + * {@code RuntimePermission("canProcessApplicationEvents")} * permission, or the calling thread is not allowed to create a * subprocess * @throws UnsupportedOperationException if the current platform @@ -778,7 +785,7 @@ public class Desktop { * @since 9 */ public void setOpenFileHandler(final OpenFilesHandler openFileHandler) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkExec(); checkRead(); checkActionSupport(Action.APP_OPEN_FILE); @@ -800,12 +807,14 @@ public class Desktop { * @param printFileHandler handler * @throws SecurityException if a security manager exists and its * {@link java.lang.SecurityManager#checkPrintJobAccess()} method denies - * the permission to print. + * the permission to print or it denies the + * {@code RuntimePermission("canProcessApplicationEvents")} permission * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_PRINT_FILE} action * @since 9 */ public void setPrintFileHandler(final PrintFilesHandler printFileHandler) { + checkEventsProcessingPermission(); SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPrintJobAccess(); @@ -832,7 +841,7 @@ public class Desktop { * * @param openURIHandler handler * - * {@code AWTPermission("showWindowWithoutWarningBanner")} + * {@code RuntimePermission("canProcessApplicationEvents")} * permission, or the calling thread is not allowed to create a * subprocess * @throws UnsupportedOperationException if the current platform @@ -840,7 +849,7 @@ public class Desktop { * @since 9 */ public void setOpenURIHandler(final OpenURIHandler openURIHandler) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkExec(); checkActionSupport(Action.APP_OPEN_URI); peer.setOpenURIHandler(openURIHandler); @@ -856,12 +865,14 @@ public class Desktop { * asked to quit * * @throws SecurityException if a security manager exists and it - * will not allow the caller to invoke {@code System.exit} + * will not allow the caller to invoke {@code System.exit} or it denies the + * {@code RuntimePermission("canProcessApplicationEvents")} permission * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_QUIT_HANDLER} action * @since 9 */ public void setQuitHandler(final QuitHandler quitHandler) { + checkEventsProcessingPermission(); checkQuitPermission(); checkActionSupport(Action.APP_QUIT_HANDLER); peer.setQuitHandler(quitHandler); @@ -874,13 +885,15 @@ public class Desktop { * @param strategy the way this application should be shutdown * * @throws SecurityException if a security manager exists and it - * will not allow the caller to invoke {@code System.exit} + * will not allow the caller to invoke {@code System.exit} or it denies the + * {@code RuntimePermission("canProcessApplicationEvents")} permission * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_QUIT_STRATEGY} action * @see QuitStrategy * @since 9 */ public void setQuitStrategy(final QuitStrategy strategy) { + checkEventsProcessingPermission(); checkQuitPermission(); checkActionSupport(Action.APP_QUIT_STRATEGY); peer.setQuitStrategy(strategy); @@ -901,13 +914,15 @@ public class Desktop { * effectively "kill -KILL" your application. * * @throws SecurityException if a security manager exists and it - * will not allow the caller to invoke {@code System.exit} + * will not allow the caller to invoke {@code System.exit} or it denies the + * {@code RuntimePermission("canProcessApplicationEvents")} permission * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action * @see #disableSuddenTermination() * @since 9 */ public void enableSuddenTermination() { + checkEventsProcessingPermission(); checkQuitPermission(); checkActionSupport(Action.APP_SUDDEN_TERMINATION); peer.enableSuddenTermination(); @@ -920,13 +935,15 @@ public class Desktop { * may not be terminated without notification. * * @throws SecurityException if a security manager exists and it - * will not allow the caller to invoke {@code System.exit} + * will not allow the caller to invoke {@code System.exit} or it denies the + * {@code RuntimePermission("canProcessApplicationEvents")} permission * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action * @see #enableSuddenTermination() * @since 9 */ public void disableSuddenTermination() { + checkEventsProcessingPermission(); checkQuitPermission(); checkActionSupport(Action.APP_SUDDEN_TERMINATION); peer.disableSuddenTermination(); @@ -938,13 +955,13 @@ public class Desktop { * @param allWindows if all windows of this application should be moved to * the foreground, or only the foremost one * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_REQUEST_FOREGROUND} action * @since 9 */ public void requestForeground(final boolean allWindows) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkActionSupport(Action.APP_REQUEST_FOREGROUND); peer.requestForeground(allWindows); } @@ -957,13 +974,13 @@ public class Desktop { * and registered in the Info.plist with CFBundleHelpBookFolder * * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_HELP_VIEWER} action * @since 9 */ public void openHelpViewer() { - checkAWTPermission(); + checkEventsProcessingPermission(); checkActionSupport(Action.APP_HELP_VIEWER); peer.openHelpViewer(); } @@ -975,13 +992,13 @@ public class Desktop { * * @param menuBar to use when no other frames are active * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Desktop.Action#APP_MENU_BAR} action * @since 9 */ public void setDefaultMenuBar(final JMenuBar menuBar) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkActionSupport(Action.APP_MENU_BAR); peer.setDefaultMenuBar(menuBar); } diff --git a/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java b/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java index 22710085e83..5510da3bdac 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java @@ -179,14 +179,13 @@ public class Taskbar { /** * Calls to the security manager's {@code checkPermission} method with - * an {@code AWTPermission("showWindowWithoutWarningBanner")} - * permission. + * an {@code RuntimePermission("canProcessApplicationEvents")} permissions. */ - private void checkAWTPermission(){ + private void checkEventsProcessingPermission(){ SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new AWTPermission( - "showWindowWithoutWarningBanner")); + sm.checkPermission(new RuntimePermission( + "canProcessApplicationEvents")); } } @@ -262,12 +261,12 @@ public class Taskbar { * @param enabled disables this request if false * @param critical if this is an important request * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#USER_ATTENTION} feature */ public void requestUserAttention(final boolean enabled, final boolean critical) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.USER_ATTENTION); peer.requestUserAttention(enabled, critical); } @@ -277,12 +276,12 @@ public class Taskbar { * * @param w window * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#USER_ATTENTION_WINDOW} feature */ public void requestWindowUserAttention(Window w) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.USER_ATTENTION_WINDOW); peer.requestWindowUserAttention(w); } @@ -293,12 +292,12 @@ public class Taskbar { * * @param menu the PopupMenu to attach to this application * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#MENU} feature */ public void setMenu(final PopupMenu menu) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.MENU); peer.setMenu(menu); } @@ -308,12 +307,12 @@ public class Taskbar { * * @return the PopupMenu * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#MENU} feature */ public PopupMenu getMenu() { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.MENU); return peer.getMenu(); } @@ -323,12 +322,12 @@ public class Taskbar { * * @param image to change * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature */ public void setIconImage(final Image image) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_IMAGE); peer.setIconImage(image); } @@ -338,12 +337,12 @@ public class Taskbar { * * @return an image of this application's icon * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature */ public Image getIconImage() { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_IMAGE); return peer.getIconImage(); } @@ -360,13 +359,13 @@ public class Taskbar { * Passing {@code null} as parameter hides the badge. * @param badge label to affix to the icon * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#ICON_BADGE_NUMBER} * or {@link Taskbar.Feature#ICON_BADGE_TEXT} feature */ public void setIconBadge(final String badge) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_BADGE_NUMBER); peer.setIconBadge(badge); } @@ -379,12 +378,12 @@ public class Taskbar { * @param w window to update * @param badge image to affix to the icon * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#ICON_BADGE_IMAGE_WINDOW} feature */ public void setWindowIconBadge(Window w, final Image badge) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_BADGE_IMAGE_WINDOW); if (w != null) { peer.setWindowIconBadge(w, badge); @@ -396,11 +395,13 @@ public class Taskbar { * Affixes a small system-provided progress bar to this application's icon. * * @param value from 0 to 100, other to disable progress indication + * @throws SecurityException if a security manager exists and it denies the + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#PROGRESS_VALUE} feature */ public void setProgressValue(int value) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.PROGRESS_VALUE); peer.setProgressValue(value); } @@ -411,12 +412,12 @@ public class Taskbar { * @param w window to update * @param value from 0 to 100, other to disable progress indication * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#PROGRESS_VALUE_WINDOW} feature */ public void setWindowProgressValue(Window w, int value) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.PROGRESS_VALUE_WINDOW); if (w != null) { peer.setWindowProgressValue(w, value); @@ -434,12 +435,12 @@ public class Taskbar { * @see State#INDETERMINATE * @see State#ERROR * @throws SecurityException if a security manager exists and it denies the - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. + * {@code RuntimePermission("canProcessApplicationEvents")} permission. * @throws UnsupportedOperationException if the current platform * does not support the {@link Taskbar.Feature#PROGRESS_STATE_WINDOW} feature */ public void setWindowProgressState(Window w, State state) { - checkAWTPermission(); + checkEventsProcessingPermission(); checkFeatureSupport(Feature.PROGRESS_STATE_WINDOW); if (w != null) { peer.setWindowProgressState(w, state); From 517cfed246af86805b3df88ae141f4c38e71034a Mon Sep 17 00:00:00 2001 From: Srikanth Adayapalam Date: Wed, 28 Sep 2016 09:05:20 +0530 Subject: [PATCH 082/207] 8166363: Method with reordered type parameter bounds compiles with @Override annotation but does not actually override superclass method Reviewed-by: vromero --- .../com/sun/tools/javac/comp/TransTypes.java | 8 +-- .../generics/bridges/ReorderedBoundsTest.java | 65 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/javac/generics/bridges/ReorderedBoundsTest.java diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java index 9f2ff731f2e..3e9b2ae4107 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -415,10 +415,10 @@ public class TransTypes extends TreeTranslator { if (!isSameMemberWhenErased(dest, impl, impl_erasure)) return true; - // If the erasure of the return type is different, a - // bridge is needed. - return !types.isSameType(impl_erasure.getReturnType(), - method_erasure.getReturnType()); + /* Bottom line: A bridge is needed if the erasure of the implementation + is different from that of the method that it overrides. + */ + return !types.isSameType(impl_erasure, method_erasure); } else { // method and impl are the same... if ((method.flags() & ABSTRACT) != 0) { diff --git a/langtools/test/tools/javac/generics/bridges/ReorderedBoundsTest.java b/langtools/test/tools/javac/generics/bridges/ReorderedBoundsTest.java new file mode 100644 index 00000000000..0fdaae8a40b --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/ReorderedBoundsTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8166363 + * @summary Method with reordered type parameter bounds compiles with Override annotation but does not actually override superclass method. + * @run main ReorderedBoundsTest + */ + +import java.io.Serializable; + +public class ReorderedBoundsTest { + public static class Parent { + public String printClassName(T t) { + return "Parent"; + } + } + + public static class OrderedChild extends Parent { + @Override + public String printClassName(T t) { + return "OrderedChild"; + } + } + + public static class ReorderedChild extends Parent { + @Override + public String printClassName(T t) { + return "ReorderedChild"; + } + } + + public static void main(String[] args) { + + String s; + Parent p = new OrderedChild(); + if (!(s = p.printClassName(new StringBuilder())).equals("OrderedChild")) + throw new AssertionError("Bad output: " + s); + + p = new ReorderedChild(); + if (!(s = p.printClassName(new StringBuilder())).equals("ReorderedChild")) + throw new AssertionError("Bad output: " + s); + } +} \ No newline at end of file From b9ad123afae6f1bb837fa265c11beae5083b0166 Mon Sep 17 00:00:00 2001 From: Shinya Yoshida Date: Wed, 28 Sep 2016 16:36:10 +0900 Subject: [PATCH 083/207] 8154714: jshell tool: add exports support Reviewed-by: jlahoda, rfield --- .../jdk/internal/jshell/tool/JShellTool.java | 31 +++++++++++++++++-- .../jshell/tool/resources/l10n.properties | 9 +++++- langtools/test/jdk/jshell/ToolBasicTest.java | 18 ++++++++++- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index 203132444f2..6cfb6e13c89 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -199,6 +199,7 @@ public class JShellTool implements MessageHandler { private boolean feedbackInitialized = false; private String commandLineFeedbackMode = null; private List remoteVMOptions = new ArrayList<>(); + private List compilerOptions = new ArrayList<>(); SourceCodeAnalysis analysis; JShell state = null; @@ -558,9 +559,14 @@ public class JShellTool implements MessageHandler { parser.accepts("s"); parser.accepts("v"); OptionSpec r = parser.accepts("R").withRequiredArg(); + OptionSpec c = parser.accepts("C").withRequiredArg(); parser.acceptsAll(asList("h", "help")); parser.accepts("version"); parser.accepts("full-version"); + + parser.accepts("X"); + OptionSpec addExports = parser.accepts("add-exports").withRequiredArg(); + NonOptionArgumentSpec loadFileSpec = parser.nonOptions(); OptionSet options; @@ -585,6 +591,10 @@ public class JShellTool implements MessageHandler { printUsage(); return null; } + if (options.has("X")) { + printUsageX(); + return null; + } if (options.has("version")) { cmdout.printf("jshell %s\n", version()); return null; @@ -630,7 +640,19 @@ public class JShellTool implements MessageHandler { commandLineFeedbackMode = "verbose"; } if (options.has(r)) { - remoteVMOptions = options.valuesOf(r); + remoteVMOptions.addAll(options.valuesOf(r)); + } + if (options.has(c)) { + compilerOptions.addAll(options.valuesOf(c)); + } + + if (options.has(addExports)) { + List exports = options.valuesOf(addExports).stream() + .map(mp -> mp + "=ALL-UNNAMED") + .flatMap(mp -> Stream.of("--add-exports", mp)) + .collect(toList()); + remoteVMOptions.addAll(exports); + compilerOptions.addAll(exports); } return options.valuesOf(loadFileSpec); @@ -640,6 +662,10 @@ public class JShellTool implements MessageHandler { cmdout.print(getResourceString("help.usage")); } + private void printUsageX() { + cmdout.print(getResourceString("help.usage.x")); + } + /** * Message handler to use during initial start-up. */ @@ -683,7 +709,8 @@ public class JShellTool implements MessageHandler { .idGenerator((sn, i) -> (currentNameSpace == startNamespace || state.status(sn).isActive()) ? currentNameSpace.tid(sn) : errorNamespace.tid(sn)) - .remoteVMOptions(remoteVMOptions.toArray(new String[remoteVMOptions.size()])) + .remoteVMOptions(remoteVMOptions.stream().toArray(String[]::new)) + .compilerOptions(compilerOptions.stream().toArray(String[]::new)) .build(); shutdownSubscription = state.onShutdown((JShell deadState) -> { if (deadState == state) { diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties index 5434e949328..beb1f0fd13f 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties @@ -164,8 +164,15 @@ where possible options include:\n\ \ Use one -J for each runtime flag or flag argument\n\ \ -R Pass to the remote runtime system.\n\ \ Use one -R for each remote flag or flag argument\n\ +\ -C Pass to the compiler.\n\ +\ Use one -C for each compiler flag or flag argument\n\ \ --help Print this synopsis of standard options\n\ -\ --version Version information\n +\ --version Version information\n\ +\ -X Print help on non-standard options\n +help.usage.x = \ +\ --add-exports / Export specified module-private package to snippets\n\ +\ \n\ +\These options are non-standard and subject to change without notice.\n help.list.summary = list the source you have typed help.list.args = [|-all|-start] diff --git a/langtools/test/jdk/jshell/ToolBasicTest.java b/langtools/test/jdk/jshell/ToolBasicTest.java index 7ccf529fb2d..fde5a57f989 100644 --- a/langtools/test/jdk/jshell/ToolBasicTest.java +++ b/langtools/test/jdk/jshell/ToolBasicTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 + * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 * @summary Tests for Basic tests for REPL tool * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -574,4 +574,20 @@ public class ToolBasicTest extends ReplToolTesting { } } + public void testAddExports() { + test(false, new String[]{"--no-startup"}, + a -> assertCommandOutputStartsWith(a, "import jdk.internal.misc.VM;", "| Error:") + ); + test(false, new String[]{"--no-startup", + "-R--add-exports", "-Rjava.base/jdk.internal.misc=ALL-UNNAMED", + "-C--add-exports", "-Cjava.base/jdk.internal.misc=ALL-UNNAMED"}, + a -> assertImport(a, "import jdk.internal.misc.VM;", "", "jdk.internal.misc.VM"), + a -> assertCommand(a, "System.err.println(VM.isBooted())", "", "", null, "", "true\n") + ); + test(false, new String[]{"--no-startup", "--add-exports", "java.base/jdk.internal.misc"}, + a -> assertImport(a, "import jdk.internal.misc.VM;", "", "jdk.internal.misc.VM"), + a -> assertCommand(a, "System.err.println(VM.isBooted())", "", "", null, "", "true\n") + ); + } + } From 3f1ae2ad4ed5721116a26f46ff14691fab3f1225 Mon Sep 17 00:00:00 2001 From: Jayathirth D V Date: Thu, 29 Sep 2016 10:57:34 +0530 Subject: [PATCH 084/207] 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener Reviewed-by: prr, bpb, serb, psadhukhan --- .../imageio/plugins/bmp/BMPImageWriter.java | 20 +-- .../imageio/plugins/gif/GIFImageWriter.java | 30 ++-- .../imageio/plugins/png/PNGImageWriter.java | 63 +++---- .../imageio/plugins/tiff/TIFFImageWriter.java | 19 +- jdk/test/javax/imageio/WriteAbortTest.java | 169 ++++++++++++++++++ 5 files changed, 243 insertions(+), 58 deletions(-) create mode 100644 jdk/test/javax/imageio/WriteAbortTest.java diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java index 164aa9769ae..d904d777917 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -156,6 +156,10 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { clearAbortRequest(); processImageStarted(0); + if (abortRequested()) { + processWriteAborted(); + return; + } if (param == null) param = getDefaultWriteParam(); @@ -583,12 +587,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { stream.write(embedded_stream.toByteArray()); embedded_stream = null; - if (abortRequested()) { - processWriteAborted(); - } else { - processImageComplete(); - stream.flushBefore(stream.getStreamPosition()); - } + processImageComplete(); + stream.flushBefore(stream.getStreamPosition()); return; } @@ -606,9 +606,6 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { destScanlineLength = destScanlineBytes / (DataBuffer.getDataTypeSize(dataType)>>3); } for (int i = 0; i < h; i++) { - if (abortRequested()) { - break; - } int row = minY + i; @@ -724,6 +721,9 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { } processImageProgress(100.0f * (((float)i) / ((float)h))); + if (abortRequested()) { + break; + } } if (compressionType == BI_RLE4 || diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java index afb81aa2307..61b00538596 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -574,7 +574,6 @@ public class GIFImageWriter extends ImageWriter { IIOMetadata sm, IIOImage iioimage, ImageWriteParam p) throws IOException { - clearAbortRequest(); RenderedImage image = iioimage.getRenderedImage(); @@ -829,11 +828,11 @@ public class GIFImageWriter extends ImageWriter { image.getTile(0, 0) : image.getData(); for (int y = dy; y < dh; y += ddy) { if (numRowsWritten % progressReportRowPeriod == 0) { + processImageProgress((numRowsWritten*100.0F)/dh); if (abortRequested()) { processWriteAborted(); return; } - processImageProgress((numRowsWritten*100.0F)/dh); } raster.getSamples(sx, sy, sw, 1, 0, sbuf); @@ -857,11 +856,11 @@ public class GIFImageWriter extends ImageWriter { lineStride *= ddy; for (int y = dy; y < dh; y += ddy) { if (numRowsWritten % progressReportRowPeriod == 0) { + processImageProgress((numRowsWritten*100.0F)/dh); if (abortRequested()) { processWriteAborted(); return; } - processImageProgress((numRowsWritten*100.0F)/dh); } compressor.compress(data, offset, dw); @@ -924,7 +923,12 @@ public class GIFImageWriter extends ImageWriter { int progressReportRowPeriod = Math.max(destHeight/20, 1); + clearAbortRequest(); processImageStarted(imageIndex); + if (abortRequested()) { + processWriteAborted(); + return; + } if (interlaceFlag) { if (DEBUG) System.out.println("Writing interlaced"); @@ -973,6 +977,9 @@ public class GIFImageWriter extends ImageWriter { writeRowsOpt(data, offset, lineStride, compressor, 1, 2, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); + if (abortRequested()) { + return; + } } else { writeRows(image, compressor, sourceXOffset, periodX, @@ -1016,6 +1023,9 @@ public class GIFImageWriter extends ImageWriter { sourceWidth, 1, 2, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); + if (abortRequested()) { + return; + } } } else { if (DEBUG) System.out.println("Writing non-interlaced"); @@ -1031,6 +1041,9 @@ public class GIFImageWriter extends ImageWriter { writeRowsOpt(data, offset, lineStride, compressor, 0, 1, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); + if (abortRequested()) { + return; + } } else { writeRows(image, compressor, sourceXOffset, periodX, @@ -1038,15 +1051,12 @@ public class GIFImageWriter extends ImageWriter { sourceWidth, 0, 1, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); + if (abortRequested()) { + return; + } } } - if (abortRequested()) { - return; - } - - processImageProgress(100.0F); - compressor.flush(); stream.write(0x00); diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java index e58c7af8b18..f1660f8a159 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1234,43 +1234,46 @@ public final class PNGImageWriter extends ImageWriter { clearAbortRequest(); processImageStarted(0); + if (abortRequested()) { + processWriteAborted(); + } else { + try { + write_magic(); + write_IHDR(); - try { - write_magic(); - write_IHDR(); + write_cHRM(); + write_gAMA(); + write_iCCP(); + write_sBIT(); + write_sRGB(); - write_cHRM(); - write_gAMA(); - write_iCCP(); - write_sBIT(); - write_sRGB(); + write_PLTE(); - write_PLTE(); + write_hIST(); + write_tRNS(); + write_bKGD(); - write_hIST(); - write_tRNS(); - write_bKGD(); + write_pHYs(); + write_sPLT(); + write_tIME(); + write_tEXt(); + write_iTXt(); + write_zTXt(); - write_pHYs(); - write_sPLT(); - write_tIME(); - write_tEXt(); - write_iTXt(); - write_zTXt(); + writeUnknownChunks(); - writeUnknownChunks(); + write_IDAT(im, deflaterLevel); - write_IDAT(im, deflaterLevel); - - if (abortRequested()) { - processWriteAborted(); - } else { - // Finish up and inform the listeners we are done - writeIEND(); - processImageComplete(); + if (abortRequested()) { + processWriteAborted(); + } else { + // Finish up and inform the listeners we are done + writeIEND(); + processImageComplete(); + } + } catch (IOException e) { + throw new IIOException("I/O error writing PNG file!", e); } - } catch (IOException e) { - throw new IIOException("I/O error writing PNG file!", e); } } } diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java index 9924c3d2210..8e0942d75b7 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java @@ -2437,6 +2437,10 @@ public class TIFFImageWriter extends ImageWriter { clearAbortRequest(); processImageStarted(0); + if (abortRequested()) { + processWriteAborted(); + return; + } // Optionally write the header. if (writeHeader) { @@ -2587,9 +2591,6 @@ public class TIFFImageWriter extends ImageWriter { nextSpace = pos + byteCount; } - pixelsDone += tileRect.width*tileRect.height; - processImageProgress(100.0F*pixelsDone/totalPixels); - // Fill in the offset and byte count for the file stream.mark(); stream.seek(stripOrTileOffsetsPosition); @@ -2600,14 +2601,16 @@ public class TIFFImageWriter extends ImageWriter { stream.writeInt(byteCount); stripOrTileByteCountsPosition += 4; stream.reset(); + + pixelsDone += tileRect.width*tileRect.height; + processImageProgress(100.0F*pixelsDone/totalPixels); + if (abortRequested()) { + processWriteAborted(); + return; + } } catch (IOException e) { throw new IIOException("I/O error writing TIFF file!", e); } - - if (abortRequested()) { - processWriteAborted(); - return; - } } } diff --git a/jdk/test/javax/imageio/WriteAbortTest.java b/jdk/test/javax/imageio/WriteAbortTest.java new file mode 100644 index 00000000000..624ce16c94e --- /dev/null +++ b/jdk/test/javax/imageio/WriteAbortTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + * @test + * @bug 8164931 + * @summary Test verifies that if we call ImageWriter.abort() in + * IIOWriteProgressListener.imageStarted() or + * IIOWriteProgressListener.imageProgress() are we + * calling IIOWriteProgressListener.readAborted() for all readers. + * @run main WriteAbortTest + */ +import java.awt.image.BufferedImage; +import java.io.File; +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageInputStream; +import java.awt.Color; +import java.awt.Graphics2D; +import java.nio.file.Files; +import javax.imageio.ImageWriter; +import javax.imageio.event.IIOWriteProgressListener; +import javax.imageio.stream.ImageOutputStream; + +public class WriteAbortTest implements IIOWriteProgressListener { + + ImageWriter writer = null; + ImageOutputStream ios = null; + BufferedImage bimg = null; + File file; + boolean startAbort = false; + boolean startAborted = false; + boolean progressAbort = false; + boolean progressAborted = false; + Color srccolor = Color.red; + int width = 100; + int heght = 100; + + public WriteAbortTest(String format) throws Exception { + try { + System.out.println("Test for format " + format); + bimg = new BufferedImage(width, heght, + BufferedImage.TYPE_INT_RGB); + + Graphics2D g = bimg.createGraphics(); + g.setColor(srccolor); + g.fillRect(0, 0, width, heght); + g.dispose(); + + file = File.createTempFile("src_", "." + format, new File(".")); + ImageInputStream ios = ImageIO.createImageOutputStream(file); + + ImageWriter writer = + ImageIO.getImageWritersByFormatName(format).next(); + + writer.setOutput(ios); + writer.addIIOWriteProgressListener(this); + + // Abort writing in IIOWriteProgressListener.imageStarted(). + startAbort = true; + writer.write(bimg); + startAbort = false; + + // Abort writing in IIOWriteProgressListener.imageProgress(). + progressAbort = true; + writer.write(bimg); + progressAbort = false; + + ios.close(); + /* + * All abort requests from imageStarted,imageProgress + * from IIOWriteProgressListener should be reached + * otherwise throw RuntimeException. + */ + if (!(startAborted + && progressAborted)) { + throw new RuntimeException("All IIOWriteProgressListener abort" + + " requests are not processed for format " + + format); + } + } finally { + Files.delete(file.toPath()); + } + } + + /* + * Abstract methods that we need to implement from + * IIOWriteProgressListener, and relevant for this test case. + */ + @Override + public void imageStarted(ImageWriter source, int imageIndex) { + System.out.println("imageStarted called"); + if (startAbort) { + source.abort(); + } + } + + @Override + public void imageProgress(ImageWriter source, float percentageDone) { + System.out.println("imageProgress called"); + if (progressAbort) { + source.abort(); + } + } + + @Override + public void writeAborted(ImageWriter source) { + System.out.println("writeAborted called"); + // Verify IIOWriteProgressListener.imageStarted() abort request. + if (startAbort) { + System.out.println("imageStarted aborted "); + startAborted = true; + } + + // Verify IIOWriteProgressListener.imageProgress() abort request. + if (progressAbort) { + System.out.println("imageProgress aborted "); + progressAborted = true; + } + } + + public static void main(String args[]) throws Exception { + final String[] formats = {"bmp", "png", "gif", "jpg", "tif"}; + for (String format : formats) { + new WriteAbortTest(format); + } + } + + /* + * Remaining abstract methods that we need to implement from + * IIOWriteProgressListener, but not relevant for this test case. + */ + @Override + public void imageComplete(ImageWriter source) { + } + + @Override + public void thumbnailStarted(ImageWriter source, int imageIndex, + int thumbnailIndex) { + } + + @Override + public void thumbnailProgress(ImageWriter source, float percentageDone) { + } + + @Override + public void thumbnailComplete(ImageWriter source) { + } +} + From 295923ce812314013d93a2de85f3e59d8f9e77e9 Mon Sep 17 00:00:00 2001 From: Jayathirth D V Date: Thu, 29 Sep 2016 11:13:42 +0530 Subject: [PATCH 085/207] 8166685: We should unpin stream and pixel buffer in case of setjmp during writeImage in JPEG Reviewed-by: prr, psadhukhan --- jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c index 9be3de81285..7fe4bd9847c 100644 --- a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c +++ b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c @@ -2872,6 +2872,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage if (setjmp(jerr->setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error while writing. */ + RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); if (!(*env)->ExceptionOccurred(env)) { char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message) ((j_common_ptr) cinfo, From 20a821ae7c965b4f6a2ca447ad34a97410b12789 Mon Sep 17 00:00:00 2001 From: Shinya Yoshida Date: Thu, 29 Sep 2016 17:36:22 +0900 Subject: [PATCH 086/207] 8166744: JShell: java.lang.IndexOutOfBoundsException for legal history access Reviewed-by: rfield, jlahoda --- langtools/test/jdk/jshell/HistoryTest.java | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/langtools/test/jdk/jshell/HistoryTest.java b/langtools/test/jdk/jshell/HistoryTest.java index 3513e778c22..2dfc9a36a4d 100644 --- a/langtools/test/jdk/jshell/HistoryTest.java +++ b/langtools/test/jdk/jshell/HistoryTest.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8166744 * @summary Test Completion * @modules jdk.internal.le/jdk.internal.jline.extra * jdk.jshell/jdk.internal.jshell.tool @@ -75,6 +76,44 @@ public class HistoryTest extends ReplToolTesting { }); } + public void test8166744() { + test( + a -> {if (!a) setCommandInput("class C {\n");}, + a -> {if (!a) setCommandInput("void f() {\n");}, + a -> {if (!a) setCommandInput("}\n");}, + a -> {assertCommand(a, "}", "| created class C");}, + a -> { + if (!a) { + try { + previousAndAssert(getHistory(), "}"); + previousAndAssert(getHistory(), "}"); + previousAndAssert(getHistory(), "void f() {"); + previousAndAssert(getHistory(), "class C {"); + getHistory().add("class C{"); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + assertCommand(a, "int dummy;", "dummy ==> 0"); + }); + test( + a -> {if (!a) setCommandInput("class C {\n");}, + a -> {if (!a) setCommandInput("void f() {\n");}, + a -> {if (!a) setCommandInput("}\n");}, + a -> {assertCommand(a, "}", "| created class C");}, + a -> { + if (!a) { + try { + previousSnippetAndAssert(getHistory(), "class C {"); + getHistory().add("class C{"); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + assertCommand(a, "int dummy;", "dummy ==> 0"); + }); + } + private EditingHistory getHistory() throws Exception { Field input = repl.getClass().getDeclaredField("input"); input.setAccessible(true); From 31db3330450f61d020427b73d5c283cdb1ec8ca6 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 29 Sep 2016 16:45:08 +0000 Subject: [PATCH 087/207] Added tag jdk-9+138 for changeset de6f69208f82 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index a0cde0979fb..5fdee3f6017 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -380,3 +380,4 @@ be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133 82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135 3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136 d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137 +67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138 From 762708dbb8958afab57bc2dc54565ed377073c22 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 29 Sep 2016 16:45:08 +0000 Subject: [PATCH 088/207] Added tag jdk-9+138 for changeset f8823c55a1b7 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index e47bd43b69b..46f6d728864 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -380,3 +380,4 @@ f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131 094d0db606db976045f594dba47d4593b715cc81 jdk-9+135 aa053a3faf266c12b4fd5272da431a3e08e4a3e3 jdk-9+136 258cf18fa7fc59359b874f8743b7168dc48baf73 jdk-9+137 +27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138 From 5e40fe543e5ffc6f1f1471eca55cfb7ce7f18547 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 29 Sep 2016 16:45:09 +0000 Subject: [PATCH 089/207] Added tag jdk-9+138 for changeset b4b4c1119f39 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index c6f688c2bbd..02397a6cce1 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -540,3 +540,4 @@ b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134 3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135 a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136 dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137 +fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138 From 54ca65037bd63ace7bfb885cf9803d544e47bc52 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 29 Sep 2016 16:45:10 +0000 Subject: [PATCH 090/207] Added tag jdk-9+138 for changeset 7223a315fd01 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index eb923642658..0b75f1ff5b9 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -380,3 +380,4 @@ e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130 f695240370c77a25fed88225a392e7d530cb4d78 jdk-9+135 f1eafcb0eb7182b937bc93f214d8cabd01ec4d59 jdk-9+136 a8d5fe567ae72b4931040e59dd4478363f9004f5 jdk-9+137 +69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138 From c954db5127d86303f7406d40fc1b33c8dc4e7584 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 29 Sep 2016 16:45:10 +0000 Subject: [PATCH 091/207] Added tag jdk-9+138 for changeset 8ced0dd94a6e --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 73800b65dcd..cada8dfb457 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -383,3 +383,4 @@ ab1d78d395d4cb8be426ff181211da1a4085cf01 jdk-9+134 22631824f55128a7ab6605493b3001a37af6a168 jdk-9+135 09ec13a99f50a4a346180d1e3b0fd8bc1ee399ce jdk-9+136 297c16d401c534cb879809d2a746d21ca99d2954 jdk-9+137 +7d3a8f52b124db26ba8425c2931b748dd9d2791b jdk-9+138 From 08c0fa1dbf368d004b3d7df823b47a3878e5a727 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 29 Sep 2016 16:45:12 +0000 Subject: [PATCH 092/207] Added tag jdk-9+138 for changeset 4b05dadfb69d --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 959e99614ce..81a826500af 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -380,3 +380,4 @@ f08683786207a48b652266b3b7b908e6c863c3fc jdk-9+134 af5eb8f3ffd21288305a54ea177ffad75021a741 jdk-9+135 c8f02f0ecbd7cd6700f47416e4b7e9d5ec20ad77 jdk-9+136 dd56c243c199a540c9f1fbff4855f0934b32a9d0 jdk-9+137 +90dd93e668a521642382561c47abe96ee2e065b7 jdk-9+138 From 6bda29a2da32074d1b59f13e316d40fe1a4118fa Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 29 Sep 2016 16:45:12 +0000 Subject: [PATCH 093/207] Added tag jdk-9+138 for changeset b9a1cb9ed1d3 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 41633a26b9a..8157fdd8c91 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -371,3 +371,4 @@ e05400ba935753c77697af936db24657eb811022 jdk-9+134 cb00d5ef023a18a66fcb4311ed4474d4145c66e9 jdk-9+135 f11b8f5c4ccbf9c87d283815abac6c0117fba3c0 jdk-9+136 17ed43add2f9e3528686cd786ae2ed49c8ed36e9 jdk-9+137 +4a6ee1185fc821df063e4d1537fa7ad2ebe9eb02 jdk-9+138 From 33b751c3d4b0519ffa1eeb5d57ac2cb7165933c9 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Thu, 29 Sep 2016 21:31:09 -0700 Subject: [PATCH 094/207] 8166238: Update jdeps for GNU-style long form options Reviewed-by: alanb --- .../com/sun/tools/jdeps/JdepsTask.java | 52 ++--- .../tools/jdeps/resources/jdeps.properties | 184 +++++++++--------- langtools/test/tools/jdeps/APIDeps.java | 2 +- .../jdeps/jdkinternals/ShowReplacement.java | 2 +- .../tools/jdeps/modules/GenModuleInfo.java | 4 +- .../test/tools/jdeps/modules/InverseDeps.java | 14 +- .../jdeps/modules/src/m3/module-info.java | 2 +- 7 files changed, 133 insertions(+), 127 deletions(-) diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java index 862c5261859..3bacd6fc034 100644 --- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java @@ -150,7 +150,7 @@ class JdepsTask { task.options.help = true; } }, - new Option(true, "-dotoutput") { + new Option(true, "-dotoutput", "--dot-output") { void process(JdepsTask task, String opt, String arg) throws BadArgs { Path p = Paths.get(arg); if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) { @@ -191,7 +191,7 @@ class JdepsTask { } } }, - new Option(false, "-apionly") { + new Option(false, "-apionly", "--api-only") { void process(JdepsTask task, String opt, String arg) { task.options.apiOnly = true; } @@ -203,7 +203,7 @@ class JdepsTask { task.options.addmods.addAll(mods); } }, - new Option(true, "--gen-module-info") { + new Option(true, "--generate-module-info") { void process(JdepsTask task, String opt, String arg) throws BadArgs { Path p = Paths.get(arg); if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) { @@ -212,7 +212,7 @@ class JdepsTask { task.options.genModuleInfo = Paths.get(arg); } }, - new Option(false, "-jdkinternals") { + new Option(false, "-jdkinternals", "--jdk-internals") { void process(JdepsTask task, String opt, String arg) { task.options.findJDKInternals = true; task.options.verbose = CLASS; @@ -263,19 +263,36 @@ class JdepsTask { task.options.addmods.add(arg); } }, + new Option(true, "--multi-release") { + void process(JdepsTask task, String opt, String arg) throws BadArgs { + if (arg.equalsIgnoreCase("base")) { + task.options.multiRelease = JarFile.baseVersion(); + } else { + try { + int v = Integer.parseInt(arg); + if (v < 9) { + throw new BadArgs("err.invalid.arg.for.option", arg); + } + } catch (NumberFormatException x) { + throw new BadArgs("err.invalid.arg.for.option", arg); + } + task.options.multiRelease = Runtime.Version.parse(arg); + } + } + }, // ---- Target filtering options ---- - new Option(true, "-p", "-package") { + new Option(true, "-p", "-package", "--package") { void process(JdepsTask task, String opt, String arg) { task.options.packageNames.add(arg); } }, - new Option(true, "-e", "-regex") { + new Option(true, "-e", "-regex", "--regex") { void process(JdepsTask task, String opt, String arg) { task.options.regex = Pattern.compile(arg); } }, - new Option(true, "-requires") { + new Option(true, "--require") { void process(JdepsTask task, String opt, String arg) { task.options.requires.add(arg); } @@ -336,7 +353,7 @@ class JdepsTask { } }, - new Option(false, "-I", "-inverse") { + new Option(false, "-I", "--inverse") { void process(JdepsTask task, String opt, String arg) { task.options.inverse = true; // equivalent to the inverse of compile-time view analysis @@ -361,7 +378,7 @@ class JdepsTask { } }, - new Option(false, "-version") { + new Option(false, "-version", "--version") { void process(JdepsTask task, String opt, String arg) { task.options.version = true; } @@ -390,23 +407,6 @@ class JdepsTask { } } }, - new Option(true, "--multi-release") { - void process(JdepsTask task, String opt, String arg) throws BadArgs { - if (arg.equalsIgnoreCase("base")) { - task.options.multiRelease = JarFile.baseVersion(); - } else { - try { - int v = Integer.parseInt(arg); - if (v < 9) { - throw new BadArgs("err.invalid.arg.for.option", arg); - } - } catch (NumberFormatException x) { - throw new BadArgs("err.invalid.arg.for.option", arg); - } - task.options.multiRelease = Runtime.Version.parse(arg); - } - } - }, }; private static final String PROGNAME = "jdeps"; diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties index 821c99d54e9..c2858c84120 100644 --- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties @@ -13,162 +13,168 @@ warn.prefix=Warning: main.opt.h=\ \ -h -? -help\n\ -\ --help Print this usage message +\ --help Print this usage message main.opt.version=\ -\ -version Version information +\ -version --version Version information main.opt.v=\ -\ -v -verbose Print all class level dependencies\n\ -\ Equivalent to -verbose:class -filter:none.\n\ -\ -verbose:package Print package-level dependencies excluding\n\ -\ dependencies within the same package by default\n\ -\ -verbose:class Print class-level dependencies excluding\n\ -\ dependencies within the same package by default +\ -v -verbose Print all class level dependences\n\ +\ Equivalent to -verbose:class -filter:none.\n\ +\ -verbose:package Print package-level dependences excluding\n\ +\ dependences within the same package by default\n\ +\ -verbose:class Print class-level dependences excluding\n\ +\ dependences within the same package by default main.opt.s=\ -\ -s -summary Print dependency summary only. +\ -s -summary Print dependency summary only. main.opt.f=\ -\ -f -filter Filter dependences matching the given\n\ -\ pattern. If given multiple times, the last\n\ -\ one will be used.\n\ -\ -filter:package Filter dependences within the same package.\n\ -\ This is the default.\n\ -\ -filter:archive Filter dependences within the same archive.\n\ -\ -filter:module Filter dependences within the same module.\n\ -\ -filter:none No -filter:package and -filter:archive\n\ -\ filtering. Filtering specified via the\n\ -\ -filter option still applies.\n\ +\ -f -filter Filter dependences matching the given\n\ +\ pattern. If given multiple times, the last\n\ +\ one will be used.\n\ +\ -filter:package Filter dependences within the same package.\n\ +\ This is the default.\n\ +\ -filter:archive Filter dependences within the same archive.\n\ +\ -filter:module Filter dependences within the same module.\n\ +\ -filter:none No -filter:package and -filter:archive\n\ +\ filtering. Filtering specified via the\n\ +\ -filter option still applies.\n\ main.opt.p=\n\ -\Options to filter dependencies:\n\ -\ -p -package Finds dependences matching the given package\n\ -\ name (may be given multiple times). +\Options to filter dependences:\n\ +\ -p \n\ +\ -package \n\ +\ --package Finds dependences matching the given package\n\ +\ name (may be given multiple times). main.opt.e=\ -\ -e -regex Finds dependences matching the given pattern. +\ -e \n\ +\ -regex \n\ +\ --regex Finds dependences matching the given pattern. -main.opt.requires=\ -\ -requires Finds dependences matching the given module\n\ -\ name (may be given multiple times).\n\ -\ -package, -regex, -requires are mutual exclusive. +main.opt.require=\ +\ --require Finds dependences matching the given module\n\ +\ name (may be given multiple times). --package,\n\ +\ --regex, --require are mutual exclusive. main.opt.include=\n\ \Options to filter classes to be analyzed:\n\ -\ -include Restrict analysis to classes matching pattern\n\ -\ This option filters the list of classes to\n\ -\ be analyzed. It can be used together with\n\ -\ -p and -e which apply pattern to the dependences +\ -include Restrict analysis to classes matching pattern\n\ +\ This option filters the list of classes to\n\ +\ be analyzed. It can be used together with\n\ +\ -p and -e which apply pattern to the dependences main.opt.P=\ -\ -P -profile Show profile containing a package +\ -P -profile Show profile containing a package main.opt.cp=\ \ -cp \n\ \ -classpath \n\ -\ --class-path Specify where to find class files +\ --class-path Specify where to find class files main.opt.module-path=\ -\ --module-path ... Specify module path +\ --module-path Specify module path main.opt.upgrade-module-path=\ -\ --upgrade-module-path ... Specify upgrade module path +\ --upgrade-module-path Specify upgrade module path main.opt.system=\ -\ --system Specify an alternate system module path +\ --system Specify an alternate system module path main.opt.add-modules=\ \ --add-modules [,...]\n\ -\ Adds modules to the root set for analysis +\ Adds modules to the root set for analysis main.opt.m=\ \ -m \n\ -\ --module Specify the root module for analysis +\ --module Specify the root module for analysis main.opt.R=\ -\ -R -recursive Recursively traverse all run-time dependencies.\n\ -\ The -R option implies -filter:none. If -p,\n\ -\ -e, -foption is specified, only the matching\n\ -\ dependences are analyzed. +\ -R -recursive Recursively traverse all run-time dependences.\n\ +\ The -R option implies -filter:none. If -p,\n\ +\ -e, -foption is specified, only the matching\n\ +\ dependences are analyzed. main.opt.I=\ -\ -I -inverse Analyzes the dependences per other given options\n\ -\ and then find all artifacts that directly\n\ -\ and indirectly depend on the matching nodes.\n\ -\ This is equivalent to the inverse of\n\ -\ compile-time view analysis and print\n\ -\ dependency summary. This option must use\n\ -\ with -requires, -package or -regex option. +\ -I --inverse Analyzes the dependences per other given options\n\ +\ and then find all artifacts that directly\n\ +\ and indirectly depend on the matching nodes.\n\ +\ This is equivalent to the inverse of\n\ +\ compile-time view analysis and print\n\ +\ dependency summary. This option must use\n\ +\ with --require, --package or --regex option. main.opt.compile-time=\ -\ --compile-time Compile-time view of transitive dependencies\n\ -\ i.e. compile-time view of -R option.\n\ -\ Analyzes the dependences per other given options\n\ -\ If a dependence is found from a directory,\n\ -\ a JAR file or a module, all classes in that \n\ -\ containing archive are analyzed. +\ --compile-time Compile-time view of transitive dependences\n\ +\ i.e. compile-time view of -R option.\n\ +\ Analyzes the dependences per other given options\n\ +\ If a dependence is found from a directory,\n\ +\ a JAR file or a module, all classes in that \n\ +\ containing archive are analyzed. main.opt.apionly=\ -\ -apionly Restrict analysis to APIs i.e. dependences\n\ -\ from the signature of public and protected\n\ -\ members of public classes including field\n\ -\ type, method parameter types, returned type,\n\ -\ checked exception types etc. +\ -apionly\n\ +\ --api-only Restrict analysis to APIs i.e. dependences\n\ +\ from the signature of public and protected\n\ +\ members of public classes including field\n\ +\ type, method parameter types, returned type,\n\ +\ checked exception types etc. -main.opt.gen-module-info=\ -\ --gen-module-info

Generate module-info.java under the specified\n\ -\ directory. The specified JAR files will be\n\ -\ analyzed. This option cannot be used with\n\ -\ -dotoutput or -cp. +main.opt.generate-module-info=\ +\ --generate-module-info Generate module-info.java under the specified\n\ +\ directory. The specified JAR files will be\n\ +\ analyzed. This option cannot be used with\n\ +\ --dot-output or --class-path. main.opt.check=\ \ --check [,...\n\ -\ Analyze the dependence of the specified modules\n\ -\ It prints the module descriptor, the resulting\n\ -\ module dependences after analysis and the\n\ -\ graph after transition reduction. It also\n\ -\ identifies any unused qualified exports. +\ Analyze the dependence of the specified modules\n\ +\ It prints the module descriptor, the resulting\n\ +\ module dependences after analysis and the\n\ +\ graph after transition reduction. It also\n\ +\ identifies any unused qualified exports. main.opt.dotoutput=\ -\ -dotoutput Destination directory for DOT file output +\ -dotoutput \n\ +\ --dot-output Destination directory for DOT file output main.opt.jdkinternals=\ -\ -jdkinternals Finds class-level dependences on JDK internal\n\ -\ APIs. By default, it analyzes all classes\n\ -\ on -classpath and input files unless -include\n\ -\ option is specified. This option cannot be\n\ -\ used with -p, -e and -s options.\n\ -\ WARNING: JDK internal APIs are inaccessible. +\ -jdkinternals\n\ +\ --jdk-internals Finds class-level dependences on JDK internal\n\ +\ APIs. By default, it analyzes all classes\n\ +\ on --class-path and input files unless -include\n\ +\ option is specified. This option cannot be\n\ +\ used with -p, -e and -s options.\n\ +\ WARNING: JDK internal APIs are inaccessible. main.opt.depth=\ -\ -depth= Specify the depth of the transitive\n\ -\ dependency analysis +\ -depth= Specify the depth of the transitive\n\ +\ dependency analysis main.opt.q=\ -\ -q -quiet Do not show missing dependencies from \n\ -\ -genmoduleinfo output. +\ -q -quiet Do not show missing dependences from \n\ +\ --generate-module-info output. main.opt.multi-release=\ -\ --multi-release Specifies the version when processing\n\ -\ multi-release jar files. should\n\ -\ be integer >= 9 or base. +\ --multi-release Specifies the version when processing\n\ +\ multi-release jar files. should\n\ +\ be integer >= 9 or base. err.unknown.option=unknown option: {0} err.missing.arg=no value given for {0} err.invalid.arg.for.option=invalid argument for option: {0} err.option.after.class=option must be specified before classes: {0} -err.genmoduleinfo.not.jarfile={0} not valid for --gen-module-info option (must be non-modular JAR file) +err.genmoduleinfo.not.jarfile={0} not valid for --generate-module-info option (must be non-modular JAR file) err.profiles.msg=No profile information err.exception.message={0} err.invalid.path=invalid path: {0} err.invalid.module.option=Cannot set {0} with {1} option. -err.invalid.filters=Only one of -package (-p), -regex (-e), -requires option can be set +err.invalid.filters=Only one of --package (-p), --regex (-e), --require option can be set err.module.not.found=module not found: {0} err.root.module.not.set=root module set empty -err.invalid.inverse.option={0} cannot be used with -inverse option -err.inverse.filter.not.set={0} cannot be used with -inverse option +err.invalid.inverse.option={0} cannot be used with --inverse option err.multirelease.option.exists={0} is not a multi-release jar file, but the --multi-release option is set err.multirelease.option.notfound={0} is a multi-release jar file, but the --multi-release option is not set err.multirelease.version.associated=class {0} already associated with version {1}, trying to add version {2} @@ -178,7 +184,7 @@ warn.split.package=package {0} defined in {1} {2} warn.replace.useJDKInternals=\ JDK internal APIs are unsupported and private to JDK implementation that are\n\ subject to be removed or changed incompatibly and could break your application.\n\ -Please modify your code to eliminate dependency on any JDK internal APIs.\n\ +Please modify your code to eliminate dependence on any JDK internal APIs.\n\ For the most recent update on JDK internal API replacements, please check:\n\ {0} diff --git a/langtools/test/tools/jdeps/APIDeps.java b/langtools/test/tools/jdeps/APIDeps.java index 78665f5b258..2e50ccf0135 100644 --- a/langtools/test/tools/jdeps/APIDeps.java +++ b/langtools/test/tools/jdeps/APIDeps.java @@ -135,7 +135,7 @@ public class APIDeps { "java.util.Set", "c.C", "d.D", "c.I", "e.E", "m.Bar"}, new String[] {"compact1", testDirBasename, mDir.getName()}, - new String[] {"-classpath", testDir.getPath(), "-verbose", "-P", "-apionly"}); + new String[] {"-classpath", testDir.getPath(), "-verbose", "-P", "--api-only"}); return errors; } diff --git a/langtools/test/tools/jdeps/jdkinternals/ShowReplacement.java b/langtools/test/tools/jdeps/jdkinternals/ShowReplacement.java index dfe0f5f8a19..7f5bb5ea456 100644 --- a/langtools/test/tools/jdeps/jdkinternals/ShowReplacement.java +++ b/langtools/test/tools/jdeps/jdkinternals/ShowReplacement.java @@ -116,7 +116,7 @@ public class ShowReplacement { @Test public void removedPackage() { Path file = Paths.get("q", "RemovedPackage.class"); - String[] output = JdepsUtil.jdeps("-jdkinternals", CLASSES_DIR.resolve(file).toString()); + String[] output = JdepsUtil.jdeps("--jdk-internals", CLASSES_DIR.resolve(file).toString()); int i = 0; // expect no replacement while (i < output.length && !output[i].contains("Suggested Replacement")) { diff --git a/langtools/test/tools/jdeps/modules/GenModuleInfo.java b/langtools/test/tools/jdeps/modules/GenModuleInfo.java index b056c9405f8..3cc391af3c4 100644 --- a/langtools/test/tools/jdeps/modules/GenModuleInfo.java +++ b/langtools/test/tools/jdeps/modules/GenModuleInfo.java @@ -23,7 +23,7 @@ /* * @test - * @summary Tests jdeps --gen-module-info option + * @summary Tests jdeps --generate-module-info option * @library ../lib * @build CompilerUtils JdepsUtil * @modules jdk.jdeps/com.sun.tools.jdeps @@ -106,7 +106,7 @@ public class GenModuleInfo { .map(mn -> LIBS_DIR.resolve(mn + ".jar")) .map(Path::toString); - JdepsUtil.jdeps(Stream.concat(Stream.of("--gen-module-info", DEST_DIR.toString()), + JdepsUtil.jdeps(Stream.concat(Stream.of("--generate-module-info", DEST_DIR.toString()), files).toArray(String[]::new)); // check file exists diff --git a/langtools/test/tools/jdeps/modules/InverseDeps.java b/langtools/test/tools/jdeps/modules/InverseDeps.java index 6ec3352692b..884651d83f9 100644 --- a/langtools/test/tools/jdeps/modules/InverseDeps.java +++ b/langtools/test/tools/jdeps/modules/InverseDeps.java @@ -91,7 +91,7 @@ public class InverseDeps { @DataProvider(name = "testrequires") public Object[][] expected1() { return new Object[][] { - // -requires and result + // --require and result { "java.sql", new String[][] { new String[] { "java.sql", "m5" }, } @@ -117,7 +117,7 @@ public class InverseDeps { @Test(dataProvider = "testrequires") public void testrequires(String name, String[][] expected) throws Exception { - String cmd1 = String.format("jdeps -inverse --module-path %s -requires %s --add-modules %s%n", + String cmd1 = String.format("jdeps --inverse --module-path %s --require %s --add-modules %s%n", MODS_DIR, name, modules.stream().collect(Collectors.joining(","))); try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd1)) { @@ -128,7 +128,7 @@ public class InverseDeps { runJdeps(jdeps, expected); } - String cmd2 = String.format("jdeps -inverse --module-path %s -requires %s" + + String cmd2 = String.format("jdeps --inverse --module-path %s --require %s" + " --add-modules ALL-MODULE-PATH%n", LIBS_DIR, name); // automatic module @@ -164,7 +164,7 @@ public class InverseDeps { @Test(dataProvider = "testpackage") public void testpackage(String name, String[][] expected) throws Exception { - String cmd = String.format("jdeps -inverse --module-path %s -package %s --add-modules %s%n", + String cmd = String.format("jdeps --inverse --module-path %s -package %s --add-modules %s%n", MODS_DIR, name, modules.stream().collect(Collectors.joining(","))); try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd)) { jdeps.appModulePath(MODS_DIR.toString()) @@ -195,7 +195,7 @@ public class InverseDeps { @Test(dataProvider = "testregex") public void testregex(String name, String[][] expected) throws Exception { - String cmd = String.format("jdeps -inverse --module-path %s -regex %s --add-modules %s%n", + String cmd = String.format("jdeps --inverse --module-path %s -regex %s --add-modules %s%n", MODS_DIR, name, modules.stream().collect(Collectors.joining(","))); try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd)) { @@ -240,7 +240,7 @@ public class InverseDeps { Path jarfile = LIBS_DIR.resolve("m7.jar"); - String cmd1 = String.format("jdeps -inverse -classpath %s -regex %s %s%n", + String cmd1 = String.format("jdeps --inverse -classpath %s -regex %s %s%n", cpath, name, jarfile); try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd1)) { jdeps.verbose("-verbose:class") @@ -253,7 +253,7 @@ public class InverseDeps { Set paths = modules.stream() .map(mn -> LIBS_DIR.resolve(mn + ".jar")) .collect(Collectors.toSet()); - String cmd2 = String.format("jdeps -inverse -regex %s %s%n", name, paths); + String cmd2 = String.format("jdeps --inverse -regex %s %s%n", name, paths); try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd2)) { jdeps.verbose("-verbose:class").regex(name); paths.forEach(jdeps::addRoot); diff --git a/langtools/test/tools/jdeps/modules/src/m3/module-info.java b/langtools/test/tools/jdeps/modules/src/m3/module-info.java index e58165da18d..62557e8f0b6 100644 --- a/langtools/test/tools/jdeps/modules/src/m3/module-info.java +++ b/langtools/test/tools/jdeps/modules/src/m3/module-info.java @@ -24,7 +24,7 @@ module m3 { requires public java.sql; requires public m2; - requires java.logging; // TODO: --gen-module-info to do transitive reduction + requires java.logging; // TODO: --generate-module-info to do transitive reduction requires public m1; exports p3; } From 7ddf27c21d805b6971e62242bfcc66e4b16e267c Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 30 Sep 2016 09:05:40 +0200 Subject: [PATCH 095/207] 8160630: libjimage.so and others should link statically to libgcc Reviewed-by: ihse, tbell --- common/autoconf/buildjdk-spec.gmk.in | 1 + common/autoconf/generated-configure.sh | 80 ++------------------------ common/autoconf/lib-std.m4 | 50 ++-------------- 3 files changed, 12 insertions(+), 119 deletions(-) diff --git a/common/autoconf/buildjdk-spec.gmk.in b/common/autoconf/buildjdk-spec.gmk.in index c4b7d9051cc..a643d82e45b 100644 --- a/common/autoconf/buildjdk-spec.gmk.in +++ b/common/autoconf/buildjdk-spec.gmk.in @@ -33,6 +33,7 @@ include @SPEC@ CC := @BUILD_CC@ CXX := @BUILD_CXX@ LD := @BUILD_LD@ +LDCXX := @BUILD_LDCXX@ AS := @BUILD_AS@ NM := @BUILD_NM@ AR := @BUILD_AR@ diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 796784ed18b..48b23344af8 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -687,7 +687,6 @@ XMKMF MSVCP_DLL MSVCR_DLL LIBCXX -STATIC_CXX_SETTING FIXPATH_DETACH_FLAG FIXPATH BUILD_GTEST @@ -5092,7 +5091,7 @@ VS_SDK_PLATFORM_NAME_2013= #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1474894604 +DATE_WHEN_GENERATED=1475218974 ############################################################################### # @@ -53087,49 +53086,10 @@ fi if test "x$OPENJDK_TARGET_OS" = xlinux; then - # Test if -lstdc++ works. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dynamic link of stdc++ is possible" >&5 -$as_echo_n "checking if dynamic link of stdc++ is possible... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - OLD_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -lstdc++" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - has_dynamic_libstdcxx=yes -else - has_dynamic_libstdcxx=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CXXFLAGS="$OLD_CXXFLAGS" - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_dynamic_libstdcxx" >&5 -$as_echo "$has_dynamic_libstdcxx" >&6; } - # Test if stdc++ can be linked statically. { $as_echo "$as_me:${as_lineno-$LINENO}: checking if static link of stdc++ is possible" >&5 $as_echo_n "checking if static link of stdc++ is possible... " >&6; } - STATIC_STDCXX_FLAGS="-Wl,-Bstatic -lstdc++ -lgcc -Wl,-Bdynamic" + STATIC_STDCXX_FLAGS="-static-libstdc++ -static-libgcc" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -53137,9 +53097,7 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex ac_compiler_gnu=$ac_cv_cxx_compiler_gnu OLD_LIBS="$LIBS" - OLD_CXX="$CXX" LIBS="$STATIC_STDCXX_FLAGS" - CXX="$CC" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -53159,7 +53117,6 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$OLD_LIBS" - CXX="$OLD_CXX" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -53169,59 +53126,34 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_static_libstdcxx" >&5 $as_echo "$has_static_libstdcxx" >&6; } - if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then - as_fn_error $? "Cannot link to stdc++, neither dynamically nor statically!" "$LINENO" 5 - fi - if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then as_fn_error $? "Static linking of libstdc++ was not possible!" "$LINENO" 5 fi - if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then - as_fn_error $? "Dynamic linking of libstdc++ was not possible!" "$LINENO" 5 - fi - # If dynamic was requested, it's available since it would fail above otherwise. # If dynamic wasn't requested, go with static unless it isn't available. { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5 $as_echo_n "checking how to link with libstdc++... " >&6; } - if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then - LIBCXX="$LIBCXX -lstdc++" - # To help comparisons with old build, put stdc++ first in JVM_LIBS - JVM_LIBS="-lstdc++ $JVM_LIBS" - # Ideally, we should test stdc++ for the BUILD toolchain separately. For now - # just use the same setting as for the TARGET toolchain. - OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS" - LDCXX="$CXX" - STATIC_CXX_SETTING="STATIC_CXX=false" + if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \ + || [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5 $as_echo "dynamic" >&6; } else LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS" - JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc" - # To help comparisons with old build, put stdc++ first in JVM_LIBS - JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS" + JVM_LDFLAGS="$JVM_LDFLAGS $STATIC_STDCXX_FLAGS" # Ideally, we should test stdc++ for the BUILD toolchain separately. For now # just use the same setting as for the TARGET toolchain. - OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc" - OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS" - LDCXX="$CC" - STATIC_CXX_SETTING="STATIC_CXX=true" + OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $STATIC_STDCXX_FLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5 $as_echo "static" >&6; } fi fi - # libCrun is the c++ runtime-library with SunStudio (roughly the equivalent of gcc's libstdc++.so) if test "x$TOOLCHAIN_TYPE" = xsolstudio && test "x$LIBCXX" = x; then LIBCXX="${SYSROOT}/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1" fi - # TODO better (platform agnostic) test - if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$LIBCXX" = x && test "x$TOOLCHAIN_TYPE" = xgcc; then - LIBCXX="-lstdc++" - fi # Setup Windows runtime dlls diff --git a/common/autoconf/lib-std.m4 b/common/autoconf/lib-std.m4 index 6fa0b4844af..ceb8a45ca89 100644 --- a/common/autoconf/lib-std.m4 +++ b/common/autoconf/lib-std.m4 @@ -45,84 +45,44 @@ AC_DEFUN_ONCE([LIB_SETUP_STD_LIBS], ) if test "x$OPENJDK_TARGET_OS" = xlinux; then - # Test if -lstdc++ works. - AC_MSG_CHECKING([if dynamic link of stdc++ is possible]) - AC_LANG_PUSH(C++) - OLD_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -lstdc++" - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [return 0;])], - [has_dynamic_libstdcxx=yes], - [has_dynamic_libstdcxx=no]) - CXXFLAGS="$OLD_CXXFLAGS" - AC_LANG_POP(C++) - AC_MSG_RESULT([$has_dynamic_libstdcxx]) - # Test if stdc++ can be linked statically. AC_MSG_CHECKING([if static link of stdc++ is possible]) - STATIC_STDCXX_FLAGS="-Wl,-Bstatic -lstdc++ -lgcc -Wl,-Bdynamic" + STATIC_STDCXX_FLAGS="-static-libstdc++ -static-libgcc" AC_LANG_PUSH(C++) OLD_LIBS="$LIBS" - OLD_CXX="$CXX" LIBS="$STATIC_STDCXX_FLAGS" - CXX="$CC" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [return 0;])], [has_static_libstdcxx=yes], [has_static_libstdcxx=no]) LIBS="$OLD_LIBS" - CXX="$OLD_CXX" AC_LANG_POP(C++) AC_MSG_RESULT([$has_static_libstdcxx]) - if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then - AC_MSG_ERROR([Cannot link to stdc++, neither dynamically nor statically!]) - fi - if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then AC_MSG_ERROR([Static linking of libstdc++ was not possible!]) fi - if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then - AC_MSG_ERROR([Dynamic linking of libstdc++ was not possible!]) - fi - # If dynamic was requested, it's available since it would fail above otherwise. # If dynamic wasn't requested, go with static unless it isn't available. AC_MSG_CHECKING([how to link with libstdc++]) - if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then - LIBCXX="$LIBCXX -lstdc++" - # To help comparisons with old build, put stdc++ first in JVM_LIBS - JVM_LIBS="-lstdc++ $JVM_LIBS" - # Ideally, we should test stdc++ for the BUILD toolchain separately. For now - # just use the same setting as for the TARGET toolchain. - OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS" - LDCXX="$CXX" - STATIC_CXX_SETTING="STATIC_CXX=false" + if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \ + || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then AC_MSG_RESULT([dynamic]) else LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS" - JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc" - # To help comparisons with old build, put stdc++ first in JVM_LIBS - JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS" + JVM_LDFLAGS="$JVM_LDFLAGS $STATIC_STDCXX_FLAGS" # Ideally, we should test stdc++ for the BUILD toolchain separately. For now # just use the same setting as for the TARGET toolchain. - OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc" - OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS" - LDCXX="$CC" - STATIC_CXX_SETTING="STATIC_CXX=true" + OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $STATIC_STDCXX_FLAGS" AC_MSG_RESULT([static]) fi fi - AC_SUBST(STATIC_CXX_SETTING) # libCrun is the c++ runtime-library with SunStudio (roughly the equivalent of gcc's libstdc++.so) if test "x$TOOLCHAIN_TYPE" = xsolstudio && test "x$LIBCXX" = x; then LIBCXX="${SYSROOT}/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1" fi - # TODO better (platform agnostic) test - if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$LIBCXX" = x && test "x$TOOLCHAIN_TYPE" = xgcc; then - LIBCXX="-lstdc++" - fi AC_SUBST(LIBCXX) # Setup Windows runtime dlls From ebba4ba1c1bb44237f644dc10c00114c12374bdc Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 30 Sep 2016 09:06:02 +0200 Subject: [PATCH 096/207] 8160630: libjimage.so and others should link statically to libgcc Reviewed-by: ihse, tbell --- hotspot/make/lib/CompileGtest.gmk | 4 ++-- hotspot/make/lib/CompileJvm.gmk | 9 +-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/hotspot/make/lib/CompileGtest.gmk b/hotspot/make/lib/CompileGtest.gmk index 803413b8402..1f7c317a427 100644 --- a/hotspot/make/lib/CompileGtest.gmk +++ b/hotspot/make/lib/CompileGtest.gmk @@ -55,7 +55,7 @@ endif # Disabling switch warning for clang because of test source. $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \ - TOOLCHAIN := $(JVM_TOOLCHAIN), \ + TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ LIBRARY := jvm, \ OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \ OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/objs, \ @@ -95,7 +95,7 @@ TARGETS += $(BUILD_GTEST_LIBJVM) ################################################################################ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \ - TOOLCHAIN := $(JVM_TOOLCHAIN), \ + TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ PROGRAM := gtestLauncher, \ OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \ EXTRA_FILES := $(GTEST_LAUNCHER_SRC), \ diff --git a/hotspot/make/lib/CompileJvm.gmk b/hotspot/make/lib/CompileJvm.gmk index 65d58e40e93..6901fc27d76 100644 --- a/hotspot/make/lib/CompileJvm.gmk +++ b/hotspot/make/lib/CompileJvm.gmk @@ -143,13 +143,6 @@ ifneq ($(filter $(OPENJDK_TARGET_OS), linux macosx windows), ) JVM_PRECOMPILED_HEADER := $(HOTSPOT_TOPDIR)/src/share/vm/precompiled/precompiled.hpp endif -ifneq ($(filter $(OPENJDK_TARGET_OS), macosx aix solaris), ) - # On macosx, aix and solaris we have to link with the C++ compiler - JVM_TOOLCHAIN := TOOLCHAIN_LINK_CXX -else - JVM_TOOLCHAIN := TOOLCHAIN_DEFAULT -endif - ifeq ($(OPENJDK_TARGET_CPU), x86) JVM_EXCLUDE_PATTERNS += x86_64 else ifeq ($(OPENJDK_TARGET_CPU), x86_64) @@ -194,7 +187,7 @@ JVM_OPTIMIZATION ?= HIGHEST_JVM # Now set up the actual compilation of the main hotspot native library $(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \ - TOOLCHAIN := $(JVM_TOOLCHAIN), \ + TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ LIBRARY := jvm, \ OUTPUT_DIR := $(JVM_OUTPUTDIR), \ SRC := $(JVM_SRC_DIRS), \ From 61a21b5a3e5d281b8c72cc198101047a7a01686b Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 30 Sep 2016 09:06:21 +0200 Subject: [PATCH 097/207] 8160630: libjimage.so and others should link statically to libgcc Reviewed-by: ihse, tbell --- jdk/make/lib/CoreLibraries.gmk | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk index bfe94de4d6a..58213bbdf4c 100644 --- a/jdk/make/lib/CoreLibraries.gmk +++ b/jdk/make/lib/CoreLibraries.gmk @@ -236,10 +236,6 @@ TARGETS += $(BUILD_LIBZIP) ########################################################################################## -ifeq ($(OPENJDK_TARGET_OS), aix) - LIBJIMAGE_TOOLCHAIN := TOOLCHAIN_LINK_CXX -endif # OPENJDK_TARGET_OS aix - JIMAGELIB_CPPFLAGS := \ -I$(JDK_TOPDIR)/src/java.base/share/native/libjava \ -I$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjava \ @@ -249,7 +245,7 @@ JIMAGELIB_CPPFLAGS := \ $(eval $(call SetupNativeCompilation,BUILD_LIBJIMAGE, \ LIBRARY := jimage, \ - TOOLCHAIN := $(LIBJIMAGE_TOOLCHAIN), \ + TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ OPTIMIZATION := LOW, \ SRC := $(JDK_TOPDIR)/src/java.base/share/native/libjimage \ From ec9d2a571f9feaef620094ca2d636d225b00969f Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 30 Sep 2016 17:05:54 +0300 Subject: [PATCH 098/207] 8165263: Remove code in MetaData that hacks into private fields of Collections implementation classes Reviewed-by: mchung, alexsch --- .../share/classes/java/beans/MetaData.java | 99 ------------------- .../java/beans/XMLEncoder/EnumPrivate.java | 35 ------- .../java/beans/XMLEncoder/EnumPublic.java | 24 ----- ...va_util_Collections_CheckedCollection.java | 49 --------- .../java_util_Collections_CheckedList.java | 48 --------- .../java_util_Collections_CheckedMap.java | 48 --------- ...l_Collections_CheckedRandomAccessList.java | 50 ---------- .../java_util_Collections_CheckedSet.java | 48 --------- ...ava_util_Collections_CheckedSortedMap.java | 50 ---------- ...ava_util_Collections_CheckedSortedSet.java | 50 ---------- .../beans/XMLEncoder/java_util_EnumMap.java | 49 --------- .../XMLEncoder/java_util_JumboEnumSet.java | 49 --------- .../XMLEncoder/java_util_RegularEnumSet.java | 49 --------- 13 files changed, 648 deletions(-) delete mode 100644 jdk/test/java/beans/XMLEncoder/EnumPrivate.java delete mode 100644 jdk/test/java/beans/XMLEncoder/EnumPublic.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedCollection.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedList.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedMap.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedRandomAccessList.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSet.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedMap.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedSet.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_EnumMap.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_JumboEnumSet.java delete mode 100644 jdk/test/java/beans/XMLEncoder/java_util_RegularEnumSet.java diff --git a/jdk/src/java.desktop/share/classes/java/beans/MetaData.java b/jdk/src/java.desktop/share/classes/java/beans/MetaData.java index 4110064bcd0..1443ce2b54f 100644 --- a/jdk/src/java.desktop/share/classes/java/beans/MetaData.java +++ b/jdk/src/java.desktop/share/classes/java/beans/MetaData.java @@ -510,102 +510,6 @@ private abstract static class java_util_Collections extends PersistenceDelegate return new Expression(oldInstance, Collections.class, "synchronizedSortedMap", new Object[]{map}); } } - - static final class CheckedCollection_PersistenceDelegate extends java_util_Collections { - protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); - List list = new ArrayList<>((Collection) oldInstance); - return new Expression(oldInstance, Collections.class, "checkedCollection", new Object[]{list, type}); - } - } - - static final class CheckedList_PersistenceDelegate extends java_util_Collections { - protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); - List list = new LinkedList<>((Collection) oldInstance); - return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type}); - } - } - - static final class CheckedRandomAccessList_PersistenceDelegate extends java_util_Collections { - protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); - List list = new ArrayList<>((Collection) oldInstance); - return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type}); - } - } - - static final class CheckedSet_PersistenceDelegate extends java_util_Collections { - protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); - Set set = new HashSet<>((Set) oldInstance); - return new Expression(oldInstance, Collections.class, "checkedSet", new Object[]{set, type}); - } - } - - static final class CheckedSortedSet_PersistenceDelegate extends java_util_Collections { - protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); - SortedSet set = new TreeSet<>((SortedSet) oldInstance); - return new Expression(oldInstance, Collections.class, "checkedSortedSet", new Object[]{set, type}); - } - } - - static final class CheckedMap_PersistenceDelegate extends java_util_Collections { - protected Expression instantiate(Object oldInstance, Encoder out) { - Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); - Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); - Map map = new HashMap<>((Map) oldInstance); - return new Expression(oldInstance, Collections.class, "checkedMap", new Object[]{map, keyType, valueType}); - } - } - - static final class CheckedSortedMap_PersistenceDelegate extends java_util_Collections { - protected Expression instantiate(Object oldInstance, Encoder out) { - Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); - Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); - SortedMap map = new TreeMap<>((SortedMap) oldInstance); - return new Expression(oldInstance, Collections.class, "checkedSortedMap", new Object[]{map, keyType, valueType}); - } - } -} - -/** - * The persistence delegate for {@code java.util.EnumMap} classes. - * - * @author Sergey A. Malenkov - */ -static final class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { - protected boolean mutatesTo(Object oldInstance, Object newInstance) { - return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); - } - - protected Expression instantiate(Object oldInstance, Encoder out) { - return new Expression(oldInstance, EnumMap.class, "new", new Object[] {getType(oldInstance)}); - } - - private static Object getType(Object instance) { - return MetaData.getPrivateFieldValue(instance, "java.util.EnumMap.keyType"); - } -} - -/** - * The persistence delegate for {@code java.util.EnumSet} classes. - * - * @author Sergey A. Malenkov - */ -static final class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { - protected boolean mutatesTo(Object oldInstance, Object newInstance) { - return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); - } - - protected Expression instantiate(Object oldInstance, Encoder out) { - return new Expression(oldInstance, EnumSet.class, "noneOf", new Object[] {getType(oldInstance)}); - } - - private static Object getType(Object instance) { - return MetaData.getPrivateFieldValue(instance, "java.util.EnumSet.elementType"); - } } // Collection @@ -1313,9 +1217,6 @@ static final class sun_swing_PrintColorUIResource_PersistenceDelegate extends Pe internalPersistenceDelegates.put("java.sql.Date", new java_util_Date_PersistenceDelegate()); internalPersistenceDelegates.put("java.sql.Time", new java_util_Date_PersistenceDelegate()); - - internalPersistenceDelegates.put("java.util.JumboEnumSet", new java_util_EnumSet_PersistenceDelegate()); - internalPersistenceDelegates.put("java.util.RegularEnumSet", new java_util_EnumSet_PersistenceDelegate()); } @SuppressWarnings("rawtypes") diff --git a/jdk/test/java/beans/XMLEncoder/EnumPrivate.java b/jdk/test/java/beans/XMLEncoder/EnumPrivate.java deleted file mode 100644 index 05c56007d65..00000000000 --- a/jdk/test/java/beans/XMLEncoder/EnumPrivate.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -enum EnumPrivate { - A0,B0,C0,D0,E0,F0,G0,H0,I0,J0,K0,L0,M0,N0,O0,P0,Q0,R0,S0,T0,U0,V0,W0,X0,Y0,Z0, - A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1, - A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2, - A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3, - A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4, - A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,O5,P5,Q5,R5,S5,T5,U5,V5,W5,X5,Y5,Z5, - A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,N6,O6,P6,Q6,R6,S6,T6,U6,V6,W6,X6,Y6,Z6, - A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,N7,O7,P7,Q7,R7,S7,T7,U7,V7,W7,X7,Y7,Z7, - A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,O8,P8,Q8,R8,S8,T8,U8,V8,W8,X8,Y8,Z8, - A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,O9,P9,Q9,R9,S9,T9,U9,V9,W9,X9,Y9,Z9, -} diff --git a/jdk/test/java/beans/XMLEncoder/EnumPublic.java b/jdk/test/java/beans/XMLEncoder/EnumPublic.java deleted file mode 100644 index dc592b98a5f..00000000000 --- a/jdk/test/java/beans/XMLEncoder/EnumPublic.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 enum EnumPublic {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedCollection.java b/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedCollection.java deleted file mode 100644 index 8cd2ae7d562..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedCollection.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6505888 - * @summary Tests CheckedCollection encoding - * @author Sergey Malenkov - */ - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class java_util_Collections_CheckedCollection extends AbstractTest> { - public static void main(String[] args) { - new java_util_Collections_CheckedCollection().test(true); - } - - protected Collection getObject() { - List list = Collections.singletonList("string"); - return Collections.checkedCollection(list, String.class); - } - - protected Collection getAnotherObject() { - List list = Collections.emptyList(); - return Collections.checkedCollection(list, String.class); - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedList.java b/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedList.java deleted file mode 100644 index d5dcc11d482..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedList.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6505888 - * @summary Tests CheckedList encoding - * @author Sergey Malenkov - */ - -import java.util.Collections; -import java.util.List; - -public final class java_util_Collections_CheckedList extends AbstractTest> { - public static void main(String[] args) { - new java_util_Collections_CheckedList().test(true); - } - - protected List getObject() { - List list = Collections.singletonList("string"); - return Collections.checkedList(list, String.class); - } - - protected List getAnotherObject() { - List list = Collections.emptyList(); - return Collections.checkedList(list, String.class); - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedMap.java b/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedMap.java deleted file mode 100644 index eb3e5300589..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedMap.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6505888 - * @summary Tests CheckedMap encoding - * @author Sergey Malenkov - */ - -import java.util.Collections; -import java.util.Map; - -public final class java_util_Collections_CheckedMap extends AbstractTest> { - public static void main(String[] args) { - new java_util_Collections_CheckedMap().test(true); - } - - protected Map getObject() { - Map map = Collections.singletonMap("key", "value"); - return Collections.checkedMap(map, String.class, String.class); - } - - protected Map getAnotherObject() { - Map map = Collections.emptyMap(); - return Collections.checkedMap(map, String.class, String.class); - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedRandomAccessList.java b/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedRandomAccessList.java deleted file mode 100644 index 85c8887dc67..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedRandomAccessList.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6505888 - * @summary Tests CheckedRandomAccessList encoding - * @author Sergey Malenkov - */ - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public final class java_util_Collections_CheckedRandomAccessList extends AbstractTest> { - public static void main(String[] args) { - new java_util_Collections_CheckedRandomAccessList().test(true); - } - - protected List getObject() { - List list = new ArrayList(); - list.add("string"); - return Collections.checkedList(list, String.class); - } - - protected List getAnotherObject() { - List list = new ArrayList(); - return Collections.checkedList(list, String.class); - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSet.java b/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSet.java deleted file mode 100644 index 47573c35e56..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSet.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6505888 - * @summary Tests CheckedSet encoding - * @author Sergey Malenkov - */ - -import java.util.Collections; -import java.util.Set; - -public final class java_util_Collections_CheckedSet extends AbstractTest> { - public static void main(String[] args) { - new java_util_Collections_CheckedSet().test(true); - } - - protected Set getObject() { - Set set = Collections.singleton("string"); - return Collections.checkedSet(set, String.class); - } - - protected Set getAnotherObject() { - Set set = Collections.emptySet(); - return Collections.checkedSet(set, String.class); - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedMap.java b/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedMap.java deleted file mode 100644 index 984b8e6bc78..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedMap.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6505888 - * @summary Tests CheckedSortedMap encoding - * @author Sergey Malenkov - */ - -import java.util.Collections; -import java.util.SortedMap; -import java.util.TreeMap; - -public final class java_util_Collections_CheckedSortedMap extends AbstractTest> { - public static void main(String[] args) { - new java_util_Collections_CheckedSortedMap().test(true); - } - - protected SortedMap getObject() { - SortedMap map = new TreeMap(); - map.put("key", "value"); - return Collections.checkedSortedMap(map, String.class, String.class); - } - - protected SortedMap getAnotherObject() { - SortedMap map = new TreeMap(); - return Collections.checkedSortedMap(map, String.class, String.class); - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedSet.java b/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedSet.java deleted file mode 100644 index a9ecc1b6e64..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_Collections_CheckedSortedSet.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6505888 - * @summary Tests CheckedSortedSet encoding - * @author Sergey Malenkov - */ - -import java.util.Collections; -import java.util.SortedSet; -import java.util.TreeSet; - -public final class java_util_Collections_CheckedSortedSet extends AbstractTest> { - public static void main(String[] args) { - new java_util_Collections_CheckedSortedSet().test(true); - } - - protected SortedSet getObject() { - SortedSet set = new TreeSet(); - set.add("string"); - return Collections.checkedSortedSet(set, String.class); - } - - protected SortedSet getAnotherObject() { - SortedSet set = new TreeSet(); - return Collections.checkedSortedSet(set, String.class); - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_EnumMap.java b/jdk/test/java/beans/XMLEncoder/java_util_EnumMap.java deleted file mode 100644 index ea25648a051..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_EnumMap.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6536295 - * @summary Tests EnumMap encoding - * @author Sergey Malenkov - */ - -import java.util.EnumMap; -import java.util.Map; - -public final class java_util_EnumMap extends AbstractTest> { - public static void main(String[] args) { - new java_util_EnumMap().test(true); - } - - protected Map getObject() { - return new EnumMap(EnumPublic.class); - } - - protected Map getAnotherObject() { - Map map = new EnumMap(EnumPublic.class); - map.put(EnumPublic.A, "value"); - map.put(EnumPublic.Z, null); - return map; - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_JumboEnumSet.java b/jdk/test/java/beans/XMLEncoder/java_util_JumboEnumSet.java deleted file mode 100644 index 06257469ed2..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_JumboEnumSet.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6536295 - * @summary Tests JumboEnumSet encoding - * @author Sergey Malenkov - */ - -import java.util.EnumSet; -import java.util.Set; - -public final class java_util_JumboEnumSet extends AbstractTest> { - public static void main(String[] args) { - new java_util_JumboEnumSet().test(true); - } - - protected Set getObject() { - return EnumSet.noneOf(EnumPrivate.class); - } - - protected Set getAnotherObject() { - Set set = EnumSet.noneOf(EnumPrivate.class); - set.add(EnumPrivate.A0); - set.add(EnumPrivate.Z9); - return set; - } -} diff --git a/jdk/test/java/beans/XMLEncoder/java_util_RegularEnumSet.java b/jdk/test/java/beans/XMLEncoder/java_util_RegularEnumSet.java deleted file mode 100644 index f43de52a353..00000000000 --- a/jdk/test/java/beans/XMLEncoder/java_util_RegularEnumSet.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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 6536295 - * @summary Tests RegularEnumSet encoding - * @author Sergey Malenkov - */ - -import java.util.EnumSet; -import java.util.Set; - -public final class java_util_RegularEnumSet extends AbstractTest> { - public static void main(String[] args) { - new java_util_RegularEnumSet().test(true); - } - - protected Set getObject() { - return EnumSet.noneOf(EnumPublic.class); - } - - protected Set getAnotherObject() { - Set set = EnumSet.noneOf(EnumPublic.class); - set.add(EnumPublic.A); - set.add(EnumPublic.Z); - return set; - } -} From 566b0cca41ca47557226acef6d8b9757c7b66f92 Mon Sep 17 00:00:00 2001 From: Peter Levart Date: Fri, 30 Sep 2016 17:34:08 +0200 Subject: [PATCH 099/207] 8166842: String.hashCode() has a non-benign data race Reviewed-by: shade, alanb, martin --- jdk/src/java.base/share/classes/java/lang/String.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/String.java b/jdk/src/java.base/share/classes/java/lang/String.java index 729f5e31381..9bcc69963c7 100644 --- a/jdk/src/java.base/share/classes/java/lang/String.java +++ b/jdk/src/java.base/share/classes/java/lang/String.java @@ -1516,11 +1516,12 @@ public final class String * @return a hash code value for this object. */ public int hashCode() { - if (hash == 0 && value.length > 0) { - hash = isLatin1() ? StringLatin1.hashCode(value) - : StringUTF16.hashCode(value); + int h = hash; + if (h == 0 && value.length > 0) { + hash = h = isLatin1() ? StringLatin1.hashCode(value) + : StringUTF16.hashCode(value); } - return hash; + return h; } /** From 6b29ad4ffc03b9163a894862f21ea95fe7636d03 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Fri, 30 Sep 2016 10:30:57 -0700 Subject: [PATCH 100/207] 8166976: TestCipherPBECons has wrong @run line Reviewed-by: snikandrova, wetmore, rasbold --- .../com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jdk/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java b/jdk/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java index c42952342e0..e3167068029 100644 --- a/jdk/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java +++ b/jdk/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java @@ -36,7 +36,6 @@ import javax.crypto.NoSuchPaddingException; * @author Yun Ke * @author Bill Situ * @author Yu-Ching (Valerie) PENG - * @run main TestCipherKeyWrapperPBEKey */ public class TestCipherPBECons { From 70e402c190203e0f875117b62817ce40b9e709f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 30 Sep 2016 19:40:31 +0200 Subject: [PATCH 101/207] 8166902: Nested object literal property maps not reset in optimistic recompilation Reviewed-by: lagergren, attila --- .../internal/codegen/CodeGenerator.java | 53 +++++++------------ .../internal/codegen/SpillObjectCreator.java | 3 +- nashorn/test/script/basic/JDK-8166902.js | 43 +++++++++++++++ 3 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8166902.js diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java index c9fa06880f9..fce1195c44a 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -2485,11 +2485,6 @@ final class CodeGenerator extends NodeOperatorVisitor(this, tuples) { @Override protected void loadValue(final Expression node, final Type type) { - loadExpressionAsType(node, type); + // Use generic type in order to avoid conversion between object types + loadExpressionAsType(node, Type.generic(type)); }}; } @@ -2578,10 +2574,7 @@ final class CodeGenerator extends NodeOperatorVisitor objectLiteralMaps; // The line number at the continuation point private int lineNumber; // The active catch label, in case the continuation point is in a try/catch block @@ -5364,20 +5355,15 @@ final class CodeGenerator extends NodeOperatorVisitor(); + } + objectLiteralMaps.put(objectLiteralStackDepth, objectLiteralMap); } - void setObjectLiteralStackDepth(final int objectLiteralStackDepth) { - this.objectLiteralStackDepth = objectLiteralStackDepth; - } - - PropertyMap getObjectLiteralMap() { - return objectLiteralMap; - } - - void setObjectLiteralMap(final PropertyMap objectLiteralMap) { - this.objectLiteralMap = objectLiteralMap; + PropertyMap getObjectLiteralMap(final int stackDepth) { + return objectLiteralMaps == null ? null : objectLiteralMaps.get(stackDepth); } @Override @@ -5467,10 +5453,9 @@ final class CodeGenerator extends NodeOperatorVisitor { @Override protected void loadValue(final Expression expr, final Type type) { - codegen.loadExpressionAsType(expr, type); + // Use generic type in order to avoid conversion between object types + codegen.loadExpressionAsType(expr, Type.generic(type)); } @Override diff --git a/nashorn/test/script/basic/JDK-8166902.js b/nashorn/test/script/basic/JDK-8166902.js new file mode 100644 index 00000000000..fb164501681 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8166902.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8166902: Nested object literal property maps not reset in optimistic recompilation + * + * @test + * @run + */ + +var o = { + a: "A", + b: "B" +}; + +var m = { + x: { z: o.a }, + y: o.b +}; + +Assert.assertEquals(m.x.z, "A"); +Assert.assertEquals(m.y, "B"); + From e4d641863186b7d44579b991a0aae4e7371d8d56 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Fri, 30 Sep 2016 10:52:19 -0700 Subject: [PATCH 102/207] 8166981: RGBColorConvertTest has wrong @run line Reviewed-by: prr, rasbold, serb --- jdk/test/sun/java2d/cmm/ColorConvertOp/RGBColorConvertTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jdk/test/sun/java2d/cmm/ColorConvertOp/RGBColorConvertTest.java b/jdk/test/sun/java2d/cmm/ColorConvertOp/RGBColorConvertTest.java index b537a5c667c..e8afd5a929e 100644 --- a/jdk/test/sun/java2d/cmm/ColorConvertOp/RGBColorConvertTest.java +++ b/jdk/test/sun/java2d/cmm/ColorConvertOp/RGBColorConvertTest.java @@ -26,7 +26,6 @@ * @bug 6279846 * @summary Verifies that transform between the same ICC color spaces does not * change pixels - * @run main ColorConvertTest */ import java.awt.image.*; From d055089575daa1d8b7ec628805eb8da7fcb8ae0c Mon Sep 17 00:00:00 2001 From: Clemens Eisserer Date: Fri, 30 Sep 2016 11:45:30 -0700 Subject: [PATCH 103/207] 8162591: All existing gradient paint implementations have issues with coordinates/sizes larger than Short.MAX_VALUE (exactly) on any Linux systems Reviewed-by: flar, serb, prr --- .../unix/classes/sun/java2d/xr/XRPaints.java | 40 ++++++----- .../unix/classes/sun/java2d/xr/XRUtils.java | 10 +++ .../sun/java2d/xrender/HugeGradientTest.java | 71 +++++++++++++++++++ 3 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 jdk/test/sun/java2d/xrender/HugeGradientTest.java diff --git a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java index 07cba15ec3f..d5729423ce0 100644 --- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java +++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java @@ -95,15 +95,15 @@ abstract class XRPaints { private XRGradient() { } - /** - * There are no restrictions for accelerating GradientPaint, so this - * method always returns true. - */ @Override boolean isPaintValid(SunGraphics2D sg2d) { - return true; + GradientPaint paint = (GradientPaint) sg2d.paint; + + return XRUtils.isPointCoordInShortRange(paint.getPoint1()) + && XRUtils.isPointCoordInShortRange(paint.getPoint2()); } + @Override void setXRPaint(SunGraphics2D sg2d, Paint pt) { GradientPaint paint = (GradientPaint) pt; @@ -130,24 +130,27 @@ abstract class XRPaints { @Override boolean isPaintValid(SunGraphics2D sg2d) { - return ((LinearGradientPaint) sg2d.getPaint()).getColorSpace() == ColorSpaceType.SRGB; + LinearGradientPaint paint = (LinearGradientPaint) sg2d.getPaint(); + + return paint.getColorSpace() == ColorSpaceType.SRGB + && XRUtils.isPointCoordInShortRange(paint.getStartPoint()) + && XRUtils.isPointCoordInShortRange(paint.getEndPoint()) + && paint.getTransform().getDeterminant() != 0.0; } @Override void setXRPaint(SunGraphics2D sg2d, Paint pt) { LinearGradientPaint paint = (LinearGradientPaint) pt; - Color[] colors = paint.getColors(); Point2D pt1 = paint.getStartPoint(); Point2D pt2 = paint.getEndPoint(); - int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); float[] fractions = paint.getFractions(); int[] pixels = convertToIntArgbPixels(colors); - AffineTransform at = paint.getTransform(); + try { - at.invert(); + at.invert(); } catch (NoninvertibleTransformException ex) { ex.printStackTrace(); } @@ -165,8 +168,12 @@ abstract class XRPaints { @Override boolean isPaintValid(SunGraphics2D sg2d) { RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint; - return grad.getFocusPoint().equals(grad.getCenterPoint()) - && grad.getColorSpace() == ColorSpaceType.SRGB; + + return grad.getColorSpace() == ColorSpaceType.SRGB + && grad.getFocusPoint().equals(grad.getCenterPoint()) + && XRUtils.isPointCoordInShortRange(grad.getCenterPoint()) + && grad.getRadius() <= Short.MAX_VALUE + && grad.getTransform().getDeterminant() != 0.0; } @Override @@ -174,18 +181,17 @@ abstract class XRPaints { RadialGradientPaint paint = (RadialGradientPaint) pt; Color[] colors = paint.getColors(); Point2D center = paint.getCenterPoint(); + float cx = (float) center.getX(); + float cy = (float) center.getY(); + AffineTransform at = paint.getTransform(); int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); float[] fractions = paint.getFractions(); int[] pixels = convertToIntArgbPixels(colors); float radius = paint.getRadius(); - float cx = (float) center.getX(); - float cy = (float) center.getY(); - - AffineTransform at = paint.getTransform(); try { - at.invert(); + at.invert(); } catch (NoninvertibleTransformException ex) { ex.printStackTrace(); } diff --git a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java index 9c571e3990d..b9208f0747e 100644 --- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java +++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java @@ -26,6 +26,7 @@ package sun.java2d.xr; import java.awt.*; +import java.awt.geom.Point2D; import java.awt.MultipleGradientPaint.*; import java.awt.geom.AffineTransform; import java.awt.image.*; @@ -260,6 +261,15 @@ public class XRUtils { return (x > 65535 ? 65535 : (x < 0) ? 0 : x); } + public static boolean isDoubleInShortRange(double dbl) { + return dbl <= Short.MAX_VALUE && dbl >= Short.MIN_VALUE; + } + + public static boolean isPointCoordInShortRange(Point2D p) { + return isDoubleInShortRange(p.getX()) && isDoubleInShortRange(p.getY()); + } + + public static boolean isTransformQuadrantRotated(AffineTransform tr) { return ((tr.getType() & (AffineTransform.TYPE_GENERAL_ROTATION | AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0); diff --git a/jdk/test/sun/java2d/xrender/HugeGradientTest.java b/jdk/test/sun/java2d/xrender/HugeGradientTest.java new file mode 100644 index 00000000000..40e3d6ca040 --- /dev/null +++ b/jdk/test/sun/java2d/xrender/HugeGradientTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * 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.image.*; +import javax.swing.*; + +/** + * @test + * @bug 8162591 + * @summary tests gradients with start/endpoints exceeding Short.MAX coordinates + * @author ceisserer + */ +public class HugeGradientTest extends Frame { + public static volatile boolean success = false; + + public HugeGradientTest() { + Image dstImg = getGraphicsConfiguration() + .createCompatibleVolatileImage(30, 30); + Graphics2D g = (Graphics2D) dstImg.getGraphics(); + + g.setPaint(new LinearGradientPaint(0f, Short.MAX_VALUE, 0f, Short.MAX_VALUE +31, + new float[]{0f, 1f}, new Color[]{Color.BLACK, Color.RED})); + g.translate(0, -Short.MAX_VALUE); + g.fillRect (0, 0, Short.MAX_VALUE*2 , Short.MAX_VALUE*2); + + BufferedImage readBackImg = new BufferedImage(dstImg.getWidth(null), + dstImg.getHeight(null), BufferedImage.TYPE_INT_RGB); + readBackImg.getGraphics().drawImage(dstImg, 0, 0, null); + + for (int x = 0; x < readBackImg.getWidth(); x++) { + for (int y = 0; y < readBackImg.getHeight(); y++) { + int redVal = (readBackImg.getRGB(x, y) & 0x00FF0000) >> 16; + + if (redVal > 127) { + return; + } + } + } + + throw new RuntimeException("Test Failed"); + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + new HugeGradientTest(); + } + }); + } +} From 63a1a87940dfe235911a2f27fa9e470dd7cf42e7 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Fri, 30 Sep 2016 22:57:41 +0400 Subject: [PATCH 104/207] 8165234: Provide a way to not close toggle menu items on mouse click on component level Reviewed-by: serb, ssadetsky --- .../plaf/motif/MotifCheckBoxMenuItemUI.java | 4 +- .../motif/MotifRadioButtonMenuItemUI.java | 5 +- .../javax/swing/JCheckBoxMenuItem.java | 11 +- .../javax/swing/JRadioButtonMenuItem.java | 11 +- .../swing/plaf/basic/BasicLookAndFeel.java | 2 - .../swing/plaf/basic/BasicMenuItemUI.java | 12 +- .../classes/sun/swing/SwingUtilities2.java | 19 +++ .../CloseOnMouseClickPropertyTest.java | 154 ++++++++++++------ 8 files changed, 154 insertions(+), 64 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxMenuItemUI.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxMenuItemUI.java index d377dab7344..bcaf72cbe26 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxMenuItemUI.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifCheckBoxMenuItemUI.java @@ -33,6 +33,7 @@ import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI; import java.awt.*; import java.awt.event.*; +import sun.swing.SwingUtilities2; /** @@ -89,7 +90,8 @@ public class MotifCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI Point p = e.getPoint(); if(p.x >= 0 && p.x < menuItem.getWidth() && p.y >= 0 && p.y < menuItem.getHeight()) { - if (UIManager.getBoolean("CheckBoxMenuItem.closeOnMouseClick")) { + String property = "CheckBoxMenuItem.doNotCloseOnMouseClick"; + if (!SwingUtilities2.getBoolean(menuItem, property)) { manager.clearSelectedPath(); } menuItem.doClick(0); diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonMenuItemUI.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonMenuItemUI.java index 2aa3a514309..3cc793fccae 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonMenuItemUI.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifRadioButtonMenuItemUI.java @@ -33,6 +33,7 @@ import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI; import java.awt.*; import java.awt.event.*; import java.io.Serializable; +import sun.swing.SwingUtilities2; /** @@ -97,8 +98,8 @@ public class MotifRadioButtonMenuItemUI extends BasicRadioButtonMenuItemUI Point p = e.getPoint(); if(p.x >= 0 && p.x < menuItem.getWidth() && p.y >= 0 && p.y < menuItem.getHeight()) { - String property = "RadioButtonMenuItem.closeOnMouseClick"; - if (UIManager.getBoolean(property)) { + String property = "RadioButtonMenuItem.doNotCloseOnMouseClick"; + if (!SwingUtilities2.getBoolean(menuItem, property)) { manager.clearSelectedPath(); } menuItem.doClick(0); diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JCheckBoxMenuItem.java b/jdk/src/java.desktop/share/classes/javax/swing/JCheckBoxMenuItem.java index 39757f4a9dd..dea89064036 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JCheckBoxMenuItem.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JCheckBoxMenuItem.java @@ -58,10 +58,13 @@ import javax.accessibility.*; *

* Some times it is required to select several check box menu items from a menu. * In this case it is useful that clicking on one check box menu item does not - * close the menu. Such behavior can be controlled by the Look and Feel property - * named {@code "CheckBoxMenuItem.closeOnMouseClick"}. The default value is - * {@code true}. Setting the property to {@code false} prevents the menu from - * closing when it is clicked by the mouse. + * close the menu. Such behavior can be controlled either by client + * {@link JComponent#putClientProperty} or the Look and Feel + * {@link UIManager#put} property named + * {@code "CheckBoxMenuItem.doNotCloseOnMouseClick"}. The default value is + * {@code false}. Setting the property to {@code true} prevents the menu from + * closing when it is clicked by the mouse. If the client property is set its + * value is always used; otherwise the {@literal L&F} property is queried. * Note: some {@code L&F}s may ignore this property. All built-in {@code L&F}s * inherit this behaviour. *

diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JRadioButtonMenuItem.java b/jdk/src/java.desktop/share/classes/javax/swing/JRadioButtonMenuItem.java index f73ee417d5e..1d5eb2369e9 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JRadioButtonMenuItem.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JRadioButtonMenuItem.java @@ -52,10 +52,13 @@ import javax.accessibility.*; *

* Some menus can have several button groups with radio button menu items. In * this case it is useful that clicking on one radio button menu item does not - * close the menu. Such behavior can be controlled by the Look and Feel property - * named {@code "RadioButtonMenuItem.closeOnMouseClick"}. The default value is - * {@code true}. Setting the property to {@code false} prevents the menu from - * closing when it is clicked by the mouse. + * close the menu. Such behavior can be controlled either by client + * {@link JComponent#putClientProperty} or the Look and Feel + * {@link UIManager#put} property named + * {@code "RadioButtonMenuItem.doNotCloseOnMouseClick"}. The default value is + * {@code false}. Setting the property to {@code true} prevents the menu from + * closing when it is clicked by the mouse. If the client property is set its + * value is always used; otherwise the {@literal L&F} property is queried. * Note: some {@code L&F}s may ignore this property. All built-in {@code L&F}s * inherit this behaviour. *

diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java index ffbcd89fa85..6b8beeeafe3 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -1055,7 +1055,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab "RadioButtonMenuItem.checkIcon", radioButtonMenuItemIcon, "RadioButtonMenuItem.arrowIcon", menuItemArrowIcon, "RadioButtonMenuItem.commandSound", null, - "RadioButtonMenuItem.closeOnMouseClick", Boolean.TRUE, "CheckBoxMenuItem.font", dialogPlain12, "CheckBoxMenuItem.acceleratorFont", dialogPlain12, @@ -1072,7 +1071,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab "CheckBoxMenuItem.checkIcon", checkBoxMenuItemIcon, "CheckBoxMenuItem.arrowIcon", menuItemArrowIcon, "CheckBoxMenuItem.commandSound", null, - "CheckBoxMenuItem.closeOnMouseClick", Boolean.TRUE, "Menu.font", dialogPlain12, "Menu.acceleratorFont", dialogPlain12, diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java index 27bcb103e3f..e797c937d33 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -936,13 +936,15 @@ public class BasicMenuItemUI extends MenuItemUI } } - boolean closeOnMouseClick() { + boolean doNotCloseOnMouseClick() { if (menuItem instanceof JCheckBoxMenuItem) { - return UIManager.getBoolean("CheckBoxMenuItem.closeOnMouseClick"); + String property = "CheckBoxMenuItem.doNotCloseOnMouseClick"; + return SwingUtilities2.getBoolean(menuItem, property); } else if (menuItem instanceof JRadioButtonMenuItem) { - return UIManager.getBoolean("RadioButtonMenuItem.closeOnMouseClick"); + String property = "RadioButtonMenuItem.doNotCloseOnMouseClick"; + return SwingUtilities2.getBoolean(menuItem, property); } - return true; + return false; } /** @@ -967,7 +969,7 @@ public class BasicMenuItemUI extends MenuItemUI BasicLookAndFeel.playSound(menuItem, getPropertyPrefix() + ".commandSound"); } - if (closeOnMouseClick()) { + if (!doNotCloseOnMouseClick()) { // Visual feedback if (msm == null) { msm = MenuSelectionManager.defaultManager(); diff --git a/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java b/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java index 5119ab7a18d..ab67aae0154 100644 --- a/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java +++ b/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java @@ -2046,6 +2046,25 @@ public class SwingUtilities2 { return false; } + /** + * Returns the client property for the given key if it is set; otherwise + * returns the {@L&F} property. + * + * @param component the component + * @param key an {@code String} specifying the key for the desired boolean value + * @return the boolean value of the client property if it is set or the {@L&F} + * property in other case. + */ + public static boolean getBoolean(JComponent component, String key) { + Object clientProperty = component.getClientProperty(key); + + if (clientProperty instanceof Boolean) { + return Boolean.TRUE.equals(clientProperty); + } + + return UIManager.getBoolean(key); + } + /** * Used to listen to "blit" repaints in RepaintManager. */ diff --git a/jdk/test/javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java b/jdk/test/javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java index 5846371fa35..e11b74a4880 100644 --- a/jdk/test/javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java +++ b/jdk/test/javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java @@ -37,45 +37,67 @@ import javax.swing.UIManager; /* * @test - * @bug 8158566 8160879 8160977 + * @bug 8158566 8160879 8160977 8158566 * @summary Provide a Swing property which modifies MenuItemUI behaviour */ public class CloseOnMouseClickPropertyTest { + private static final String CHECK_BOX_PROP = "CheckBoxMenuItem." + + "doNotCloseOnMouseClick"; + private static final String RADIO_BUTTON_PROP = "RadioButtonMenuItem" + + ".doNotCloseOnMouseClick"; + private static JFrame frame; private static JMenu menu; + private static TestItem[] TEST_ITEMS = { + new TestItem(TestType.CHECK_BOX_MENU_ITEM, true, true), + new TestItem(TestType.CHECK_BOX_MENU_ITEM, true, false), + new TestItem(TestType.CHECK_BOX_MENU_ITEM, false, true), + new TestItem(TestType.CHECK_BOX_MENU_ITEM, false, false), + + new TestItem(TestType.CHECK_BOX_MENU_ITEM, null, true), + new TestItem(TestType.CHECK_BOX_MENU_ITEM, null, false), + new TestItem(TestType.CHECK_BOX_MENU_ITEM, true, null), + new TestItem(TestType.CHECK_BOX_MENU_ITEM, false, null), + + + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, true, true), + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, true, false), + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, false, true), + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, false, false), + + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, true, null), + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, false, null), + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, null, true), + new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, null, false), + + new TestItem(TestType.MENU_ITEM, true, true), + new TestItem(TestType.MENU_ITEM, true, false), + new TestItem(TestType.MENU_ITEM, false, true), + new TestItem(TestType.MENU_ITEM, false, false), + + new TestItem(TestType.MENU_ITEM, true, null), + new TestItem(TestType.MENU_ITEM, false, null), + new TestItem(TestType.MENU_ITEM, null, true), + new TestItem(TestType.MENU_ITEM, null, false), + }; + public static void main(String[] args) throws Exception { for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { UIManager.setLookAndFeel(info.getClassName()); - test(true); - - setProperty(false); - test(false); - - setProperty(true); - test(true); + for (TestItem testItem : TEST_ITEMS) { + test(testItem); + } } } - private static void setProperty(boolean closeOnMouseClick) { - UIManager.put("CheckBoxMenuItem.closeOnMouseClick", closeOnMouseClick); - UIManager.put("RadioButtonMenuItem.closeOnMouseClick", closeOnMouseClick); - } - - private static void test(boolean closeOnMouseClick) throws Exception { - for (TestType testType : TestType.values()) { - test(testType, closeOnMouseClick); - } - } - - private static void test(TestType testType, boolean closeOnMouseClick) - throws Exception { + private static void test(TestItem item) throws Exception { Robot robot = new Robot(); robot.setAutoDelay(50); - SwingUtilities.invokeAndWait(() -> createAndShowGUI(testType)); + SwingUtilities.invokeAndWait(() -> createAndShowGUI(item)); robot.waitForIdle(); Point point = getClickPoint(true); @@ -94,21 +116,13 @@ public class CloseOnMouseClickPropertyTest { JMenuItem menuItem = menu.getItem(0); boolean isShowing = menuItem.isShowing(); frame.dispose(); - - if (TestType.MENU_ITEM.equals(testType)) { - if (isShowing) { - throw new RuntimeException("Menu Item is not closed!"); - } - } else { - if (isShowing ^ !closeOnMouseClick) { - throw new RuntimeException("Property is not taken into account:" - + " closeOnMouseClick"); - } + if (isShowing ^ item.doNotCloseOnMouseClick()) { + throw new RuntimeException("Property is not taken into account!"); } }); } - private static void createAndShowGUI(TestType testType) { + private static void createAndShowGUI(TestItem testItem) { frame = new JFrame(); frame.setSize(300, 300); @@ -116,23 +130,15 @@ public class CloseOnMouseClickPropertyTest { JMenuBar menuBar = new JMenuBar(); menu = new JMenu("Menu"); - menu.add(getMenuItem(testType)); + JMenuItem menuItem = testItem.getMenuItem(); + testItem.setProperties(menuItem); + menu.add(menuItem); menuBar.add(menu); + frame.setJMenuBar(menuBar); frame.setVisible(true); } - private static JMenuItem getMenuItem(TestType testType) { - switch (testType) { - case CHECK_BOX_MENU_ITEM: - return new JCheckBoxMenuItem("Check Box"); - case RADIO_BUTTON_MENU_ITEM: - return new JRadioButtonMenuItem("Radio Button"); - default: - return new JMenuItem("Menu Item"); - } - } - private static Point getClickPoint(boolean parent) throws Exception { Point points[] = new Point[1]; @@ -157,4 +163,60 @@ public class CloseOnMouseClickPropertyTest { CHECK_BOX_MENU_ITEM, RADIO_BUTTON_MENU_ITEM } -} + + static class TestItem { + + TestType type; + Boolean compDoNotCloseOnMouseClick; + Boolean lafDoNotCloseOnMouseClick; + + public TestItem(TestType type, + Boolean compDoNotCloseOnMouseClick, + Boolean lafDoNotCloseOnMouseClick) + { + this.type = type; + this.compDoNotCloseOnMouseClick = compDoNotCloseOnMouseClick; + this.lafDoNotCloseOnMouseClick = lafDoNotCloseOnMouseClick; + } + + boolean doNotCloseOnMouseClick() { + switch (type) { + case MENU_ITEM: + return false; + default: + return compDoNotCloseOnMouseClick != null + ? compDoNotCloseOnMouseClick + : lafDoNotCloseOnMouseClick; + } + } + + void setProperties(JMenuItem menuItem) { + switch (type) { + case CHECK_BOX_MENU_ITEM: + menuItem.putClientProperty(CHECK_BOX_PROP, compDoNotCloseOnMouseClick); + UIManager.put(CHECK_BOX_PROP, lafDoNotCloseOnMouseClick); + break; + case RADIO_BUTTON_MENU_ITEM: + menuItem.putClientProperty(RADIO_BUTTON_PROP, compDoNotCloseOnMouseClick); + UIManager.put(RADIO_BUTTON_PROP, lafDoNotCloseOnMouseClick); + break; + default: + menuItem.putClientProperty(CHECK_BOX_PROP, compDoNotCloseOnMouseClick); + menuItem.putClientProperty(RADIO_BUTTON_PROP, compDoNotCloseOnMouseClick); + UIManager.put(CHECK_BOX_PROP, lafDoNotCloseOnMouseClick); + UIManager.put(RADIO_BUTTON_PROP, lafDoNotCloseOnMouseClick); + } + } + + JMenuItem getMenuItem() { + switch (type) { + case CHECK_BOX_MENU_ITEM: + return new JCheckBoxMenuItem("Check Box"); + case RADIO_BUTTON_MENU_ITEM: + return new JRadioButtonMenuItem("Radio Button"); + default: + return new JMenuItem("Menu Item"); + } + } + } +} \ No newline at end of file From c95a4b0b729bc5a7dc790567bb18ae4a17d7dc87 Mon Sep 17 00:00:00 2001 From: Semyon Sadetsky Date: Fri, 30 Sep 2016 22:10:44 +0300 Subject: [PATCH 105/207] 8132664: closed/javax/swing/DataTransfer/DefaultNoDrop/DefaultNoDrop.java locks on Windows Reviewed-by: serb --- .../native/libawt/windows/awt_DnDDS.cpp | 18 ++++++++++++++++-- .../native/libawt/windows/awt_Toolkit.cpp | 8 +++++++- .../native/libawt/windows/awt_Toolkit.h | 3 ++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp index 27999b6b551..4432634e97e 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -266,11 +266,14 @@ void AwtDragSource::_DoDragDrop(void* param) { dragSource->Signal(); + AwtToolkit &toolkit = AwtToolkit::GetInstance(); + toolkit.isInDoDragDropLoop = TRUE; res = ::DoDragDrop(dragSource, dragSource, convertActionsToDROPEFFECT(dragSource->m_actions), &effects ); + toolkit.isInDoDragDropLoop = FALSE; if (effects == DROPEFFECT_NONE && dragSource->m_dwPerformedDropEffect != DROPEFFECT_NONE) { effects = dragSource->m_dwPerformedDropEffect; @@ -626,6 +629,7 @@ ULONG __stdcall AwtDragSource::Release() { */ HRESULT __stdcall AwtDragSource::QueryContinueDrag(BOOL fEscapeKeyPressed, DWORD grfKeyState) { + AwtToolkit::GetInstance().eventNumber++; TRY; JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -681,6 +685,7 @@ HRESULT __stdcall AwtDragSource::QueryContinueDrag(BOOL fEscapeKeyPressed, DWOR */ HRESULT __stdcall AwtDragSource::GiveFeedback(DWORD dwEffect) { + AwtToolkit::GetInstance().eventNumber++; TRY; JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -760,6 +765,7 @@ HRESULT __stdcall AwtDragSource::GiveFeedback(DWORD dwEffect) { HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium) { + AwtToolkit::GetInstance().eventNumber++; TRY; STGMEDIUM *pPicMedia = PictureDragHelper::FindData(*pFormatEtc); if (NULL != pPicMedia) { @@ -934,6 +940,7 @@ HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc, HRESULT __stdcall AwtDragSource::GetDataHere(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium) { + AwtToolkit::GetInstance().eventNumber++; TRY; if (pmedium->pUnkForRelease != (IUnknown *)NULL) { @@ -1036,6 +1043,7 @@ HRESULT __stdcall AwtDragSource::GetDataHere(FORMATETC __RPC_FAR *pFormatEtc, */ HRESULT __stdcall AwtDragSource::QueryGetData(FORMATETC __RPC_FAR *pFormatEtc) { + AwtToolkit::GetInstance().eventNumber++; TRY; return MatchFormatEtc(pFormatEtc, (FORMATETC *)NULL); @@ -1049,6 +1057,7 @@ HRESULT __stdcall AwtDragSource::QueryGetData(FORMATETC __RPC_FAR *pFormatEtc) */ HRESULT __stdcall AwtDragSource::GetCanonicalFormatEtc(FORMATETC __RPC_FAR *pFormatEtcIn, FORMATETC __RPC_FAR *pFormatEtcOut) { + AwtToolkit::GetInstance().eventNumber++; TRY; HRESULT res = MatchFormatEtc(pFormatEtcIn, (FORMATETC *)NULL); @@ -1069,6 +1078,7 @@ HRESULT __stdcall AwtDragSource::GetCanonicalFormatEtc(FORMATETC __RPC_FAR *pFo */ HRESULT __stdcall AwtDragSource::SetData(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium, BOOL fRelease) { + AwtToolkit::GetInstance().eventNumber++; if (pFormatEtc->cfFormat == CF_PERFORMEDDROPEFFECT && pmedium->tymed == TYMED_HGLOBAL) { m_dwPerformedDropEffect = *(DWORD*)::GlobalLock(pmedium->hGlobal); ::GlobalUnlock(pmedium->hGlobal); @@ -1091,6 +1101,7 @@ HRESULT __stdcall AwtDragSource::SetData(FORMATETC __RPC_FAR *pFormatEtc, STGMED */ HRESULT __stdcall AwtDragSource::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC *__RPC_FAR *ppenumFormatEtc) { + AwtToolkit::GetInstance().eventNumber++; TRY; *ppenumFormatEtc = new ADSIEnumFormatEtc(this); @@ -1104,6 +1115,7 @@ HRESULT __stdcall AwtDragSource::EnumFormatEtc(DWORD dwDirection, IEnumFORMATET */ HRESULT __stdcall AwtDragSource::DAdvise(FORMATETC __RPC_FAR *pFormatEtc, DWORD advf, IAdviseSink __RPC_FAR *pAdvSink, DWORD __RPC_FAR *pdwConnection) { + AwtToolkit::GetInstance().eventNumber++; return E_NOTIMPL; } @@ -1112,6 +1124,7 @@ HRESULT __stdcall AwtDragSource::DAdvise(FORMATETC __RPC_FAR *pFormatEtc, DWORD */ HRESULT __stdcall AwtDragSource::DUnadvise(DWORD dwConnection) { + AwtToolkit::GetInstance().eventNumber++; return OLE_E_ADVISENOTSUPPORTED; } @@ -1120,6 +1133,7 @@ HRESULT __stdcall AwtDragSource::DUnadvise(DWORD dwConnection) { */ HRESULT __stdcall AwtDragSource::EnumDAdvise(IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise) { + AwtToolkit::GetInstance().eventNumber++; return OLE_E_ADVISENOTSUPPORTED; } @@ -1127,7 +1141,7 @@ const UINT AwtDragSource::PROCESS_ID_FORMAT = ::RegisterClipboardFormat(TEXT("_SUNW_JAVA_AWT_PROCESS_ID")); HRESULT __stdcall AwtDragSource::GetProcessId(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium) { - + AwtToolkit::GetInstance().eventNumber++; if ((pFormatEtc->tymed & TYMED_HGLOBAL) == 0) { return DV_E_TYMED; } else if (pFormatEtc->lindex != -1) { diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp index ca8a3deb321..0fffffbf725 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -334,6 +334,7 @@ AwtToolkit::AwtToolkit() { ::GetKeyboardState(m_lastKeyboardState); m_waitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + isInDoDragDropLoop = FALSE; eventNumber = 0; } @@ -2752,7 +2753,12 @@ Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong t AwtToolkit & tk = AwtToolkit::GetInstance(); DWORD eventNumber = tk.eventNumber; tk.PostMessage(WM_SYNC_WAIT, 0, 0); - ::WaitForSingleObject(tk.m_waitEvent, INFINITE); + for(long t = 2; t < timeout && + WAIT_TIMEOUT == ::WaitForSingleObject(tk.m_waitEvent, 2); t+=2) { + if (tk.isInDoDragDropLoop) { + break; + } + } DWORD newEventNumber = tk.eventNumber; return (newEventNumber - eventNumber) > 2; } diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h index 254c89241d2..05da58b1c51 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h @@ -388,7 +388,8 @@ public: static BOOL activateKeyboardLayout(HKL hkl); HANDLE m_waitEvent; - DWORD eventNumber; + volatile DWORD eventNumber; + volatile BOOL isInDoDragDropLoop; private: HWND CreateToolkitWnd(LPCTSTR name); From 799f344fccd19fa88b52dfb0a591b7eabbe2a1c8 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 30 Sep 2016 13:15:22 -0700 Subject: [PATCH 106/207] 8166144: New javadoc options don't conform to JEP 293 (GNU style options) Reviewed-by: ksrini, bpatel --- .../com/sun/tools/javac/main/Option.java | 5 +- .../jdk/javadoc/internal/api/JavadocTool.java | 8 +- .../formats/html/ConfigurationImpl.java | 55 +-- .../html/resources/standard.properties | 240 +++++++------ .../doclets/toolkit/Configuration.java | 117 +++---- .../jdk/javadoc/internal/tool/Messager.java | 12 +- .../jdk/javadoc/internal/tool/Start.java | 193 +++++++++-- .../jdk/javadoc/internal/tool/ToolOption.java | 212 ++++++------ .../tool/resources/javadoc.properties | 314 ++++++++++++------ .../jdk/javadoc/doclet/lib/JavadocTester.java | 18 + .../doclet/testHelpOption/TestHelpOption.java | 29 +- .../doclet/testXOption/TestXOption.java | 30 +- .../jdk/javadoc/tool/CheckResourceKeys.java | 6 + .../jdk/javadoc/tool/OptionSyntaxTest.java | 293 ++++++++++++++++ .../tool/api/basic/IsSupportedOptionTest.java | 4 +- .../javadoc/tool/modules/FilterOptions.java | 24 +- .../jdk/javadoc/tool/modules/Modules.java | 8 +- 17 files changed, 1122 insertions(+), 446 deletions(-) create mode 100644 langtools/test/jdk/javadoc/tool/OptionSyntaxTest.java diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java index 03327387b47..a869718d6b3 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java @@ -425,8 +425,7 @@ public enum Option { J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, ArgKind.ADJACENT) { @Override public boolean process(OptionHelper helper, String option) { - throw new AssertionError - ("the -J flag should be caught by the launcher."); + throw new AssertionError("the -J flag should be caught by the launcher."); } }, @@ -691,7 +690,7 @@ public enum Option { * This option takes an argument. * If the name of option ends with ':' or '=', the argument must be provided directly * after that separator. - * Otherwise, if may appear after an '=' or in the following argument position. + * Otherwise, it may appear after an '=' or in the following argument position. */ REQUIRED, diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java index f9a5d52e454..8c9fe181321 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java @@ -165,9 +165,11 @@ public class JavadocTool implements DocumentationTool { public int isSupportedOption(String option) { if (option == null) throw new NullPointerException(); - for (ToolOption o: ToolOption.values()) { - if (o.opt.equals(option)) - return o.hasArg ? 1 : 0; + for (ToolOption o : ToolOption.values()) { + for (String name : o.names) { + if (name.equals(option)) + return o.hasArg ? 1 : 0; + } } return -1; } diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java index c737469218e..d2607ba41b8 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java @@ -595,8 +595,9 @@ public class ConfigurationImpl extends Configuration { @Override public Set getSupportedOptions() { + Resources resources = getResources(); Doclet.Option[] options = { - new Option(this, "-bottom", 1) { + new Option(resources, "-bottom", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -604,7 +605,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-charset", 1) { + new Option(resources, "-charset", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -612,7 +613,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-doctitle", 1) { + new Option(resources, "-doctitle", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -620,7 +621,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-footer", 1) { + new Option(resources, "-footer", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -628,7 +629,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-header", 1) { + new Option(resources, "-header", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -636,7 +637,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-helpfile", 1) { + new Option(resources, "-helpfile", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -644,7 +645,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-html4") { + new Option(resources, "-html4") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -652,7 +653,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-html5") { + new Option(resources, "-html5") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -660,7 +661,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-nohelp") { + new Option(resources, "-nohelp") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -668,7 +669,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-nodeprecatedlist") { + new Option(resources, "-nodeprecatedlist") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -676,7 +677,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-noindex") { + new Option(resources, "-noindex") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -684,7 +685,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-nonavbar") { + new Option(resources, "-nonavbar") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -692,7 +693,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Hidden(this, "-nooverview") { + new Hidden(resources, "-nooverview") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -700,7 +701,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-notree") { + new Option(resources, "-notree") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -708,7 +709,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-overview", 1) { + new Option(resources, "-overview", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -716,7 +717,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "--frames") { + new Option(resources, "--frames") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -724,7 +725,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "--no-frames") { + new Option(resources, "--no-frames") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -732,7 +733,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Hidden(this, "-packagesheader", 1) { + new Hidden(resources, "-packagesheader", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -740,7 +741,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-splitindex") { + new Option(resources, "-splitindex") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -748,7 +749,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-stylesheetfile", 1) { + new Option(resources, "-stylesheetfile", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -756,7 +757,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-top", 1) { + new Option(resources, "-top", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -764,7 +765,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-use") { + new Option(resources, "-use") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -772,7 +773,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new Option(this, "-windowtitle", 1) { + new Option(resources, "-windowtitle", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -780,7 +781,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new XOption(this, "-Xdoclint") { + new XOption(resources, "-Xdoclint") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -788,7 +789,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new XOption(this, "-Xdocrootparent", 1) { + new XOption(resources, "-Xdocrootparent", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -796,7 +797,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new XOption(this, "doclet.xusage.xdoclint-extended.", "-Xdoclint:", 0) { + new XOption(resources, "doclet.usage.xdoclint-extended", "-Xdoclint:", 0) { @Override public boolean matches(String option) { return option.toLowerCase().startsWith(getName().toLowerCase()); @@ -809,7 +810,7 @@ public class ConfigurationImpl extends Configuration { return true; } }, - new XOption(this, "doclet.xusage.xdoclint-package.", "-Xdoclint/package:", 0) { + new XOption(resources, "doclet.usage.xdoclint-package", "-Xdoclint/package:", 0) { @Override public boolean matches(String option) { return option.toLowerCase().startsWith(getName().toLowerCase()); diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index 4f7018178f7..a56d6c006d1 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -191,144 +191,196 @@ doclet.Groupname_already_used=In -group option, groupname already used: {0} doclet.Same_package_name_used=Package name format used twice: {0} # option specifiers -doclet.usage.d.parameters= -doclet.usage.d.description=Destination directory for output files +doclet.usage.d.parameters=\ + +doclet.usage.d.description=\ + Destination directory for output files -doclet.usage.use.description=Create class and package usage pages +doclet.usage.use.description=\ + Create class and package usage pages -doclet.usage.version.description=Include @version paragraphs +doclet.usage.version.description=\ + Include @version paragraphs -doclet.usage.author.description=Include @author paragraphs +doclet.usage.author.description=\ + Include @author paragraphs -doclet.usage.docfilessubdirs.description=Recursively copy doc-file subdirectories +doclet.usage.docfilessubdirs.description=\ + Recursively copy doc-file subdirectories -doclet.usage.splitindex.description=Split index into one file per letter +doclet.usage.splitindex.description=\ + Split index into one file per letter -doclet.usage.overview.parameters= -doclet.usage.overview.description=Read overview documentation from HTML file +doclet.usage.overview.parameters=\ + +doclet.usage.overview.description=\ + Read overview documentation from HTML file +doclet.usage.windowtitle.parameters=\ + +doclet.usage.windowtitle.description=\ + Browser window title for the documentation -doclet.usage.windowtitle.parameters= -doclet.usage.windowtitle.description=Browser window title for the documentation +doclet.usage.doctitle.parameters=\ + +doclet.usage.doctitle.description=\ + Include title for the overview page -doclet.usage.doctitle.parameters= -doclet.usage.doctitle.description=Include title for the overview page +doclet.usage.header.parameters=\ + +doclet.usage.header.description=\ + Include header text for each page -doclet.usage.header.parameters= -doclet.usage.header.description=Include header text for each page +doclet.usage.html4.description=\ + Generate HTML 4.01 output -doclet.usage.html4.description=Generate HTML 4.01 output +doclet.usage.html5.description=\ + Generate HTML 5 output -doclet.usage.html5.description=Generate HTML 5 output +doclet.usage.footer.parameters=\ + +doclet.usage.footer.description=\ + Include footer text for each page -doclet.usage.footer.parameters= -doclet.usage.footer.description=Include footer text for each page +doclet.usage.top.parameters=\ + +doclet.usage.top.description=\ + Include top text for each page -doclet.usage.top.parameters= -doclet.usage.top.description=Include top text for each page +doclet.usage.bottom.parameters=\ + +doclet.usage.bottom.description=\ + Include bottom text for each page -doclet.usage.bottom.parameters= -doclet.usage.bottom.description=Include bottom text for each page +doclet.usage.link.parameters=\ + +doclet.usage.link.description=\ + Create links to javadoc output at -doclet.usage.link.parameters= -doclet.usage.link.description=Create links to javadoc output at +doclet.usage.linkoffline.parameters=\ + +doclet.usage.linkoffline.description=\ + Link to docs at using package list at -doclet.usage.linkoffline.parameters= -doclet.usage.linkoffline.description=Link to docs at using package list\n\ -\ at +doclet.usage.excludedocfilessubdir.parameters=\ + :.. +doclet.usage.excludedocfilessubdir.description=\ + Exclude any doc-files subdirectories with given name -doclet.usage.excludedocfilessubdir.parameters=:.. -doclet.usage.excludedocfilessubdir.description=\n\ -\ Exclude any doc-files subdirectories with\n\ -\ given name +doclet.usage.group.parameters=\ + :.. +doclet.usage.group.description=\ + Group specified packages together in overview page -doclet.usage.group.parameters= :.. -doclet.usage.group.description=Group specified packages together\n\ -\ in overview page +doclet.usage.nocomment.description=\ + Suppress description and tags, generate only declarations -doclet.usage.nocomment.description=Suppress description and tags, generate\n\ -\ only declarations +doclet.usage.nodeprecated.description=\ + Do not include @deprecated information -doclet.usage.nodeprecated.description=Do not include @deprecated information +doclet.usage.noqualifier.parameters=\ + ::.. +doclet.usage.noqualifier.description=\ + Exclude the list of qualifiers from the output -doclet.usage.noqualifier.parameters=::.. -doclet.usage.noqualifier.description=Exclude the list of qualifiers from the output +doclet.usage.nosince.description=\ + Do not include @since information -doclet.usage.nosince.description=Do not include @since information +doclet.usage.notimestamp.description=\ + Do not include hidden time stamp -doclet.usage.notimestamp.description=Do not include hidden time stamp +doclet.usage.nodeprecatedlist.description=\ + Do not generate deprecated list -doclet.usage.nodeprecatedlist.description=Do not generate deprecated list +doclet.usage.notree.description=\ + Do not generate class hierarchy -doclet.usage.notree.description=Do not generate class hierarchy +doclet.usage.noindex.description=\ + Do not generate index -doclet.usage.noindex.description=Do not generate index +doclet.usage.nohelp.description=\ + Do not generate help link -doclet.usage.nohelp.description=Do not generate help link +doclet.usage.nonavbar.description=\ + Do not generate navigation bar -doclet.usage.nonavbar.description=Do not generate navigation bar +doclet.usage.nooverview.description=\ + Do not generate overview pages -doclet.usage.nooverview.description=Do not generate overview pages +doclet.usage.serialwarn.description=\ + Generate warning about @serial tag -doclet.usage.serialwarn.description=Generate warning about @serial tag +doclet.usage.tag.parameters=\ + ::

+doclet.usage.tag.description=\ + Specify single argument custom tags -doclet.usage.tag.parameters=::
-doclet.usage.tag.description=\n\ -\ Specify single argument custom tags +doclet.usage.taglet.description=\ + The fully qualified name of Taglet to register -doclet.usage.taglet.description=The fully qualified name of Taglet to register +doclet.usage.tagletpath.description=\ + The path to Taglets -doclet.usage.tagletpath.description=The path to Taglets +doclet.usage.charset.parameters=\ + +doclet.usage.charset.description=\ + Charset for cross-platform viewing of generated documentation -doclet.usage.charset.parameters= -doclet.usage.charset.description=Charset for cross-platform viewing of\n\ -\ generated documentation +doclet.usage.helpfile.parameters=\ + +doclet.usage.helpfile.description=\ + Include file that help link links to -doclet.usage.helpfile.parameters= -doclet.usage.helpfile.description=Include file that help link links to +doclet.usage.linksource.description=\ + Generate source in HTML -doclet.usage.linksource.description=Generate source in HTML +doclet.usage.sourcetab.parameters=\ + +doclet.usage.sourcetab.description=\ + Specify the number of spaces each tab takes up in the source -doclet.usage.sourcetab.parameters= -doclet.usage.sourcetab.description=Specify the number of spaces each tab\n\ -\ takes up in the source +doclet.usage.keywords.description=\ + Include HTML meta tags with package, class and member info -doclet.usage.keywords.description=Include HTML meta tags with package,\n\ -\ class and member info +doclet.usage.stylesheetfile.parameters=\ + +doclet.usage.stylesheetfile.description=\ + File to change style of the generated documentation -doclet.usage.stylesheetfile.parameters= -doclet.usage.stylesheetfile.description=File to change style of the generated\n\ -\ documentation +doclet.usage.docencoding.parameters=\ + +doclet.usage.docencoding.description=\ + Specify the character encoding for the output -doclet.usage.docencoding.parameters= -doclet.usage.docencoding.description=Specify the character encoding for the output +doclet.usage.frames.description=\ + Enable the use of frames in the generated output (default) -doclet.usage.frames.description=Enable the use of frames in the generated output (default) +doclet.usage.no-frames.description=\ + Disable the use of frames in the generated output -doclet.usage.no-frames.description=Disable the use of frames in the generated output +doclet.usage.xdocrootparent.parameters=\ + +doclet.usage.xdocrootparent.description=\ + Replaces all @docRoot followed by /.. in doc comments with\n\ + -doclet.xusage.xdocrootparent.parameters= -doclet.xusage.xdocrootparent.description=Replaces all @docRoot followed by /..\n\ -\ in doc comments with +doclet.usage.xdoclint.description=\ + Enable recommended checks for problems in javadoc comments -doclet.xusage.xdoclint.description=Enable recommended checks for problems in\n\ -\ javadoc comments - -doclet.xusage.xdoclint-extended.parameters=(all|none|[-]) +doclet.usage.xdoclint-extended.parameters=\ + (all|none|[-]) # L10N: do not localize these words: all none accessibility html missing reference syntax -doclet.xusage.xdoclint-extended.description=Enable or disable specific checks\n\ -\ for problems in javadoc comments, where \n\ -\ is one of accessibility, html,\n\ -\ missing, reference, or syntax.\n +doclet.usage.xdoclint-extended.description=\ + Enable or disable specific checks for problems in javadoc\n\ + comments, where is one of accessibility, html,\n\ + missing, reference, or syntax. -doclet.xusage.xdoclint-package.parameters=([-]) -doclet.xusage.xdoclint-package.description=\n\ -\ Enable or disable checks in specific\n\ -\ packages. is a comma separated\n\ -\ list of package specifiers. Package\n\ -\ specifier is either a qualified name of a\n\ -\ package or a package name prefix followed\n\ -\ by .*, which expands to all sub-packages\n\ -\ of the given package. Prefix the package\n\ -\ specifier with - to disable checks for\n\ -\ the specified packages.\n +doclet.usage.xdoclint-package.parameters=\ + ([-]) +doclet.usage.xdoclint-package.description=\ + Enable or disable checks in specific packages. is a\n\ + comma separated list of package specifiers. A package\n\ + specifier is either a qualified name of a package or a package\n\ + name prefix followed by .*, which expands to all sub-packages\n\ + of the given package. Prefix the package specifier with - to\n\ + disable checks for the specified packages. diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java index 393f261c607..5fbf6d9d34d 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java @@ -404,8 +404,9 @@ public abstract class Configuration { } public Set getSupportedOptions() { + Resources resources = getResources(); Doclet.Option[] options = { - new Option(this, "-author") { + new Option(resources, "-author") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -413,7 +414,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-d", 1) { + new Option(resources, "-d", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -421,7 +422,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-docencoding", 1) { + new Option(resources, "-docencoding", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -429,7 +430,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-docfilessubdirs") { + new Option(resources, "-docfilessubdirs") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -437,7 +438,7 @@ public abstract class Configuration { return true; } }, - new Hidden(this, "-encoding", 1) { + new Hidden(resources, "-encoding", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -445,7 +446,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-excludedocfilessubdir", 1) { + new Option(resources, "-excludedocfilessubdir", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -453,7 +454,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-group", 2) { + new Option(resources, "-group", 2) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -461,7 +462,7 @@ public abstract class Configuration { return true; } }, - new Hidden(this, "-javafx") { + new Hidden(resources, "-javafx") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -469,7 +470,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-keywords") { + new Option(resources, "-keywords") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -477,7 +478,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-link", 1) { + new Option(resources, "-link", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -486,7 +487,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-linksource") { + new Option(resources, "-linksource") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -494,7 +495,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-linkoffline", 2) { + new Option(resources, "-linkoffline", 2) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -503,7 +504,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-nocomment") { + new Option(resources, "-nocomment") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -511,7 +512,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-nodeprecated") { + new Option(resources, "-nodeprecated") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -519,7 +520,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-nosince") { + new Option(resources, "-nosince") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -527,7 +528,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-notimestamp") { + new Option(resources, "-notimestamp") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -535,7 +536,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-noqualifier", 1) { + new Option(resources, "-noqualifier", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -543,7 +544,7 @@ public abstract class Configuration { return true; } }, - new Hidden(this, "-quiet") { + new Hidden(resources, "-quiet") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -551,7 +552,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-serialwarn") { + new Option(resources, "-serialwarn") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -559,7 +560,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-sourcetab", 1) { + new Option(resources, "-sourcetab", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -578,7 +579,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-tag", 1) { + new Option(resources, "-tag", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -589,7 +590,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-taglet", 1) { + new Option(resources, "-taglet", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -600,7 +601,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-tagletpath", 1) { + new Option(resources, "-tagletpath", 1) { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -608,7 +609,7 @@ public abstract class Configuration { return true; } }, - new Option(this, "-version") { + new Option(resources, "-version") { @Override public boolean process(String opt, ListIterator args) { optionsProcessed.add(this); @@ -1057,37 +1058,30 @@ public abstract class Configuration { private final String description; private final int argCount; - protected final Configuration c; + protected Option(Resources resources, String name, int argCount) { + this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-*", ""), name, argCount); + } - protected Option(Configuration config, String keyName, String name, int argCount) { - c = config; + protected Option(Resources resources, String keyBase, String name, int argCount) { this.name = name; - String desc = getOptionsMessage(keyName + "description"); + String desc = getOptionsMessage(resources, keyBase + ".description"); if (desc.isEmpty()) { this.description = ""; this.parameters = ""; } else { this.description = desc; - this.parameters = getOptionsMessage(keyName + "parameters"); + this.parameters = getOptionsMessage(resources, keyBase + ".parameters"); } this.argCount = argCount; } - protected Option(String prefix, Configuration config, String name, int argCount) { - this(config, prefix + name.toLowerCase().replaceAll("^-*", "") + ".", name, argCount); + protected Option(Resources resources, String name) { + this(resources, name, 0); } - protected Option(Configuration config, String name, int argCount) { - this("doclet.usage.", config, name, argCount); - } - - protected Option(Configuration config, String name) { - this(config, name, 0); - } - - private String getOptionsMessage(String key) { + private String getOptionsMessage(Resources resources, String key) { try { - return c.getResources().getText(key); + return resources.getText(key); } catch (MissingResourceException ignore) { return ""; } @@ -1113,19 +1107,9 @@ public abstract class Configuration { return parameters; } - /** - * Maintains the formatting for javadoc -help. Note the space - * alignment. - */ @Override public String toString() { - String opt = name + (name.endsWith(":") ? "" : " ") + parameters; - StringBuffer sb = new StringBuffer(" ").append(opt).append(" "); - for (int i = opt.length(); i < 32; i++) { - sb.append(" "); - } - sb.append(description); - return sb.toString(); + return name; } @Override @@ -1135,7 +1119,14 @@ public abstract class Configuration { @Override public boolean matches(String option) { - return name.toLowerCase().equals(option.toLowerCase()); + boolean matchCase = name.startsWith("--"); + if (option.startsWith("--") && option.contains("=")) { + return name.equals(option.substring(option.indexOf("=") + 1)); + } else if (matchCase) { + return name.equals(option); + } else { + return name.toLowerCase().equals(option.toLowerCase()); + } } @Override @@ -1146,16 +1137,16 @@ public abstract class Configuration { public abstract class XOption extends Option { - public XOption(Configuration config, String keyname, String name, int argCount) { - super(config, keyname, name, argCount); + public XOption(Resources resources, String prefix, String name, int argCount) { + super(resources, prefix, name, argCount); } - public XOption(Configuration config, String name, int argCount) { - super("doclet.xusage.", config, name, argCount); + public XOption(Resources resources, String name, int argCount) { + super(resources, name, argCount); } - public XOption(Configuration config, String name) { - this(config, name, 0); + public XOption(Resources resources, String name) { + this(resources, name, 0); } @Override @@ -1166,12 +1157,12 @@ public abstract class Configuration { public abstract class Hidden extends Option { - public Hidden(Configuration config, String name, int argCount) { - super("doclet.xusage.", config, name, argCount); + public Hidden(Resources resources, String name, int argCount) { + super(resources, name, argCount); } - public Hidden(Configuration config, String name) { - this(config, name, 0); + public Hidden(Resources resources, String name) { + this(resources, name, 0); } @Override diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java index 0da657f3d1c..37829952b91 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java @@ -255,7 +255,7 @@ public class Messager extends Log implements Reporter { private void incrementErrorCount(String prefix, String msg) { if (nerrors < MaxErrors) { PrintWriter errWriter = getWriter(WriterKind.ERROR); - errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg); + printRawLines(errWriter, prefix + ": " + getText("javadoc.error") + " - " + msg); errWriter.flush(); prompt(); nerrors++; @@ -293,7 +293,7 @@ public class Messager extends Log implements Reporter { private void incrementWarningCount(String prefix, String msg) { if (nwarnings < MaxWarnings) { PrintWriter warnWriter = getWriter(WriterKind.WARNING); - warnWriter.println(prefix + ": " + getText("javadoc.warning") + " - " + msg); + printRawLines(warnWriter, prefix + ": " + getText("javadoc.warning") + " - " + msg); warnWriter.flush(); nwarnings++; } @@ -318,9 +318,9 @@ public class Messager extends Log implements Reporter { PrintWriter noticeWriter = getWriter(WriterKind.NOTICE); if (path == null) { - noticeWriter.println(msg); + printRawLines(noticeWriter, msg); } else { - noticeWriter.println(prefix + ": " + msg); + printRawLines(noticeWriter, prefix + ": " + msg); } noticeWriter.flush(); } @@ -334,9 +334,9 @@ public class Messager extends Log implements Reporter { PrintWriter noticeWriter = getWriter(WriterKind.NOTICE); if (e == null) { - noticeWriter.println(msg); + printRawLines(noticeWriter, msg); } else { - noticeWriter.println(pos + ": " + msg); + printRawLines(noticeWriter, pos + ": " + msg); } noticeWriter.flush(); } diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java index 956c9cbc353..431826c5e94 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java @@ -31,14 +31,18 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Path; import java.text.BreakIterator; +import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; @@ -61,6 +65,7 @@ import com.sun.tools.javac.util.Options; import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet.Option; import jdk.javadoc.doclet.DocletEnvironment; +import jdk.javadoc.internal.doclets.toolkit.Resources; import static javax.tools.DocumentationTool.Location.*; @@ -168,7 +173,10 @@ public class Start extends ToolOption.Helper { } void usage(boolean exit) { - usage("main.usage", "-help", "main.usage.foot", exit); + usage("main.usage", "-help", "main.usage.foot"); + + if (exit) + throw new Messager.ExitJavadoc(); } @Override @@ -177,30 +185,128 @@ public class Start extends ToolOption.Helper { } void Xusage(boolean exit) { - usage("main.Xusage", "-X", "main.Xusage.foot", exit); - } - - private void usage(String main, String option, String foot, boolean exit) { - messager.notice(main); - // let doclet print usage information (does nothing on error) - if (docletClass != null) { - String name = doclet.getName(); - Set