diff --git a/make/hotspot/lib/JvmFeatures.gmk b/make/hotspot/lib/JvmFeatures.gmk index d8800d37a3278..3647806e1d726 100644 --- a/make/hotspot/lib/JvmFeatures.gmk +++ b/make/hotspot/lib/JvmFeatures.gmk @@ -121,6 +121,7 @@ ifneq ($(call check-jvm-feature, cds), true) classListParser.cpp \ classLoaderDataShared.cpp \ classLoaderExt.cpp \ + cppVtables.cpp \ dumpAllocStats.cpp \ dynamicArchive.cpp \ filemap.cpp \ diff --git a/make/scripts/generate-symbol-data.sh b/make/scripts/generate-symbol-data.sh index 3ce684041dc4b..56aa8016dd6a8 100644 --- a/make/scripts/generate-symbol-data.sh +++ b/make/scripts/generate-symbol-data.sh @@ -63,7 +63,7 @@ if [ ! -f symbols ] ; then exit 1 fi; -if [ "`hg status .`x" != "x" ] ; then +if [ "`git status --porcelain=v1 .`x" != "x" ] ; then echo "The make/data/symbols directory contains local changes!" >&2 exit 1 fi; diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 234f0f59dc9fa..5970a898bf227 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -614,8 +614,8 @@ alloc_class chunk3(RFLAGS); // Several register classes are automatically defined based upon information in // this architecture description. // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) -// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) -// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) +// 2) reg_class compiler_method_reg ( /* as def'd in frame section */ ) +// 2) reg_class interpreter_method_reg ( /* as def'd in frame section */ ) // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) // @@ -2410,12 +2410,6 @@ const int Matcher::float_pressure(int default_pressure_threshold) { return default_pressure_threshold; } -int Matcher::regnum_to_fpu_offset(int regnum) -{ - Unimplemented(); - return 0; -} - // Is this branch offset short enough that a short branch can be used? // // NOTE: If the platform does not provide any short branch variants, then @@ -4049,8 +4043,8 @@ frame %{ // Inline Cache Register or Method for I2C. inline_cache_reg(R12); - // Method Oop Register when calling interpreter. - interpreter_method_oop_reg(R12); + // Method Register when calling interpreter. + interpreter_method_reg(R12); // Number of stack slots consumed by locking an object sync_stack_slots(2); @@ -5619,9 +5613,9 @@ operand inline_cache_RegP(iRegP reg) interface(REG_INTER); %} -operand interpreter_method_oop_RegP(iRegP reg) +operand interpreter_method_RegP(iRegP reg) %{ - constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg + constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_reg match(reg); match(iRegPNoSp); op_cost(0); diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 2236be870d02b..4c2376731811e 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -997,10 +997,6 @@ const int Matcher::float_pressure(int default_pressure_threshold) { return default_pressure_threshold; } -int Matcher::regnum_to_fpu_offset(int regnum) { - return regnum - 32; // The FP registers are in the second chunk -} - // Vector width in bytes const int Matcher::vector_width_in_bytes(BasicType bt) { return MaxVectorSize; @@ -1667,7 +1663,7 @@ frame %{ // These two registers define part of the calling convention // between compiled code and the interpreter. inline_cache_reg(R_Ricklass); // Inline Cache Register or Method* for I2C - interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter + interpreter_method_reg(R_Rmethod); // Method Register when calling interpreter // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] cisc_spilling_operand_name(indOffset); @@ -2527,7 +2523,7 @@ operand inline_cache_regP(iRegP reg) %{ interface(REG_INTER); %} -operand interpreter_method_oop_regP(iRegP reg) %{ +operand interpreter_method_regP(iRegP reg) %{ constraint(ALLOC_IN_RC(Rmethod_regP)); match(reg); format %{ %} diff --git a/src/hotspot/cpu/arm/arm_32.ad b/src/hotspot/cpu/arm/arm_32.ad index 1767f69a287dd..177c1a7cae01f 100644 --- a/src/hotspot/cpu/arm/arm_32.ad +++ b/src/hotspot/cpu/arm/arm_32.ad @@ -196,7 +196,7 @@ alloc_class chunk2(APSR, FPSCR); // Several register classes are automatically defined based upon information in // this architecture description. // 1) reg_class inline_cache_reg ( as defined in frame section ) -// 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) +// 2) reg_class interpreter_method_reg ( as defined in frame section ) // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) // diff --git a/src/hotspot/cpu/ppc/c2_init_ppc.cpp b/src/hotspot/cpu/ppc/c2_init_ppc.cpp index fdf4062728cb0..e8668a4bfafd1 100644 --- a/src/hotspot/cpu/ppc/c2_init_ppc.cpp +++ b/src/hotspot/cpu/ppc/c2_init_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,12 +40,6 @@ void Compile::pd_compiler2_init() { } } - if (PowerArchitecturePPC64 == 6) { - if (FLAG_IS_DEFAULT(InsertEndGroupPPC64)) { - FLAG_SET_ERGO(InsertEndGroupPPC64, true); - } - } - if (!VM_Version::has_isel() && FLAG_IS_DEFAULT(ConditionalMoveLimit)) { FLAG_SET_ERGO(ConditionalMoveLimit, 0); } diff --git a/src/hotspot/cpu/ppc/globals_ppc.hpp b/src/hotspot/cpu/ppc/globals_ppc.hpp index 866d52bc07328..ccc3ffaa9f22b 100644 --- a/src/hotspot/cpu/ppc/globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/globals_ppc.hpp @@ -134,12 +134,6 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong); product(bool, UseStaticBranchPredictionForUncommonPathsPPC64, false, \ "Use static branch prediction hints for uncommon paths.") \ \ - product(bool, UsePower6SchedulerPPC64, false, \ - "Use Power6 Scheduler.") \ - \ - product(bool, InsertEndGroupPPC64, false, \ - "Insert EndGroup instructions to optimize for Power6.") \ - \ /* Trap based checks. */ \ /* Trap based checks use the ppc trap instructions to check certain */ \ /* conditions. This instruction raises a SIGTRAP caught by the */ \ diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 5915a3b37626e..e504b0ce62cc6 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -535,8 +535,8 @@ alloc_class chunk4 ( // information in this architecture description. // 1) reg_class inline_cache_reg ( as defined in frame section ) -// 2) reg_class compiler_method_oop_reg ( as defined in frame section ) -// 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) +// 2) reg_class compiler_method_reg ( as defined in frame section ) +// 2) reg_class interpreter_method_reg ( as defined in frame section ) // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) // @@ -1370,31 +1370,6 @@ void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { } #endif -// Macro used instead of the common __ to emulate the pipes of PPC. -// Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the -// micro scheduler to cope with "hand written" assembler like in the prolog. Though -// still no scheduling of this code is possible, the micro scheduler is aware of the -// code and can update its internal data. The following mechanism is used to achieve this: -// The micro scheduler calls size() of each compound node during scheduling. size() does a -// dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. -#if 0 // TODO: PPC port -#define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ - C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ - _masm. -#define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ - C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) -#define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ - C->hb_scheduling()->_pdScheduling->advance_offset -#else -#define ___(op) if (UsePower6SchedulerPPC64) \ - Unimplemented(); \ - _masm. -#define ___stop if (UsePower6SchedulerPPC64) \ - Unimplemented() -#define ___advance if (UsePower6SchedulerPPC64) \ - Unimplemented() -#endif - void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { Compile* C = ra_->C; C2_MacroAssembler _masm(&cbuf); @@ -1414,10 +1389,10 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { // Add nop at beginning of all frameless methods to prevent any // oop instructions from getting overwritten by make_not_entrant // (patching attempt would fail). - ___(nop) nop(); + __ nop(); } else { // Get return pc. - ___(mflr) mflr(return_pc); + __ mflr(return_pc); } if (C->clinit_barrier_on_entry()) { @@ -1477,9 +1452,9 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { if (Assembler::is_simm(stdoffset, 16)) { // Signed 16 bit offset, a simple std is ok. if (UseLoadInstructionsForStackBangingPPC64) { - ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); + __ ld(R0, (int)(signed short)stdoffset, R1_SP); } else { - ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); + __ std(R0, (int)(signed short)stdoffset, R1_SP); } } else if (Assembler::is_simm(stdoffset, 31)) { // Use largeoffset calculations for addis & ld/std. @@ -1487,11 +1462,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); Register tmp = R11; - ___(addis) addis(tmp, R1_SP, hi); + __ addis(tmp, R1_SP, hi); if (UseLoadInstructionsForStackBangingPPC64) { - ___(ld) ld(R0, lo, tmp); + __ ld(R0, lo, tmp); } else { - ___(std) std(R0, lo, tmp); + __ std(R0, lo, tmp); } } else { ShouldNotReachHere(); @@ -1506,19 +1481,9 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); ciMethod *currMethod = C->method(); - // Optimized version for most common case. - if (UsePower6SchedulerPPC64 && - !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && - !(false /* ConstantsALot TODO: PPC port*/)) { - ___(or) mr(callers_sp, R1_SP); - ___(std) std(return_pc, _abi(lr), R1_SP); - ___(stdu) stdu(R1_SP, -offset, R1_SP); - return; - } - if (!method_is_frameless) { // Get callers sp. - ___(or) mr(callers_sp, R1_SP); + __ mr(callers_sp, R1_SP); // Push method's frame, modifies SP. assert(Assembler::is_uimm(framesize, 32U), "wrong type"); @@ -1527,17 +1492,17 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { Register tmp = push_frame_temp; // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). if (Assembler::is_simm(-offset, 16)) { - ___(stdu) stdu(R1_SP, -offset, R1_SP); + __ stdu(R1_SP, -offset, R1_SP); } else { long x = -offset; // Had to insert load_const(tmp, -offset). - ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); - ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); - ___(rldicr) sldi(tmp, tmp, 32); - ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); - ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); + __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); + __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); + __ sldi(tmp, tmp, 32); + __ oris(tmp, tmp, (x & 0xffff0000) >> 16); + __ ori( tmp, tmp, (x & 0x0000ffff)); - ___(stdux) stdux(R1_SP, R1_SP, tmp); + __ stdux(R1_SP, R1_SP, tmp); } } #if 0 // TODO: PPC port @@ -1552,14 +1517,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { #endif if (!method_is_frameless) { // Save return pc. - ___(std) std(return_pc, _abi(lr), callers_sp); + __ std(return_pc, _abi(lr), callers_sp); } C->output()->set_frame_complete(cbuf.insts_size()); } -#undef ___ -#undef ___stop -#undef ___advance uint MachPrologNode::size(PhaseRegAlloc *ra_) const { // Variable size. determine dynamically. @@ -1641,35 +1603,6 @@ const Pipeline * MachEpilogNode::pipeline() const { return MachNode::pipeline_class(); } -#if 0 // TODO: PPC port -void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { - C2_MacroAssembler _masm(&cbuf); - if (LoadPollAddressFromThread) { - _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); - } else { - _masm.nop(); - } -} - -uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { - if (LoadPollAddressFromThread) { - return 4; - } else { - return 4; - } -} - -#ifndef PRODUCT -void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { - st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); -} -#endif - -const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { - return RSCRATCH1_BITS64_REG_mask(); -} -#endif // PPC port - // ============================================================================= // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or @@ -1952,102 +1885,6 @@ uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { return implementation(NULL, ra_, true, NULL); } -#if 0 // TODO: PPC port -ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { -#ifndef PRODUCT - if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; -#endif - assert(ra_->node_regs_max_index() != 0, ""); - - // Get registers to move. - OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); - OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); - OptoReg::Name dst_hi = ra_->get_reg_second(n); - OptoReg::Name dst_lo = ra_->get_reg_first(n); - - enum RC src_lo_rc = rc_class(src_lo); - enum RC dst_lo_rc = rc_class(dst_lo); - - if (src_lo == dst_lo && src_hi == dst_hi) - return ppc64Opcode_none; // Self copy, no move. - - // -------------------------------------- - // Memory->Memory Spill. Use R0 to hold the value. - if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { - return ppc64Opcode_compound; - } - - // -------------------------------------- - // Check for float->int copy; requires a trip through memory. - if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { - Unimplemented(); - } - - // -------------------------------------- - // Check for integer reg-reg copy. - if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { - Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); - Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); - if (Rsrc == Rdst) { - return ppc64Opcode_none; - } else { - return ppc64Opcode_or; - } - } - - // Check for integer store. - if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { - if (src_hi != OptoReg::Bad) { - return ppc64Opcode_std; - } else { - return ppc64Opcode_stw; - } - } - - // Check for integer load. - if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { - if (src_hi != OptoReg::Bad) { - return ppc64Opcode_ld; - } else { - return ppc64Opcode_lwz; - } - } - - // Check for float reg-reg copy. - if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { - return ppc64Opcode_fmr; - } - - // Check for float store. - if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { - if (src_hi != OptoReg::Bad) { - return ppc64Opcode_stfd; - } else { - return ppc64Opcode_stfs; - } - } - - // Check for float load. - if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { - if (src_hi != OptoReg::Bad) { - return ppc64Opcode_lfd; - } else { - return ppc64Opcode_lfs; - } - } - - // -------------------------------------------------------------------- - // Check for hi bits still needing moving. Only happens for misaligned - // arguments to native calls. - if (src_hi == dst_hi) { - return ppc64Opcode_none; // Self copy; no move. - } - - ShouldNotReachHere(); - return ppc64Opcode_undefined; -} -#endif // PPC port - #ifndef PRODUCT void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { st->print("NOP \t// %d nops to pad for loops.", _count); @@ -2143,13 +1980,6 @@ void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { // Argument is valid and klass is as expected, continue. } -#if 0 // TODO: PPC port -// Optimize UEP code on z (save a load_const() call in main path). -int MachUEPNode::ep_offset() { - return 0; -} -#endif - uint MachUEPNode::size(PhaseRegAlloc *ra_) const { // Variable size. Determine dynamically. return MachNode::size(ra_); @@ -2335,12 +2165,6 @@ const int Matcher::float_pressure(int default_pressure_threshold) { return default_pressure_threshold; } -int Matcher::regnum_to_fpu_offset(int regnum) { - // No user for this method? - Unimplemented(); - return 999; -} - const bool Matcher::convL2FSupported(void) { // fcfids can do the conversion (>= Power7). // fcfid + frsp showed rounding problem when result should be 0x3f800001. @@ -2678,23 +2502,19 @@ const bool Matcher::convi2l_type_required = true; // needs for encoding need to be specified. encode %{ enc_class enc_unimplemented %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); __ unimplemented("Unimplemented mach node encoding in AD file.", 13); %} enc_class enc_untested %{ #ifdef ASSERT - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); __ untested("Untested mach node encoding in AD file."); #else - // TODO: PPC port $archOpcode(ppc64Opcode_none); #endif %} enc_class enc_lbz(iRegIdst dst, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lbz); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lbz($dst$$Register, Idisp, $mem$$base$$Register); @@ -2702,7 +2522,6 @@ encode %{ // Load acquire. enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lbz($dst$$Register, Idisp, $mem$$base$$Register); @@ -2711,7 +2530,6 @@ encode %{ %} enc_class enc_lhz(iRegIdst dst, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lhz); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); @@ -2720,7 +2538,6 @@ encode %{ // Load acquire. enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); @@ -2730,7 +2547,6 @@ encode %{ %} enc_class enc_lwz(iRegIdst dst, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lwz); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); @@ -2739,7 +2555,6 @@ encode %{ // Load acquire. enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); @@ -2749,7 +2564,6 @@ encode %{ %} enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ld); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); // Operand 'ds' requires 4-alignment. @@ -2759,7 +2573,6 @@ encode %{ // Load acquire. enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); // Operand 'ds' requires 4-alignment. @@ -2770,14 +2583,12 @@ encode %{ %} enc_class enc_lfd(RegF dst, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lfd); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); %} enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ld); C2_MacroAssembler _masm(&cbuf); int toc_offset = 0; @@ -2801,7 +2612,6 @@ encode %{ %} enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); C2_MacroAssembler _masm(&cbuf); @@ -3036,7 +2846,6 @@ encode %{ %} enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ld); C2_MacroAssembler _masm(&cbuf); int toc_offset = 0; @@ -3069,7 +2878,6 @@ encode %{ %} enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); C2_MacroAssembler _masm(&cbuf); if (!ra_->C->output()->in_scratch_emit_size()) { @@ -3204,14 +3012,12 @@ encode %{ %} enc_class enc_stw(iRegIsrc src, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_stw); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ stw($src$$Register, Idisp, $mem$$base$$Register); %} enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_std); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); // Operand 'ds' requires 4-alignment. @@ -3220,14 +3026,12 @@ encode %{ %} enc_class enc_stfs(RegF src, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_stfs); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); %} enc_class enc_stfd(RegF src, memory mem) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_stfd); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); @@ -3236,7 +3040,6 @@ encode %{ // Use release_store for card-marking to ensure that previous // oop-stores are visible before the card-mark change. enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // FIXME: Implement this as a cmove and use a fixed condition code // register which is written on every transition to compiled code, // e.g. in call-stub and when returning from runtime stubs. @@ -3252,18 +3055,8 @@ encode %{ C2_MacroAssembler _masm(&cbuf); Label skip_storestore; -#if 0 // TODO: PPC port - // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the - // StoreStore barrier conditionally. - __ lwz(R0, 0, $releaseFieldAddr$$Register); - __ cmpwi($crx$$CondRegister, R0, 0); - __ beq_predict_taken($crx$$CondRegister, skip_storestore); -#endif __ li(R0, 0); __ membar(Assembler::StoreStore); -#if 0 // TODO: PPC port - __ bind(skip_storestore); -#endif // Do the store. if ($mem$$index == 0) { @@ -3468,7 +3261,6 @@ encode %{ %} enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmove); C2_MacroAssembler _masm(&cbuf); int cc = $cmp$$cmpcode; @@ -3478,12 +3270,10 @@ encode %{ // Branch if not (cmp crx). __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); __ mr($dst$$Register, $src$$Register); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmove); C2_MacroAssembler _masm(&cbuf); Label done; @@ -3491,20 +3281,17 @@ encode %{ // Branch if not (cmp crx). __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); __ li($dst$$Register, $src$$constant); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} // This enc_class is needed so that scheduler gets proper // input mapping for latency computation. enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_andc); C2_MacroAssembler _masm(&cbuf); __ andc($dst$$Register, $src1$$Register, $src2$$Register); %} enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); @@ -3517,7 +3304,6 @@ encode %{ %} enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); @@ -3530,30 +3316,25 @@ encode %{ %} enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmove); C2_MacroAssembler _masm(&cbuf); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); Label done; __ bso($crx$$CondRegister, done); __ ld($dst$$Register, Idisp, $mem$$base$$Register); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmove); C2_MacroAssembler _masm(&cbuf); Label done; __ bso($crx$$CondRegister, done); __ mffprd($dst$$Register, $src$$FloatRegister); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_bc); C2_MacroAssembler _masm(&cbuf); Label d; // dummy @@ -3583,7 +3364,6 @@ encode %{ enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ // The scheduler doesn't know about branch shortening, so we set the opcode // to ppc64Opcode_bc in order to hide this detail from the scheduler. - // TODO: PPC port $archOpcode(ppc64Opcode_bc); C2_MacroAssembler _masm(&cbuf); Label d; // dummy @@ -3611,47 +3391,6 @@ encode %{ MacroAssembler::bc_far_optimize_on_relocate); %} - // Branch used with Power6 scheduling (can be shortened without changing the node). - enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ - // The scheduler doesn't know about branch shortening, so we set the opcode - // to ppc64Opcode_bc in order to hide this detail from the scheduler. - // TODO: PPC port $archOpcode(ppc64Opcode_bc); - - C2_MacroAssembler _masm(&cbuf); - Label d; // dummy - __ bind(d); - Label* p = ($lbl$$label); - // `p' is `NULL' when this encoding class is used only to - // determine the size of the encoded instruction. - Label& l = (NULL == p)? d : *(p); - int cc = $cmp$$cmpcode; - int flags_reg = $crx$$reg; - int bhint = Assembler::bhintNoHint; - - if (UseStaticBranchPredictionForUncommonPathsPPC64) { - if (_prob <= PROB_NEVER) { - bhint = Assembler::bhintIsNotTaken; - } else if (_prob >= PROB_ALWAYS) { - bhint = Assembler::bhintIsTaken; - } - } - -#if 0 // TODO: PPC port - if (_size == 8) { - // Tell the conditional far branch to optimize itself when being relocated. - __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), - cc_to_biint(cc, flags_reg), - l, - MacroAssembler::bc_far_optimize_on_relocate); - } else { - __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), - cc_to_biint(cc, flags_reg), - l); - } -#endif - Unimplemented(); - %} - // Postalloc expand emitter for loading a replicatef float constant from // the method's TOC. // Enc_class needed as consttanttablebase is not supported by postalloc @@ -3698,7 +3437,6 @@ encode %{ // This enc_class is needed so that scheduler gets proper // input mapping for latency computation. enc_class enc_poll(immI dst, iRegLdst poll) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ld); // Fake operand dst needed for PPC scheduler. assert($dst$$constant == 0x0, "dst must be 0x0"); @@ -3756,7 +3494,6 @@ encode %{ // // Usage of r1 and r2 in the stubs allows to distinguish them. enc_class enc_java_static_call(method meth) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_bl); C2_MacroAssembler _masm(&cbuf); address entry_point = (address)$meth$$method; @@ -3806,7 +3543,6 @@ encode %{ // Second node of expanded dynamic call - the call. enc_class enc_java_dynamic_call_sched(method meth) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_bl); C2_MacroAssembler _masm(&cbuf); @@ -3863,7 +3599,6 @@ encode %{ call->_tf = _tf; call->_entry_point = _entry_point; call->_cnt = _cnt; - call->_argsize = _argsize; call->_oop_map = _oop_map; call->_jvms = _jvms; call->_jvmadj = _jvmadj; @@ -3910,7 +3645,6 @@ encode %{ // Toc is only passed so that it can be used in ins_encode statement. // In the code we have to use $constanttablebase. enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); int start_offset = __ offset(); @@ -3968,7 +3702,6 @@ encode %{ // a runtime call enc_class enc_java_to_runtime_call (method meth) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); C2_MacroAssembler _masm(&cbuf); const address start_pc = __ pc(); @@ -4002,7 +3735,6 @@ encode %{ // This enc_class is needed so that scheduler gets proper // input mapping for latency computation. enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); C2_MacroAssembler _masm(&cbuf); __ mtctr($src$$Register); %} @@ -4067,7 +3799,6 @@ encode %{ call->_tf = _tf; call->_entry_point = _entry_point; call->_cnt = _cnt; - call->_argsize = _argsize; call->_oop_map = _oop_map; guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); call->_jvms = NULL; @@ -4124,8 +3855,8 @@ frame %{ // Inline Cache Register or method for I2C. inline_cache_reg(R19); // R19_method - // Method Oop Register when calling interpreter. - interpreter_method_oop_reg(R19); // R19_method + // Method Register when calling interpreter. + interpreter_method_reg(R19); // R19_method // Optional: name the operand used by cisc-spilling to access // [stack_pointer + offset]. @@ -5034,15 +4765,15 @@ operand inline_cache_regP(iRegPdst reg) %{ interface(REG_INTER); %} -operand compiler_method_oop_regP(iRegPdst reg) %{ - constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg +operand compiler_method_regP(iRegPdst reg) %{ + constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_reg match(reg); format %{ %} interface(REG_INTER); %} -operand interpreter_method_oop_regP(iRegPdst reg) %{ - constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg +operand interpreter_method_regP(iRegPdst reg) %{ + constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_reg match(reg); format %{ %} interface(REG_INTER); @@ -5511,7 +5242,6 @@ instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ format %{ "EXTSB $dst, $src \t// byte->int" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_extsb); __ extsb($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -5669,7 +5399,6 @@ instruct loadS(iRegIdst dst, memory mem) %{ format %{ "LHA $dst, $mem" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lha); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lha($dst$$Register, Idisp, $mem$$base$$Register); %} @@ -5686,7 +5415,6 @@ instruct loadS_ac(iRegIdst dst, memory mem) %{ "ISYNC" %} size(12); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lha($dst$$Register, Idisp, $mem$$base$$Register); __ twi_0($dst$$Register); @@ -5793,7 +5521,6 @@ instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ format %{ "LWA $dst, $mem \t// loadI2L" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lwa); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lwa($dst$$Register, Idisp, $mem$$base$$Register); %} @@ -5810,7 +5537,6 @@ instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ "ISYNC" %} size(12); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lwa); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lwa($dst$$Register, Idisp, $mem$$base$$Register); __ twi_0($dst$$Register); @@ -6012,7 +5738,6 @@ instruct loadF(regF dst, memory mem) %{ format %{ "LFS $dst, $mem" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lfs); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); %} @@ -6032,7 +5757,6 @@ instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ "ISYNC" %} size(16); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); Label next; __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); @@ -6069,7 +5793,6 @@ instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ "ISYNC" %} size(16); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); Label next; __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); @@ -6104,7 +5827,6 @@ instruct loadToc_hi(iRegLdst dst) %{ format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); %} ins_pipe(pipe_class_default); @@ -6118,7 +5840,6 @@ instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ori); __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); %} ins_pipe(pipe_class_default); @@ -6131,7 +5852,6 @@ instruct loadConI16(iRegIdst dst, immI16 src) %{ format %{ "LI $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -6145,7 +5865,6 @@ instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ format %{ "LIS $dst, $src.hi" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); // Lis sign extends 16-bit src then shifts it 16 bit to the left. __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); %} @@ -6162,7 +5881,6 @@ instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ format %{ "ORI $dst, $src1.hi, $src2.lo" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ori); __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); %} ins_pipe(pipe_class_default); @@ -6190,7 +5908,6 @@ instruct loadConL16(iRegLdst dst, immL16 src) %{ format %{ "LI $dst, $src \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -6204,7 +5921,6 @@ instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ format %{ "LIS $dst, $src.hi \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); %} ins_pipe(pipe_class_default); @@ -6220,7 +5936,6 @@ instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ format %{ "ORI $dst, $src1, $src2.lo" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ori); __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); %} ins_pipe(pipe_class_default); @@ -6300,7 +6015,6 @@ instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ld); int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); %} @@ -6327,7 +6041,6 @@ instruct loadConN0(iRegNdst dst, immN_0 src) %{ format %{ "LI $dst, $src \t// compressed ptr" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, 0); %} ins_pipe(pipe_class_default); @@ -6341,7 +6054,6 @@ instruct loadConN_hi(iRegNdst dst, immN src) %{ format %{ "LIS $dst, $src \t// narrow oop hi" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); %} ins_pipe(pipe_class_default); @@ -6355,7 +6067,6 @@ instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); RelocationHolder rspec = oop_Relocation::spec(oop_index); @@ -6386,7 +6097,6 @@ instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src$$Register, 0x20); %} ins_pipe(pipe_class_default); @@ -6399,7 +6109,6 @@ instruct loadBase(iRegLdst dst) %{ format %{ "LoadConst $dst, heapbase" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); %} ins_pipe(pipe_class_default); @@ -6447,7 +6156,6 @@ instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ format %{ "LIS $dst, $src \t// narrow klass hi" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); %} @@ -6463,7 +6171,6 @@ instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src2$$Register, 0x20); %} ins_pipe(pipe_class_default); @@ -6479,7 +6186,6 @@ instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ori); intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); @@ -6537,7 +6243,6 @@ instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ format %{ "LI $dst, $src \t// ptr" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -6585,7 +6290,6 @@ instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ld); int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); %} @@ -6622,7 +6326,6 @@ instruct loadConF(regF dst, immF src, iRegLdst toc) %{ format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lfs); address float_address = __ float_constant($src$$constant); if (float_address == NULL) { ciEnv::current()->record_out_of_memory_failure(); @@ -6645,7 +6348,6 @@ instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ "ADDIS $toc, $toc, -offset_hi"%} size(12); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); FloatRegister Rdst = $dst$$FloatRegister; Register Rtoc = $toc$$Register; address float_address = __ float_constant($src$$constant); @@ -6686,7 +6388,6 @@ instruct loadConD(regD dst, immD src, iRegLdst toc) %{ format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lfd); address float_address = __ double_constant($src$$constant); if (float_address == NULL) { ciEnv::current()->record_out_of_memory_failure(); @@ -6710,7 +6411,6 @@ instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ "ADDIS $toc, $toc, -offset_hi" %} size(12); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); FloatRegister Rdst = $dst$$FloatRegister; Register Rtoc = $toc$$Register; address float_address = __ double_constant($src$$constant); @@ -6753,7 +6453,6 @@ instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); __ dcbz($src$$Register, $mem$$base$$Register); %} ins_pipe(pipe_class_memory); @@ -6767,7 +6466,6 @@ instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); __ dcbz($mem$$base$$Register); %} ins_pipe(pipe_class_memory); @@ -6781,7 +6479,6 @@ instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); __ dcbtst($src$$Register, $mem$$base$$Register); %} ins_pipe(pipe_class_memory); @@ -6795,7 +6492,6 @@ instruct prefetch_alloc_no_offset(indirectMemory mem) %{ format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); __ dcbtst($mem$$base$$Register); %} ins_pipe(pipe_class_memory); @@ -6811,7 +6507,6 @@ instruct storeB(memory mem, iRegIsrc src) %{ format %{ "STB $src, $mem \t// byte" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_stb); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ stb($src$$Register, Idisp, $mem$$base$$Register); %} @@ -6826,7 +6521,6 @@ instruct storeC(memory mem, iRegIsrc src) %{ format %{ "STH $src, $mem \t// short" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sth); int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); __ sth($src$$Register, Idisp, $mem$$base$$Register); %} @@ -6980,7 +6674,6 @@ instruct storeCM_G1(memory mem, immI_0 zero) %{ format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} size(8); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ li(R0, 0); //__ release(); // G1: oops are allowed to get visible after dirty marking guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); @@ -7002,7 +6695,6 @@ instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ format %{ "SRDI $dst, $src, 3 \t// encode" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); %} ins_pipe(pipe_class_default); @@ -7016,7 +6708,6 @@ instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ format %{ "SUB $dst, $src, oop_base \t// encode" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); %} ins_pipe(pipe_class_default); @@ -7032,7 +6723,6 @@ instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" "done:" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Label done; __ beq($crx$$CondRegister, done); __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); @@ -7051,7 +6741,6 @@ instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ size(4); ins_encode %{ // This is a Power7 instruction for which no machine description exists. - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -7065,7 +6754,6 @@ instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); %} ins_pipe(pipe_class_default); @@ -7104,7 +6792,6 @@ instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); %} ins_pipe(pipe_class_default); @@ -7119,7 +6806,6 @@ instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ format %{ "MR $dst, $src \t// Ptr->Narrow" %} // variable size, 0 or 4. ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ mr_if_needed($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -7136,7 +6822,6 @@ instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); %} ins_pipe(pipe_class_default); @@ -7150,7 +6835,6 @@ instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); %} ins_pipe(pipe_class_default); @@ -7169,7 +6853,6 @@ instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" "done:" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Label done; __ beq($crx$$CondRegister, done); __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); @@ -7190,7 +6873,6 @@ instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ size(4); ins_encode %{ // This is a Power7 instruction for which no machine description exists. - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -7219,7 +6901,6 @@ instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); %} ins_pipe(pipe_class_default); @@ -7236,7 +6917,6 @@ instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); %} ins_pipe(pipe_class_default); @@ -7347,7 +7027,6 @@ instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} // variable size, 0 or 4. ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ mr_if_needed($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -7362,7 +7041,6 @@ instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} // variable size, 0 or 4. ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ mr_if_needed($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -7381,7 +7059,6 @@ instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ format %{ "SRDI $dst, $src, 3 \t// encode" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); %} ins_pipe(pipe_class_default); @@ -7396,7 +7073,6 @@ instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ format %{ "SUB $dst, $base, $src \t// encode" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_subf); __ subf($dst$$Register, $base$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -7410,7 +7086,6 @@ instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); %} ins_pipe(pipe_class_default); @@ -7470,7 +7145,6 @@ instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); %} ins_pipe(pipe_class_default); @@ -7486,7 +7160,6 @@ instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_add); __ add($dst$$Register, $base$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -7550,7 +7223,6 @@ instruct membar_acquire() %{ format %{ "MEMBAR-acquire" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); __ acquire(); %} ins_pipe(pipe_class_default); @@ -7584,7 +7256,6 @@ instruct membar_release() %{ format %{ "MEMBAR-release" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); __ release(); %} ins_pipe(pipe_class_default); @@ -7597,7 +7268,6 @@ instruct membar_storestore() %{ format %{ "MEMBAR-store-store" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); __ membar(Assembler::StoreStore); %} ins_pipe(pipe_class_default); @@ -7620,7 +7290,6 @@ instruct membar_volatile() %{ format %{ "MEMBAR-volatile" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sync); __ fence(); %} ins_pipe(pipe_class_default); @@ -7679,7 +7348,6 @@ instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) ins_encode %{ // This is a Power7 instruction for which no machine description // exists. Anyways, the scheduler should be off on Power7. - // TODO: PPC port $archOpcode(ppc64Opcode_compound); int cc = $cmp$$cmpcode; __ isel($dst$$Register, $crx$$CondRegister, (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); @@ -7696,7 +7364,7 @@ instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7709,7 +7377,7 @@ instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7725,7 +7393,6 @@ instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) ins_encode %{ // This is a Power7 instruction for which no machine description // exists. Anyways, the scheduler should be off on Power7. - // TODO: PPC port $archOpcode(ppc64Opcode_compound); int cc = $cmp$$cmpcode; __ isel($dst$$Register, $crx$$CondRegister, (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); @@ -7742,7 +7409,7 @@ instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7755,7 +7422,7 @@ instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7771,7 +7438,6 @@ instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) ins_encode %{ // This is a Power7 instruction for which no machine description // exists. Anyways, the scheduler should be off on Power7. - // TODO: PPC port $archOpcode(ppc64Opcode_compound); int cc = $cmp$$cmpcode; __ isel($dst$$Register, $crx$$CondRegister, (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); @@ -7789,7 +7455,7 @@ instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7802,7 +7468,7 @@ instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7818,7 +7484,6 @@ instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) ins_encode %{ // This is a Power7 instruction for which no machine description // exists. Anyways, the scheduler should be off on Power7. - // TODO: PPC port $archOpcode(ppc64Opcode_compound); int cc = $cmp$$cmpcode; __ isel($dst$$Register, $crx$$CondRegister, (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); @@ -7835,7 +7500,7 @@ instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7848,7 +7513,7 @@ instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); ins_pipe(pipe_class_default); %} @@ -7861,15 +7526,13 @@ instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); + size(8); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); Label done; assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); // Branch if not (cmp crx). __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); __ fmr($dst$$FloatRegister, $src$$FloatRegister); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} ins_pipe(pipe_class_default); @@ -7883,15 +7546,13 @@ instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); + size(8); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); Label done; assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); // Branch if not (cmp crx). __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); __ fmr($dst$$FloatRegister, $src$$FloatRegister); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} ins_pipe(pipe_class_default); @@ -7913,7 +7574,6 @@ instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLs effect(TEMP cr0); format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, NULL, true); @@ -7933,7 +7593,6 @@ instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRe format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); __ stdcx_($newVal$$Register, $mem_ptr$$Register); %} ins_pipe(pipe_class_memory); @@ -7949,7 +7608,6 @@ instruct loadPLocked(iRegPdst dst, memory mem) %{ format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); %} ins_pipe(pipe_class_memory); @@ -7969,7 +7627,6 @@ instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -7989,7 +7646,6 @@ instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIs effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8009,7 +7665,6 @@ instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8029,7 +7684,6 @@ instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIs effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8048,7 +7702,6 @@ instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8067,7 +7720,6 @@ instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8086,7 +7738,6 @@ instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8105,7 +7756,6 @@ instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8127,7 +7777,6 @@ instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, @@ -8142,7 +7791,6 @@ instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, @@ -8157,7 +7805,6 @@ instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, @@ -8172,7 +7819,6 @@ instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, @@ -8187,7 +7833,6 @@ instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, @@ -8202,7 +7847,6 @@ instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, @@ -8217,7 +7861,6 @@ instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, @@ -8232,7 +7875,6 @@ instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, @@ -8247,7 +7889,6 @@ instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, @@ -8262,7 +7903,6 @@ instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. @@ -8279,7 +7919,6 @@ instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, @@ -8294,7 +7933,6 @@ instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. @@ -8311,7 +7949,6 @@ instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // value is never passed to caller. __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, @@ -8327,7 +7964,6 @@ instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. @@ -8344,7 +7980,6 @@ instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, @@ -8359,7 +7994,6 @@ instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. @@ -8378,7 +8012,6 @@ instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8393,7 +8026,6 @@ instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8408,7 +8040,6 @@ instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8429,7 +8060,6 @@ instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8450,7 +8080,6 @@ instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8465,7 +8094,6 @@ instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8480,7 +8108,6 @@ instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8501,7 +8128,6 @@ instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8522,7 +8148,6 @@ instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8537,7 +8162,6 @@ instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8558,7 +8182,6 @@ instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8573,7 +8196,6 @@ instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8594,7 +8216,6 @@ instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8609,7 +8230,6 @@ instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8630,7 +8250,6 @@ instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8645,7 +8264,6 @@ instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), @@ -8903,7 +8521,6 @@ instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isr format %{ "ADD $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_add); __ add($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -8916,7 +8533,6 @@ instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "ADD $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_add); __ add($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -8942,7 +8558,6 @@ instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ format %{ "ADDI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ addi($dst$$Register, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -8954,7 +8569,6 @@ instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ format %{ "ADDIS $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); %} ins_pipe(pipe_class_default); @@ -8966,7 +8580,6 @@ instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "ADD $dst, $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_add); __ add($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -8979,7 +8592,6 @@ instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "ADD $dst, $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_add); __ add($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9006,7 +8618,6 @@ instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_add); __ add($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9019,7 +8630,6 @@ instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ format %{ "ADDI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ addi($dst$$Register, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -9033,7 +8643,6 @@ instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ format %{ "ADDIS $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); %} ins_pipe(pipe_class_default); @@ -9045,7 +8654,6 @@ instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ format %{ "ADD $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_add); __ add($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9059,7 +8667,6 @@ instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ format %{ "ADDI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ addi($dst$$Register, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -9073,7 +8680,6 @@ instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ format %{ "ADDIS $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); %} ins_pipe(pipe_class_default); @@ -9088,7 +8694,6 @@ instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "SUBF $dst, $src2, $src1" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_subf); __ subf($dst$$Register, $src2$$Register, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -9105,7 +8710,6 @@ instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_subfic); __ subfic($dst$$Register, $src2$$Register, $src1$$constant); %} ins_pipe(pipe_class_default); @@ -9121,7 +8725,6 @@ instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ format %{ "SRAWI $dst, $src, #31" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_srawi); __ srawi($dst$$Register, $src$$Register, 0x1f); %} ins_pipe(pipe_class_default); @@ -9145,7 +8748,6 @@ instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ format %{ "NEG $dst, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_neg); __ neg($dst$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9157,7 +8759,6 @@ instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "SUBF $dst, $src2, $src1 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_subf); __ subf($dst$$Register, $src2$$Register, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -9170,7 +8771,6 @@ instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_subf); __ subf($dst$$Register, $src2$$Register, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -9186,7 +8786,6 @@ instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ format %{ "SRADI $dst, $src, #63" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sradi); __ sradi($dst$$Register, $src$$Register, 0x3f); %} ins_pipe(pipe_class_default); @@ -9202,7 +8801,6 @@ instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ format %{ "SRADI $dst, $src, #63" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sradi); __ sradi($dst$$Register, $src$$Register, 0x3f); %} ins_pipe(pipe_class_default); @@ -9227,7 +8825,6 @@ instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ format %{ "NEG $dst, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_neg); __ neg($dst$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9240,7 +8837,6 @@ instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ format %{ "NEG $dst, $src2 \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_neg); __ neg($dst$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9257,7 +8853,6 @@ instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "MULLW $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mullw); __ mullw($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9271,7 +8866,6 @@ instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ format %{ "MULLI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mulli); __ mulli($dst$$Register, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -9284,7 +8878,6 @@ instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "MULLD $dst $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mulld); __ mulld($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9298,7 +8891,6 @@ instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "MULHD $dst $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9312,7 +8904,6 @@ instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ format %{ "MULLI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mulli); __ mulli($dst$$Register, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -9326,7 +8917,6 @@ instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) format %{ "NEG $dst, $src1 \t// /-1" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_neg); __ neg($dst$$Register, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -9343,7 +8933,6 @@ instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_divw); __ divw($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9357,13 +8946,11 @@ instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ format %{ "CMOVE $dst, neg($src1), $crx" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); + size(8); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmove); Label done; __ bne($crx$$CondRegister, done); __ neg($dst$$Register, $src1$$Register); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} ins_pipe(pipe_class_default); @@ -9391,7 +8978,6 @@ instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) format %{ "NEG $dst, $src1 \t// /-1, long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_neg); __ neg($dst$$Register, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -9406,7 +8992,6 @@ instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_divd); __ divd($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9420,13 +9005,11 @@ instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ format %{ "CMOVE $dst, neg($src1), $crx" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); + size(8); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmove); Label done; __ bne($crx$$CondRegister, done); __ neg($dst$$Register, $src1$$Register); - // TODO PPC port __ endgroup_if_needed(_size == 12); __ bind(done); %} ins_pipe(pipe_class_default); @@ -9496,7 +9079,6 @@ instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src$$Register, $mask$$constant); %} ins_pipe(pipe_class_default); @@ -9510,7 +9092,6 @@ instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "SLW $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_slw); __ slw($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9534,7 +9115,6 @@ instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); %} ins_pipe(pipe_class_default); @@ -9548,7 +9128,6 @@ instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi long src2 = $src2$$constant; long src3 = $src3$$constant; long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); @@ -9569,7 +9148,6 @@ instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immI format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi long src2 = $src2$$constant; long src3 = $src3$$constant; long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); @@ -9590,7 +9168,6 @@ instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ format %{ "SLD $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sld); __ sld($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9614,7 +9191,6 @@ instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); %} ins_pipe(pipe_class_default); @@ -9628,7 +9204,6 @@ instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ size(4); format %{ "SLDI $dst, i2l($src1), $src2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); %} ins_pipe(pipe_class_default); @@ -9643,7 +9218,6 @@ instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldic); __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -9657,7 +9231,6 @@ instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "SRAW $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sraw); __ sraw($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9682,7 +9255,6 @@ instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_srawi); __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); %} ins_pipe(pipe_class_default); @@ -9696,7 +9268,6 @@ instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ format %{ "SRAD $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_srad); __ srad($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9722,7 +9293,6 @@ instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sradi); __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); %} ins_pipe(pipe_class_default); @@ -9735,7 +9305,6 @@ instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_sradi); __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); %} ins_pipe(pipe_class_default); @@ -9749,7 +9318,6 @@ instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "SRW $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_srw); __ srw($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9775,7 +9343,6 @@ instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); %} ins_pipe(pipe_class_default); @@ -9789,7 +9356,6 @@ instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ format %{ "SRD $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_srd); __ srd($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -9815,7 +9381,6 @@ instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); %} ins_pipe(pipe_class_default); @@ -9828,7 +9393,6 @@ instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); %} ins_pipe(pipe_class_default); @@ -9841,7 +9405,6 @@ instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); %} ins_pipe(pipe_class_default); @@ -9854,7 +9417,6 @@ instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, imm format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); int rshift = ($src2$$constant) & 0x1f; int length = log2_long(((jlong) $src3$$constant) + 1); if (rshift + length > 32) { @@ -9873,7 +9435,6 @@ instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, imm format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); int rshift = ($src2$$constant) & 0x3f; int length = log2_long(((jlong) $src3$$constant) + 1); if (rshift + length > 64) { @@ -9891,7 +9452,6 @@ instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ format %{ "EXTSW $dst, $src \t// int->int" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_extsw); __ extsw($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -9907,7 +9467,6 @@ instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) format %{ "ROTLWI $dst, $src, $lshift" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); %} ins_pipe(pipe_class_default); @@ -9921,7 +9480,6 @@ instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) format %{ "ROTRWI $dst, $rshift" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); %} ins_pipe(pipe_class_default); @@ -9936,7 +9494,6 @@ instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ format %{ "FADDS $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fadds); __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -9949,7 +9506,6 @@ instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ format %{ "FADD $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fadd); __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -9962,7 +9518,6 @@ instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ format %{ "FSUBS $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -9974,7 +9529,6 @@ instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ format %{ "FSUB $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fsub); __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -9986,7 +9540,6 @@ instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ format %{ "FMULS $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -9998,7 +9551,6 @@ instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ format %{ "FMUL $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmul); __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10010,7 +9562,6 @@ instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ format %{ "FDIVS $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10022,7 +9573,6 @@ instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ format %{ "FDIV $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10034,7 +9584,6 @@ instruct absF_reg(regF dst, regF src) %{ format %{ "FABS $dst, $src \t// float" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fabs); __ fabs($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10046,7 +9595,6 @@ instruct absD_reg(regD dst, regD src) %{ format %{ "FABS $dst, $src \t// double" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fabs); __ fabs($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10057,7 +9605,6 @@ instruct negF_reg(regF dst, regF src) %{ format %{ "FNEG $dst, $src \t// float" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fneg); __ fneg($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10068,7 +9615,6 @@ instruct negD_reg(regD dst, regD src) %{ format %{ "FNEG $dst, $src \t// double" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fneg); __ fneg($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10080,7 +9626,6 @@ instruct negF_absF_reg(regF dst, regF src) %{ format %{ "FNABS $dst, $src \t// float" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); __ fnabs($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10092,7 +9637,6 @@ instruct negD_absD_reg(regD dst, regD src) %{ format %{ "FNABS $dst, $src \t// double" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); __ fnabs($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10105,7 +9649,6 @@ instruct sqrtD_reg(regD dst, regD src) %{ format %{ "FSQRT $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10120,7 +9663,6 @@ instruct sqrtF_reg(regF dst, regF src) %{ format %{ "FSQRTS $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10157,7 +9699,6 @@ instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ format %{ "FMADDS $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10170,7 +9711,6 @@ instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ format %{ "FMADD $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10184,7 +9724,6 @@ instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10198,7 +9737,6 @@ instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ format %{ "FNMSUB $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10212,7 +9750,6 @@ instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ format %{ "FNMADDS $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10226,7 +9763,6 @@ instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ format %{ "FNMADD $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10239,7 +9775,6 @@ instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ format %{ "FMSUBS $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10252,7 +9787,6 @@ instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ format %{ "FMSUB $dst, $src1, $src2, $src3" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -10269,7 +9803,6 @@ instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "AND $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_and); __ andr($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10282,7 +9815,6 @@ instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsReg format %{ "ANDIS $dst, $src1, $src2.hi" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_andis_); __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); %} ins_pipe(pipe_class_default); @@ -10296,7 +9828,6 @@ instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 format %{ "ANDI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_andi_); // FIXME: avoid andi_ ? __ andi_($dst$$Register, $src1$$Register, $src2$$constant); %} @@ -10309,7 +9840,6 @@ instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ format %{ "ANDWI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); %} ins_pipe(pipe_class_default); @@ -10320,7 +9850,6 @@ instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src format %{ "ANDWI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); %} ins_pipe(pipe_class_default); @@ -10332,7 +9861,6 @@ instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) % format %{ "ANDWI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); __ rlwinm($dst$$Register, $src1$$Register, 0, (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); %} @@ -10347,7 +9875,6 @@ instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "AND $dst, $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_and); __ andr($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10361,7 +9888,6 @@ instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 format %{ "ANDI $dst, $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_andi_); // FIXME: avoid andi_ ? __ andi_($dst$$Register, $src1$$Register, $src2$$constant); %} @@ -10374,7 +9900,6 @@ instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ format %{ "ANDDI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); %} ins_pipe(pipe_class_default); @@ -10385,7 +9910,6 @@ instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src format %{ "ANDDI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); %} ins_pipe(pipe_class_default); @@ -10399,7 +9923,6 @@ instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2mi format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); %} ins_pipe(pipe_class_default); @@ -10413,7 +9936,6 @@ instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "OR $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10426,7 +9948,6 @@ instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "OR $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10452,7 +9973,6 @@ instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ format %{ "ORI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ori); __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); %} ins_pipe(pipe_class_default); @@ -10466,7 +9986,6 @@ instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ size(4); format %{ "OR $dst, $src1, $src2 \t// long" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10480,7 +9999,6 @@ instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10494,7 +10012,6 @@ instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ format %{ "ORI $dst, $src1, $con \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_ori); __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); %} ins_pipe(pipe_class_default); @@ -10508,7 +10025,6 @@ instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "XOR $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_xor); __ xorr($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10521,7 +10037,6 @@ instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ format %{ "XOR $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_xor); __ xorr($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10547,7 +10062,6 @@ instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ format %{ "XORI $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_xori); __ xori($dst$$Register, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -10561,7 +10075,6 @@ instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "XOR $dst, $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_xor); __ xorr($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10575,7 +10088,6 @@ instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_xor); __ xorr($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10589,7 +10101,6 @@ instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ format %{ "XORI $dst, $src1, $src2 \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_xori); __ xori($dst$$Register, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_default); @@ -10602,7 +10113,6 @@ instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ format %{ "NOT $dst, $src1 ($src2)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_nor); __ nor($dst$$Register, $src1$$Register, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -10615,7 +10125,6 @@ instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ format %{ "NOT $dst, $src1 ($src2) \t// long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_nor); __ nor($dst$$Register, $src1$$Register, $src1$$Register); %} ins_pipe(pipe_class_default); @@ -10641,7 +10150,6 @@ instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ format %{ "ANDC $dst, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_andc); __ andc($dst$$Register, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); @@ -10768,7 +10276,6 @@ instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ format %{ "LFS $dst, $src \t// MoveI2F" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_lfs); int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); %} @@ -10856,7 +10363,6 @@ instruct moveReg(iRegLdst dst, iRegIsrc src) %{ format %{ "MR $dst, $src \t// replicate " %} // variable size, 0 or 4. ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ mr_if_needed($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -10871,7 +10377,6 @@ instruct castX2P(iRegPdst dst, iRegLsrc src) %{ format %{ "MR $dst, $src \t// Long->Ptr" %} // variable size, 0 or 4. ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ mr_if_needed($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -10884,7 +10389,6 @@ instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ format %{ "MR $dst, $src \t// Ptr->Long" %} // variable size, 0 or 4. ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ mr_if_needed($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -10999,7 +10503,6 @@ instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerO format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); %} ins_pipe(pipe_class_default); @@ -11101,7 +10604,6 @@ instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_srawi); __ srawi($dst$$Register, $src1$$Register, 0x1f); %} ins_pipe(pipe_class_default); @@ -11119,7 +10621,6 @@ instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ format %{ "EXTSB $dst, $src \t// byte->int" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_extsb); __ extsb($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -11141,7 +10642,6 @@ instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ format %{ "EXTSH $dst, $src \t// short->int" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_extsh); __ extsh($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -11154,7 +10654,6 @@ instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ format %{ "EXTSW $dst, $src \t// long->long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_extsw); __ extsw($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -11165,7 +10664,6 @@ instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ format %{ "MR $dst, $src \t// long->int" %} // variable size, 0 or 4 ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_or); __ mr_if_needed($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -11179,7 +10677,6 @@ instruct convD2IRaw_regD(regD dst, regD src) %{ format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11194,7 +10691,7 @@ instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ format %{ "cmovI $crx, $dst, $src" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); ins_pipe(pipe_class_default); %} @@ -11208,7 +10705,7 @@ instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ format %{ "cmovI $crx, $dst, $src" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_bso_reg(dst, crx, src) ); ins_pipe(pipe_class_default); %} @@ -11361,7 +10858,6 @@ instruct convF2IRaw_regF(regF dst, regF src) %{ format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11406,7 +10902,6 @@ instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ format %{ "EXTSW $dst, $src \t// int->long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_extsw); __ extsw($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -11420,7 +10915,6 @@ instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src$$Register, 32); %} ins_pipe(pipe_class_default); @@ -11434,7 +10928,6 @@ instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); __ clrldi($dst$$Register, $src$$Register, 32); %} ins_pipe(pipe_class_default); @@ -11448,7 +10941,6 @@ instruct convF2LRaw_regF(regF dst, regF src) %{ format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); __ fctidz($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11463,7 +10955,7 @@ instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ format %{ "cmovL $crx, $dst, $src" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); ins_pipe(pipe_class_default); %} @@ -11477,7 +10969,7 @@ instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ format %{ "cmovL $crx, $dst, $src" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); + size(8); ins_encode( enc_cmove_bso_reg(dst, crx, src) ); ins_pipe(pipe_class_default); %} @@ -11624,7 +11116,6 @@ instruct convD2LRaw_regD(regD dst, regD src) %{ format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); __ fctidz($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11673,7 +11164,6 @@ instruct convL2DRaw_regD(regD dst, regD src) %{ format %{ "FCFID $dst, $src \t// convL2D" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); __ fcfid($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11685,7 +11175,6 @@ instruct convD2F_reg(regF dst, regD src) %{ format %{ "FRSP $dst, $src \t// convD2F" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_frsp); __ frsp($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11718,7 +11207,6 @@ instruct convL2FRaw_regF(regF dst, regD src) %{ format %{ "FCFIDS $dst, $src \t// convL2F" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); __ fcfids($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11847,7 +11335,6 @@ instruct convF2D_reg(regD dst, regF src) %{ format %{ "FMR $dst, $src \t// float->double" %} // variable size, 0 or 4 ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmr); __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -11862,7 +11349,6 @@ instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ size(4); format %{ "CMPW $crx, $src1, $src2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmp); __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_compare); @@ -11873,7 +11359,6 @@ instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ format %{ "CMPWI $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -11886,7 +11371,6 @@ instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_andi_); __ andi_(R0, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -11897,7 +11381,6 @@ instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ format %{ "CMPD $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmp); __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_compare); @@ -11908,7 +11391,6 @@ instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ format %{ "CMPDI $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -11920,7 +11402,6 @@ instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ format %{ "CMPLD $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_compare); @@ -11931,7 +11412,6 @@ instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ format %{ "CMPLDI $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -11943,7 +11423,6 @@ instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zer format %{ "AND R0, $src1, $src2 \t// BTST long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_and_); __ and_(R0, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_compare); @@ -11955,7 +11434,6 @@ instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_andi_); __ andi_(R0, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -11970,16 +11448,14 @@ instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ format %{ "cmovI $crx, $dst, -1, 0, +1" %} // Worst case is branch + move + branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); + size(16); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmove); Label done; // li(Rdst, 0); // equal -> 0 __ beq($crx$$CondRegister, done); __ li($dst$$Register, 1); // greater -> +1 __ bgt($crx$$CondRegister, done); __ li($dst$$Register, -1); // unordered or less -> -1 - // TODO: PPC port__ endgroup_if_needed(_size == 20); __ bind(done); %} ins_pipe(pipe_class_compare); @@ -12068,7 +11544,6 @@ instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, l format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_twi); if ($cmp$$cmpcode == 0x1 /* less_equal */) { __ trap_range_check_le($src_length$$Register, $index$$constant); } else { @@ -12095,7 +11570,6 @@ instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_tw); if ($cmp$$cmpcode == 0x0 /* greater_equal */) { __ trap_range_check_ge($src_index$$Register, $src_length$$Register); } else { @@ -12122,7 +11596,6 @@ instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, l format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_twi); if ($cmp$$cmpcode == 0x0 /* greater_equal */) { __ trap_range_check_ge($src_index$$Register, $length$$constant); } else { @@ -12140,7 +11613,6 @@ instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_compare); @@ -12151,7 +11623,6 @@ instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ size(4); format %{ "CMPLWI $crx, $src1, $src2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -12173,7 +11644,6 @@ instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_tdi); if ($cmp$$cmpcode == 0xA) { __ trap_null_check($value$$Register); } else { @@ -12194,7 +11664,6 @@ instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ ins_cost(2); format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_compare); @@ -12208,7 +11677,6 @@ instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -12230,7 +11698,6 @@ instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_tdi); if ($cmp$$cmpcode == 0xA) { __ trap_null_check($value$$Register); } else { @@ -12249,7 +11716,6 @@ instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_compare); @@ -12260,7 +11726,6 @@ instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); %} ins_pipe(pipe_class_compare); @@ -12277,7 +11742,6 @@ instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ format %{ "CMPDI $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); %} ins_pipe(pipe_class_compare); @@ -12294,7 +11758,6 @@ instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ format %{ "cmpFUrd $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -12309,14 +11772,12 @@ instruct cmov_bns_less(flagsReg crx) %{ format %{ "cmov $crx" %} // Worst case is branch + move + stop, no stop without scheduler. - size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); + size(12); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); Label done; __ bns($crx$$CondRegister, done); // not unordered -> keep crx __ li(R0, 0); __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' - // TODO PPC port __ endgroup_if_needed(_size == 16); __ bind(done); %} ins_pipe(pipe_class_default); @@ -12409,7 +11870,6 @@ instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ format %{ "cmpFUrd $crx, $src1, $src2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); %} ins_pipe(pipe_class_default); @@ -12614,7 +12074,6 @@ instruct branch(label labl) %{ format %{ "B $labl" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_b); Label d; // dummy __ bind(d); Label* p = $labl$$label; @@ -12654,7 +12113,6 @@ instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ // Same match rule as `branchCon'. match(If cmp crx); effect(USE crx, USE lbl); - predicate(!false /* TODO: PPC port HB_Schedule*/); // Higher cost than `branchCon'. ins_cost(5*BRANCH_COST); @@ -12667,26 +12125,6 @@ instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ ins_pipe(pipe_class_default); %} -// Conditional Branch used with Power6 scheduler (can be far or short). -instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ - // Same match rule as `branchCon'. - match(If cmp crx); - effect(USE crx, USE lbl); - predicate(false /* TODO: PPC port HB_Schedule*/); - // Higher cost than `branchCon'. - ins_cost(5*BRANCH_COST); - - // Actually size doesn't depend on alignment but on shortening. - ins_variable_size_depending_on_alignment(true); - // long variant. - ins_short_branch(0); - - format %{ "B_FAR$cmp $crx, $lbl" %} - size(8); // worst case - ins_encode( enc_bc_short_far(crx, cmp, lbl) ); - ins_pipe(pipe_class_default); -%} - instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ match(CountedLoopEnd cmp crx); effect(USE labl); @@ -12704,7 +12142,6 @@ instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ match(CountedLoopEnd cmp crx); effect(USE labl); - predicate(!false /* TODO: PPC port HB_Schedule */); ins_cost(BRANCH_COST); // Long variant. @@ -12716,25 +12153,6 @@ instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ ins_pipe(pipe_class_default); %} -// Conditional Branch used with Power6 scheduler (can be far or short). -instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ - match(CountedLoopEnd cmp crx); - effect(USE labl); - predicate(false /* TODO: PPC port HB_Schedule */); - // Higher cost than `branchCon'. - ins_cost(5*BRANCH_COST); - - // Actually size doesn't depend on alignment but on shortening. - ins_variable_size_depending_on_alignment(true); - // Long variant. - ins_short_branch(0); - - format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} - size(8); // worst case - ins_encode( enc_bc_short_far(crx, cmp, labl) ); - ins_pipe(pipe_class_default); -%} - // ============================================================================ // Java runtime operations, intrinsics and other complex operations. @@ -12754,7 +12172,6 @@ instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P supe format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, $tmp_klass$$Register, NULL, $result$$Register); %} @@ -12770,7 +12187,6 @@ instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iR format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, UseBiasedLocking && !UseOptoBiasInlining); @@ -12789,7 +12205,6 @@ instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, /*Biased Locking*/ false, @@ -12810,7 +12225,6 @@ instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, UseBiasedLocking && !UseOptoBiasInlining, @@ -12829,7 +12243,6 @@ instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, /*Biased Locking*/ false, /*TM*/ true); @@ -12847,7 +12260,6 @@ instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); %} ins_pipe(pipe_class_default); @@ -12860,7 +12272,6 @@ instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ format %{ "SUB $dst, $end, $start \t// array size in bytes" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_subf); __ subf($dst$$Register, $start$$Register, $end$$Register); %} ins_pipe(pipe_class_default); @@ -12874,7 +12285,6 @@ instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy format %{ "ClearArray $cnt, $base" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 %} ins_pipe(pipe_class_default); @@ -12888,7 +12298,6 @@ instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRe format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 %} ins_pipe(pipe_class_default); @@ -12902,7 +12311,6 @@ instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, reg format %{ "ClearArray $cnt, $base" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 %} ins_pipe(pipe_class_default); @@ -12916,7 +12324,6 @@ instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4Re ins_cost(300); format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register, $tmp$$Register, @@ -12933,7 +12340,6 @@ instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4Re ins_cost(300); format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register, $tmp$$Register, @@ -12950,7 +12356,6 @@ instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4R ins_cost(300); format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_compare($str1$$Register, $str2$$Register, $cnt1$$Register, $cnt2$$Register, $tmp$$Register, @@ -12967,7 +12372,6 @@ instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4R ins_cost(300); format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_compare($str2$$Register, $str1$$Register, $cnt2$$Register, $cnt1$$Register, $tmp$$Register, @@ -12984,7 +12388,6 @@ instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst ins_cost(300); format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ array_equals(false, $str1$$Register, $str2$$Register, $cnt$$Register, $tmp$$Register, $result$$Register, true /* byte */); @@ -13000,7 +12403,6 @@ instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst ins_cost(300); format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ array_equals(false, $str1$$Register, $str2$$Register, $cnt$$Register, $tmp$$Register, $result$$Register, false /* byte */); @@ -13016,7 +12418,6 @@ instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, ins_cost(300); format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ array_equals(true, $ary1$$Register, $ary2$$Register, $tmp1$$Register, $tmp2$$Register, $result$$Register, true /* byte */); @@ -13032,7 +12433,6 @@ instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, ins_cost(300); format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ array_equals(true, $ary1$$Register, $ary2$$Register, $tmp1$$Register, $tmp2$$Register, $result$$Register, false /* byte */); @@ -13054,7 +12454,6 @@ instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); immPOper *needleOper = (immPOper *)$needleImm; const TypeOopPtr *t = needleOper->type()->isa_oopptr(); ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * @@ -13088,7 +12487,6 @@ instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); immPOper *needleOper = (immPOper *)$needleImm; const TypeOopPtr *t = needleOper->type()->isa_oopptr(); ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * @@ -13115,7 +12513,6 @@ instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycn "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); immPOper *needleOper = (immPOper *)$needleImm; const TypeOopPtr *t = needleOper->type()->isa_oopptr(); ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * @@ -13143,7 +12540,6 @@ instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Node *ndl = in(operand_index($needle)); // The node that defines needle. ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); guarantee(needle_values, "sanity"); @@ -13178,7 +12574,6 @@ instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Node *ndl = in(operand_index($needle)); // The node that defines needle. ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); guarantee(needle_values, "sanity"); @@ -13206,7 +12601,6 @@ instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Node *ndl = in(operand_index($needle)); // The node that defines needle. ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); guarantee(needle_values, "sanity"); @@ -13229,7 +12623,6 @@ instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_indexof_char($result$$Register, $haystack$$Register, $haycnt$$Register, $ch$$Register, 0 /* this is not used if the character is already in a register */, @@ -13254,7 +12647,6 @@ instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Node *ndl = in(operand_index($needle)); // The node that defines needle. ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); @@ -13282,7 +12674,6 @@ instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Node *ndl = in(operand_index($needle)); // The node that defines needle. ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); @@ -13310,7 +12701,6 @@ instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Node *ndl = in(operand_index($needle)); // The node that defines needle. ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); @@ -13335,7 +12725,6 @@ instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRe format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_indexof($result$$Register, $haystack$$Register, $haycnt$$Register, $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. @@ -13357,7 +12746,6 @@ instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRe format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_indexof($result$$Register, $haystack$$Register, $haycnt$$Register, $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. @@ -13379,7 +12767,6 @@ instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iR format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ string_indexof($result$$Register, $haystack$$Register, $haycnt$$Register, $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. @@ -13397,7 +12784,6 @@ instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst re ins_cost(300); format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Label Lskip, Ldone; __ li($result$$Register, 0); __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, @@ -13420,7 +12806,6 @@ instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc l ins_cost(300); format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Label Ldone; __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); @@ -13441,7 +12826,6 @@ instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst t ins_cost(300); format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, $tmp1$$Register, $tmp2$$Register); %} @@ -13457,7 +12841,6 @@ instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst r ins_cost(300); format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); Label Lslow, Lfailure1, Lfailure2, Ldone; __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); @@ -13514,7 +12897,6 @@ instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegC ins_cost(DEFAULT_COST*2); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ cmpw(CCR0, $src1$$Register, $src2$$Register); __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); %} @@ -13548,7 +12930,6 @@ instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegC ins_cost(DEFAULT_COST*2); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ cmpw(CCR0, $src1$$Register, $src2$$Register); __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); %} @@ -13566,7 +12947,6 @@ instruct popCountI(iRegIdst dst, iRegIsrc src) %{ format %{ "POPCNTW $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); __ popcntw($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -13581,7 +12961,6 @@ instruct popCountL(iRegIdst dst, iRegLsrc src) %{ format %{ "POPCNTD $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); __ popcntd($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -13595,7 +12974,6 @@ instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ format %{ "CNTLZW $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); __ cntlzw($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -13609,7 +12987,6 @@ instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ format %{ "CNTLZD $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); __ cntlzd($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -13623,7 +13000,6 @@ instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ format %{ "CNTLZD $dst, $src" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); __ cntlzd($dst$$Register, $src$$Register); %} ins_pipe(pipe_class_default); @@ -13700,7 +13076,6 @@ instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ format %{ "INSRWI $dst, $src, $pos, $shift" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); %} ins_pipe(pipe_class_default); @@ -13714,7 +13089,6 @@ instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ format %{ "INSRWI $dst, $src, $pos, $shift" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); %} ins_pipe(pipe_class_default); @@ -14109,7 +13483,6 @@ instruct repl32(iRegLdst dst) %{ format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); __ insrdi($dst$$Register, $dst$$Register, 32, 0); %} ins_pipe(pipe_class_default); @@ -14123,7 +13496,6 @@ instruct repl48(iRegLdst dst) %{ format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); __ insrdi($dst$$Register, $dst$$Register, 48, 0); %} ins_pipe(pipe_class_default); @@ -14137,7 +13509,6 @@ instruct repl56(iRegLdst dst) %{ format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); __ insrdi($dst$$Register, $dst$$Register, 56, 0); %} ins_pipe(pipe_class_default); @@ -14160,7 +13531,6 @@ instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ format %{ "LI $dst, #0 \t// replicate8B" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -14172,7 +13542,6 @@ instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ format %{ "LI $dst, #-1 \t// replicate8B" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -14234,7 +13603,6 @@ instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ format %{ "LI $dst, #0 \t// replicate4S" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -14246,7 +13614,6 @@ instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ format %{ "LI $dst, -1 \t// replicate4S" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -14308,7 +13675,6 @@ instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ format %{ "LI $dst, #0 \t// replicate2I" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -14320,7 +13686,6 @@ instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ format %{ "LI $dst, -1 \t// replicate2I" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); %} ins_pipe(pipe_class_default); @@ -14398,7 +13763,6 @@ instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ format %{ "LI $dst, #0 \t// replicate2F" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addi); __ li($dst$$Register, 0x0); %} ins_pipe(pipe_class_default); @@ -14846,7 +14210,6 @@ instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ format %{ "add_ $op1, $op2\t# overflow check long" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ li(R0, 0); __ mtxer(R0); // clear XER.SO __ addo_(R0, $op1$$Register, $op2$$Register); @@ -14859,7 +14222,6 @@ instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ li(R0, 0); __ mtxer(R0); // clear XER.SO __ subfo_(R0, $op2$$Register, $op1$$Register); @@ -14872,7 +14234,6 @@ instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ format %{ "nego_ R0, $op2\t# overflow check long" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ li(R0, 0); __ mtxer(R0); // clear XER.SO __ nego_(R0, $op2$$Register); @@ -14885,7 +14246,6 @@ instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ li(R0, 0); __ mtxer(R0); // clear XER.SO __ mulldo_(R0, $op1$$Register, $op2$$Register); @@ -15150,7 +14510,6 @@ instruct CallLeafDirect(method meth) %{ format %{ "BCTRL \t// leaf call $meth ==> " %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); __ bctrl(); %} ins_pipe(pipe_class_call); @@ -15199,7 +14558,6 @@ instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ "BCTR \t// tail call" %} size(8); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ mtctr($jump_target$$Register); __ bctr(); %} @@ -15212,7 +14570,6 @@ instruct Ret() %{ format %{ "BLR \t// branch to link register" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_blr); // LR is restored in MachEpilogNode. Just do the RET here. __ blr(); %} @@ -15234,7 +14591,6 @@ instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ "BCTR \t// TailJump, exception oop: $ex_oop" %} size(12); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); __ mtctr($jump_target$$Register); __ bctr(); @@ -15263,7 +14619,6 @@ instruct RethrowException() %{ format %{ "Jmp rethrow_stub" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_compound); cbuf.set_insts_mark(); __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); %} @@ -15278,7 +14633,6 @@ instruct ShouldNotReachHere() %{ format %{ "ShouldNotReachHere" %} ins_encode %{ if (is_reachable()) { - // TODO: PPC port $archOpcode(ppc64Opcode_tdi); __ stop(_halt_reason); } %} @@ -15312,7 +14666,6 @@ instruct endGroup() %{ format %{ "End Bundle (ori r1, r1, 0)" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); __ endgroup(); %} ins_pipe(pipe_class_default); @@ -15328,7 +14681,6 @@ instruct fxNop() %{ format %{ "fxNop" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmr); __ nop(); %} ins_pipe(pipe_class_default); @@ -15342,7 +14694,6 @@ instruct fpNop0() %{ format %{ "fpNop0" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmr); __ fpnop0(); %} ins_pipe(pipe_class_default); @@ -15356,7 +14707,6 @@ instruct fpNop1() %{ format %{ "fpNop1" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_fmr); __ fpnop1(); %} ins_pipe(pipe_class_default); @@ -15367,7 +14717,6 @@ instruct brNop0() %{ size(4); format %{ "brNop0" %} ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); __ brnop0(); %} ins_is_nop(true); @@ -15382,7 +14731,6 @@ instruct brNop1() %{ format %{ "brNop1" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); __ brnop1(); %} ins_pipe(pipe_class_default); @@ -15396,7 +14744,6 @@ instruct brNop2() %{ format %{ "brNop2" %} size(4); ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); __ brnop2(); %} ins_pipe(pipe_class_default); diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index 9b729b5baa974..58bc1bc9caa5e 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -116,13 +116,6 @@ void VM_Version::initialize() { FLAG_SET_ERGO(TrapBasedRangeChecks, false); } - // On Power6 test for section size. - if (PowerArchitecturePPC64 == 6) { - determine_section_size(); - // TODO: PPC port } else { - // TODO: PPC port PdScheduling::power6SectorSize = 0x20; - } - if (PowerArchitecturePPC64 >= 8) { if (FLAG_IS_DEFAULT(SuperwordUseVSX)) { FLAG_SET_ERGO(SuperwordUseVSX, true); @@ -567,240 +560,6 @@ void VM_Version::print_features() { } } -#ifdef COMPILER2 -// Determine section size on power6: If section size is 8 instructions, -// there should be a difference between the two testloops of ~15 %. If -// no difference is detected the section is assumed to be 32 instructions. -void VM_Version::determine_section_size() { - - int unroll = 80; - - const int code_size = (2* unroll * 32 + 100)*BytesPerInstWord; - - // Allocate space for the code. - ResourceMark rm; - CodeBuffer cb("detect_section_size", code_size, 0); - MacroAssembler* a = new MacroAssembler(&cb); - - uint32_t *code = (uint32_t *)a->pc(); - // Emit code. - void (*test1)() = (void(*)())(void *)a->function_entry(); - - Label l1; - - a->li(R4, 1); - a->sldi(R4, R4, 28); - a->b(l1); - a->align(CodeEntryAlignment); - - a->bind(l1); - - for (int i = 0; i < unroll; i++) { - // Schleife 1 - // ------- sector 0 ------------ - // ;; 0 - a->nop(); // 1 - a->fpnop0(); // 2 - a->fpnop1(); // 3 - a->addi(R4,R4, -1); // 4 - - // ;; 1 - a->nop(); // 5 - a->fmr(F6, F6); // 6 - a->fmr(F7, F7); // 7 - a->endgroup(); // 8 - // ------- sector 8 ------------ - - // ;; 2 - a->nop(); // 9 - a->nop(); // 10 - a->fmr(F8, F8); // 11 - a->fmr(F9, F9); // 12 - - // ;; 3 - a->nop(); // 13 - a->fmr(F10, F10); // 14 - a->fmr(F11, F11); // 15 - a->endgroup(); // 16 - // -------- sector 16 ------------- - - // ;; 4 - a->nop(); // 17 - a->nop(); // 18 - a->fmr(F15, F15); // 19 - a->fmr(F16, F16); // 20 - - // ;; 5 - a->nop(); // 21 - a->fmr(F17, F17); // 22 - a->fmr(F18, F18); // 23 - a->endgroup(); // 24 - // ------- sector 24 ------------ - - // ;; 6 - a->nop(); // 25 - a->nop(); // 26 - a->fmr(F19, F19); // 27 - a->fmr(F20, F20); // 28 - - // ;; 7 - a->nop(); // 29 - a->fmr(F21, F21); // 30 - a->fmr(F22, F22); // 31 - a->brnop0(); // 32 - - // ------- sector 32 ------------ - } - - // ;; 8 - a->cmpdi(CCR0, R4, unroll); // 33 - a->bge(CCR0, l1); // 34 - a->blr(); - - // Emit code. - void (*test2)() = (void(*)())(void *)a->function_entry(); - // uint32_t *code = (uint32_t *)a->pc(); - - Label l2; - - a->li(R4, 1); - a->sldi(R4, R4, 28); - a->b(l2); - a->align(CodeEntryAlignment); - - a->bind(l2); - - for (int i = 0; i < unroll; i++) { - // Schleife 2 - // ------- sector 0 ------------ - // ;; 0 - a->brnop0(); // 1 - a->nop(); // 2 - //a->cmpdi(CCR0, R4, unroll); - a->fpnop0(); // 3 - a->fpnop1(); // 4 - a->addi(R4,R4, -1); // 5 - - // ;; 1 - - a->nop(); // 6 - a->fmr(F6, F6); // 7 - a->fmr(F7, F7); // 8 - // ------- sector 8 --------------- - - // ;; 2 - a->endgroup(); // 9 - - // ;; 3 - a->nop(); // 10 - a->nop(); // 11 - a->fmr(F8, F8); // 12 - - // ;; 4 - a->fmr(F9, F9); // 13 - a->nop(); // 14 - a->fmr(F10, F10); // 15 - - // ;; 5 - a->fmr(F11, F11); // 16 - // -------- sector 16 ------------- - - // ;; 6 - a->endgroup(); // 17 - - // ;; 7 - a->nop(); // 18 - a->nop(); // 19 - a->fmr(F15, F15); // 20 - - // ;; 8 - a->fmr(F16, F16); // 21 - a->nop(); // 22 - a->fmr(F17, F17); // 23 - - // ;; 9 - a->fmr(F18, F18); // 24 - // -------- sector 24 ------------- - - // ;; 10 - a->endgroup(); // 25 - - // ;; 11 - a->nop(); // 26 - a->nop(); // 27 - a->fmr(F19, F19); // 28 - - // ;; 12 - a->fmr(F20, F20); // 29 - a->nop(); // 30 - a->fmr(F21, F21); // 31 - - // ;; 13 - a->fmr(F22, F22); // 32 - } - - // -------- sector 32 ------------- - // ;; 14 - a->cmpdi(CCR0, R4, unroll); // 33 - a->bge(CCR0, l2); // 34 - - a->blr(); - uint32_t *code_end = (uint32_t *)a->pc(); - a->flush(); - - cb.insts()->set_end((u_char*)code_end); - - double loop1_seconds,loop2_seconds, rel_diff; - uint64_t start1, stop1; - - start1 = os::current_thread_cpu_time(false); - (*test1)(); - stop1 = os::current_thread_cpu_time(false); - loop1_seconds = (stop1- start1) / (1000 *1000 *1000.0); - - - start1 = os::current_thread_cpu_time(false); - (*test2)(); - stop1 = os::current_thread_cpu_time(false); - - loop2_seconds = (stop1 - start1) / (1000 *1000 *1000.0); - - rel_diff = (loop2_seconds - loop1_seconds) / loop1_seconds *100; - - if (PrintAssembly || PrintStubCode) { - ttyLocker ttyl; - tty->print_cr("Decoding section size detection stub at " INTPTR_FORMAT " before execution:", p2i(code)); - // Use existing decode function. This enables the [MachCode] format which is needed to DecodeErrorFile. - Disassembler::decode(&cb, (u_char*)code, (u_char*)code_end, tty); - tty->print_cr("Time loop1 :%f", loop1_seconds); - tty->print_cr("Time loop2 :%f", loop2_seconds); - tty->print_cr("(time2 - time1) / time1 = %f %%", rel_diff); - - if (rel_diff > 12.0) { - tty->print_cr("Section Size 8 Instructions"); - } else{ - tty->print_cr("Section Size 32 Instructions or Power5"); - } - } - -#if 0 // TODO: PPC port - // Set sector size (if not set explicitly). - if (FLAG_IS_DEFAULT(Power6SectorSize128PPC64)) { - if (rel_diff > 12.0) { - PdScheduling::power6SectorSize = 0x20; - } else { - PdScheduling::power6SectorSize = 0x80; - } - } else if (Power6SectorSize128PPC64) { - PdScheduling::power6SectorSize = 0x80; - } else { - PdScheduling::power6SectorSize = 0x20; - } -#endif - if (UsePower6SchedulerPPC64) Unimplemented(); -} -#endif // COMPILER2 - void VM_Version::determine_features() { #if defined(ABI_ELFv2) // 1 InstWord per call for the blr instruction. diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.hpp b/src/hotspot/cpu/ppc/vm_version_ppc.hpp index fa94a71d992ea..984bfd0140db1 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp @@ -84,8 +84,7 @@ class VM_Version: public Abstract_VM_Version { static void print_features(); static void determine_features(); // also measures cache line size static void config_dscr(); // Power 8: Configure Data Stream Control Register. - static void determine_section_size(); - static void power6_micro_bench(); + public: // Initialization static void initialize(); diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index 3c468e751d58e..24c8178f1dcd8 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -1258,7 +1258,7 @@ void LIR_Assembler::emit_static_call_stub() { __ relocate(static_stub_Relocation::spec(call_pc)); - // See also Matcher::interpreter_method_oop_reg(). + // See also Matcher::interpreter_method_reg(). AddressLiteral meta = __ allocate_metadata_address(NULL); bool success = __ load_const_from_toc(Z_method, meta); diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index e5d6acc0caa2f..bb98182d7814a 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -278,8 +278,8 @@ alloc_class chunk2( // information in this architecture description. // 1) reg_class inline_cache_reg (as defined in frame section) -// 2) reg_class compiler_method_oop_reg (as defined in frame section) -// 2) reg_class interpreter_method_oop_reg (as defined in frame section) +// 2) reg_class compiler_method_reg (as defined in frame section) +// 2) reg_class interpreter_method_reg (as defined in frame section) // 3) reg_class stack_slots(/* one chunk of stack-based "registers" */) // Integer Register Classes @@ -1569,11 +1569,6 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType return ret_value; // Per default match rules are supported. } -int Matcher::regnum_to_fpu_offset(int regnum) { - ShouldNotReachHere(); - return regnum - 32; // The FP registers are in the second chunk. -} - const bool Matcher::has_predicated_vectors(void) { return false; } @@ -2468,10 +2463,10 @@ frame %{ // interpreter_arg_ptr_reg(Z_R6); // Temporary in compiled entry-points - // compiler_method_oop_reg(Z_R1);//Z_R1_scratch + // compiler_method_reg(Z_R1);//Z_R1_scratch - // Method Oop Register when calling interpreter - interpreter_method_oop_reg(Z_R9);//Z_method + // Method Register when calling interpreter + interpreter_method_reg(Z_R9);//Z_method // Optional: name the operand used by cisc-spilling to access // [stack_pointer + offset]. @@ -3536,15 +3531,15 @@ operand inline_cache_regP(iRegP reg) %{ interface(REG_INTER); %} -operand compiler_method_oop_regP(iRegP reg) %{ - constraint(ALLOC_IN_RC(z_r1_RegP)); // compiler_method_oop_reg +operand compiler_method_regP(iRegP reg) %{ + constraint(ALLOC_IN_RC(z_r1_RegP)); // compiler_method_reg match(reg); format %{ %} interface(REG_INTER); %} -operand interpreter_method_oop_regP(iRegP reg) %{ - constraint(ALLOC_IN_RC(z_r9_regP)); // interpreter_method_oop_reg +operand interpreter_method_regP(iRegP reg) %{ + constraint(ALLOC_IN_RC(z_r9_regP)); // interpreter_method_reg match(reg); format %{ %} interface(REG_INTER); diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index ef04d33c7f47e..2a02e99c259b6 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -2589,6 +2589,38 @@ void Assembler::evmovdqub(XMMRegister dst, KRegister mask, Address src, int vect emit_operand(dst, src); } +void Assembler::evmovdqu(XMMRegister dst, KRegister mask, Address src, int vector_len, int type) { + assert(VM_Version::supports_avx512vlbw(), ""); + InstructionMark im(this); + bool wide = type == T_SHORT || type == T_LONG || type == T_CHAR; + bool bwinstr = type == T_BYTE || type == T_SHORT || type == T_CHAR; + InstructionAttr attributes(vector_len, /* vex_w */ wide, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); + attributes.set_embedded_opmask_register_specifier(mask); + attributes.set_is_evex_instruction(); + int prefix = bwinstr ? VEX_SIMD_F2 : VEX_SIMD_F3; + vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); + emit_int8(0x6F); + emit_operand(dst, src); +} + +void Assembler::evmovdqu(Address dst, KRegister mask, XMMRegister src, int vector_len, int type) { + assert(VM_Version::supports_avx512vlbw(), ""); + assert(src != xnoreg, "sanity"); + InstructionMark im(this); + bool wide = type == T_SHORT || type == T_LONG || type == T_CHAR; + bool bwinstr = type == T_BYTE || type == T_SHORT || type == T_CHAR; + InstructionAttr attributes(vector_len, /* vex_w */ wide, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); + attributes.reset_is_clear_context(); + attributes.set_embedded_opmask_register_specifier(mask); + attributes.set_is_evex_instruction(); + int prefix = bwinstr ? VEX_SIMD_F2 : VEX_SIMD_F3; + vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); + emit_int8(0x7F); + emit_operand(src, dst); +} + void Assembler::evmovdquw(XMMRegister dst, Address src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionMark im(this); @@ -7803,6 +7835,13 @@ void Assembler::shlxq(Register dst, Register src1, Register src2) { emit_int16((unsigned char)0xF7, (0xC0 | encode)); } +void Assembler::shrxq(Register dst, Register src1, Register src2) { + assert(VM_Version::supports_bmi2(), ""); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true); + int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes); + emit_int16((unsigned char)0xF7, (0xC0 | encode)); +} + #ifndef _LP64 void Assembler::incl(Register dst) { diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index bbcfb7ec64e64..8bc7bb9a4880a 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -826,7 +826,6 @@ class Assembler : public AbstractAssembler { void decl(Register dst); void decl(Address dst); - void decq(Register dst); void decq(Address dst); void incl(Register dst); @@ -911,6 +910,7 @@ class Assembler : public AbstractAssembler { void popa_uncached(); #endif void vzeroupper_uncached(); + void decq(Register dst); void pusha(); void popa(); @@ -1519,6 +1519,10 @@ class Assembler : public AbstractAssembler { void evmovdquq(XMMRegister dst, Address src, int vector_len); void evmovdquq(XMMRegister dst, XMMRegister src, int vector_len); + // Generic move instructions. + void evmovdqu(Address dst, KRegister mask, XMMRegister src, int vector_len, int type); + void evmovdqu(XMMRegister dst, KRegister mask, Address src, int vector_len, int type); + // Move lower 64bit to high 64bit in 128bit register void movlhps(XMMRegister dst, XMMRegister src); @@ -2021,6 +2025,8 @@ class Assembler : public AbstractAssembler { void shlxl(Register dst, Register src1, Register src2); void shlxq(Register dst, Register src1, Register src2); + void shrxq(Register dst, Register src1, Register src2); + //====================VECTOR ARITHMETIC===================================== diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 07a97bf10b747..9f10353726127 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -1218,6 +1218,20 @@ void C2_MacroAssembler::reduce8L(int opcode, Register dst, Register src1, XMMReg reduce_operation_256(opcode, vtmp2, vtmp2, src2); reduce4L(opcode, dst, src1, vtmp2, vtmp1, vtmp2); } + +void C2_MacroAssembler::genmask(Register dst, Register len, Register temp) { + if (ArrayCopyPartialInlineSize <= 32) { + mov64(dst, 1); + shlxq(dst, dst, len); + decq(dst); + } else { + mov64(dst, -1); + movq(temp, len); + negptr(temp); + addptr(temp, 64); + shrxq(dst, dst, temp); + } +} #endif // _LP64 void C2_MacroAssembler::reduce2F(int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp) { diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index f16b193a21d9f..13466460bc337 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -93,6 +93,7 @@ void reduceI(int opcode, int vlen, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2); #ifdef _LP64 void reduceL(int opcode, int vlen, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2); + void genmask(Register dst, Register len, Register temp); #endif // _LP64 // dst = reduce(op, src2) using vtmp as temps diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 0fd3cc9b4f08a..230808096b996 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -761,6 +761,8 @@ void VM_Version::get_processor_features() { if (is_intel()) { // Intel cpus specific settings if (is_knights_family()) { _features &= ~CPU_VZEROUPPER; + _features &= ~CPU_AVX512BW; + _features &= ~CPU_AVX512VL; } } @@ -1162,7 +1164,7 @@ void VM_Version::get_processor_features() { #endif // COMPILER2 && ASSERT if (!FLAG_IS_DEFAULT(AVX3Threshold)) { - if (!is_power_of_2(AVX3Threshold)) { + if (AVX3Threshold !=0 && !is_power_of_2(AVX3Threshold)) { warning("AVX3Threshold must be a power of 2"); FLAG_SET_DEFAULT(AVX3Threshold, 4096); } @@ -1411,6 +1413,29 @@ void VM_Version::get_processor_features() { MaxLoopPad = 11; } #endif // COMPILER2 + + if (FLAG_IS_DEFAULT(ArrayCopyPartialInlineSize) || + (!FLAG_IS_DEFAULT(ArrayCopyPartialInlineSize) && + ArrayCopyPartialInlineSize != 0 && + ArrayCopyPartialInlineSize != 32 && + ArrayCopyPartialInlineSize != 64)) { + int pi_size = 0; + if (MaxVectorSize > 32 && AVX3Threshold == 0) { + pi_size = 64; + } else if (MaxVectorSize >= 32) { + pi_size = 32; + } + if(!FLAG_IS_DEFAULT(ArrayCopyPartialInlineSize)) { + warning("Setting ArrayCopyPartialInlineSize as %d", pi_size); + } + ArrayCopyPartialInlineSize = pi_size; + } + + if (ArrayCopyPartialInlineSize > MaxVectorSize) { + ArrayCopyPartialInlineSize = MaxVectorSize; + warning("Setting ArrayCopyPartialInlineSize as MaxVectorSize"); + } + if (FLAG_IS_DEFAULT(UseXMMForArrayCopy)) { UseXMMForArrayCopy = true; // use SSE2 movq on new Intel cpus } diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 89ca2468a2158..ab94ee3838d94 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1405,6 +1405,13 @@ const bool Matcher::match_rule_supported(int opcode) { return false; } break; + case Op_VectorMaskGen: + case Op_VectorMaskedLoad: + case Op_VectorMaskedStore: + if (UseAVX < 3) { + return false; + } + break; #ifndef _LP64 case Op_AddReductionVF: case Op_AddReductionVD: @@ -1477,6 +1484,16 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType return false; } break; + case Op_VectorMaskGen: + case Op_VectorMaskedLoad: + case Op_VectorMaskedStore: + if (!VM_Version::supports_avx512bw()) { + return false; + } + if ((size_in_bits != 512) && !VM_Version::supports_avx512vl()) { + return false; + } + break; case Op_CMoveVD: if (vlen != 4) { return false; // implementation limitation (only vcmov4D_reg is present) @@ -5444,3 +5461,52 @@ instruct vprorate(vec dst, vec src, vec shift) %{ ins_pipe( pipe_slow ); %} +#ifdef _LP64 +// ---------------------------------- Masked Block Copy ------------------------------------ + +instruct vmasked_load64(vec dst, memory mem, rRegL mask) %{ + match(Set dst (VectorMaskedLoad mem mask)); + format %{ "vector_masked_load $dst, $mem, $mask \t! vector masked copy" %} + ins_encode %{ + BasicType elmType = this->bottom_type()->is_vect()->element_basic_type(); + int vector_len = vector_length_encoding(this); + //TODO: KRegister to be made valid "bound" operand to promote sharing. + __ kmovql(k2, $mask$$Register); + __ evmovdqu($dst$$XMMRegister, k2, $mem$$Address, vector_len, elmType); + %} + ins_pipe( pipe_slow ); +%} + +instruct vmask_gen(rRegL dst, rRegL len, rRegL tempLen) %{ + match(Set dst (VectorMaskGen len)); + effect(TEMP_DEF dst, TEMP tempLen); + format %{ "vector_mask_gen $len \t! vector mask generator" %} + ins_encode %{ + __ genmask($dst$$Register, $len$$Register, $tempLen$$Register); + %} + ins_pipe( pipe_slow ); +%} + +instruct vmask_gen_imm(rRegL dst, immL len) %{ + match(Set dst (VectorMaskGen len)); + format %{ "vector_mask_gen $len \t! vector mask generator" %} + ins_encode %{ + __ mov64($dst$$Register, (1L << ($len$$constant & 63)) -1); + %} + ins_pipe( pipe_slow ); +%} + +instruct vmasked_store64(memory mem, vec src, rRegL mask) %{ + match(Set mem (VectorMaskedStore mem (Binary src mask))); + format %{ "vector_masked_store $mem, $src, $mask \t! vector masked store" %} + ins_encode %{ + const MachNode* src_node = static_cast(this->in(this->operand_index($src))); + BasicType elmType = src_node->bottom_type()->is_vect()->element_basic_type(); + int vector_len = vector_length_encoding(src_node); + //TODO: KRegister to be made valid "bound" operand to promote sharing. + __ kmovql(k2, $mask$$Register); + __ evmovdqu($mem$$Address, k2, $src$$XMMRegister, vector_len, elmType); + %} + ins_pipe( pipe_slow ); +%} +#endif // _LP64 diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 98f676e163c52..e572f3ca895b6 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -131,8 +131,8 @@ alloc_class chunk0( ECX, EBX, EBP, EDI, EAX, EDX, ESI, ESP, // Several register classes are automatically defined based upon information in // this architecture description. // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) -// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) -// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) +// 2) reg_class compiler_method_reg ( /* as def'd in frame section */ ) +// 2) reg_class interpreter_method_reg ( /* as def'd in frame section */ ) // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) // // Class for no registers (empty set). @@ -1371,10 +1371,6 @@ uint MachUEPNode::size(PhaseRegAlloc *ra_) const { //============================================================================= -int Matcher::regnum_to_fpu_offset(int regnum) { - return regnum - 32; // The FP registers are in the second chunk -} - // This is UltraSparc specific, true just means we have fast l2f conversion const bool Matcher::convL2FSupported(void) { return true; @@ -1931,7 +1927,7 @@ encode %{ // enc_class Java_Interpreter_Call (label labl) %{ // JAVA INTERPRETER CALL // // int ic_reg = Matcher::inline_cache_reg(); // // int ic_encode = Matcher::_regEncode[ic_reg]; -// // int imo_reg = Matcher::interpreter_method_oop_reg(); +// // int imo_reg = Matcher::interpreter_method_reg(); // // int imo_encode = Matcher::_regEncode[imo_reg]; // // // // Interpreter expects method_ptr in EBX, currently a callee-saved register, @@ -3194,7 +3190,7 @@ frame %{ // These three registers define part of the calling convention // between compiled code and the interpreter. inline_cache_reg(EAX); // Inline Cache Register - interpreter_method_oop_reg(EBX); // Method Oop Register when calling interpreter + interpreter_method_reg(EBX); // Method Register when calling interpreter // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] cisc_spilling_operand_name(indOffset32); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 0d229331f0227..9664b4a30410b 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -161,8 +161,8 @@ alloc_class chunk0(R10, R10_H, // Several register classes are automatically defined based upon information in // this architecture description. // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) -// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) -// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) +// 2) reg_class compiler_method_reg ( /* as def'd in frame section */ ) +// 2) reg_class interpreter_method_reg ( /* as def'd in frame section */ ) // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) // @@ -1578,11 +1578,6 @@ uint MachUEPNode::size(PhaseRegAlloc* ra_) const //============================================================================= -int Matcher::regnum_to_fpu_offset(int regnum) -{ - return regnum - 32; // The FP registers are in the second chunk -} - // This is UltraSparc specific, true just means we have fast l2f conversion const bool Matcher::convL2FSupported(void) { return true; @@ -2743,7 +2738,7 @@ frame // These three registers define part of the calling convention // between compiled code and the interpreter. inline_cache_reg(RAX); // Inline Cache Register - interpreter_method_oop_reg(RBX); // Method Oop Register when + interpreter_method_reg(RBX); // Method Register when // calling interpreter // Optional: name the operand used by cisc-spilling to access diff --git a/src/hotspot/cpu/zero/interpreterFrame_zero.hpp b/src/hotspot/cpu/zero/interpreterFrame_zero.hpp index 4e96d7b34817c..a8066080d54b7 100644 --- a/src/hotspot/cpu/zero/interpreterFrame_zero.hpp +++ b/src/hotspot/cpu/zero/interpreterFrame_zero.hpp @@ -57,8 +57,8 @@ class InterpreterFrame : public ZeroFrame { protected: enum Layout { istate_off = jf_header_words + - (align_up_(sizeof(BytecodeInterpreter), - wordSize) >> LogBytesPerWord) - 1, + (align_up(sizeof(BytecodeInterpreter), + wordSize) >> LogBytesPerWord) - 1, header_words }; diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp index 82d24da77f830..198ee4eb586be 100644 --- a/src/hotspot/share/adlc/adlparse.cpp +++ b/src/hotspot/share/adlc/adlparse.cpp @@ -1002,7 +1002,11 @@ void ADLParser::frame_parse(void) { skipws(); } if (strcmp(token,"interpreter_method_oop_reg")==0) { - interpreter_method_oop_parse(frame, false); + parse_err(WARN, "Using obsolete Token, interpreter_method_oop_reg"); + skipws(); + } + if (strcmp(token,"interpreter_method_reg")==0) { + interpreter_method_parse(frame, false); } if (strcmp(token,"cisc_spilling_operand_name")==0) { cisc_spilling_operand_name_parse(frame, false); @@ -1130,9 +1134,9 @@ void ADLParser::inline_cache_parse(FrameForm *frame, bool native) { frame->_inline_cache_reg = parse_one_arg("inline cache reg entry"); } -//------------------------------interpreter_method_oop_parse------------------ -void ADLParser::interpreter_method_oop_parse(FrameForm *frame, bool native) { - frame->_interpreter_method_oop_reg = parse_one_arg("method reg entry"); +//------------------------------interpreter_method_parse------------------ +void ADLParser::interpreter_method_parse(FrameForm *frame, bool native) { + frame->_interpreter_method_reg = parse_one_arg("method reg entry"); } //------------------------------cisc_spilling_operand_parse--------------------- diff --git a/src/hotspot/share/adlc/adlparse.hpp b/src/hotspot/share/adlc/adlparse.hpp index a2ec2d784d64d..f73c3a5c36565 100644 --- a/src/hotspot/share/adlc/adlparse.hpp +++ b/src/hotspot/share/adlc/adlparse.hpp @@ -115,7 +115,7 @@ class ADLParser { void interpreter_frame_pointer_parse(FrameForm *frame, bool native); void inline_cache_parse(FrameForm *frame, bool native); void interpreter_arg_ptr_parse(FrameForm *frame, bool native); - void interpreter_method_oop_parse(FrameForm *frame, bool native); + void interpreter_method_parse(FrameForm *frame, bool native); void cisc_spilling_operand_name_parse(FrameForm *frame, bool native); void stack_alignment_parse(FrameForm *frame); void return_addr_parse(FrameForm *frame, bool native); diff --git a/src/hotspot/share/adlc/forms.cpp b/src/hotspot/share/adlc/forms.cpp index ef72faa4a57a3..c911fdc6321ff 100644 --- a/src/hotspot/share/adlc/forms.cpp +++ b/src/hotspot/share/adlc/forms.cpp @@ -268,6 +268,7 @@ Form::DataType Form::is_load_from_memory(const char *opType) const { if( strcmp(opType,"LoadRange")==0 ) return Form::idealI; if( strcmp(opType,"LoadS")==0 ) return Form::idealS; if( strcmp(opType,"LoadVector")==0 ) return Form::idealV; + if( strcmp(opType,"VectorMaskedLoad")==0 ) return Form::idealV; assert( strcmp(opType,"Load") != 0, "Must type Loads" ); return Form::none; } @@ -284,6 +285,7 @@ Form::DataType Form::is_store_to_memory(const char *opType) const { if( strcmp(opType,"StoreN")==0) return Form::idealN; if( strcmp(opType,"StoreNKlass")==0) return Form::idealNKlass; if( strcmp(opType,"StoreVector")==0 ) return Form::idealV; + if( strcmp(opType,"VectorMaskedStore")==0 ) return Form::idealV; assert( strcmp(opType,"Store") != 0, "Must type Stores" ); return Form::none; } diff --git a/src/hotspot/share/adlc/formsopt.hpp b/src/hotspot/share/adlc/formsopt.hpp index cc2434a328cf1..0ee97160e3ad2 100644 --- a/src/hotspot/share/adlc/formsopt.hpp +++ b/src/hotspot/share/adlc/formsopt.hpp @@ -336,7 +336,7 @@ class FrameForm : public Form { // Public Data char *_sync_stack_slots; char *_inline_cache_reg; - char *_interpreter_method_oop_reg; + char *_interpreter_method_reg; char *_interpreter_frame_pointer_reg; char *_cisc_spilling_operand_name; char *_frame_pointer; diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index 4ac726bdf6df4..3aedd877c7626 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -779,6 +779,7 @@ bool InstructForm::captures_bottom_type(FormDict &globals) const { !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") || !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") || #endif + !strcmp(_matrule->_rChild->_opType,"VectorMaskGen")|| !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeP") || !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN"))) return true; else if ( is_ideal_load() == Form::idealP ) return true; @@ -3484,7 +3485,7 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const { "StoreB","StoreC","Store" ,"StoreFP", "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" , "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" , - "StoreVector", "LoadVector", + "StoreVector", "LoadVector", "VectorMaskedLoad", "VectorMaskedStore", "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned", "LoadPLocked", "StorePConditional", "StoreIConditional", "StoreLConditional", @@ -4168,8 +4169,8 @@ bool MatchRule::is_vector() const { "RShiftVB","RShiftVS","RShiftVI","RShiftVL", "URShiftVB","URShiftVS","URShiftVI","URShiftVL", "ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD", - "RoundDoubleModeV","RotateLeftV" , "RotateRightV", "LoadVector","StoreVector", - "FmaVD", "FmaVF","PopCountVI", + "RoundDoubleModeV", "RotateLeftV" , "RotateRightV", "LoadVector","StoreVector", + "FmaVD", "FmaVF","PopCountVI","VectorMaskedLoad","VectorMaskedStore", // Next are not supported currently. "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D", "ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD" diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp index 8ccab58391679..674748dd1aaae 100644 --- a/src/hotspot/share/adlc/output_c.cpp +++ b/src/hotspot/share/adlc/output_c.cpp @@ -4192,12 +4192,12 @@ void ArchDesc::buildFrameMethods(FILE *fp_cpp) { fprintf(fp_cpp,"int Matcher::inline_cache_reg_encode() {"); fprintf(fp_cpp," return _regEncode[inline_cache_reg()]; }\n\n"); - // Interpreter's Method Oop Register, mask definition, and encoding - fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_oop_reg() {"); + // Interpreter's Method Register, mask definition, and encoding + fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_reg() {"); fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n", - _frame->_interpreter_method_oop_reg); - fprintf(fp_cpp,"int Matcher::interpreter_method_oop_reg_encode() {"); - fprintf(fp_cpp," return _regEncode[interpreter_method_oop_reg()]; }\n\n"); + _frame->_interpreter_method_reg); + fprintf(fp_cpp,"int Matcher::interpreter_method_reg_encode() {"); + fprintf(fp_cpp," return _regEncode[interpreter_method_reg()]; }\n\n"); // Interpreter's Frame Pointer Register, mask definition, and encoding fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_frame_pointer_reg() {"); diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index bd178fd2046db..9eeeea27f0d4c 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -453,10 +453,10 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, Klass* kls; if (!require_local) { kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, - KILL_COMPILE_ON_FATAL_(fail_type)); + CHECK_AND_CLEAR_(fail_type)); } else { kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, - KILL_COMPILE_ON_FATAL_(fail_type)); + CHECK_AND_CLEAR_(fail_type)); } found_klass = kls; } diff --git a/src/hotspot/share/ci/ciField.cpp b/src/hotspot/share/ci/ciField.cpp index 23ba2f1ba608b..df4dfc9ae634a 100644 --- a/src/hotspot/share/ci/ciField.cpp +++ b/src/hotspot/share/ci/ciField.cpp @@ -400,7 +400,7 @@ bool ciField::will_link(ciMethod* accessing_method, _name->get_symbol(), _signature->get_symbol(), methodHandle(THREAD, accessing_method->get_Method())); fieldDescriptor result; - LinkResolver::resolve_field(result, link_info, bc, false, KILL_COMPILE_ON_FATAL_(false)); + LinkResolver::resolve_field(result, link_info, bc, false, CHECK_AND_CLEAR_(false)); // update the hit-cache, unless there is a problem with memory scoping: if (accessing_method->holder()->is_shared() || !is_shared()) { diff --git a/src/hotspot/share/ci/ciUtilities.inline.hpp b/src/hotspot/share/ci/ciUtilities.inline.hpp index 5c6293145a400..8b752cd812a66 100644 --- a/src/hotspot/share/ci/ciUtilities.inline.hpp +++ b/src/hotspot/share/ci/ciUtilities.inline.hpp @@ -66,27 +66,4 @@ #define GUARDED_VM_QUICK_ENTRY(action) \ {if (IS_IN_VM) { action } else { VM_QUICK_ENTRY_MARK; { action }}} -// Redefine this later. -#define KILL_COMPILE_ON_FATAL_(result) \ - THREAD); \ - if (HAS_PENDING_EXCEPTION) { \ - if (PENDING_EXCEPTION->klass() == \ - SystemDictionary::ThreadDeath_klass()) { \ - /* Kill the compilation. */ \ - fatal("unhandled ci exception"); \ - return (result); \ - } \ - CLEAR_PENDING_EXCEPTION; \ - return (result); \ - } \ - (void)(0 - -#define KILL_COMPILE_ON_ANY \ - THREAD); \ - if (HAS_PENDING_EXCEPTION) { \ - fatal("unhandled ci exception"); \ - CLEAR_PENDING_EXCEPTION; \ - } \ -(void)(0 - #endif // SHARE_CI_CIUTILITIES_INLINE_HPP diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index b1d32e92ed9f9..304afaba3b3d9 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -655,6 +655,22 @@ static RunTimeSharedDictionary _unregistered_dictionary; static RunTimeSharedDictionary _dynamic_builtin_dictionary; static RunTimeSharedDictionary _dynamic_unregistered_dictionary; + +Handle SystemDictionaryShared::create_jar_manifest(const char* manifest_chars, size_t size, TRAPS) { + typeArrayOop buf = oopFactory::new_byteArray((int)size, CHECK_NH); + typeArrayHandle bufhandle(THREAD, buf); + ArrayAccess<>::arraycopy_from_native(reinterpret_cast(manifest_chars), + buf, typeArrayOopDesc::element_offset(0), size); + Handle bais = JavaCalls::construct_new_instance(SystemDictionary::ByteArrayInputStream_klass(), + vmSymbols::byte_array_void_signature(), + bufhandle, CHECK_NH); + // manifest = new Manifest(ByteArrayInputStream) + Handle manifest = JavaCalls::construct_new_instance(SystemDictionary::Jar_Manifest_klass(), + vmSymbols::input_stream_void_signature(), + bais, CHECK_NH); + return manifest; +} + oop SystemDictionaryShared::shared_protection_domain(int index) { return ((objArrayOop)_shared_protection_domains.resolve())->obj_at(index); } @@ -671,30 +687,17 @@ Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TR Handle manifest ; if (shared_jar_manifest(shared_path_index) == NULL) { SharedClassPathEntry* ent = FileMapInfo::shared_path(shared_path_index); - long size = ent->manifest_size(); - if (size <= 0) { + size_t size = (size_t)ent->manifest_size(); + if (size == 0) { return Handle(); } // ByteArrayInputStream bais = new ByteArrayInputStream(buf); const char* src = ent->manifest(); assert(src != NULL, "No Manifest data"); - typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_NH); - typeArrayHandle bufhandle(THREAD, buf); - ArrayAccess<>::arraycopy_from_native(reinterpret_cast(src), - buf, typeArrayOopDesc::element_offset(0), size); - - Handle bais = JavaCalls::construct_new_instance(SystemDictionary::ByteArrayInputStream_klass(), - vmSymbols::byte_array_void_signature(), - bufhandle, CHECK_NH); - - // manifest = new Manifest(bais) - manifest = JavaCalls::construct_new_instance(SystemDictionary::Jar_Manifest_klass(), - vmSymbols::input_stream_void_signature(), - bais, CHECK_NH); + manifest = create_jar_manifest(src, size, THREAD); atomic_set_shared_jar_manifest(shared_path_index, manifest()); } - manifest = Handle(THREAD, shared_jar_manifest(shared_path_index)); assert(manifest.not_null(), "sanity"); return manifest; diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp index e7b6974a0073b..fe55b7a5cd786 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.hpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp @@ -320,6 +320,7 @@ class SystemDictionaryShared: public SystemDictionary { static void print_table_statistics(outputStream* st) NOT_CDS_RETURN; static bool empty_dumptime_table() NOT_CDS_RETURN_(true); static void start_dumping() NOT_CDS_RETURN; + static Handle create_jar_manifest(const char* man, size_t size, TRAPS) NOT_CDS_RETURN_(Handle()); DEBUG_ONLY(static bool no_class_loading_should_happen() {return _no_class_loading_should_happen;}) diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 6993a2010b36a..97cc1c35a19d4 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -601,19 +601,16 @@ void register_jfr_phasetype_serializer(CompilerType compiler_type) { ResourceMark rm; static bool first_registration = true; if (compiler_type == compiler_jvmci) { - // register serializer, phases will be added later lazily. - GrowableArray* jvmci_phase_names = new GrowableArray(1); - jvmci_phase_names->append("NOT_A_PHASE_NAME"); - CompilerEvent::PhaseEvent::register_phases(jvmci_phase_names); + CompilerEvent::PhaseEvent::get_phase_id("NOT_A_PHASE_NAME", false, false, false); first_registration = false; #ifdef COMPILER2 } else if (compiler_type == compiler_c2) { assert(first_registration, "invariant"); // c2 must be registered first. GrowableArray* c2_phase_names = new GrowableArray(PHASE_NUM_TYPES); for (int i = 0; i < PHASE_NUM_TYPES; i++) { - c2_phase_names->append(CompilerPhaseTypeHelper::to_string((CompilerPhaseType)i)); + const char* phase_name = CompilerPhaseTypeHelper::to_string((CompilerPhaseType) i); + CompilerEvent::PhaseEvent::get_phase_id(phase_name, false, false, false); } - CompilerEvent::PhaseEvent::register_phases(c2_phase_names); first_registration = false; #endif // COMPILER2 } diff --git a/src/hotspot/share/compiler/compilerEvent.cpp b/src/hotspot/share/compiler/compilerEvent.cpp index 5aca2de285691..f89db6ce38955 100644 --- a/src/hotspot/share/compiler/compilerEvent.cpp +++ b/src/hotspot/share/compiler/compilerEvent.cpp @@ -34,67 +34,84 @@ class PhaseTypeGuard : public StackObj { private: static Semaphore _mutex_semaphore; + bool _enabled; public: - PhaseTypeGuard() { - _mutex_semaphore.wait(); + PhaseTypeGuard(bool enabled=true) { + if (enabled) { + _mutex_semaphore.wait(); + _enabled = true; + } else { + _enabled = false; + } } ~PhaseTypeGuard() { - _mutex_semaphore.signal(); + if (_enabled) { + _mutex_semaphore.signal(); + } } }; Semaphore PhaseTypeGuard::_mutex_semaphore(1); -static void write_phases(JfrCheckpointWriter& writer, u4 base_idx, GrowableArray* phases) { - assert(phases != NULL, "invariant"); - assert(phases->is_nonempty(), "invariant"); - const u4 nof_entries = phases->length(); - writer.write_count(nof_entries); - for (u4 i = 0; i < nof_entries; i++) { - writer.write_key(base_idx + i); - writer.write(phases->at(i)); - } -} - +// Table for mapping compiler phases names to int identifiers. static GrowableArray* phase_names = NULL; class CompilerPhaseTypeConstant : public JfrSerializer { public: void serialize(JfrCheckpointWriter& writer) { PhaseTypeGuard guard; - write_phases(writer, 0, phase_names); + assert(phase_names != NULL, "invariant"); + assert(phase_names->is_nonempty(), "invariant"); + const u4 nof_entries = phase_names->length(); + writer.write_count(nof_entries); + for (u4 i = 0; i < nof_entries; i++) { + writer.write_key(i); + writer.write(phase_names->at(i)); + } } }; -// This function provides support for adding dynamic entries to JFR type CompilerPhaseType. -// The mapping for CompilerPhaseType is maintained as growable array phase_names. -// The serializer CompilerPhaseTypeConstant must be registered with JFR at vm init. -// Registration of new phase names creates mapping, serialize it for current chunk and registers its serializer with JFR if it is not already done. -int CompilerEvent::PhaseEvent::register_phases(GrowableArray* new_phases) { - int idx = -1; - if (new_phases == NULL || new_phases->is_empty()) { - return idx; +static int lookup_phase(const char* phase_name) { + for (int i = 0; i < phase_names->length(); i++) { + const char* name = phase_names->at(i); + if (strcmp(name, phase_name) == 0) { + return i; + } } + return -1; +} + +int CompilerEvent::PhaseEvent::get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) { + int index; bool register_jfr_serializer = false; { - PhaseTypeGuard guard; + PhaseTypeGuard guard(sync); if (phase_names == NULL) { - phase_names = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray(100, mtCompiler); + phase_names = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(100, mtCompiler); register_jfr_serializer = true; + } else if (may_exist) { + index = lookup_phase(phase_name); + if (index != -1) { + return index; + } + } else { + assert((index = lookup_phase(phase_name)) == -1, "phase name \"%s\" already registered: %d", phase_name, index); } - idx = phase_names->length(); - phase_names->appendAll(new_phases); - guarantee(phase_names->length() < 256, "exceeds maximum supported phases"); + + index = phase_names->length(); + phase_names->append(use_strdup ? strdup(phase_name) : phase_name); } if (register_jfr_serializer) { JfrSerializer::register_serializer(TYPE_COMPILERPHASETYPE, false, new CompilerPhaseTypeConstant()); } else if (Jfr::is_recording()) { - // serialize new_phases. + // serialize new phase. JfrCheckpointWriter writer; writer.write_type(TYPE_COMPILERPHASETYPE); - write_phases(writer, idx, new_phases); + writer.write_count(1); + writer.write_key(index); + writer.write(phase_name); } - return idx; + return index; } void CompilerEvent::CompilationEvent::post(EventCompilation& event, int compile_id, CompilerType compiler_type, Method* method, int compile_level, bool success, bool is_osr, int code_size, int inlined_bytecodes) { diff --git a/src/hotspot/share/compiler/compilerEvent.hpp b/src/hotspot/share/compiler/compilerEvent.hpp index ae94d4cf185fe..65fc296b66b3d 100644 --- a/src/hotspot/share/compiler/compilerEvent.hpp +++ b/src/hotspot/share/compiler/compilerEvent.hpp @@ -64,15 +64,13 @@ class CompilerEvent : AllStatic { class PhaseEvent : AllStatic { friend class CompilerPhaseTypeConstant; public: - /** - * Register compiler phases for JFR type CompilerPhaseType serialization purposes. - * This method is called during compiler creation or during compilation. - * Registration will serialize the passed in phase constants, supporting bulk and/or incremental registrations. - * This method returns start index of new list that just got appended to phase_names. - * Param new_phases may contain duplicates. - * Return value could be used for mapping purpose at caller site, or caller can assume explicit order of registration. - */ - static int register_phases(GrowableArray* new_phases) NOT_JFR_RETURN_(-1); + + // Gets a unique identifier for `phase_name`, computing and registering it first if necessary. + // If `may_exist` is true, then current registrations are searched first. If false, then + // there must not be an existing registration for `phase_name`. + // If `use_strdup` is true, then `phase_name` is strdup'ed before registration. + // If `sync` is true, then access to the registration table is synchronized. + static int get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) NOT_JFR_RETURN_(-1); static void post(EventCompilerPhase& event, const Ticks& start_time, int phase, int compile_id, int level) NOT_JFR_RETURN(); static void post(EventCompilerPhase& event, jlong start_time, int phase, int compile_id, int level) { diff --git a/src/hotspot/share/gc/epsilon/epsilonArguments.cpp b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp index 52652ed687c6e..17cac8d86bf7a 100644 --- a/src/hotspot/share/gc/epsilon/epsilonArguments.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp @@ -28,7 +28,6 @@ #include "gc/shared/gcArguments.hpp" #include "runtime/globals.hpp" #include "runtime/globals_extension.hpp" -#include "runtime/vm_version.hpp" #include "utilities/macros.hpp" size_t EpsilonArguments::conservative_max_heap_alignment() { diff --git a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp index da48b3f1ec571..b039a949dcfaa 100644 --- a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp @@ -41,7 +41,7 @@ EpsilonBarrierSet::EpsilonBarrierSet() : BarrierSet( make_barrier_set_c1(), make_barrier_set_c2(), NULL /* barrier_set_nmethod */, - BarrierSet::FakeRtti(BarrierSet::EpsilonBarrierSet)) {}; + BarrierSet::FakeRtti(BarrierSet::EpsilonBarrierSet)) {} void EpsilonBarrierSet::on_thread_create(Thread *thread) { EpsilonThreadLocalData::create(thread); diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp index 78d08a4dd5ad3..7e77026ac5a1b 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp @@ -46,7 +46,6 @@ jint EpsilonHeap::initialize() { _virtual_space.initialize(heap_rs, init_byte_size); MemRegion committed_region((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high()); - MemRegion reserved_region((HeapWord*)_virtual_space.low_boundary(), (HeapWord*)_virtual_space.high_boundary()); initialize_reserved_region(heap_rs); diff --git a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp index 666cbfdebe793..6ced6ae55f7d1 100644 --- a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp @@ -27,7 +27,6 @@ #include "gc/epsilon/epsilonHeap.hpp" #include "gc/shared/generationCounters.hpp" #include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" #include "memory/metaspaceCounters.hpp" #include "memory/resourceArea.hpp" #include "services/memoryService.hpp" diff --git a/src/hotspot/share/gc/g1/g1Analytics.cpp b/src/hotspot/share/gc/g1/g1Analytics.cpp index 853de98da2459..c817d27a899c8 100644 --- a/src/hotspot/share/gc/g1/g1Analytics.cpp +++ b/src/hotspot/share/gc/g1/g1Analytics.cpp @@ -224,7 +224,11 @@ void G1Analytics::report_rs_length(double rs_length) { } double G1Analytics::predict_alloc_rate_ms() const { - return predict_zero_bounded(_alloc_rate_ms_seq); + if (enough_samples_available(_alloc_rate_ms_seq)) { + return predict_zero_bounded(_alloc_rate_ms_seq); + } else { + return 0.0; + } } double G1Analytics::predict_concurrent_refine_rate_ms() const { diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index c7bda3940f260..11938aba1c7d4 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -46,6 +46,7 @@ #include "gc/shared/gcPolicyCounters.hpp" #include "logging/log.hpp" #include "runtime/arguments.hpp" +#include "runtime/globals.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/debug.hpp" @@ -61,8 +62,8 @@ G1Policy::G1Policy(STWGCTimer* gc_timer) : _ihop_control(create_ihop_control(&_old_gen_alloc_tracker, &_predictor)), _policy_counters(new GCPolicyCounters("GarbageFirst", 1, 2)), _full_collection_start_sec(0.0), + _young_list_desired_length(0), _young_list_target_length(0), - _young_list_fixed_length(0), _young_list_max_length(0), _eden_surv_rate_group(new G1SurvRateGroup()), _survivor_surv_rate_group(new G1SurvRateGroup()), @@ -107,14 +108,11 @@ void G1Policy::init(G1CollectedHeap* g1h, G1CollectionSet* collection_set) { assert(Heap_lock->owned_by_self(), "Locking discipline."); - if (!use_adaptive_young_list_length()) { - _young_list_fixed_length = _young_gen_sizer->min_desired_young_length(); - } _young_gen_sizer->adjust_max_new_size(_g1h->max_expandable_regions()); _free_regions_at_end_of_collection = _g1h->num_free_regions(); - update_young_list_max_and_target_length(); + update_young_length_bounds(); // We may immediately start allocating regions and placing them on the // collection set list. Initialize the per-collection set info _collection_set->start_incremental_building(); @@ -189,158 +187,255 @@ void G1Policy::record_new_heap_size(uint new_number_of_regions) { _ihop_control->update_target_occupancy(new_number_of_regions * HeapRegion::GrainBytes); } -uint G1Policy::calculate_young_list_desired_min_length(uint base_min_length) const { +uint G1Policy::calculate_desired_eden_length_by_mmu() const { + // One could argue that any useful eden length to keep any MMU would be 1, but + // in theory this is possible. Other constraints enforce a minimum eden of 1 + // anyway. uint desired_min_length = 0; if (use_adaptive_young_list_length()) { - if (_analytics->num_alloc_rate_ms() > 3) { - double now_sec = os::elapsedTime(); - double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; - double alloc_rate_ms = _analytics->predict_alloc_rate_ms(); - desired_min_length = (uint) ceil(alloc_rate_ms * when_ms); - } else { - // otherwise we don't have enough info to make the prediction - } + double now_sec = os::elapsedTime(); + double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; + double alloc_rate_ms = _analytics->predict_alloc_rate_ms(); + desired_min_length = (uint) ceil(alloc_rate_ms * when_ms); } - desired_min_length += base_min_length; - // make sure we don't go below any user-defined minimum bound - return MAX2(_young_gen_sizer->min_desired_young_length(), desired_min_length); -} - -uint G1Policy::calculate_young_list_desired_max_length() const { - // Here, we might want to also take into account any additional - // constraints (i.e., user-defined minimum bound). Currently, we - // effectively don't set this bound. - return _young_gen_sizer->max_desired_young_length(); -} - -uint G1Policy::update_young_list_max_and_target_length() { - return update_young_list_max_and_target_length(_analytics->predict_rs_length()); -} - -uint G1Policy::update_young_list_max_and_target_length(size_t rs_length) { - uint unbounded_target_length = update_young_list_target_length(rs_length); - update_max_gc_locker_expansion(); - return unbounded_target_length; -} + return desired_min_length; +} + +void G1Policy::update_young_length_bounds() { + update_young_length_bounds(_analytics->predict_rs_length()); +} + +void G1Policy::update_young_length_bounds(size_t rs_length) { + _young_list_desired_length = calculate_young_desired_length(rs_length); + _young_list_target_length = calculate_young_target_length(_young_list_desired_length); + _young_list_max_length = calculate_young_max_length(_young_list_target_length); + + log_debug(gc,ergo,heap)("Young list lengths: desired: %u, target: %u, max: %u", + _young_list_desired_length, + _young_list_target_length, + _young_list_max_length); +} + +// Calculates desired young gen length. It is calculated from: +// +// - sizer min/max bounds on young gen +// - pause time goal for whole young gen evacuation +// - MMU goal influencing eden to make GCs spaced apart. +// - a minimum one eden region length. +// +// We may enter with already allocated eden and survivor regions, that may be +// higher than the maximum, or the above goals may result in a desired value +// smaller than are already allocated. +// The main reason is revising young length, with or without the GCLocker being +// active. +// +uint G1Policy::calculate_young_desired_length(size_t rs_length) const { + uint min_young_length_by_sizer = _young_gen_sizer->min_desired_young_length(); + uint max_young_length_by_sizer = _young_gen_sizer->max_desired_young_length(); + + assert(min_young_length_by_sizer >= 1, "invariant"); + assert(max_young_length_by_sizer >= min_young_length_by_sizer, "invariant"); + + // Absolute minimum eden length. + // Enforcing a minimum eden length helps at startup when the predictors are not + // yet trained on the application to avoid unnecessary (but very short) full gcs + // on very small (initial) heaps. + uint const MinDesiredEdenLength = 1; -uint G1Policy::update_young_list_target_length(size_t rs_length) { - YoungTargetLengths young_lengths = young_list_target_lengths(rs_length); - _young_list_target_length = young_lengths.first; + // Calculate the absolute and desired min bounds first. - return young_lengths.second; -} + // This is how many survivor regions we already have. + const uint survivor_length = _g1h->survivor_regions_count(); + // Size of the already allocated young gen. + const uint allocated_young_length = _g1h->young_regions_count(); + // This is the absolute minimum young length that we can return. Ensure that we + // don't go below any user-defined minimum bound; but we might have already + // allocated more than that for various reasons. In this case, use that. + uint absolute_min_young_length = MAX2(allocated_young_length, min_young_length_by_sizer); + // Calculate the absolute max bounds. After evac failure or when revising the + // young length we might have exceeded absolute min length or absolute_max_length, + // so adjust the result accordingly. + uint absolute_max_young_length = MAX2(max_young_length_by_sizer, absolute_min_young_length); + + uint desired_eden_length_by_mmu = 0; + uint desired_eden_length_by_pause = 0; + + uint desired_young_length = 0; + if (use_adaptive_young_list_length()) { + desired_eden_length_by_mmu = calculate_desired_eden_length_by_mmu(); -G1Policy::YoungTargetLengths G1Policy::young_list_target_lengths(size_t rs_length) const { - YoungTargetLengths result; + const size_t pending_cards = _analytics->predict_pending_cards(); + double survivor_base_time_ms = predict_base_elapsed_time_ms(pending_cards, rs_length); - // Calculate the absolute and desired min bounds first. + desired_eden_length_by_pause = + calculate_desired_eden_length_by_pause(survivor_base_time_ms, + absolute_min_young_length - survivor_length, + absolute_max_young_length - survivor_length); - // This is how many young regions we already have (currently: the survivors). - const uint base_min_length = _g1h->survivor_regions_count(); - uint desired_min_length = calculate_young_list_desired_min_length(base_min_length); - // This is the absolute minimum young length. Ensure that we - // will at least have one eden region available for allocation. - uint absolute_min_length = base_min_length + MAX2(_g1h->eden_regions_count(), (uint)1); - // If we shrank the young list target it should not shrink below the current size. - desired_min_length = MAX2(desired_min_length, absolute_min_length); - // Calculate the absolute and desired max bounds. + // Incorporate MMU concerns; assume that it overrides the pause time + // goal, as the default value has been chosen to effectively disable it. + // Also request at least one eden region, see above for reasons. + uint desired_eden_length = MAX3(desired_eden_length_by_pause, + desired_eden_length_by_mmu, + MinDesiredEdenLength); - uint desired_max_length = calculate_young_list_desired_max_length(); - - uint young_list_target_length = 0; - if (use_adaptive_young_list_length()) { - if (collector_state()->in_young_only_phase()) { - young_list_target_length = - calculate_young_list_target_length(rs_length, - base_min_length, - desired_min_length, - desired_max_length); - } else { - // Don't calculate anything and let the code below bound it to - // the desired_min_length, i.e., do the next GC as soon as - // possible to maximize how many old regions we can add to it. - } + desired_young_length = desired_eden_length + survivor_length; } else { // The user asked for a fixed young gen so we'll fix the young gen // whether the next GC is young or mixed. - young_list_target_length = _young_list_fixed_length; - } - - result.second = young_list_target_length; - - // We will try our best not to "eat" into the reserve. - uint absolute_max_length = 0; - if (_free_regions_at_end_of_collection > _reserve_regions) { - absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions; + desired_young_length = min_young_length_by_sizer; } - if (desired_max_length > absolute_max_length) { - desired_max_length = absolute_max_length; + // Clamp to absolute min/max after we determined desired lengths. + desired_young_length = clamp(desired_young_length, absolute_min_young_length, absolute_max_young_length); + + log_trace(gc, ergo, heap)("Young desired length %u " + "survivor length %u " + "allocated young length %u " + "absolute min young length %u " + "absolute max young length %u " + "desired eden length by mmu %u " + "desired eden length by pause %u " + "desired eden length by default %u", + desired_young_length, survivor_length, + allocated_young_length, absolute_min_young_length, + absolute_max_young_length, desired_eden_length_by_mmu, + desired_eden_length_by_pause, + MinDesiredEdenLength); + + assert(desired_young_length >= allocated_young_length, "must be"); + return desired_young_length; +} + +// Limit the desired (wished) young length by current free regions. If the request +// can be satisfied without using up reserve regions, do so, otherwise eat into +// the reserve, giving away at most what the heap sizer allows. +uint G1Policy::calculate_young_target_length(uint desired_young_length) const { + uint allocated_young_length = _g1h->young_regions_count(); + + uint receiving_additional_eden; + if (allocated_young_length >= desired_young_length) { + // Already used up all we actually want (may happen as G1 revises the + // young list length concurrently, or caused by gclocker). Do not allow more, + // potentially resulting in GC. + receiving_additional_eden = 0; + log_trace(gc, ergo, heap)("Young target length: Already used up desired young %u allocated %u", + desired_young_length, + allocated_young_length); + } else { + // Now look at how many free regions are there currently, and the heap reserve. + // We will try our best not to "eat" into the reserve as long as we can. If we + // do, we at most eat the sizer's minimum regions into the reserve or half the + // reserve rounded up (if possible; this is an arbitrary value). + + uint max_to_eat_into_reserve = MIN2(_young_gen_sizer->min_desired_young_length(), + (_reserve_regions + 1) / 2); + + log_trace(gc, ergo, heap)("Young target length: Common " + "free regions at end of collection %u " + "desired young length %u " + "reserve region %u " + "max to eat into reserve %u", + _free_regions_at_end_of_collection, + desired_young_length, + _reserve_regions, + max_to_eat_into_reserve); + + if (_free_regions_at_end_of_collection <= _reserve_regions) { + // Fully eat (or already eating) into the reserve, hand back at most absolute_min_length regions. + uint receiving_young = MIN3(_free_regions_at_end_of_collection, + desired_young_length, + max_to_eat_into_reserve); + // We could already have allocated more regions than what we could get + // above. + receiving_additional_eden = allocated_young_length < receiving_young ? + receiving_young - allocated_young_length : 0; + + log_trace(gc, ergo, heap)("Young target length: Fully eat into reserve " + "receiving young %u receiving additional eden %u", + receiving_young, + receiving_additional_eden); + } else if (_free_regions_at_end_of_collection < (desired_young_length + _reserve_regions)) { + // Partially eat into the reserve, at most max_to_eat_into_reserve regions. + uint free_outside_reserve = _free_regions_at_end_of_collection - _reserve_regions; + assert(free_outside_reserve < desired_young_length, + "must be %u %u", + free_outside_reserve, desired_young_length); + + uint receiving_within_reserve = MIN2(desired_young_length - free_outside_reserve, + max_to_eat_into_reserve); + uint receiving_young = free_outside_reserve + receiving_within_reserve; + // Again, we could have already allocated more than we could get. + receiving_additional_eden = allocated_young_length < receiving_young ? + receiving_young - allocated_young_length : 0; + + log_trace(gc, ergo, heap)("Young target length: Partially eat into reserve " + "free outside reserve %u " + "receiving within reserve %u " + "receiving young %u " + "receiving additional eden %u", + free_outside_reserve, receiving_within_reserve, + receiving_young, receiving_additional_eden); + } else { + // No need to use the reserve. + receiving_additional_eden = desired_young_length - allocated_young_length; + log_trace(gc, ergo, heap)("Young target length: No need to use reserve " + "receiving additional eden %u", + receiving_additional_eden); + } } - // Make sure we don't go over the desired max length, nor under the - // desired min length. In case they clash, desired_min_length wins - // which is why that test is second. - if (young_list_target_length > desired_max_length) { - young_list_target_length = desired_max_length; - } - if (young_list_target_length < desired_min_length) { - young_list_target_length = desired_min_length; - } + uint target_young_length = allocated_young_length + receiving_additional_eden; - assert(young_list_target_length > base_min_length, - "we should be able to allocate at least one eden region"); - assert(young_list_target_length >= absolute_min_length, "post-condition"); + assert(target_young_length >= allocated_young_length, "must be"); - result.first = young_list_target_length; - return result; + log_trace(gc, ergo, heap)("Young target length: " + "young target length %u " + "allocated young length %u " + "received additional eden %u", + target_young_length, allocated_young_length, + receiving_additional_eden); + return target_young_length; } -uint G1Policy::calculate_young_list_target_length(size_t rs_length, - uint base_min_length, - uint desired_min_length, - uint desired_max_length) const { - assert(use_adaptive_young_list_length(), "pre-condition"); - assert(collector_state()->in_young_only_phase(), "only call this for young GCs"); - - // In case some edge-condition makes the desired max length too small... - if (desired_max_length <= desired_min_length) { - return desired_min_length; +uint G1Policy::calculate_desired_eden_length_by_pause(double base_time_ms, + uint min_eden_length, + uint max_eden_length) const { + if (!next_gc_should_be_mixed(NULL, NULL)) { + return calculate_desired_eden_length_before_young_only(base_time_ms, + min_eden_length, + max_eden_length); + } else { + return calculate_desired_eden_length_before_mixed(base_time_ms, + min_eden_length, + max_eden_length); } +} + + +uint G1Policy::calculate_desired_eden_length_before_young_only(double base_time_ms, + uint min_eden_length, + uint max_eden_length) const { + assert(use_adaptive_young_list_length(), "pre-condition"); - // We'll adjust min_young_length and max_young_length not to include - // the already allocated young regions (i.e., so they reflect the - // min and max eden regions we'll allocate). The base_min_length - // will be reflected in the predictions by the - // survivor_regions_evac_time prediction. - assert(desired_min_length > base_min_length, "invariant"); - uint min_young_length = desired_min_length - base_min_length; - assert(desired_max_length > base_min_length, "invariant"); - uint max_young_length = desired_max_length - base_min_length; - - const double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; - const size_t pending_cards = _analytics->predict_pending_cards(); - const double base_time_ms = predict_base_elapsed_time_ms(pending_cards, rs_length); - const uint available_free_regions = _free_regions_at_end_of_collection; - const uint base_free_regions = - available_free_regions > _reserve_regions ? available_free_regions - _reserve_regions : 0; + assert(min_eden_length <= max_eden_length, "must be %u %u", min_eden_length, max_eden_length); // Here, we will make sure that the shortest young length that // makes sense fits within the target pause time. G1YoungLengthPredictor p(base_time_ms, - base_free_regions, - target_pause_time_ms, + _free_regions_at_end_of_collection, + _mmu_tracker->max_gc_time() * 1000.0, this); - if (p.will_fit(min_young_length)) { + if (p.will_fit(min_eden_length)) { // The shortest young length will fit into the target pause time; // we'll now check whether the absolute maximum number of young // regions will fit in the target pause time. If not, we'll do // a binary search between min_young_length and max_young_length. - if (p.will_fit(max_young_length)) { + if (p.will_fit(max_eden_length)) { // The maximum young length will fit into the target pause time. // We are done so set min young length to the maximum length (as // the result is assumed to be returned in min_young_length). - min_young_length = max_young_length; + min_eden_length = max_eden_length; } else { // The maximum possible number of young regions will not fit within // the target pause time so we'll search for the optimal @@ -357,37 +452,56 @@ uint G1Policy::calculate_young_list_target_length(size_t rs_length, // does, it becomes the new min. If it doesn't, it becomes // the new max. This way we maintain the loop invariants. - assert(min_young_length < max_young_length, "invariant"); - uint diff = (max_young_length - min_young_length) / 2; + assert(min_eden_length < max_eden_length, "invariant"); + uint diff = (max_eden_length - min_eden_length) / 2; while (diff > 0) { - uint young_length = min_young_length + diff; - if (p.will_fit(young_length)) { - min_young_length = young_length; + uint eden_length = min_eden_length + diff; + if (p.will_fit(eden_length)) { + min_eden_length = eden_length; } else { - max_young_length = young_length; + max_eden_length = eden_length; } - assert(min_young_length < max_young_length, "invariant"); - diff = (max_young_length - min_young_length) / 2; + assert(min_eden_length < max_eden_length, "invariant"); + diff = (max_eden_length - min_eden_length) / 2; } // The results is min_young_length which, according to the // loop invariants, should fit within the target pause time. // These are the post-conditions of the binary search above: - assert(min_young_length < max_young_length, - "otherwise we should have discovered that max_young_length " + assert(min_eden_length < max_eden_length, + "otherwise we should have discovered that max_eden_length " "fits into the pause target and not done the binary search"); - assert(p.will_fit(min_young_length), - "min_young_length, the result of the binary search, should " + assert(p.will_fit(min_eden_length), + "min_eden_length, the result of the binary search, should " "fit into the pause target"); - assert(!p.will_fit(min_young_length + 1), - "min_young_length, the result of the binary search, should be " + assert(!p.will_fit(min_eden_length + 1), + "min_eden_length, the result of the binary search, should be " "optimal, so no larger length should fit into the pause target"); } } else { // Even the minimum length doesn't fit into the pause time // target, return it as the result nevertheless. } - return base_min_length + min_young_length; + return min_eden_length; +} + +uint G1Policy::calculate_desired_eden_length_before_mixed(double survivor_base_time_ms, + uint min_eden_length, + uint max_eden_length) const { + G1CollectionSetCandidates* candidates = _collection_set->candidates(); + + uint min_old_regions_end = MIN2(candidates->cur_idx() + calc_min_old_cset_length(), candidates->num_regions()); + double predicted_region_evac_time_ms = survivor_base_time_ms; + for (uint i = candidates->cur_idx(); i < min_old_regions_end; i++) { + HeapRegion* r = candidates->at(i); + predicted_region_evac_time_ms += predict_region_total_time_ms(r, false); + } + uint desired_eden_length_by_min_cset_length = + calculate_desired_eden_length_before_young_only(predicted_region_evac_time_ms, + min_eden_length, + max_eden_length); + + return desired_eden_length_by_min_cset_length; } double G1Policy::predict_survivor_regions_evac_time() const { @@ -417,8 +531,7 @@ void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_length) { // add 10% to avoid having to recalculate often size_t rs_length_prediction = rs_length * 1100 / 1000; update_rs_length_prediction(rs_length_prediction); - - update_young_list_max_and_target_length(rs_length_prediction); + update_young_length_bounds(rs_length_prediction); } } @@ -466,7 +579,7 @@ void G1Policy::record_full_collection_end() { _free_regions_at_end_of_collection = _g1h->num_free_regions(); _survivor_surv_rate_group->reset(); - update_young_list_max_and_target_length(); + update_young_length_bounds(); update_rs_length_prediction(); _old_gen_alloc_tracker.reset_after_gc(_g1h->humongous_regions_count() * HeapRegion::GrainBytes); @@ -798,15 +911,10 @@ void G1Policy::record_collection_pause_end(double pause_time_ms) { // Do not update dynamic IHOP due to G1 periodic collection as it is highly likely // that in this case we are not running in a "normal" operating mode. if (_g1h->gc_cause() != GCCause::_g1_periodic_collection) { - // IHOP control wants to know the expected young gen length if it were not - // restrained by the heap reserve. Using the actual length would make the - // prediction too small and the limit the young gen every time we get to the - // predicted target occupancy. - size_t last_unrestrained_young_length = update_young_list_max_and_target_length(); + update_young_length_bounds(); _old_gen_alloc_tracker.reset_after_gc(_g1h->humongous_regions_count() * HeapRegion::GrainBytes); update_ihop_prediction(app_time_ms / 1000.0, - last_unrestrained_young_length * HeapRegion::GrainBytes, is_young_only_pause(this_pause)); _ihop_control->send_trace_event(_g1h->gc_tracer_stw()); @@ -857,7 +965,6 @@ G1IHOPControl* G1Policy::create_ihop_control(const G1OldGenAllocationTracker* ol } void G1Policy::update_ihop_prediction(double mutator_time_s, - size_t young_gen_size, bool this_gc_was_young_only) { // Always try to update IHOP prediction. Even evacuation failures give information // about e.g. whether to start IHOP earlier next time. @@ -885,6 +992,11 @@ void G1Policy::update_ihop_prediction(double mutator_time_s, // marking, which makes any prediction useless. This increases the accuracy of the // prediction. if (this_gc_was_young_only && mutator_time_s > min_valid_time) { + // IHOP control wants to know the expected young gen length if it were not + // restrained by the heap reserve. Using the actual length would make the + // prediction too small and the limit the young gen every time we get to the + // predicted target occupancy. + size_t young_gen_size = young_list_desired_length() * HeapRegion::GrainBytes; _ihop_control->update_allocation_info(mutator_time_s, young_gen_size); report = true; } @@ -991,7 +1103,7 @@ void G1Policy::print_age_table() { _survivors_age_table.print_age_table(_tenuring_threshold); } -void G1Policy::update_max_gc_locker_expansion() { +uint G1Policy::calculate_young_max_length(uint target_young_length) const { uint expansion_region_num = 0; if (GCLockerEdenExpansionPercent > 0) { double perc = (double) GCLockerEdenExpansionPercent / 100.0; @@ -999,11 +1111,10 @@ void G1Policy::update_max_gc_locker_expansion() { // We use ceiling so that if expansion_region_num_d is > 0.0 (but // less than 1.0) we'll get 1. expansion_region_num = (uint) ceil(expansion_region_num_d); - } else { - assert(expansion_region_num == 0, "sanity"); } - _young_list_max_length = _young_list_target_length + expansion_region_num; - assert(_young_list_target_length <= _young_list_max_length, "post-condition"); + uint max_length = target_young_length + expansion_region_num; + assert(target_young_length <= max_length, "overflow"); + return max_length; } // Calculates survivor space parameters. @@ -1238,8 +1349,10 @@ bool G1Policy::next_gc_should_be_mixed(const char* true_action_str, const char* false_action_str) const { G1CollectionSetCandidates* candidates = _collection_set->candidates(); - if (candidates->is_empty()) { - log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str); + if (candidates == NULL || candidates->is_empty()) { + if (false_action_str != NULL) { + log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str); + } return false; } @@ -1248,12 +1361,24 @@ bool G1Policy::next_gc_should_be_mixed(const char* true_action_str, double reclaimable_percent = reclaimable_bytes_percent(reclaimable_bytes); double threshold = (double) G1HeapWastePercent; if (reclaimable_percent <= threshold) { - log_debug(gc, ergo)("%s (reclaimable percentage not over threshold). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT, - false_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent); + if (false_action_str != NULL) { + log_debug(gc, ergo)("%s (reclaimable percentage below threshold). " + "candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) " + "threshold: " UINTX_FORMAT, + false_action_str, + candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, + G1HeapWastePercent); + } return false; } - log_debug(gc, ergo)("%s (candidate old regions available). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT, - true_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent); + if (true_action_str != NULL) { + log_debug(gc, ergo)("%s (candidate old regions available). " + "candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) " + "threshold: " UINTX_FORMAT, + true_action_str, + candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, + G1HeapWastePercent); + } return true; } diff --git a/src/hotspot/share/gc/g1/g1Policy.hpp b/src/hotspot/share/gc/g1/g1Policy.hpp index dff561fbdc8ab..677b012ffd839 100644 --- a/src/hotspot/share/gc/g1/g1Policy.hpp +++ b/src/hotspot/share/gc/g1/g1Policy.hpp @@ -60,7 +60,6 @@ class G1Policy: public CHeapObj { const G1Predictions* predictor); // Update the IHOP control with necessary statistics. void update_ihop_prediction(double mutator_time_s, - size_t young_gen_size, bool this_gc_was_young_only); void report_ihop_statistics(); @@ -78,8 +77,8 @@ class G1Policy: public CHeapObj { double _full_collection_start_sec; + uint _young_list_desired_length; uint _young_list_target_length; - uint _young_list_fixed_length; // The max number of regions we can extend the eden by while the GC // locker is active. This should be >= _young_list_target_length; @@ -168,6 +167,10 @@ class G1Policy: public CHeapObj { private: G1CollectionSet* _collection_set; + + bool next_gc_should_be_mixed(const char* true_action_str, + const char* false_action_str) const; + double average_time_ms(G1GCPhaseTimes::GCParPhases phase) const; double other_time_ms(double pause_time_ms) const; @@ -189,44 +192,44 @@ class G1Policy: public CHeapObj { double _mark_remark_start_sec; double _mark_cleanup_start_sec; - // Updates the internal young list maximum and target lengths. Returns the - // unbounded young list target length. If no rs_length parameter is passed, - // predict the RS length using the prediction model, otherwise use the - // given rs_length as the prediction. - uint update_young_list_max_and_target_length(); - uint update_young_list_max_and_target_length(size_t rs_length); - - // Update the young list target length either by setting it to the - // desired fixed value or by calculating it using G1's pause - // prediction model. - // Returns the unbounded young list target length. - uint update_young_list_target_length(size_t rs_length); - - // Calculate and return the minimum desired young list target - // length. This is the minimum desired young list length according - // to the user's inputs. - uint calculate_young_list_desired_min_length(uint base_min_length) const; - - // Calculate and return the maximum desired young list target - // length. This is the maximum desired young list length according - // to the user's inputs. - uint calculate_young_list_desired_max_length() const; - - // Calculate and return the maximum young list target length that - // can fit into the pause time goal. The parameters are: rs_length - // represent the prediction of how large the young RSet lengths will - // be, base_min_length is the already existing number of regions in - // the young list, min_length and max_length are the desired min and - // max young list length according to the user's inputs. - uint calculate_young_list_target_length(size_t rs_length, - uint base_min_length, - uint desired_min_length, - uint desired_max_length) const; - - // Result of the bounded_young_list_target_length() method, containing both the - // bounded as well as the unbounded young list target lengths in this order. - typedef Pair YoungTargetLengths; - YoungTargetLengths young_list_target_lengths(size_t rs_length) const; + // Updates the internal young gen maximum and target and desired lengths. + // If no rs_length parameter is passed, predict the RS length using the + // prediction model, otherwise use the given rs_length as the prediction. + void update_young_length_bounds(); + void update_young_length_bounds(size_t rs_length); + + // Calculate and return the minimum desired eden length based on the MMU target. + uint calculate_desired_eden_length_by_mmu() const; + + // Calculate the desired eden length meeting the pause time goal. + // The parameters are: rs_length represents the prediction of how large the + // young RSet lengths will be, min_eden_length and max_eden_length are the bounds + // (inclusive) within eden can grow. + uint calculate_desired_eden_length_by_pause(double base_time_ms, + uint min_eden_length, + uint max_eden_length) const; + + // Calculate the desired eden length that can fit into the pause time + // goal before young only gcs. + uint calculate_desired_eden_length_before_young_only(double base_time_ms, + uint min_eden_length, + uint max_eden_length) const; + + // Calculates the desired eden length before mixed gc so that after adding the + // minimum amount of old gen regions from the collection set, the eden fits into + // the pause time goal. + uint calculate_desired_eden_length_before_mixed(double survivor_base_time_ms, + uint min_eden_length, + uint max_eden_length) const; + + // Calculate desired young length based on current situation without taking actually + // available free regions into account. + uint calculate_young_desired_length(size_t rs_length) const; + // Limit the given desired young length to available free regions. + uint calculate_young_target_length(uint desired_young_length) const; + // The GCLocker might cause us to need more regions than the target. Calculate + // the maximum number of regions to use in that case. + uint calculate_young_max_length(uint target_young_length) const; void update_rs_length_prediction(); void update_rs_length_prediction(size_t prediction); @@ -337,9 +340,6 @@ class G1Policy: public CHeapObj { void print_phases(); - bool next_gc_should_be_mixed(const char* true_action_str, - const char* false_action_str) const; - // Calculate and return the number of initial and optional old gen regions from // the given collection set candidates and the remaining time. void calculate_old_collection_set_regions(G1CollectionSetCandidates* candidates, @@ -376,6 +376,7 @@ class G1Policy: public CHeapObj { // the concurrent start work and start a marking cycle. void decide_on_conc_mark_initiation(); + uint young_list_desired_length() const { return _young_list_desired_length; } size_t young_list_target_length() const { return _young_list_target_length; } bool should_allocate_mutator_region() const; @@ -436,8 +437,6 @@ class G1Policy: public CHeapObj { void print_age_table(); - void update_max_gc_locker_expansion(); - void update_survivors_policy(); virtual bool force_upgrade_to_full() { diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp index 22ccd8c5f57cd..2e41655da995d 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.cpp +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp @@ -36,6 +36,7 @@ #include "gc/shared/gcWhen.hpp" #include "gc/shared/memAllocator.hpp" #include "logging/log.hpp" +#include "logging/logStream.hpp" #include "memory/metaspace.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -123,14 +124,28 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() { } void CollectedHeap::print_heap_before_gc() { - Universe::print_heap_before_gc(); + LogTarget(Debug, gc, heap) lt; + if (lt.is_enabled()) { + LogStream ls(lt); + ls.print_cr("Heap before GC invocations=%u (full %u):", total_collections(), total_full_collections()); + ResourceMark rm; + print_on(&ls); + } + if (_gc_heap_log != NULL) { _gc_heap_log->log_heap_before(this); } } void CollectedHeap::print_heap_after_gc() { - Universe::print_heap_after_gc(); + LogTarget(Debug, gc, heap) lt; + if (lt.is_enabled()) { + LogStream ls(lt); + ls.print_cr("Heap after GC invocations=%u (full %u):", total_collections(), total_full_collections()); + ResourceMark rm; + print_on(&ls); + } + if (_gc_heap_log != NULL) { _gc_heap_log->log_heap_after(this); } diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index 312050b4098e7..e20f77e0ebe06 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -113,8 +113,8 @@ class TaskQueueSuper: public CHeapObj { // N must be a power of 2 for computing modulo via masking. // N must be >= 2 for the algorithm to work at all, though larger is better. - // C++11: is_power_of_2 is not (yet) constexpr. - STATIC_ASSERT((N >= 2) && ((N & (N - 1)) == 0)); + STATIC_ASSERT(N >= 2); + STATIC_ASSERT(is_power_of_2(N)); static const uint MOD_N_MASK = N - 1; class Age { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp index 39d7d2a905660..92cec8ac66474 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp @@ -209,7 +209,6 @@ void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosur "Expect class unloading when Shenandoah cycle is running"); assert(clds != NULL, "Only possible with CLD closure"); - AlwaysTrueClosure always_true; ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc); ResourceMark rm; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp index c62407d47fdb1..b9e47394200a4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp @@ -50,7 +50,7 @@ ShenandoahStrDedupQueue::ShenandoahStrDedupQueue() : ShenandoahStrDedupQueue::~ShenandoahStrDedupQueue() { MonitorLocker ml(StringDedupQueue_lock, Mutex::_no_safepoint_check_flag); - for (size_t index = 0; index < num_queues(); index ++) { + for (size_t index = 0; index < num_queues_nv(); index ++) { release_buffers(queue_at(index)); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp index ca373f85c0a0a..1aa6d91971e2c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp @@ -99,9 +99,11 @@ class ShenandoahStrDedupQueue : public StringDedupQueue { void verify_impl(); protected: - size_t num_queues() const { return (_num_producer_queue + 2); } + size_t num_queues() const { return num_queues_nv(); } private: + inline size_t num_queues_nv() const { return (_num_producer_queue + 2); } + ShenandoahQueueBuffer* new_buffer(); void release_buffers(ShenandoahQueueBuffer* list); @@ -111,8 +113,6 @@ class ShenandoahStrDedupQueue : public StringDedupQueue { bool pop_candidate(oop& obj); void set_producer_buffer(ShenandoahQueueBuffer* buf, size_t queue_id); - - void verify(ShenandoahQueueBuffer* head); }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHSTRDEDUPQUEUE_HPP diff --git a/src/hotspot/share/gc/z/zForwardingEntry.hpp b/src/hotspot/share/gc/z/zForwardingEntry.hpp index a6db411c3141e..2aa538f0ec275 100644 --- a/src/hotspot/share/gc/z/zForwardingEntry.hpp +++ b/src/hotspot/share/gc/z/zForwardingEntry.hpp @@ -27,6 +27,7 @@ #include "gc/z/zBitField.hpp" #include "memory/allocation.hpp" #include "metaprogramming/primitiveConversions.hpp" +#include // // Forwarding entry layout @@ -46,7 +47,7 @@ // class ZForwardingEntry { - friend class PrimitiveConversions; + friend struct PrimitiveConversions::Translate; private: typedef ZBitField field_populated; @@ -79,7 +80,7 @@ class ZForwardingEntry { // Needed to allow atomic operations on ZForwardingEntry template <> -struct PrimitiveConversions::Translate : public TrueType { +struct PrimitiveConversions::Translate : public std::true_type { typedef ZForwardingEntry Value; typedef uint64_t Decayed; diff --git a/src/hotspot/share/gc/z/zGlobals.hpp b/src/hotspot/share/gc/z/zGlobals.hpp index 138b9486f03ef..690227e3a8db0 100644 --- a/src/hotspot/share/gc/z/zGlobals.hpp +++ b/src/hotspot/share/gc/z/zGlobals.hpp @@ -149,6 +149,6 @@ const size_t ZMarkProactiveFlushMax = 10; const size_t ZMarkTerminateFlushMax = 3; // Try complete mark timeout -const uint64_t ZMarkCompleteTimeout = 1; // ms +const uint64_t ZMarkCompleteTimeout = 1000; // us #endif // SHARE_GC_Z_ZGLOBALS_HPP diff --git a/src/hotspot/share/gc/z/zMark.cpp b/src/hotspot/share/gc/z/zMark.cpp index 8ea20b97fa4dd..ed409b58e87b2 100644 --- a/src/hotspot/share/gc/z/zMark.cpp +++ b/src/hotspot/share/gc/z/zMark.cpp @@ -563,9 +563,9 @@ class ZMarkTimeout : public StackObj { bool _expired; public: - ZMarkTimeout(uint64_t timeout_in_millis) : + ZMarkTimeout(uint64_t timeout_in_micros) : _start(Ticks::now()), - _timeout(_start.value() + TimeHelper::millis_to_counter(timeout_in_millis)), + _timeout(_start.value() + TimeHelper::micros_to_counter(timeout_in_micros)), _check_interval(200), _check_at(_check_interval), _check_count(0), @@ -591,9 +591,9 @@ class ZMarkTimeout : public StackObj { } }; -void ZMark::work_with_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, uint64_t timeout_in_millis) { +void ZMark::work_with_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, uint64_t timeout_in_micros) { ZStatTimer timer(ZSubPhaseMarkTryComplete); - ZMarkTimeout timeout(timeout_in_millis); + ZMarkTimeout timeout(timeout_in_micros); for (;;) { if (!drain_and_flush(stripe, stacks, cache, &timeout)) { @@ -611,15 +611,15 @@ void ZMark::work_with_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThrea } } -void ZMark::work(uint64_t timeout_in_millis) { +void ZMark::work(uint64_t timeout_in_micros) { ZMarkCache cache(_stripes.nstripes()); ZMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, ZThread::worker_id()); ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current()); - if (timeout_in_millis == 0) { + if (timeout_in_micros == 0) { work_without_timeout(&cache, stripe, stacks); } else { - work_with_timeout(&cache, stripe, stacks, timeout_in_millis); + work_with_timeout(&cache, stripe, stacks, timeout_in_micros); } // Make sure stacks have been flushed @@ -668,13 +668,13 @@ class ZMarkConcurrentRootsTask : public ZTask { class ZMarkTask : public ZTask { private: ZMark* const _mark; - const uint64_t _timeout_in_millis; + const uint64_t _timeout_in_micros; public: - ZMarkTask(ZMark* mark, uint64_t timeout_in_millis = 0) : + ZMarkTask(ZMark* mark, uint64_t timeout_in_micros = 0) : ZTask("ZMarkTask"), _mark(mark), - _timeout_in_millis(timeout_in_millis) { + _timeout_in_micros(timeout_in_micros) { _mark->prepare_work(); } @@ -683,7 +683,7 @@ class ZMarkTask : public ZTask { } virtual void work() { - _mark->work(_timeout_in_millis); + _mark->work(_timeout_in_micros); } }; diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 6b03d5da19294..a2adfc3703127 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2639,19 +2639,11 @@ C2V_VMENTRY_0(jlong, ticksNow, (JNIEnv* env, jobject)) return CompilerEvent::ticksNow(); } -C2V_VMENTRY_0(jint, registerCompilerPhases, (JNIEnv* env, jobject, jobjectArray jphases)) +C2V_VMENTRY_0(jint, registerCompilerPhase, (JNIEnv* env, jobject, jstring jphase_name)) #if INCLUDE_JFR - if (jphases == NULL) { - return -1; - } - JVMCIObjectArray phases = JVMCIENV->wrap(jphases); - int len = JVMCIENV->get_length(phases); - GrowableArray* jvmci_phase_names = new GrowableArray(len); - for (int i = 0; i < len; i++) { - JVMCIObject phase = JVMCIENV->get_object_at(phases, i); - jvmci_phase_names->append(strdup(JVMCIENV->as_utf8_string(phase))); - } - return CompilerEvent::PhaseEvent::register_phases(jvmci_phase_names); + JVMCIObject phase_name = JVMCIENV->wrap(jphase_name); + const char *name = JVMCIENV->as_utf8_string(phase_name); + return CompilerEvent::PhaseEvent::get_phase_id(name, true, true, true); #else return -1; #endif // !INCLUDE_JFR @@ -2823,7 +2815,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "addFailedSpeculation", CC "(J[B)Z", FN_PTR(addFailedSpeculation)}, {CC "callSystemExit", CC "(I)V", FN_PTR(callSystemExit)}, {CC "ticksNow", CC "()J", FN_PTR(ticksNow)}, - {CC "registerCompilerPhases", CC "([" STRING ")I", FN_PTR(registerCompilerPhases)}, + {CC "registerCompilerPhase", CC "(" STRING ")I", FN_PTR(registerCompilerPhase)}, {CC "notifyCompilerPhaseEvent", CC "(JIII)V", FN_PTR(notifyCompilerPhaseEvent)}, {CC "notifyCompilerInliningEvent", CC "(I" HS_RESOLVED_METHOD HS_RESOLVED_METHOD "ZLjava/lang/String;I)V", FN_PTR(notifyCompilerInliningEvent)}, }; diff --git a/src/hotspot/share/memory/archiveBuilder.cpp b/src/hotspot/share/memory/archiveBuilder.cpp index 8e1e3b374bb2f..adf3b63b08c9e 100644 --- a/src/hotspot/share/memory/archiveBuilder.cpp +++ b/src/hotspot/share/memory/archiveBuilder.cpp @@ -29,6 +29,7 @@ #include "logging/logMessage.hpp" #include "memory/archiveBuilder.hpp" #include "memory/archiveUtils.hpp" +#include "memory/cppVtables.hpp" #include "memory/dumpAllocStats.hpp" #include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" @@ -479,7 +480,7 @@ void ArchiveBuilder::make_shallow_copy(DumpRegion *dump_region, SourceObjInfo* s memcpy(dest, src, bytes); - intptr_t* archived_vtable = MetaspaceShared::get_archived_cpp_vtable(ref->msotype(), (address)dest); + intptr_t* archived_vtable = CppVtables::get_archived_cpp_vtable(ref->msotype(), (address)dest); if (archived_vtable != NULL) { *(address*)dest = (address)archived_vtable; ArchivePtrMarker::mark_pointer((address*)dest); diff --git a/src/hotspot/share/memory/cppVtables.cpp b/src/hotspot/share/memory/cppVtables.cpp new file mode 100644 index 0000000000000..914ea209196ff --- /dev/null +++ b/src/hotspot/share/memory/cppVtables.cpp @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 "logging/log.hpp" +#include "memory/archiveUtils.hpp" +#include "memory/cppVtables.hpp" +#include "memory/metaspaceShared.hpp" +#include "oops/instanceClassLoaderKlass.hpp" +#include "oops/instanceMirrorKlass.hpp" +#include "oops/instanceRefKlass.hpp" +#include "oops/methodData.hpp" +#include "oops/objArrayKlass.hpp" +#include "oops/typeArrayKlass.hpp" +#include "runtime/arguments.hpp" +#include "utilities/globalDefinitions.hpp" + +// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables. +// (In GCC this is the field ::_vptr, i.e., first word in the object.) +// +// Addresses of the vtables and the methods may be different across JVM runs, +// if libjvm.so is dynamically loaded at a different base address. +// +// To ensure that the Metadata objects in the CDS archive always have the correct vtable: +// +// + at dump time: we redirect the _vptr to point to our own vtables inside +// the CDS image +// + at run time: we clone the actual contents of the vtables from libjvm.so +// into our own tables. + +// Currently, the archive contain ONLY the following types of objects that have C++ vtables. +#define CPP_VTABLE_PATCH_TYPES_DO(f) \ + f(ConstantPool) \ + f(InstanceKlass) \ + f(InstanceClassLoaderKlass) \ + f(InstanceMirrorKlass) \ + f(InstanceRefKlass) \ + f(Method) \ + f(ObjArrayKlass) \ + f(TypeArrayKlass) + +class CppVtableInfo { + intptr_t _vtable_size; + intptr_t _cloned_vtable[1]; +public: + static int num_slots(int vtable_size) { + return 1 + vtable_size; // Need to add the space occupied by _vtable_size; + } + int vtable_size() { return int(uintx(_vtable_size)); } + void set_vtable_size(int n) { _vtable_size = intptr_t(n); } + intptr_t* cloned_vtable() { return &_cloned_vtable[0]; } + void zero() { memset(_cloned_vtable, 0, sizeof(intptr_t) * vtable_size()); } + // Returns the address of the next CppVtableInfo that can be placed immediately after this CppVtableInfo + static size_t byte_size(int vtable_size) { + CppVtableInfo i; + return pointer_delta(&i._cloned_vtable[vtable_size], &i, sizeof(u1)); + } +}; + +static inline intptr_t* vtable_of(Metadata* m) { + return *((intptr_t**)m); +} + +static inline DumpRegion* mc_region() { + return MetaspaceShared::misc_code_dump_space(); +} + +template class CppVtableCloner : public T { + static CppVtableInfo* _info; + + static int get_vtable_length(const char* name); + +public: + // Allocate and initialize the C++ vtable, starting from top, but do not go past end. + static intptr_t* allocate(const char* name); + + // Clone the vtable to ... + static intptr_t* clone_vtable(const char* name, CppVtableInfo* info); + + static void zero_vtable_clone() { + assert(DumpSharedSpaces, "dump-time only"); + _info->zero(); + } + + static bool is_valid_shared_object(const T* obj) { + intptr_t* vptr = *(intptr_t**)obj; + return vptr == _info->cloned_vtable(); + } + + static void init_orig_cpp_vtptr(int kind); +}; + +template CppVtableInfo* CppVtableCloner::_info = NULL; + +template +intptr_t* CppVtableCloner::allocate(const char* name) { + assert(is_aligned(mc_region()->top(), sizeof(intptr_t)), "bad alignment"); + int n = get_vtable_length(name); + _info = (CppVtableInfo*)mc_region()->allocate(CppVtableInfo::byte_size(n), sizeof(intptr_t)); + _info->set_vtable_size(n); + + intptr_t* p = clone_vtable(name, _info); + assert((char*)p == mc_region()->top(), "must be"); + + return _info->cloned_vtable(); +} + +template +intptr_t* CppVtableCloner::clone_vtable(const char* name, CppVtableInfo* info) { + if (!DumpSharedSpaces) { + assert(_info == 0, "_info is initialized only at dump time"); + _info = info; // Remember it -- it will be used by MetaspaceShared::is_valid_shared_method() + } + T tmp; // Allocate temporary dummy metadata object to get to the original vtable. + int n = info->vtable_size(); + intptr_t* srcvtable = vtable_of(&tmp); + intptr_t* dstvtable = info->cloned_vtable(); + + // We already checked (and, if necessary, adjusted n) when the vtables were allocated, so we are + // safe to do memcpy. + log_debug(cds, vtables)("Copying %3d vtable entries for %s", n, name); + memcpy(dstvtable, srcvtable, sizeof(intptr_t) * n); + return dstvtable + n; +} + +// To determine the size of the vtable for each type, we use the following +// trick by declaring 2 subclasses: +// +// class CppVtableTesterA: public InstanceKlass {virtual int last_virtual_method() {return 1;} }; +// class CppVtableTesterB: public InstanceKlass {virtual void* last_virtual_method() {return NULL}; }; +// +// CppVtableTesterA and CppVtableTesterB's vtables have the following properties: +// - Their size (N+1) is exactly one more than the size of InstanceKlass's vtable (N) +// - The first N entries have are exactly the same as in InstanceKlass's vtable. +// - Their last entry is different. +// +// So to determine the value of N, we just walk CppVtableTesterA and CppVtableTesterB's tables +// and find the first entry that's different. +// +// This works on all C++ compilers supported by Oracle, but you may need to tweak it for more +// esoteric compilers. + +template class CppVtableTesterB: public T { +public: + virtual int last_virtual_method() {return 1;} +}; + +template class CppVtableTesterA : public T { +public: + virtual void* last_virtual_method() { + // Make this different than CppVtableTesterB::last_virtual_method so the C++ + // compiler/linker won't alias the two functions. + return NULL; + } +}; + +template +int CppVtableCloner::get_vtable_length(const char* name) { + CppVtableTesterA a; + CppVtableTesterB b; + + intptr_t* avtable = vtable_of(&a); + intptr_t* bvtable = vtable_of(&b); + + // Start at slot 1, because slot 0 may be RTTI (on Solaris/Sparc) + int vtable_len = 1; + for (; ; vtable_len++) { + if (avtable[vtable_len] != bvtable[vtable_len]) { + break; + } + } + log_debug(cds, vtables)("Found %3d vtable entries for %s", vtable_len, name); + + return vtable_len; +} + +#define ALLOC_CPP_VTABLE_CLONE(c) \ + _cloned_cpp_vtptrs[c##_Kind] = CppVtableCloner::allocate(#c); \ + ArchivePtrMarker::mark_pointer(&_cloned_cpp_vtptrs[c##_Kind]); + +#define CLONE_CPP_VTABLE(c) \ + p = CppVtableCloner::clone_vtable(#c, (CppVtableInfo*)p); + +#define ZERO_CPP_VTABLE(c) \ + CppVtableCloner::zero_vtable_clone(); + +#define INIT_ORIG_CPP_VTPTRS(c) \ + CppVtableCloner::init_orig_cpp_vtptr(c##_Kind); + +#define DECLARE_CLONED_VTABLE_KIND(c) c ## _Kind, + +enum ClonedVtableKind { + // E.g., ConstantPool_Kind == 0, InstanceKlass_Kind == 1, etc. + CPP_VTABLE_PATCH_TYPES_DO(DECLARE_CLONED_VTABLE_KIND) + _num_cloned_vtable_kinds +}; + +// This is a map of all the original vtptrs. E.g., for +// ConstantPool *cp = new (...) ConstantPool(...) ; // a dynamically allocated constant pool +// the following holds true: +// _orig_cpp_vtptrs[ConstantPool_Kind] == ((intptr_t**)cp)[0] +static intptr_t* _orig_cpp_vtptrs[_num_cloned_vtable_kinds]; +static bool _orig_cpp_vtptrs_inited = false; + +template +void CppVtableCloner::init_orig_cpp_vtptr(int kind) { + assert(kind < _num_cloned_vtable_kinds, "sanity"); + T tmp; // Allocate temporary dummy metadata object to get to the original vtable. + intptr_t* srcvtable = vtable_of(&tmp); + _orig_cpp_vtptrs[kind] = srcvtable; +} + +// This is the index of all the cloned vtables. E.g., for +// ConstantPool* cp = ....; // an archived constant pool +// InstanceKlass* ik = ....;// an archived class +// the following holds true: +// _cloned_cpp_vtptrs[ConstantPool_Kind] == ((intptr_t**)cp)[0] +// _cloned_cpp_vtptrs[InstanceKlass_Kind] == ((intptr_t**)ik)[0] +static intptr_t** _cloned_cpp_vtptrs = NULL; + +void CppVtables::allocate_cloned_cpp_vtptrs() { + assert(DumpSharedSpaces, "must"); + size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof(intptr_t*); + _cloned_cpp_vtptrs = (intptr_t**)mc_region()->allocate(vtptrs_bytes, sizeof(intptr_t*)); +} + +void CppVtables::serialize_cloned_cpp_vtptrs(SerializeClosure* soc) { + soc->do_ptr((void**)&_cloned_cpp_vtptrs); +} + +intptr_t* CppVtables::get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj) { + if (!_orig_cpp_vtptrs_inited) { + CPP_VTABLE_PATCH_TYPES_DO(INIT_ORIG_CPP_VTPTRS); + _orig_cpp_vtptrs_inited = true; + } + + Arguments::assert_is_dumping_archive(); + int kind = -1; + switch (msotype) { + case MetaspaceObj::SymbolType: + case MetaspaceObj::TypeArrayU1Type: + case MetaspaceObj::TypeArrayU2Type: + case MetaspaceObj::TypeArrayU4Type: + case MetaspaceObj::TypeArrayU8Type: + case MetaspaceObj::TypeArrayOtherType: + case MetaspaceObj::ConstMethodType: + case MetaspaceObj::ConstantPoolCacheType: + case MetaspaceObj::AnnotationsType: + case MetaspaceObj::MethodCountersType: + case MetaspaceObj::RecordComponentType: + // These have no vtables. + break; + case MetaspaceObj::MethodDataType: + // We don't archive MethodData <-- should have been removed in removed_unsharable_info + ShouldNotReachHere(); + break; + default: + for (kind = 0; kind < _num_cloned_vtable_kinds; kind ++) { + if (vtable_of((Metadata*)obj) == _orig_cpp_vtptrs[kind]) { + break; + } + } + if (kind >= _num_cloned_vtable_kinds) { + fatal("Cannot find C++ vtable for " INTPTR_FORMAT " -- you probably added" + " a new subtype of Klass or MetaData without updating CPP_VTABLE_PATCH_TYPES_DO", + p2i(obj)); + } + } + + if (kind >= 0) { + assert(kind < _num_cloned_vtable_kinds, "must be"); + return _cloned_cpp_vtptrs[kind]; + } else { + return NULL; + } +} + +// This can be called at both dump time and run time: +// - clone the contents of the c++ vtables into the space +// allocated by allocate_cpp_vtable_clones() +void CppVtables::clone_cpp_vtables(intptr_t* p) { + assert(DumpSharedSpaces || UseSharedSpaces, "sanity"); + CPP_VTABLE_PATCH_TYPES_DO(CLONE_CPP_VTABLE); +} + +void CppVtables::zero_cpp_vtable_clones_for_writing() { + assert(DumpSharedSpaces, "dump-time only"); + CPP_VTABLE_PATCH_TYPES_DO(ZERO_CPP_VTABLE); +} + +// Allocate and initialize the C++ vtables, starting from top, but do not go past end. +char* CppVtables::allocate_cpp_vtable_clones() { + char* cloned_vtables = mc_region()->top(); // This is the beginning of all the cloned vtables + + assert(DumpSharedSpaces, "dump-time only"); + // Layout (each slot is a intptr_t): + // [number of slots in the first vtable = n1] + // [ slots for the first vtable] + // [number of slots in the first second = n2] + // [ slots for the second vtable] + // ... + // The order of the vtables is the same as the CPP_VTAB_PATCH_TYPES_DO macro. + CPP_VTABLE_PATCH_TYPES_DO(ALLOC_CPP_VTABLE_CLONE); + + return cloned_vtables; +} + +bool CppVtables::is_valid_shared_method(const Method* m) { + assert(MetaspaceShared::is_in_shared_metaspace(m), "must be"); + return CppVtableCloner::is_valid_shared_object(m); +} diff --git a/src/hotspot/share/memory/cppVtables.hpp b/src/hotspot/share/memory/cppVtables.hpp new file mode 100644 index 0000000000000..8604424c6fcda --- /dev/null +++ b/src/hotspot/share/memory/cppVtables.hpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_MEMORY_CPPVTABLES_HPP +#define SHARE_MEMORY_CPPVTABLES_HPP + +#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" + +class Method; +class SerializeClosure; + +// Support for C++ vtables in CDS archive. +class CppVtables : AllStatic { + static void patch_cpp_vtable_pointers(); +public: + static char* allocate_cpp_vtable_clones(); + static void allocate_cloned_cpp_vtptrs(); + static void clone_cpp_vtables(intptr_t* p); + static void zero_cpp_vtable_clones_for_writing(); + static intptr_t* get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj); + static void serialize_cloned_cpp_vtptrs(SerializeClosure* sc); + static bool is_valid_shared_method(const Method* m) NOT_CDS_RETURN_(false); +}; + +#endif // SHARE_MEMORY_CPPVTABLES_HPP diff --git a/src/hotspot/share/memory/filemap.cpp b/src/hotspot/share/memory/filemap.cpp index 643e45781ced4..2ac796751da4a 100644 --- a/src/hotspot/share/memory/filemap.cpp +++ b/src/hotspot/share/memory/filemap.cpp @@ -1846,6 +1846,7 @@ void FileMapInfo::map_heap_regions() { if (!HeapShared::open_archive_heap_region_mapped()) { assert(open_archive_heap_ranges == NULL && num_open_archive_heap_ranges == 0, "sanity"); + MetaspaceShared::disable_full_module_graph(); } } diff --git a/src/hotspot/share/memory/metaspaceShared.cpp b/src/hotspot/share/memory/metaspaceShared.cpp index c6e71299bf1ea..f017dce3cb612 100644 --- a/src/hotspot/share/memory/metaspaceShared.cpp +++ b/src/hotspot/share/memory/metaspaceShared.cpp @@ -41,6 +41,7 @@ #include "logging/logMessage.hpp" #include "memory/archiveBuilder.hpp" #include "memory/archiveUtils.inline.hpp" +#include "memory/cppVtables.hpp" #include "memory/dumpAllocStats.hpp" #include "memory/dynamicArchive.hpp" #include "memory/filemap.hpp" @@ -51,15 +52,10 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/compressedOops.inline.hpp" -#include "oops/instanceClassLoaderKlass.hpp" #include "oops/instanceMirrorKlass.hpp" -#include "oops/instanceRefKlass.hpp" -#include "oops/methodData.hpp" -#include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" #include "oops/oopHandle.hpp" -#include "oops/typeArrayKlass.hpp" #include "runtime/handles.inline.hpp" #include "runtime/os.hpp" #include "runtime/safepointVerifiers.hpp" @@ -504,7 +500,7 @@ void MetaspaceShared::serialize(SerializeClosure* soc) { SystemDictionaryShared::serialize_well_known_klasses(soc); soc->do_tag(--tag); - serialize_cloned_cpp_vtptrs(soc); + CppVtables::serialize_cloned_cpp_vtptrs(soc); soc->do_tag(--tag); CDS_JAVA_HEAP_ONLY(ClassLoaderDataShared::serialize(soc)); @@ -616,297 +612,6 @@ void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread } } -// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables. -// (In GCC this is the field ::_vptr, i.e., first word in the object.) -// -// Addresses of the vtables and the methods may be different across JVM runs, -// if libjvm.so is dynamically loaded at a different base address. -// -// To ensure that the Metadata objects in the CDS archive always have the correct vtable: -// -// + at dump time: we redirect the _vptr to point to our own vtables inside -// the CDS image -// + at run time: we clone the actual contents of the vtables from libjvm.so -// into our own tables. - -// Currently, the archive contain ONLY the following types of objects that have C++ vtables. -#define CPP_VTABLE_PATCH_TYPES_DO(f) \ - f(ConstantPool) \ - f(InstanceKlass) \ - f(InstanceClassLoaderKlass) \ - f(InstanceMirrorKlass) \ - f(InstanceRefKlass) \ - f(Method) \ - f(ObjArrayKlass) \ - f(TypeArrayKlass) - -class CppVtableInfo { - intptr_t _vtable_size; - intptr_t _cloned_vtable[1]; -public: - static int num_slots(int vtable_size) { - return 1 + vtable_size; // Need to add the space occupied by _vtable_size; - } - int vtable_size() { return int(uintx(_vtable_size)); } - void set_vtable_size(int n) { _vtable_size = intptr_t(n); } - intptr_t* cloned_vtable() { return &_cloned_vtable[0]; } - void zero() { memset(_cloned_vtable, 0, sizeof(intptr_t) * vtable_size()); } - // Returns the address of the next CppVtableInfo that can be placed immediately after this CppVtableInfo - static size_t byte_size(int vtable_size) { - CppVtableInfo i; - return pointer_delta(&i._cloned_vtable[vtable_size], &i, sizeof(u1)); - } -}; - -static inline intptr_t* vtable_of(Metadata* m) { - return *((intptr_t**)m); -} - -template class CppVtableCloner : public T { - static CppVtableInfo* _info; - - static int get_vtable_length(const char* name); - -public: - // Allocate and initialize the C++ vtable, starting from top, but do not go past end. - static intptr_t* allocate(const char* name); - - // Clone the vtable to ... - static intptr_t* clone_vtable(const char* name, CppVtableInfo* info); - - static void zero_vtable_clone() { - assert(DumpSharedSpaces, "dump-time only"); - _info->zero(); - } - - static bool is_valid_shared_object(const T* obj) { - intptr_t* vptr = *(intptr_t**)obj; - return vptr == _info->cloned_vtable(); - } - - static void init_orig_cpp_vtptr(int kind); -}; - -template CppVtableInfo* CppVtableCloner::_info = NULL; - -template -intptr_t* CppVtableCloner::allocate(const char* name) { - assert(is_aligned(_mc_region.top(), sizeof(intptr_t)), "bad alignment"); - int n = get_vtable_length(name); - _info = (CppVtableInfo*)_mc_region.allocate(CppVtableInfo::byte_size(n), sizeof(intptr_t)); - _info->set_vtable_size(n); - - intptr_t* p = clone_vtable(name, _info); - assert((char*)p == _mc_region.top(), "must be"); - - return _info->cloned_vtable(); -} - -template -intptr_t* CppVtableCloner::clone_vtable(const char* name, CppVtableInfo* info) { - if (!DumpSharedSpaces) { - assert(_info == 0, "_info is initialized only at dump time"); - _info = info; // Remember it -- it will be used by MetaspaceShared::is_valid_shared_method() - } - T tmp; // Allocate temporary dummy metadata object to get to the original vtable. - int n = info->vtable_size(); - intptr_t* srcvtable = vtable_of(&tmp); - intptr_t* dstvtable = info->cloned_vtable(); - - // We already checked (and, if necessary, adjusted n) when the vtables were allocated, so we are - // safe to do memcpy. - log_debug(cds, vtables)("Copying %3d vtable entries for %s", n, name); - memcpy(dstvtable, srcvtable, sizeof(intptr_t) * n); - return dstvtable + n; -} - -// To determine the size of the vtable for each type, we use the following -// trick by declaring 2 subclasses: -// -// class CppVtableTesterA: public InstanceKlass {virtual int last_virtual_method() {return 1;} }; -// class CppVtableTesterB: public InstanceKlass {virtual void* last_virtual_method() {return NULL}; }; -// -// CppVtableTesterA and CppVtableTesterB's vtables have the following properties: -// - Their size (N+1) is exactly one more than the size of InstanceKlass's vtable (N) -// - The first N entries have are exactly the same as in InstanceKlass's vtable. -// - Their last entry is different. -// -// So to determine the value of N, we just walk CppVtableTesterA and CppVtableTesterB's tables -// and find the first entry that's different. -// -// This works on all C++ compilers supported by Oracle, but you may need to tweak it for more -// esoteric compilers. - -template class CppVtableTesterB: public T { -public: - virtual int last_virtual_method() {return 1;} -}; - -template class CppVtableTesterA : public T { -public: - virtual void* last_virtual_method() { - // Make this different than CppVtableTesterB::last_virtual_method so the C++ - // compiler/linker won't alias the two functions. - return NULL; - } -}; - -template -int CppVtableCloner::get_vtable_length(const char* name) { - CppVtableTesterA a; - CppVtableTesterB b; - - intptr_t* avtable = vtable_of(&a); - intptr_t* bvtable = vtable_of(&b); - - // Start at slot 1, because slot 0 may be RTTI (on Solaris/Sparc) - int vtable_len = 1; - for (; ; vtable_len++) { - if (avtable[vtable_len] != bvtable[vtable_len]) { - break; - } - } - log_debug(cds, vtables)("Found %3d vtable entries for %s", vtable_len, name); - - return vtable_len; -} - -#define ALLOC_CPP_VTABLE_CLONE(c) \ - _cloned_cpp_vtptrs[c##_Kind] = CppVtableCloner::allocate(#c); \ - ArchivePtrMarker::mark_pointer(&_cloned_cpp_vtptrs[c##_Kind]); - -#define CLONE_CPP_VTABLE(c) \ - p = CppVtableCloner::clone_vtable(#c, (CppVtableInfo*)p); - -#define ZERO_CPP_VTABLE(c) \ - CppVtableCloner::zero_vtable_clone(); - -#define INIT_ORIG_CPP_VTPTRS(c) \ - CppVtableCloner::init_orig_cpp_vtptr(c##_Kind); - -#define DECLARE_CLONED_VTABLE_KIND(c) c ## _Kind, - -enum ClonedVtableKind { - // E.g., ConstantPool_Kind == 0, InstanceKlass_Kind == 1, etc. - CPP_VTABLE_PATCH_TYPES_DO(DECLARE_CLONED_VTABLE_KIND) - _num_cloned_vtable_kinds -}; - -// This is a map of all the original vtptrs. E.g., for -// ConstantPool *cp = new (...) ConstantPool(...) ; // a dynamically allocated constant pool -// the following holds true: -// _orig_cpp_vtptrs[ConstantPool_Kind] == ((intptr_t**)cp)[0] -static intptr_t* _orig_cpp_vtptrs[_num_cloned_vtable_kinds]; -static bool _orig_cpp_vtptrs_inited = false; - -template -void CppVtableCloner::init_orig_cpp_vtptr(int kind) { - assert(kind < _num_cloned_vtable_kinds, "sanity"); - T tmp; // Allocate temporary dummy metadata object to get to the original vtable. - intptr_t* srcvtable = vtable_of(&tmp); - _orig_cpp_vtptrs[kind] = srcvtable; -} - -// This is the index of all the cloned vtables. E.g., for -// ConstantPool* cp = ....; // an archived constant pool -// InstanceKlass* ik = ....;// an archived class -// the following holds true: -// _cloned_cpp_vtptrs[ConstantPool_Kind] == ((intptr_t**)cp)[0] -// _cloned_cpp_vtptrs[InstanceKlass_Kind] == ((intptr_t**)ik)[0] -static intptr_t** _cloned_cpp_vtptrs = NULL; - -void MetaspaceShared::allocate_cloned_cpp_vtptrs() { - assert(DumpSharedSpaces, "must"); - size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof(intptr_t*); - _cloned_cpp_vtptrs = (intptr_t**)_mc_region.allocate(vtptrs_bytes, sizeof(intptr_t*)); -} - -void MetaspaceShared::serialize_cloned_cpp_vtptrs(SerializeClosure* soc) { - soc->do_ptr((void**)&_cloned_cpp_vtptrs); -} - -intptr_t* MetaspaceShared::get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj) { - if (!_orig_cpp_vtptrs_inited) { - CPP_VTABLE_PATCH_TYPES_DO(INIT_ORIG_CPP_VTPTRS); - _orig_cpp_vtptrs_inited = true; - } - - Arguments::assert_is_dumping_archive(); - int kind = -1; - switch (msotype) { - case MetaspaceObj::SymbolType: - case MetaspaceObj::TypeArrayU1Type: - case MetaspaceObj::TypeArrayU2Type: - case MetaspaceObj::TypeArrayU4Type: - case MetaspaceObj::TypeArrayU8Type: - case MetaspaceObj::TypeArrayOtherType: - case MetaspaceObj::ConstMethodType: - case MetaspaceObj::ConstantPoolCacheType: - case MetaspaceObj::AnnotationsType: - case MetaspaceObj::MethodCountersType: - case MetaspaceObj::RecordComponentType: - // These have no vtables. - break; - case MetaspaceObj::MethodDataType: - // We don't archive MethodData <-- should have been removed in removed_unsharable_info - ShouldNotReachHere(); - break; - default: - for (kind = 0; kind < _num_cloned_vtable_kinds; kind ++) { - if (vtable_of((Metadata*)obj) == _orig_cpp_vtptrs[kind]) { - break; - } - } - if (kind >= _num_cloned_vtable_kinds) { - fatal("Cannot find C++ vtable for " INTPTR_FORMAT " -- you probably added" - " a new subtype of Klass or MetaData without updating CPP_VTABLE_PATCH_TYPES_DO", - p2i(obj)); - } - } - - if (kind >= 0) { - assert(kind < _num_cloned_vtable_kinds, "must be"); - return _cloned_cpp_vtptrs[kind]; - } else { - return NULL; - } -} - -// This can be called at both dump time and run time: -// - clone the contents of the c++ vtables into the space -// allocated by allocate_cpp_vtable_clones() -void MetaspaceShared::clone_cpp_vtables(intptr_t* p) { - assert(DumpSharedSpaces || UseSharedSpaces, "sanity"); - CPP_VTABLE_PATCH_TYPES_DO(CLONE_CPP_VTABLE); -} - -void MetaspaceShared::zero_cpp_vtable_clones_for_writing() { - assert(DumpSharedSpaces, "dump-time only"); - CPP_VTABLE_PATCH_TYPES_DO(ZERO_CPP_VTABLE); -} - -// Allocate and initialize the C++ vtables, starting from top, but do not go past end. -char* MetaspaceShared::allocate_cpp_vtable_clones() { - char* cloned_vtables = _mc_region.top(); // This is the beginning of all the cloned vtables - - assert(DumpSharedSpaces, "dump-time only"); - // Layout (each slot is a intptr_t): - // [number of slots in the first vtable = n1] - // [ slots for the first vtable] - // [number of slots in the first second = n2] - // [ slots for the second vtable] - // ... - // The order of the vtables is the same as the CPP_VTAB_PATCH_TYPES_DO macro. - CPP_VTABLE_PATCH_TYPES_DO(ALLOC_CPP_VTABLE_CLONE); - - return cloned_vtables; -} - -bool MetaspaceShared::is_valid_shared_method(const Method* m) { - assert(is_in_shared_metaspace(m), "must be"); - return CppVtableCloner::is_valid_shared_object(m); -} - class VM_PopulateDumpSharedSpace: public VM_Operation { private: GrowableArray *_closed_archive_heap_regions; @@ -1075,9 +780,9 @@ void VM_PopulateDumpSharedSpace::doit() { builder.gather_source_objs(); - MetaspaceShared::allocate_cloned_cpp_vtptrs(); + CppVtables::allocate_cloned_cpp_vtptrs(); char* cloned_vtables = _mc_region.top(); - MetaspaceShared::allocate_cpp_vtable_clones(); + CppVtables::allocate_cpp_vtable_clones(); { _mc_region.pack(&_rw_region); @@ -1118,7 +823,7 @@ void VM_PopulateDumpSharedSpace::doit() { // The vtable clones contain addresses of the current process. // We don't want to write these addresses into the archive. Same for i2i buffer. - MetaspaceShared::zero_cpp_vtable_clones_for_writing(); + CppVtables::zero_cpp_vtable_clones_for_writing(); memset(MetaspaceShared::i2i_entry_code_buffers(), 0, MetaspaceShared::i2i_entry_code_buffers_size()); @@ -1384,6 +1089,8 @@ void MetaspaceShared::preload_and_dump(TRAPS) { HeapShared::init_for_dumping(THREAD); + // exercise the manifest processing code to ensure classes used by CDS are always archived + SystemDictionaryShared::create_jar_manifest("Manifest-Version: 1.0\n", strlen("Manifest-Version: 1.0\n"), THREAD); // Rewrite and link classes log_info(cds)("Rewriting and linking classes ..."); @@ -2026,7 +1733,7 @@ void MetaspaceShared::initialize_shared_spaces() { _i2i_entry_code_buffers = static_mapinfo->i2i_entry_code_buffers(); _i2i_entry_code_buffers_size = static_mapinfo->i2i_entry_code_buffers_size(); char* buffer = static_mapinfo->cloned_vtables(); - clone_cpp_vtables((intptr_t*)buffer); + CppVtables::clone_cpp_vtables((intptr_t*)buffer); // Verify various attributes of the archive, plus initialize the // shared string/symbol tables diff --git a/src/hotspot/share/memory/metaspaceShared.hpp b/src/hotspot/share/memory/metaspaceShared.hpp index 9b01ddf9f6546..8ffd20f5c453a 100644 --- a/src/hotspot/share/memory/metaspaceShared.hpp +++ b/src/hotspot/share/memory/metaspaceShared.hpp @@ -168,13 +168,6 @@ class MetaspaceShared : AllStatic { static bool is_shared_dynamic(void* p) NOT_CDS_RETURN_(false); - static char* allocate_cpp_vtable_clones(); - static void clone_cpp_vtables(intptr_t* p); - static void zero_cpp_vtable_clones_for_writing(); - static void patch_cpp_vtable_pointers(); - static void serialize_cloned_cpp_vtptrs(SerializeClosure* sc); - - static bool is_valid_shared_method(const Method* m) NOT_CDS_RETURN_(false); static void serialize(SerializeClosure* sc) NOT_CDS_RETURN; static MetaspaceSharedStats* stats() { @@ -252,8 +245,6 @@ class MetaspaceShared : AllStatic { static Klass* get_relocated_klass(Klass *k, bool is_final=false); - static void allocate_cloned_cpp_vtptrs(); - static intptr_t* get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj); static void initialize_ptr_marker(CHeapBitMap* ptrmap); // This is the base address as specified by -XX:SharedBaseAddress during -Xshare:dump. diff --git a/src/hotspot/share/memory/padded.hpp b/src/hotspot/share/memory/padded.hpp index c51d1e7a63b43..08003613609e0 100644 --- a/src/hotspot/share/memory/padded.hpp +++ b/src/hotspot/share/memory/padded.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * 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,7 +34,7 @@ // when the start address is not a multiple of alignment; the second maintains // alignment of starting addresses that happen to be a multiple. #define PADDING_SIZE(type, alignment) \ - ((alignment) + align_up_(sizeof(type), (alignment))) + ((alignment) + align_up(sizeof(type), (alignment))) // Templates to create a subclass padded to avoid cache line sharing. These are // effective only when applied to derived-most (leaf) classes. @@ -69,7 +69,7 @@ class PaddedEndImpl : public T { // No padding. }; -#define PADDED_END_SIZE(type, alignment) (align_up_(sizeof(type), (alignment)) - sizeof(type)) +#define PADDED_END_SIZE(type, alignment) (align_up(sizeof(type), (alignment)) - sizeof(type)) // More memory conservative implementation of Padded. The subclass adds the // minimal amount of padding needed to make the size of the objects be aligned. diff --git a/src/hotspot/share/memory/padded.inline.hpp b/src/hotspot/share/memory/padded.inline.hpp index 939bf7b69db7b..d698f5ee1b3a2 100644 --- a/src/hotspot/share/memory/padded.inline.hpp +++ b/src/hotspot/share/memory/padded.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ template PaddedEnd* PaddedArray::create_unfreeable(uint length) { // Check that the PaddedEnd class works as intended. - STATIC_ASSERT(is_aligned_(sizeof(PaddedEnd), alignment)); + STATIC_ASSERT(is_aligned(sizeof(PaddedEnd), alignment)); // Allocate a chunk of memory large enough to allow for some alignment. void* chunk = AllocateHeap(length * sizeof(PaddedEnd) + alignment, flags); diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp index 0555dfa04d11d..ae2ad7d6e1d5b 100644 --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -1031,26 +1031,6 @@ void Universe::print_heap_at_SIGBREAK() { } } -void Universe::print_heap_before_gc() { - LogTarget(Debug, gc, heap) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print("Heap before GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections()); - ResourceMark rm; - heap()->print_on(&ls); - } -} - -void Universe::print_heap_after_gc() { - LogTarget(Debug, gc, heap) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print("Heap after GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections()); - ResourceMark rm; - heap()->print_on(&ls); - } -} - void Universe::initialize_verify_flags() { verify_flags = 0; const char delimiter[] = " ,"; diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp index 4d80ec4df411b..42b3e635ebbd8 100644 --- a/src/hotspot/share/memory/universe.hpp +++ b/src/hotspot/share/memory/universe.hpp @@ -357,8 +357,6 @@ class Universe: AllStatic { static int verify_count() { return _verify_count; } static void print_on(outputStream* st); static void print_heap_at_SIGBREAK(); - static void print_heap_before_gc(); - static void print_heap_after_gc(); // Change the number of dummy objects kept reachable by the full gc dummy // array; this should trigger relocation in a sliding compaction collector. diff --git a/src/hotspot/share/metaprogramming/primitiveConversions.hpp b/src/hotspot/share/metaprogramming/primitiveConversions.hpp index 2d9fa6e3dbbeb..08806442bf406 100644 --- a/src/hotspot/share/metaprogramming/primitiveConversions.hpp +++ b/src/hotspot/share/metaprogramming/primitiveConversions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,147 +25,102 @@ #ifndef SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP #define SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "metaprogramming/enableIf.hpp" -#include "metaprogramming/integralConstant.hpp" -#include "metaprogramming/isFloatingPoint.hpp" -#include "metaprogramming/isIntegral.hpp" -#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" #include class PrimitiveConversions : public AllStatic { + + // True if types are the same size and either is integral. + template + static constexpr bool check_cast() { + return (sizeof(To) == sizeof(From)) && + (std::is_integral::value || std::is_integral::value); + } + public: - // Return a value of type T with the same representation as x. + // template To cast(From x) + // + // Return a value of type To with the same value representation as x. // - // T and U must be of the same size. + // To and From must be of the same size. // - // At least one of T or U must be an integral type. The other must - // be an integral, floating point, or pointer type. - template static T cast(U x); + // At least one of To or From must be an integral type. The other must + // be an integral, enum, floating point, or pointer type. + + // integer -> integer + // Use static_cast for conversion. See C++14 4.7 Integral + // conversions. If To is signed and From unsigned, the result is + // implementation-defined. All supported platforms provide two's + // complement behavior, and that behavior is required by C++20. + // Using an lvalue to reference cast (see C++03 3.10/15) involves a + // reinterpret_cast, which prevents constexpr support. + template::value), + ENABLE_IF(std::is_integral::value)> + static constexpr To cast(From x) { + return static_cast(x); + } + + // integer -> enum, enum -> integer + // Use the enum's underlying type for integer -> integer cast. + template()), + ENABLE_IF(std::is_enum::value)> + static constexpr To cast(From x) { + return static_cast(cast>(x)); + } + + template()), + ENABLE_IF(std::is_enum::value)> + static constexpr To cast(From x) { + return cast(static_cast>(x)); + } + + // integer -> pointer, pointer -> integer + // Use reinterpret_cast, so no constexpr support. + template()), + ENABLE_IF(std::is_pointer::value || std::is_pointer::value)> + static To cast(From x) { + return reinterpret_cast(x); + } + + // integer -> floating point, floating point -> integer + // Use the union trick. The union trick is technically UB, but is + // widely and well supported, producing good code. In some cases, + // such as gcc, that support is explicitly documented. Using memcpy + // is the correct method, but some compilers produce wretched code + // for that method, even at maximal optimization levels. Neither + // the union trick nor memcpy provides constexpr support. + template()), + ENABLE_IF(std::is_floating_point::value || + std::is_floating_point::value)> + static To cast(From x) { + union { From from; To to; } converter = { x }; + return converter.to; + } // Support thin wrappers over primitive types. - // If derived from TrueType, provides representational conversion + // If derived from std::true_type, provides representational conversion // from T to some other type. When true, must provide // - Value: typedef for T. // - Decayed: typedef for decayed type. // - static Decayed decay(T x): return value of type Decayed with - // the same representation as x. + // the same value representation as x. // - static T recover(Decayed x): return a value of type T with the - // same representation as x. - template struct Translate : public FalseType {}; - -private: - - template - struct Cast; - - template static T cast_using_union(U x); -}; - -// Return an object of type T with the same value representation as x. -// -// T and U must be of the same size. It is expected that one of T and -// U is an integral type, and the other is an integral type, an enum type, -// or a floating point type. -// -// This implementation uses the "union trick", which seems to be the -// best of a bad set of options. Though technically undefined -// behavior, it is widely and well supported, producing good code. In -// some cases, such as gcc, that support is explicitly documented. -// -// Using memcpy is the correct method, but some compilers produce -// wretched code for that method, even at maximal optimization levels. -// -// Using static_cast is only possible for integral and enum types, not -// for floating point types. And for integral and enum conversions, -// static_cast has unspecified or implementation-defined behavior for -// some cases. C++11 can be used to avoid most or all -// of those unspecified or implementation-defined issues, though that -// may require multi-step conversions. -// -// Using reinterpret_cast of references has undefined behavior for -// many cases, and there is much less empirical basis for its use, as -// compared to the union trick. -template -inline T PrimitiveConversions::cast_using_union(U x) { - STATIC_ASSERT(sizeof(T) == sizeof(U)); - union { T t; U u; }; - u = x; - return t; -} - -////////////////////////////////////////////////////////////////////////////// -// cast(x) -// -// Cast - -// Give an informative error if the sizes differ. -template -struct PrimitiveConversions::Cast { - STATIC_ASSERT(sizeof(T) == sizeof(U)); -}; - -// Conversion between integral types. -template -struct PrimitiveConversions::Cast< - T, U, true, - typename EnableIf::value && IsIntegral::value>::type> -{ - T operator()(U x) const { return cast_using_union(x); } + // same value representation as x. + template struct Translate : public std::false_type {}; }; -// Convert an enum or floating point value to an integer value. -template -struct PrimitiveConversions::Cast< - T, U, true, - typename EnableIf::value && - (std::is_enum::value || - IsFloatingPoint::value)>::type> -{ - T operator()(U x) const { return cast_using_union(x); } -}; - -// Convert an integer to an enum or floating point value. -template -struct PrimitiveConversions::Cast< - T, U, true, - typename EnableIf::value && - (std::is_enum::value || - IsFloatingPoint::value)>::type> -{ - T operator()(U x) const { return cast_using_union(x); } -}; - -// Convert a pointer to an integral value. -template -struct PrimitiveConversions::Cast< - T, U*, true, - typename EnableIf::value>::type> -{ - T operator()(U* x) const { return reinterpret_cast(x); } -}; - -// Convert an integral value to a pointer. -template -struct PrimitiveConversions::Cast< - T*, U, true, - typename EnableIf::value>::type> -{ - T* operator()(U x) const { return reinterpret_cast(x); } -}; - -template -inline T PrimitiveConversions::cast(U x) { - return Cast()(x); -} - // jfloat and jdouble translation to integral types template<> -struct PrimitiveConversions::Translate : public TrueType { +struct PrimitiveConversions::Translate : public std::true_type { typedef double Value; typedef int64_t Decayed; @@ -174,7 +129,7 @@ struct PrimitiveConversions::Translate : public TrueType { }; template<> -struct PrimitiveConversions::Translate : public TrueType { +struct PrimitiveConversions::Translate : public std::true_type { typedef float Value; typedef int32_t Decayed; diff --git a/src/hotspot/share/oops/constantPool.hpp b/src/hotspot/share/oops/constantPool.hpp index 7e5282dfba555..783dff8a5394c 100644 --- a/src/hotspot/share/oops/constantPool.hpp +++ b/src/hotspot/share/oops/constantPool.hpp @@ -495,7 +495,7 @@ class ConstantPool : public Metadata { // a String entry. // This can happen if the user patches a live // object into a CONSTANT_String entry of an unsafe anonymous class. - // Method oops internally created for method handles may also + // Methods internally created for method handles may also // use pseudo-strings to link themselves to related metaobjects. bool is_pseudo_string_at(int which); diff --git a/src/hotspot/share/oops/markWord.cpp b/src/hotspot/share/oops/markWord.cpp index 4c599f8b6eacb..2c8ad2414dbdf 100644 --- a/src/hotspot/share/oops/markWord.cpp +++ b/src/hotspot/share/oops/markWord.cpp @@ -26,6 +26,7 @@ #include "oops/markWord.hpp" #include "runtime/thread.inline.hpp" #include "runtime/objectMonitor.hpp" +#include "utilities/ostream.hpp" void markWord::print_on(outputStream* st) const { if (is_marked()) { // last bits = 11 diff --git a/src/hotspot/share/oops/markWord.hpp b/src/hotspot/share/oops/markWord.hpp index b3d97417821cd..2846e1ae1123b 100644 --- a/src/hotspot/share/oops/markWord.hpp +++ b/src/hotspot/share/oops/markWord.hpp @@ -94,6 +94,7 @@ class BasicLock; class ObjectMonitor; class JavaThread; +class outputStream; class markWord { private: diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 3b65ba17d7c85..88a106fbeed6f 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -40,6 +40,7 @@ #include "logging/logTag.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" +#include "memory/cppVtables.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/metaspaceShared.hpp" @@ -2303,7 +2304,7 @@ bool Method::is_valid_method(const Method* m) { // Quick sanity check on pointer. return false; } else if (m->is_shared()) { - return MetaspaceShared::is_valid_shared_method(m); + return CppVtables::is_valid_shared_method(m); } else if (Metaspace::contains_non_shared(m)) { return has_method_vptr((const void*)m); } else { diff --git a/src/hotspot/share/opto/arraycopynode.cpp b/src/hotspot/share/opto/arraycopynode.cpp index d73b2634cf01b..ce133a240a47a 100644 --- a/src/hotspot/share/opto/arraycopynode.cpp +++ b/src/hotspot/share/opto/arraycopynode.cpp @@ -85,6 +85,7 @@ void ArrayCopyNode::connect_outputs(GraphKit* kit, bool deoptimize_on_exception) kit->set_all_memory_call(this); } + #ifndef PRODUCT const char* ArrayCopyNode::_kind_names[] = {"arraycopy", "arraycopy, validated arguments", "clone", "oop array clone", "CopyOf", "CopyOfRange"}; @@ -670,6 +671,7 @@ bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTra CallNode* call = NULL; guarantee(c != NULL, "step_over_gc_barrier failed, there must be something to step to."); if (c->is_Region()) { + PhiNode* phi = NULL; for (uint i = 1; i < c->req(); i++) { if (c->in(i) != NULL) { Node* n = c->in(i)->in(0); @@ -677,6 +679,20 @@ bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTra ac = call->isa_ArrayCopy(); assert(c == mb->in(0), "only for clone"); return true; + } else if (n != NULL && n->isa_Region() && + (phi = n->as_Region()->has_phi()) && + phi->in(1)->Opcode() == Op_VectorMaskedStore) { + return true; + } else { + for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { + Node* phi = c->fast_out(i); + if (phi->isa_Phi()) { + assert(phi->in(0) == c, "phi region validation"); + if(phi->in(1) && phi->in(1)->Opcode() == Op_VectorMaskedStore) { + return true; + } + } + } } } } @@ -734,3 +750,16 @@ bool ArrayCopyNode::modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseTransf } return false; } + +// As an optimization, choose optimum vector size for copy length known at compile time. +int ArrayCopyNode::get_partial_inline_vector_lane_count(BasicType type, int con_len) { + int lane_count = ArrayCopyPartialInlineSize/type2aelembytes(type); + if (con_len > 0) { + int size_in_bytes = con_len * type2aelembytes(type); + if (size_in_bytes <= 16) + lane_count = 16/type2aelembytes(type); + else if (size_in_bytes > 16 && size_in_bytes <= 32) + lane_count = 32/type2aelembytes(type); + } + return lane_count; +} diff --git a/src/hotspot/share/opto/arraycopynode.hpp b/src/hotspot/share/opto/arraycopynode.hpp index 4764715a60a18..7e0007628fe21 100644 --- a/src/hotspot/share/opto/arraycopynode.hpp +++ b/src/hotspot/share/opto/arraycopynode.hpp @@ -180,6 +180,9 @@ class ArrayCopyNode : public CallNode { bool has_negative_length_guard() const { return _has_negative_length_guard; } static bool may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase, ArrayCopyNode*& ac); + + static int get_partial_inline_vector_lane_count(BasicType type, int con_len); + bool modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseTransform* phase, bool must_modify) const; #ifndef PRODUCT diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index 668c04f379a46..505f3c40becf1 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -72,6 +72,10 @@ "actual size could be less depending on elements type") \ range(0, max_jint) \ \ + product(intx, ArrayCopyPartialInlineSize, -1, DIAGNOSTIC, \ + "Partial inline size used for array copy acceleration.") \ + range(-1, 64) \ + \ product(bool, AlignVector, true, \ "Perform vector store/load alignment in loop") \ \ diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp index bfaada851ce0e..16f5a0baae514 100644 --- a/src/hotspot/share/opto/callnode.hpp +++ b/src/hotspot/share/opto/callnode.hpp @@ -54,7 +54,6 @@ class BoxLockNode; class LockNode; class UnlockNode; class JVMState; -class OopMap; class State; class StartNode; class MachCallNode; @@ -329,14 +328,12 @@ class SafePointNode : public MultiNode { // A plain safepoint advertises no memory effects (NULL): const TypePtr* adr_type = NULL) : MultiNode( edges ), - _oop_map(NULL), _jvms(jvms), _adr_type(adr_type) { init_class_id(Class_SafePoint); } - OopMap* _oop_map; // Array of OopMap info (8-bit char) for GC JVMState* const _jvms; // Pointer to list of JVM State objects const TypePtr* _adr_type; // What type of memory does this node produce? ReplacedNodes _replaced_nodes; // During parsing: list of pair of nodes from calls to GraphKit::replace_in_map() @@ -349,8 +346,6 @@ class SafePointNode : public MultiNode { void set_jvms(JVMState* s) { *(JVMState**)&_jvms = s; // override const attribute in the accessor } - OopMap *oop_map() const { return _oop_map; } - void set_oop_map(OopMap *om) { _oop_map = om; } private: void verify_input(JVMState* jvms, uint idx) const { diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index e90c24df30806..632074e8596d9 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -371,6 +371,63 @@ bool RegionNode::is_unreachable_region(PhaseGVN *phase) const { return true; // The Region node is unreachable - it is dead. } +bool RegionNode::is_self_loop(Node* n) { + Node_List nstack; + VectorSet visited; + nstack.push(n); + visited.set(n->_idx); + + while(nstack.size()) { + n = nstack.pop(); + for(unsigned i = 1; i < n->req() ; i++) { + Node* in = n->in(i); + if (in == NULL) { + continue; + } + if (visited.test_set(in->_idx)) { + return true; + } else { + nstack.push(in); + visited.set(in->_idx); + } + } + } + + return false; +} + +// If a two input non-loop region has dead input +// edge[s] degenerate any phi node contained within it. +bool RegionNode::try_phi_disintegration(PhaseGVN *phase) { + if (req() != 3 || isa_Loop() || !in(1) || !in(2) || + (!in(1)->is_top() && !in(2)->is_top())) { + return false; + } + + PhiNode* phi = has_unique_phi(); + if (!phi) { + return false; + } + + Node* rep_node = NULL; + PhaseIterGVN *igvn = phase->is_IterGVN(); + if (in(1)->is_top() && !in(2)->is_top()) { + rep_node = phi->in(2); + } else if(in(2)->is_top() && !in(1)->is_top()) { + rep_node = phi->in(1); + } else { + rep_node = phase->C->top(); + } + + // Safety check to avoid dead/self loop creation. + if (is_self_loop(rep_node)) { + return false; + } + + igvn->replace_node(phi, rep_node); + return true; +} + bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) { // Incremental inlining + PhaseStringOpts sometimes produce: // @@ -429,6 +486,10 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (has_phis && try_clean_mem_phi(phase)) { has_phis = false; } + has_phis = (has_phi() != NULL); // Cache result + if (has_phis && try_phi_disintegration(phase)) { + has_phis = false; + } if (!has_phis) { // No Phi users? Nothing merging? for (uint i = 1; i < req()-1; i++) { diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index d2b5555a6b5fd..db565e588c67e 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -95,7 +95,9 @@ class RegionNode : public Node { virtual Node* Identity(PhaseGVN* phase); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const RegMask &out_RegMask() const; + bool is_self_loop(Node* n); bool try_clean_mem_phi(PhaseGVN *phase); + bool try_phi_disintegration(PhaseGVN *phase); bool optimize_trichotomy(PhaseIterGVN* igvn); }; diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp index e03666fb359e0..7faf615ba77b2 100644 --- a/src/hotspot/share/opto/classes.hpp +++ b/src/hotspot/share/opto/classes.hpp @@ -396,6 +396,9 @@ macro(MinReductionV) macro(MaxReductionV) macro(LoadVector) macro(StoreVector) +macro(VectorMaskedLoad) +macro(VectorMaskedStore) +macro(VectorMaskGen) macro(Pack) macro(PackB) macro(PackS) diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index ec98635a248e6..3d759f0e831d2 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -3332,6 +3332,9 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f case Op_LoadVector: case Op_StoreVector: + case Op_VectorMaskGen: + case Op_VectorMaskedLoad: + case Op_VectorMaskedStore: break; case Op_AddReductionVI: diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp index 02a3b7e36baa9..e036ec5c12817 100644 --- a/src/hotspot/share/opto/lcm.cpp +++ b/src/hotspot/share/opto/lcm.cpp @@ -686,6 +686,7 @@ void PhaseCFG::adjust_register_pressure(Node* n, Block* block, intptr_t* recalc_ case Op_StoreP: case Op_StoreN: case Op_StoreVector: + case Op_VectorMaskedStore: case Op_StoreNKlass: for (uint k = 1; k < m->req(); k++) { Node *in = m->in(k); diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index f901206f16a60..cb1d6d6937298 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp @@ -880,17 +880,14 @@ class MachCallNode : public MachSafePointNode { const TypeFunc *_tf; // Function type address _entry_point; // Address of the method being called float _cnt; // Estimate of number of times called - uint _argsize; // Size of argument block on stack const TypeFunc* tf() const { return _tf; } const address entry_point() const { return _entry_point; } const float cnt() const { return _cnt; } - uint argsize() const { return _argsize; } void set_tf(const TypeFunc* tf) { _tf = tf; } void set_entry_point(address p) { _entry_point = p; } void set_cnt(float c) { _cnt = c; } - void set_argsize(int s) { _argsize = s; } MachCallNode() : MachSafePointNode() { init_class_id(Class_MachCall); diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index b82a36ea89101..f5339601b2615 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -280,8 +280,10 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me } else if (in->is_MemBar()) { ArrayCopyNode* ac = NULL; if (ArrayCopyNode::may_modify(tinst, in->as_MemBar(), phase, ac)) { - assert(ac != NULL && ac->is_clonebasic(), "Only basic clone is a non escaping clone"); - return ac; + if (ac != NULL) { + assert(ac->is_clonebasic(), "Only basic clone is a non escaping clone"); + return ac; + } } mem = in->in(TypeFunc::Memory); } else { diff --git a/src/hotspot/share/opto/macro.hpp b/src/hotspot/share/opto/macro.hpp index 7171c05c8660a..3d08c0f20f99f 100644 --- a/src/hotspot/share/opto/macro.hpp +++ b/src/hotspot/share/opto/macro.hpp @@ -126,6 +126,11 @@ class PhaseMacroExpand : public Phase { // helper methods modeled after LibraryCallKit for array copy Node* generate_guard(Node** ctrl, Node* test, RegionNode* region, float true_prob); Node* generate_slow_guard(Node** ctrl, Node* test, RegionNode* region); + + bool generate_partial_inlining_block(Node** ctrl, MergeMemNode** mem, const TypePtr* adr_type, + RegionNode** exit_block, Node** result_memory, Node* length, + Node* src_start, Node* dst_start, BasicType type); + void generate_negative_guard(Node** ctrl, Node* index, RegionNode* region); void generate_limit_guard(Node** ctrl, Node* offset, Node* subseq_length, Node* array_length, RegionNode* region); @@ -174,7 +179,7 @@ class PhaseMacroExpand : public Phase { Node* src, Node* src_offset, Node* dest, Node* dest_offset, Node* copy_length, bool dest_uninitialized); - void generate_unchecked_arraycopy(Node** ctrl, MergeMemNode** mem, + bool generate_unchecked_arraycopy(Node** ctrl, MergeMemNode** mem, const TypePtr* adr_type, BasicType basic_elem_type, bool disjoint_bases, diff --git a/src/hotspot/share/opto/macroArrayCopy.cpp b/src/hotspot/share/opto/macroArrayCopy.cpp index ad2de04092691..121b66cde2070 100644 --- a/src/hotspot/share/opto/macroArrayCopy.cpp +++ b/src/hotspot/share/opto/macroArrayCopy.cpp @@ -27,6 +27,7 @@ #include "opto/arraycopynode.hpp" #include "oops/objArrayKlass.hpp" #include "opto/convertnode.hpp" +#include "opto/vectornode.hpp" #include "opto/graphKit.hpp" #include "opto/macro.hpp" #include "opto/runtime.hpp" @@ -169,6 +170,133 @@ void PhaseMacroExpand::generate_limit_guard(Node** ctrl, Node* offset, Node* sub generate_guard(ctrl, bol_lt, region, PROB_MIN); } +// +// Partial in-lining handling for smaller conjoint/disjoint array copies having +// length(in bytes) less than ArrayCopyPartialInlineSize. +// if (length <= ArrayCopyPartialInlineSize) { +// partial_inlining_block: +// mask = Mask_Gen +// vload = VectorMaskedLoad src , mask +// VectorMaskedStore dst, mask, vload +// } else { +// stub_block: +// callstub array_copy +// } +// exit_block: +// Phi = label partial_inlining_block:mem , label stub_block:mem (filled by caller) +// mem = MergeMem (Phi) +// control = stub_block +// +// Exit_block and associated phi(memory) are partially initialized for partial_in-lining_block +// edges. Remaining edges for exit_block coming from stub_block are connected by the caller +// post stub nodes creation. +// +// Constant copy length operation having size less than ArrayCopyPartialInlineSize prevents +// creation of additional control flow for stub_block and exit_block. +// +// Return true to emit subsequent stub calling code. +// + +bool PhaseMacroExpand::generate_partial_inlining_block(Node** ctrl, MergeMemNode** mem, const TypePtr* adr_type, + RegionNode** exit_block, Node** result_memory, Node* length, + Node* src_start, Node* dst_start, BasicType type) { + const TypePtr *src_adr_type = _igvn.type(src_start)->isa_ptr(); + + Node* orig_mem = *mem; + Node* is_lt64bytes_tp = NULL; + Node* is_lt64bytes_fp = NULL; + + int con_len = -1; + const TypeInt* lty = NULL; + uint shift = exact_log2(type2aelembytes(type)); + if (length->Opcode() == Op_ConvI2L && (lty = _igvn.type(length->in(1))->isa_int()) && lty->is_con()) { + con_len = lty->get_con() << shift; + } else if ((lty = _igvn.type(length)->isa_int()) && lty->is_con()) { + con_len = lty->get_con() << shift; + } + + // Return if copy length is greater than partial inline size limit or + // target does not supports masked load/stores. + int lane_count = ArrayCopyNode::get_partial_inline_vector_lane_count(type, con_len); + if ( con_len > ArrayCopyPartialInlineSize || + !Matcher::match_rule_supported_vector(Op_VectorMaskedLoad, lane_count, type) || + !Matcher::match_rule_supported_vector(Op_VectorMaskedStore, lane_count, type) || + !Matcher::match_rule_supported_vector(Op_VectorMaskGen, lane_count, type)) { + return true; + } + + Node* inline_block = NULL; + // Emit length comparison check for non-constant length. + if (con_len < 0) { + Node* copy_bytes = new LShiftXNode(length, intcon(shift)); + transform_later(copy_bytes); + + Node* cmp_le = new CmpULNode(copy_bytes, longcon(ArrayCopyPartialInlineSize)); + transform_later(cmp_le); + Node* bol_le = new BoolNode(cmp_le, BoolTest::le); + transform_later(bol_le); + is_lt64bytes_tp = generate_guard(ctrl, bol_le, NULL, PROB_FAIR); + is_lt64bytes_fp = *ctrl; + + inline_block = new RegionNode(2); + transform_later(inline_block); + inline_block->init_req(1, is_lt64bytes_tp); + } else { + inline_block = *ctrl; + } + + Node* mask_gen = new VectorMaskGenNode(length, TypeLong::LONG, Type::get_const_basic_type(type)); + transform_later(mask_gen); + + unsigned vec_size = lane_count * type2aelembytes(type); + if (C->max_vector_size() < vec_size) { + C->set_max_vector_size(vec_size); + } + + int alias_idx = C->get_alias_index(src_adr_type); + Node* mm = (*mem)->memory_at(alias_idx); + const TypeVect * vt = TypeVect::make(type, lane_count); + Node* masked_load = new VectorMaskedLoadNode(inline_block, mm, src_start, + src_adr_type, vt, mask_gen); + transform_later(masked_load); + + mm = (*mem)->memory_at(C->get_alias_index(adr_type)); + Node* masked_store = new VectorMaskedStoreNode(inline_block, mm, dst_start, + masked_load, adr_type, mask_gen); + transform_later(masked_store); + + // Stub region is created for non-constant copy length. + if (con_len < 0) { + // Region containing stub calling node. + RegionNode* stub_block = new RegionNode(2); + transform_later(stub_block); + stub_block->init_req(1, is_lt64bytes_fp); + + // Convergence region for inline_block and stub_block. + *exit_block = new RegionNode(3); + transform_later(*exit_block); + (*exit_block)->init_req(1, masked_store); + *result_memory = new PhiNode(*exit_block, Type::MEMORY, adr_type); + transform_later(*result_memory); + (*result_memory)->init_req(1, masked_store); + + *ctrl = stub_block; + return true; + } else { + // Prevent stub call generation for constant length less + // than partial inline size. + uint alias_idx = C->get_alias_index(adr_type); + if (alias_idx != Compile::AliasIdxBot) { + *mem = MergeMemNode::make(*mem); + (*mem)->set_memory_at(alias_idx, masked_store); + } else { + *mem = MergeMemNode::make(masked_store); + } + transform_later(*mem); + return false; + } +} + Node* PhaseMacroExpand::generate_nonpositive_guard(Node** ctrl, Node* index, bool never_negative) { if ((*ctrl)->is_top()) return NULL; @@ -559,16 +687,17 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode* } } + bool is_partial_array_copy = false; if (!(*ctrl)->is_top()) { // Generate the fast path, if possible. Node* local_ctrl = *ctrl; MergeMemNode* local_mem = MergeMemNode::make(mem); transform_later(local_mem); - generate_unchecked_arraycopy(&local_ctrl, &local_mem, - adr_type, copy_type, disjoint_bases, - src, src_offset, dest, dest_offset, - ConvI2X(copy_length), dest_uninitialized); + is_partial_array_copy = generate_unchecked_arraycopy(&local_ctrl, &local_mem, + adr_type, copy_type, disjoint_bases, + src, src_offset, dest, dest_offset, + ConvI2X(copy_length), dest_uninitialized); // Present the results of the fast call. result_region->init_req(fast_path, local_ctrl); @@ -715,13 +844,19 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode* insert_mem_bar(ctrl, &out_mem, Op_MemBarCPUOrder); } + if (is_partial_array_copy) { + assert((*ctrl)->is_Proj(), "MemBar control projection"); + assert((*ctrl)->in(0)->isa_MemBar(), "MemBar node"); + (*ctrl)->in(0)->isa_MemBar()->set_after_partial_array_copy(); + } + _igvn.replace_node(_memproj_fallthrough, out_mem); _igvn.replace_node(_ioproj_fallthrough, *io); _igvn.replace_node(_fallthroughcatchproj, *ctrl); #ifdef ASSERT const TypeOopPtr* dest_t = _igvn.type(dest)->is_oopptr(); - if (dest_t->is_known_instance()) { + if (dest_t->is_known_instance() && false == is_partial_array_copy) { ArrayCopyNode* ac = NULL; assert(ArrayCopyNode::may_modify(dest_t, (*ctrl)->in(0)->as_MemBar(), &_igvn, ac), "dependency on arraycopy lost"); assert(ac == NULL, "no arraycopy anymore"); @@ -1053,14 +1188,14 @@ Node* PhaseMacroExpand::generate_generic_arraycopy(Node** ctrl, MergeMemNode** m } // Helper function; generates the fast out-of-line call to an arraycopy stub. -void PhaseMacroExpand::generate_unchecked_arraycopy(Node** ctrl, MergeMemNode** mem, +bool PhaseMacroExpand::generate_unchecked_arraycopy(Node** ctrl, MergeMemNode** mem, const TypePtr* adr_type, BasicType basic_elem_type, bool disjoint_bases, Node* src, Node* src_offset, Node* dest, Node* dest_offset, Node* copy_length, bool dest_uninitialized) { - if ((*ctrl)->is_top()) return; + if ((*ctrl)->is_top()) return false; Node* src_start = src; Node* dest_start = dest; @@ -1075,11 +1210,43 @@ void PhaseMacroExpand::generate_unchecked_arraycopy(Node** ctrl, MergeMemNode** basictype2arraycopy(basic_elem_type, src_offset, dest_offset, disjoint_bases, copyfunc_name, dest_uninitialized); - const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type(); - Node* call = make_leaf_call(*ctrl, *mem, call_type, copyfunc_addr, copyfunc_name, adr_type, - src_start, dest_start, copy_length XTOP); + Node* result_memory = NULL; + RegionNode* exit_block = NULL; + bool gen_stub_call = true; + if (ArrayCopyPartialInlineSize > 0 && is_subword_type(basic_elem_type) && + Matcher::vector_width_in_bytes(basic_elem_type) >= 32) { + gen_stub_call = generate_partial_inlining_block(ctrl, mem, adr_type, &exit_block, &result_memory, + copy_length, src_start, dest_start, basic_elem_type); + } - finish_arraycopy_call(call, ctrl, mem, adr_type); + if (gen_stub_call) { + const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type(); + Node* call = make_leaf_call(*ctrl, *mem, call_type, copyfunc_addr, copyfunc_name, adr_type, + src_start, dest_start, copy_length XTOP); + + finish_arraycopy_call(call, ctrl, mem, adr_type); + } + + // Connecting remaining edges for exit_block coming from stub_block. + if (exit_block) { + exit_block->init_req(2, *ctrl); + + // Memory edge corresponding to stub_region. + result_memory->init_req(2, *mem); + + uint alias_idx = C->get_alias_index(adr_type); + if (alias_idx != Compile::AliasIdxBot) { + *mem = MergeMemNode::make(*mem); + (*mem)->set_memory_at(alias_idx, result_memory); + } else { + *mem = MergeMemNode::make(result_memory); + } + transform_later(*mem); + *ctrl = exit_block; + return true; + } + return false; + } } void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) { diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp index 2bbd5a28c8e8a..d6d11e9a21f3e 100644 --- a/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp @@ -1305,10 +1305,6 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) { if (OptoReg::is_valid(reg2)) rm->Insert( reg2 ); } // End of for all arguments - - // Compute number of stack slots needed to restore stack in case of - // Pascal-style argument popping. - mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area; } // Compute the max stack slot killed by any call. These will not be @@ -1346,9 +1342,6 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) { assert((mcall == NULL) || (mcall->jvms() == NULL) || (mcall->jvms()->debug_start() + mcall->_jvmadj == mcall->tf()->domain()->cnt()), ""); - // Move the OopMap - msfpt->_oop_map = sfpt->_oop_map; - // Add additional edges. if (msfpt->mach_constant_base_node_input() != (uint)-1 && !msfpt->is_MachCallLeaf()) { // For these calls we can not add MachConstantBase in expand(), as the @@ -2151,6 +2144,7 @@ bool Matcher::find_shared_visit(MStack& mstack, Node* n, uint opcode, bool& mem_ case Op_FmaVD: case Op_FmaVF: case Op_MacroLogicV: + case Op_VectorMaskedLoad: set_shared(n); // Force result into register (it will be anyways) break; case Op_ConP: { // Convert pointers above the centerline to NUL @@ -2253,6 +2247,12 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) { n->del_req(3); break; } + case Op_VectorMaskedStore: { + Node* pair = new BinaryNode(n->in(3), n->in(4)); + n->set_req(3, pair); + n->del_req(4); + break; + } case Op_LoopLimit: { Node* pair1 = new BinaryNode(n->in(1), n->in(2)); n->set_req(1, pair1); diff --git a/src/hotspot/share/opto/matcher.hpp b/src/hotspot/share/opto/matcher.hpp index 9038497aeb58c..c211557eacbe9 100644 --- a/src/hotspot/share/opto/matcher.hpp +++ b/src/hotspot/share/opto/matcher.hpp @@ -415,12 +415,12 @@ class Matcher : public PhaseTransform { // The Method-klass-holder may be passed in the inline_cache_reg // and then expanded into the inline_cache_reg and a method_ptr register - static OptoReg::Name interpreter_method_oop_reg(); - static int interpreter_method_oop_reg_encode(); + static OptoReg::Name interpreter_method_reg(); + static int interpreter_method_reg_encode(); - static OptoReg::Name compiler_method_oop_reg(); - static const RegMask &compiler_method_oop_reg_mask(); - static int compiler_method_oop_reg_encode(); + static OptoReg::Name compiler_method_reg(); + static const RegMask &compiler_method_reg_mask(); + static int compiler_method_reg_encode(); // Interpreter's Frame Pointer Register static OptoReg::Name interpreter_frame_pointer_reg(); @@ -437,9 +437,6 @@ class Matcher : public PhaseTransform { OptoReg::Name c_frame_pointer() const; static RegMask c_frame_ptr_mask; - // !!!!! Special stuff for building ScopeDescs - virtual int regnum_to_fpu_offset(int regnum); - // Is this branch offset small enough to be addressed by a short branch? bool is_short_branch_offset(int rule, int br_size, int offset); diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 4ff587c057bf4..cebeef2e742b1 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -641,7 +641,8 @@ Node* MemNode::find_previous_store(PhaseTransform* phase) { } if (st_offset != offset && st_offset != Type::OffsetBot) { - const int MAX_STORE = BytesPerLong; + const int MAX_STORE = MAX2(BytesPerLong, (int)MaxVectorSize); + assert(mem->as_Store()->memory_size() <= MAX_STORE, ""); if (st_offset >= offset + size_in_bytes || st_offset <= offset - MAX_STORE || st_offset <= offset - mem->as_Store()->memory_size()) { @@ -3744,7 +3745,8 @@ intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseGVN* phase, bool int InitializeNode::captured_store_insertion_point(intptr_t start, int size_in_bytes, PhaseTransform* phase) { - const int FAIL = 0, MAX_STORE = BytesPerLong; + const int FAIL = 0, MAX_STORE = MAX2(BytesPerLong, (int)MaxVectorSize); + if (is_complete()) return FAIL; // arraycopy got here first; punt diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp index 413c64e760467..8400129de30bd 100644 --- a/src/hotspot/share/opto/memnode.hpp +++ b/src/hotspot/share/opto/memnode.hpp @@ -1184,7 +1184,8 @@ class MemBarNode: public MultiNode { TrailingStore, LeadingStore, TrailingLoadStore, - LeadingLoadStore + LeadingLoadStore, + AfterPartialArrayCopy } _kind; #ifdef ASSERT @@ -1221,6 +1222,8 @@ class MemBarNode: public MultiNode { bool trailing() const { return _kind == TrailingLoad || _kind == TrailingStore || _kind == TrailingLoadStore; } bool leading() const { return _kind == LeadingStore || _kind == LeadingLoadStore; } bool standalone() const { return _kind == Standalone; } + void set_after_partial_array_copy() { _kind = AfterPartialArrayCopy; } + bool after_partial_array_copy() const { return _kind == AfterPartialArrayCopy; } static void set_store_pair(MemBarNode* leading, MemBarNode* trailing); static void set_load_store_pair(MemBarNode* leading, MemBarNode* trailing); diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 5856cfb8df757..e584685b3cb44 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -152,7 +152,9 @@ class TypeNode; class UnlockNode; class VectorNode; class LoadVectorNode; +class VectorMaskedLoad; class StoreVectorNode; +class VectorMaskedStore; class VectorSet; typedef void (*NFunc)(Node&,void*); extern "C" { @@ -689,8 +691,10 @@ class Node { DEFINE_CLASS_ID(Mem, Node, 4) DEFINE_CLASS_ID(Load, Mem, 0) DEFINE_CLASS_ID(LoadVector, Load, 0) + DEFINE_CLASS_ID(VectorMaskedLoad, LoadVector, 0) DEFINE_CLASS_ID(Store, Mem, 1) DEFINE_CLASS_ID(StoreVector, Store, 0) + DEFINE_CLASS_ID(VectorMaskedStore, StoreVector, 0) DEFINE_CLASS_ID(LoadStore, Mem, 2) DEFINE_CLASS_ID(LoadStoreConditional, LoadStore, 0) DEFINE_CLASS_ID(CompareAndSwap, LoadStoreConditional, 0) diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index d94f3a5329ad2..78d82485f467a 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -677,6 +677,56 @@ StoreVectorNode* StoreVectorNode::make(int opc, Node* ctl, Node* mem, return new StoreVectorNode(ctl, mem, adr, atyp, val); } +VectorMaskedLoadNode* make(int opc, Node* ctl, Node* mem, Node* src, + const TypePtr* atype, const TypeVect* vt, + Node* mask) { + return new VectorMaskedLoadNode(ctl, mem, src, atype, vt, mask); +} + +VectorMaskedStoreNode* make(int opc, Node* ctl, Node* mem, Node* dst, + Node* src, const TypePtr* atype, Node* mask) { + return new VectorMaskedStoreNode(ctl, mem, dst, src, atype, mask); +} + +VectorMaskGenNode* make(int opc, Node* src, const Type* ty, const Type* ety) { + return new VectorMaskGenNode(src, ty, ety); +} + +Node* VectorMaskedLoadNode::Ideal(PhaseGVN* phase, bool can_reshape) { + Node* mask_len = in(3)->in(1); + const TypeLong* ty = phase->type(mask_len)->isa_long(); + if (ty && ty->is_con()) { + BasicType mask_bt = ((VectorMaskGenNode*)in(3))->get_elem_type()->array_element_basic_type(); + uint load_sz = type2aelembytes(mask_bt) * ty->get_con(); + if ( load_sz == 32 || load_sz == 64) { + assert(load_sz == 32 || MaxVectorSize > 32, "Unexpected load size"); + Node* ctr = in(MemNode::Control); + Node* mem = in(MemNode::Memory); + Node* adr = in(MemNode::Address); + return phase->transform(new LoadVectorNode(ctr, mem, adr, adr_type(), vect_type())); + } + } + return NULL; +} + +Node* VectorMaskedStoreNode::Ideal(PhaseGVN* phase, bool can_reshape) { + Node* mask_len = in(4)->in(1); + const TypeLong* ty = phase->type(mask_len)->isa_long(); + if (ty && ty->is_con()) { + BasicType mask_bt = ((VectorMaskGenNode*)in(4))->get_elem_type()->array_element_basic_type(); + uint load_sz = type2aelembytes(mask_bt) * ty->get_con(); + if ( load_sz == 32 || load_sz == 64) { + assert(load_sz == 32 || MaxVectorSize > 32, "Unexpected store size"); + Node* ctr = in(MemNode::Control); + Node* mem = in(MemNode::Memory); + Node* adr = in(MemNode::Address); + Node* val = in(MemNode::ValueIn); + return phase->transform(new StoreVectorNode(ctr, mem, adr, adr_type(), val)); + } + } + return NULL; +} + // Extract a scalar element of vector. Node* ExtractNode::make(Node* v, uint position, BasicType bt) { assert((int)position < Matcher::max_vector_size(bt), "pos in range"); diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 570f0645a016d..d54611b4841a4 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -749,6 +749,63 @@ class StoreVectorNode : public StoreNode { }; +class VectorMaskedStoreNode : public StoreVectorNode { + public: + VectorMaskedStoreNode(Node* c, Node* mem, Node* dst, Node* src, const TypePtr* at, Node* mask) + : StoreVectorNode(c, mem, dst, at, src) { + assert(mask->bottom_type()->is_long(), "sanity"); + init_class_id(Class_StoreVector); + set_mismatched_access(); + add_req(mask); + } + + virtual int Opcode() const; + + virtual uint match_edge(uint idx) const { + return idx > 1; + } + Node* Ideal(PhaseGVN* phase, bool can_reshape); + + static VectorMaskedStoreNode* make(int opc, Node* ctl, Node* mem, Node* dst, Node* src, + const TypePtr* atype, Node* mask); +}; + +class VectorMaskedLoadNode : public LoadVectorNode { + public: + VectorMaskedLoadNode(Node* c, Node* mem, Node* src, const TypePtr* at, const TypeVect* vt, Node* mask) + : LoadVectorNode(c, mem, src, at, vt) { + assert(mask->bottom_type()->is_long(), "sanity"); + init_class_id(Class_LoadVector); + set_mismatched_access(); + add_req(mask); + } + + virtual int Opcode() const; + + virtual uint match_edge(uint idx) const { + return idx > 1; + } + Node* Ideal(PhaseGVN* phase, bool can_reshape); + + static VectorMaskedLoadNode* make(int opc, Node* ctl, Node* mem, Node* src, + const TypePtr* atype, const TypeVect* vt, + Node* mask); +}; + +class VectorMaskGenNode : public TypeNode { + public: + VectorMaskGenNode(Node* src, const Type* ty, const Type* ety): TypeNode(ty, 2), _elemType(ety) { + init_req(1, src); + } + + virtual int Opcode() const; + const Type* get_elem_type() { return _elemType;} + + static VectorMaskGenNode* make(int opc, Node* src, const Type* ty, const Type* ety); + private: + const Type* _elemType; +}; + //=========================Promote_Scalar_to_Vector============================ //------------------------------ReplicateBNode--------------------------------- diff --git a/src/hotspot/share/runtime/flags/jvmFlagLookup.cpp b/src/hotspot/share/runtime/flags/jvmFlagLookup.cpp index 8f628987f5696..e8d5796725110 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagLookup.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlagLookup.cpp @@ -30,9 +30,9 @@ #define DO_FLAG(type, name,...) DO_HASH(FLAG_MEMBER_ENUM(name), XSTR(name)) #define DO_HASH(flag_enum, flag_name) { \ - unsigned int hash = hash_code(flag_name); \ + u2 hash = hash_code(flag_name); \ int bucket_index = (int)(hash % NUM_BUCKETS); \ - _hashes[flag_enum] = (u2)(hash); \ + _hashes[flag_enum] = hash; \ _table[flag_enum] = _buckets[bucket_index]; \ _buckets[bucket_index] = (short)flag_enum; \ } @@ -54,10 +54,10 @@ constexpr JVMFlagLookup::JVMFlagLookup() : _buckets(), _table(), _hashes() { constexpr JVMFlagLookup _flag_lookup_table; JVMFlag* JVMFlagLookup::find_impl(const char* name, size_t length) const { - unsigned int hash = hash_code(name, length); + u2 hash = hash_code(name, length); int bucket_index = (int)(hash % NUM_BUCKETS); for (int flag_enum = _buckets[bucket_index]; flag_enum >= 0; ) { - if (_hashes[flag_enum] == (u2)hash) { + if (_hashes[flag_enum] == hash) { JVMFlag* flag = JVMFlag::flags + flag_enum; if (strncmp(name, flag->_name, length) == 0) { // We know flag->_name has at least bytes. diff --git a/src/hotspot/share/runtime/flags/jvmFlagLookup.hpp b/src/hotspot/share/runtime/flags/jvmFlagLookup.hpp index 128025b8e2242..3ac31b0e61e45 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagLookup.hpp +++ b/src/hotspot/share/runtime/flags/jvmFlagLookup.hpp @@ -51,14 +51,14 @@ class JVMFlagLookup { // This is executed at build-time only, so it doesn't matter if we walk // the string twice. - static constexpr unsigned int hash_code(const char* s) { + static constexpr u2 hash_code(const char* s) { return hash_code(s, string_len(s)); } - static constexpr unsigned int hash_code(const char* s, size_t len) { - unsigned int h = 0; + static constexpr u2 hash_code(const char* s, size_t len) { + u2 h = 0; while (len -- > 0) { - h = 31*h + (unsigned int) *s; + h = (u2)(31*h + (u2) *s); s++; } return h; diff --git a/src/hotspot/share/runtime/globals_shared.hpp b/src/hotspot/share/runtime/globals_shared.hpp index 75c78bd5be3f2..36dc94097623c 100644 --- a/src/hotspot/share/runtime/globals_shared.hpp +++ b/src/hotspot/share/runtime/globals_shared.hpp @@ -37,7 +37,7 @@ // parts of the memory system may require additional alignment // and are responsible for those alignments. #ifdef _LP64 -#define ScaleForWordSize(x) align_down_((x) * 13 / 10, HeapWordSize) +#define ScaleForWordSize(x) align_down((x) * 13 / 10, HeapWordSize) #else #define ScaleForWordSize(x) (x) #endif diff --git a/src/hotspot/share/runtime/timer.cpp b/src/hotspot/share/runtime/timer.cpp index aa64cc2bff83b..d810f4524dbd8 100644 --- a/src/hotspot/share/runtime/timer.cpp +++ b/src/hotspot/share/runtime/timer.cpp @@ -42,6 +42,11 @@ jlong TimeHelper::millis_to_counter(jlong millis) { return millis * freq; } +jlong TimeHelper::micros_to_counter(jlong micros) { + jlong freq = os::elapsed_frequency() / MICROUNITS; + return micros * freq; +} + elapsedTimer::elapsedTimer(jlong time, jlong timeUnitsPerSecond) { _active = false; jlong osTimeUnitsPerSecond = os::elapsed_frequency(); diff --git a/src/hotspot/share/runtime/timer.hpp b/src/hotspot/share/runtime/timer.hpp index 5f9cb17e6f2cc..9e29072a1241b 100644 --- a/src/hotspot/share/runtime/timer.hpp +++ b/src/hotspot/share/runtime/timer.hpp @@ -77,6 +77,7 @@ class TimeHelper { static double counter_to_seconds(jlong counter); static double counter_to_millis(jlong counter); static jlong millis_to_counter(jlong millis); + static jlong micros_to_counter(jlong micros); }; #endif // SHARE_RUNTIME_TIMER_HPP diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 669aeff7f1c63..d69954a44ce83 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -338,9 +338,9 @@ typedef HashtableEntry KlassHashtableEntry; volatile_nonstatic_field(ConstantPoolCacheEntry, _f2, intx) \ volatile_nonstatic_field(ConstantPoolCacheEntry, _flags, intx) \ \ - /********************************/ \ - /* MethodOop-related structures */ \ - /********************************/ \ + /*****************************/ \ + /* Method related structures */ \ + /*****************************/ \ \ nonstatic_field(CheckedExceptionElement, class_cp_index, u2) \ nonstatic_field(LocalVariableTableElement, start_bci, u2) \ @@ -1284,9 +1284,9 @@ typedef HashtableEntry KlassHashtableEntry; \ declare_toplevel_type(OopHandle) \ \ - /*************************************/ \ - /* MethodOop-related data structures */ \ - /*************************************/ \ + /**********************************/ \ + /* Method related data structures */ \ + /**********************************/ \ \ declare_toplevel_type(CheckedExceptionElement) \ declare_toplevel_type(LocalVariableTableElement) \ diff --git a/src/hotspot/share/services/nmtCommon.hpp b/src/hotspot/share/services/nmtCommon.hpp index 7fb7975567bb3..ea2f396fa8bb0 100644 --- a/src/hotspot/share/services/nmtCommon.hpp +++ b/src/hotspot/share/services/nmtCommon.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "utilities/align.hpp" #include "utilities/globalDefinitions.hpp" -#define CALC_OBJ_SIZE_IN_TYPE(obj, type) (align_up_(sizeof(obj), sizeof(type))/sizeof(type)) +#define CALC_OBJ_SIZE_IN_TYPE(obj, type) (align_up(sizeof(obj), sizeof(type))/sizeof(type)) // Native memory tracking level enum NMT_TrackingLevel { diff --git a/src/hotspot/share/utilities/align.hpp b/src/hotspot/share/utilities/align.hpp index 50c9808c7fade..7c7a4f67bc584 100644 --- a/src/hotspot/share/utilities/align.hpp +++ b/src/hotspot/share/utilities/align.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,65 +25,64 @@ #ifndef SHARE_UTILITIES_ALIGN_HPP #define SHARE_UTILITIES_ALIGN_HPP +#include "metaprogramming/enableIf.hpp" +#include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/powerOfTwo.hpp" - -// Signed variants of alignment helpers. There are two versions of each, a macro -// for use in places like enum definitions that require compile-time constant -// expressions and a function for all other places so as to get type checking. - -// Using '(what) & ~align_mask(alignment)' to align 'what' down is broken when -// 'alignment' is an unsigned int and 'what' is a wider type. The & operation -// will widen the inverted mask, and not sign extend it, leading to a mask with -// zeros in the most significant bits. The use of align_mask_widened() solves -// this problem. -#define align_mask(alignment) ((alignment) - 1) -#define widen_to_type_of(what, type_carrier) (true ? (what) : (type_carrier)) -#define align_mask_widened(alignment, type_carrier) widen_to_type_of(align_mask(alignment), (type_carrier)) - -#define align_down_(size, alignment) ((size) & ~align_mask_widened((alignment), (size))) - -#define align_up_(size, alignment) (align_down_((size) + align_mask(alignment), (alignment))) - -#define is_aligned_(size, alignment) (((size) & align_mask(alignment)) == 0) - -// Helpers to align sizes and check for alignment - -template -inline T align_up(T size, A alignment) { - assert(is_power_of_2(alignment), "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment); - - T ret = align_up_(size, alignment); - assert(is_aligned_(ret, alignment), "must be aligned: " UINT64_FORMAT, (uint64_t)ret); - - return ret; +#include + +// Compute mask to use for aligning to or testing alignment. +// The alignment must be a power of 2. Returns alignment - 1, which is +// a mask with all bits set below alignment's single bit. +template::value)> +static constexpr T alignment_mask(T alignment) { + assert(is_power_of_2(alignment), + "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment); + return alignment - 1; } -template -inline T align_down(T size, A alignment) { - assert(is_power_of_2(alignment), "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment); +// Some "integral" constant alignments are defined via enum. +template::value)> +static constexpr auto alignment_mask(T alignment) { + return alignment_mask(static_cast>(alignment)); +} - T ret = align_down_(size, alignment); - assert(is_aligned_(ret, alignment), "must be aligned: " UINT64_FORMAT, (uint64_t)ret); +// Align integers and check for alignment. +// The is_integral filtering here is not for disambiguation with the T* +// overloads; if those match then they are a better match. Rather, the +// is_integral filtering is to prevent back-sliding on the use of enums +// as "integral" constants that need aligning. - return ret; +template::value)> +constexpr bool is_aligned(T size, A alignment) { + return (size & alignment_mask(alignment)) == 0; } -template -inline bool is_aligned(T size, A alignment) { - assert(is_power_of_2(alignment), "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment); +template::value)> +constexpr T align_down(T size, A alignment) { + // Convert mask to T before logical_not. Otherwise, if alignment is unsigned + // and smaller than T, the result of the logical_not will be zero-extended + // by integral promotion, and upper bits of size will be discarded. + T result = size & ~T(alignment_mask(alignment)); + assert(is_aligned(result, alignment), + "must be aligned: " UINT64_FORMAT, (uint64_t)result); + return result; +} - return is_aligned_(size, alignment); +template::value)> +constexpr T align_up(T size, A alignment) { + T adjusted = size + alignment_mask(alignment); + return align_down(adjusted, alignment); } // Align down with a lower bound. If the aligning results in 0, return 'alignment'. template -inline T align_down_bounded(T size, A alignment) { - A aligned_size = align_down(size, alignment); - return aligned_size > 0 ? aligned_size : alignment; +constexpr T align_down_bounded(T size, A alignment) { + T aligned_size = align_down(size, alignment); + return (aligned_size > 0) ? aligned_size : T(alignment); } -// Helpers to align pointers and check for alignment. +// Align pointers and check for alignment. template inline T* align_up(T* ptr, A alignment) { @@ -122,7 +121,7 @@ inline bool is_object_aligned(const void* addr) { // Pad out certain offsets to jlong alignment, in HeapWord units. template -inline T align_object_offset(T offset) { +constexpr T align_object_offset(T offset) { return align_up(offset, HeapWordsPerLong); } diff --git a/src/hotspot/share/utilities/powerOfTwo.hpp b/src/hotspot/share/utilities/powerOfTwo.hpp index a8cc68fe506dc..fb96b1242f938 100644 --- a/src/hotspot/share/utilities/powerOfTwo.hpp +++ b/src/hotspot/share/utilities/powerOfTwo.hpp @@ -26,16 +26,17 @@ #define SHARE_UTILITIES_POWEROFTWO_HPP #include "metaprogramming/enableIf.hpp" -#include "metaprogramming/isIntegral.hpp" -#include "metaprogramming/isSigned.hpp" #include "utilities/count_leading_zeros.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" +#include +#include // Power of two convenience library. -template -bool is_power_of_2(T x) { +// Returns true iff there exists integer i such that (T(1) << i) == x. +template ::value)> +constexpr bool is_power_of_2(T x) { return (x > T(0)) && ((x & (x - 1)) == T(0)); } @@ -55,94 +56,36 @@ inline int exact_log2_long(jlong x) { return bits - count_leading_zeros(x) - 1; } -// Round down to the closest power of two greater to or equal to the given -// value. - -// Signed version: 0 is an invalid input, negative values are invalid -template -inline typename EnableIf::value, T>::type round_down_power_of_2(T value) { - STATIC_ASSERT(IsIntegral::value); +// Round down to the closest power of two less than or equal to the given value. +// precondition: value > 0. +template::value)> +inline T round_down_power_of_2(T value) { assert(value > 0, "Invalid value"); uint32_t lz = count_leading_zeros(value); - assert(lz < sizeof(T) * BitsPerByte, "Sanity"); - return T(1) << (sizeof(T) * BitsPerByte - 1 - lz); -} - -// Unsigned version: 0 is an invalid input -template -inline typename EnableIf::value, T>::type round_down_power_of_2(T value) { - STATIC_ASSERT(IsIntegral::value); - assert(value != 0, "Invalid value"); - uint32_t lz = count_leading_zeros(value); - assert(lz < sizeof(T) * BitsPerByte, "Sanity"); return T(1) << (sizeof(T) * BitsPerByte - 1 - lz); } -// Round up to the closest power of two greater to or equal to -// the given value. - -// Signed version: 0 is an invalid input, negative values are invalid, -// overflows with assert if value is larger than 2^30 or 2^62 for 32- and -// 64-bit integers, respectively -template -inline typename EnableIf::value, T>::type round_up_power_of_2(T value) { - STATIC_ASSERT(IsIntegral::value); - STATIC_ASSERT(IsSigned::value); +// Round up to the closest power of two greater to or equal to the given value. +// precondition: value > 0. +// precondition: value <= maximum power of two representable by T. +template::value)> +inline T round_up_power_of_2(T value) { assert(value > 0, "Invalid value"); + const T max_value = std::numeric_limits::max(); + assert(value <= (max_value - (max_value >> 1)), "Overflow"); if (is_power_of_2(value)) { return value; } uint32_t lz = count_leading_zeros(value); - assert(lz < sizeof(T) * BitsPerByte, "Sanity"); - assert(lz > 1, "Will overflow"); - return T(1) << (sizeof(T) * BitsPerByte - lz); -} - -// Unsigned version: 0 is an invalid input, overflows with assert if value -// is larger than 2^31 or 2^63 for 32- and 64-bit integers, respectively -template -inline typename EnableIf::value, T>::type round_up_power_of_2(T value) { - STATIC_ASSERT(IsIntegral::value); - STATIC_ASSERT(!IsSigned::value); - assert(value != 0, "Invalid value"); - if (is_power_of_2(value)) { - return value; - } - uint32_t lz = count_leading_zeros(value); - assert(lz < sizeof(T) * BitsPerByte, "Sanity"); - assert(lz > 0, "Will overflow"); return T(1) << (sizeof(T) * BitsPerByte - lz); } -// Helper function to get the maximum positive value. Implemented here -// since using std::numeric_limits::max() seems problematic on some -// platforms. - -template T max_value() { - if (IsSigned::value) { - // Highest positive power of two expressible in the type - uint64_t val = static_cast(1) << (sizeof(T) * BitsPerByte - 2); - // Fill lower bits with ones - val |= val >> 1; - val |= val >> 2; - val |= val >> 4; - if (sizeof(T) >= 2) val |= val >> 8; - if (sizeof(T) >= 4) val |= val >> 16; - if (sizeof(T) == 8) val |= val >> 32; - return (T)val; - } else { - return ~(static_cast(0)); - } -} - // Calculate the next power of two greater than the given value. - -// Accepts 0 (returns 1), overflows with assert if value is larger than -// or equal to 2^31 (signed: 2^30) or 2^63 (signed: 2^62), for 32- -// and 64-bit integers, respectively -template +// precondition: if signed, value >= 0. +// precondition: value < maximum power of two representable by T. +template ::value)> inline T next_power_of_2(T value) { - assert(value != max_value(), "Overflow"); + assert(value < std::numeric_limits::max(), "Overflow"); return round_up_power_of_2(value + 1); } diff --git a/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java b/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java index 109328d454980..2a09965cf3e87 100644 --- a/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java +++ b/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,6 +108,34 @@ public class MGF1ParameterSpec implements AlgorithmParameterSpec { public static final MGF1ParameterSpec SHA512_256 = new MGF1ParameterSpec("SHA-512/256"); + /** + * The MGF1ParameterSpec which uses SHA3-224 message digest + * @since 16 + */ + public static final MGF1ParameterSpec SHA3_224 = + new MGF1ParameterSpec("SHA3-224"); + + /** + * The MGF1ParameterSpec which uses SHA3-256 message digest + * @since 16 + */ + public static final MGF1ParameterSpec SHA3_256 = + new MGF1ParameterSpec("SHA3-256"); + + /** + * The MGF1ParameterSpec which uses SHA3-384 message digest + * @since 16 + */ + public static final MGF1ParameterSpec SHA3_384 = + new MGF1ParameterSpec("SHA3-384"); + + /** + * The MGF1ParameterSpec which uses SHA3-512 message digest + * @since 16 + */ + public static final MGF1ParameterSpec SHA3_512 = + new MGF1ParameterSpec("SHA3-512"); + private String mdName; /** diff --git a/src/java.base/share/classes/java/util/Calendar.java b/src/java.base/share/classes/java/util/Calendar.java index 0b0974843f335..5d3da1a1b5042 100644 --- a/src/java.base/share/classes/java/util/Calendar.java +++ b/src/java.base/share/classes/java/util/Calendar.java @@ -1796,8 +1796,10 @@ public final Date getTime() { * @param date the given Date. * @see #getTime() * @see #setTimeInMillis(long) + * @throws NullPointerException if {@code date} is {@code null} */ public final void setTime(Date date) { + Objects.requireNonNull(date, "date must not be null"); setTimeInMillis(date.getTime()); } diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java index f896322534897..c73c52e15d866 100644 --- a/src/java.base/share/classes/sun/net/www/ParseUtil.java +++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * 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,10 +34,10 @@ import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; -import sun.nio.cs.ThreadLocalCoders; import sun.nio.cs.UTF_8; /** @@ -177,9 +177,9 @@ public static String decode(String s) { StringBuilder sb = new StringBuilder(n); ByteBuffer bb = ByteBuffer.allocate(n); CharBuffer cb = CharBuffer.allocate(n); - CharsetDecoder dec = ThreadLocalCoders.decoderFor(UTF_8.INSTANCE) - .onMalformedInput(CodingErrorAction.REPORT) - .onUnmappableCharacter(CodingErrorAction.REPORT); + CharsetDecoder dec = UTF_8.INSTANCE.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); char c = s.charAt(0); for (int i = 0; i < n;) { @@ -451,6 +451,7 @@ private static void appendFragment(StringBuilder sb, String fragment) { private static String quote(String s, long lowMask, long highMask) { int n = s.length(); StringBuilder sb = null; + CharsetEncoder encoder = null; boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); @@ -468,11 +469,14 @@ private static String quote(String s, long lowMask, long highMask) { } else if (allowNonASCII && (Character.isSpaceChar(c) || Character.isISOControl(c))) { + if (encoder == null) { + encoder = UTF_8.INSTANCE.newEncoder(); + } if (sb == null) { sb = new StringBuilder(); sb.append(s, 0, i); } - appendEncoded(sb, c); + appendEncoded(encoder, sb, c); } else { if (sb != null) sb.append(c); @@ -494,11 +498,11 @@ && match(s.charAt(pos + 1), L_HEX, H_HEX) && match(s.charAt(pos + 2), L_HEX, H_HEX); } - private static void appendEncoded(StringBuilder sb, char c) { + private static void appendEncoded(CharsetEncoder encoder, + StringBuilder sb, char c) { ByteBuffer bb = null; try { - bb = ThreadLocalCoders.encoderFor(UTF_8.INSTANCE) - .encode(CharBuffer.wrap("" + c)); + bb = encoder.encode(CharBuffer.wrap("" + c)); } catch (CharacterCodingException x) { assert false; } diff --git a/src/java.base/share/classes/sun/security/provider/DSA.java b/src/java.base/share/classes/sun/security/provider/DSA.java index b0d06c55727a3..a7c42a1f35a0e 100644 --- a/src/java.base/share/classes/sun/security/provider/DSA.java +++ b/src/java.base/share/classes/sun/security/provider/DSA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,11 +47,16 @@ * Standards and Technology (NIST), using SHA digest algorithms * from FIPS180-3. * - * This file contains both the signature implementation for the - * commonly used SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA, - * as well as RawDSA, used by TLS among others. RawDSA expects - * the 20 byte SHA-1 digest as input via update rather than the - * original data like other signature implementations. + * This file contains the signature implementation for the + * SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA, SHA384withDSA, + * SHA512withDSA, SHA3-224withDSA, SHA3-256withDSA, SHA3-384withDSA, + * SHA3-512withDSA, as well as RawDSA, used by TLS among others. + * RawDSA expects the 20 byte SHA-1 digest as input via update rather + * than the original data like other signature implementations. + * + * In addition, IEEE P1363 signature format is supported. The + * corresponding implementation is registered under inP1363Format, + * e.g. SHA256withDSAinP1363Format. * * @author Benjamin Renaud * @@ -504,6 +509,78 @@ public String toString() { return printable; } + /** + * SHA3-224withDSA implementation. + */ + public static final class SHA3_224withDSA extends DSA { + public SHA3_224withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-224")); + } + } + + /** + * SHA3-224withDSA implementation that uses the IEEE P1363 format. + */ + public static final class SHA3_224withDSAinP1363Format extends DSA { + public SHA3_224withDSAinP1363Format() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-224"), true); + } + } + + /** + * Standard SHA3-256withDSA implementation. + */ + public static final class SHA3_256withDSA extends DSA { + public SHA3_256withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-256")); + } + } + + /** + * Standard SHA3-256withDSA implementation that uses the IEEE P1363 format. + */ + public static final class SHA3_256withDSAinP1363Format extends DSA { + public SHA3_256withDSAinP1363Format() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-256"), true); + } + } + + /** + * Standard SHA3-384withDSA implementation. + */ + public static final class SHA3_384withDSA extends DSA { + public SHA3_384withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-384")); + } + } + + /** + * Standard SHA3-384withDSA implementation that uses the IEEE P1363 format. + */ + public static final class SHA3_384withDSAinP1363Format extends DSA { + public SHA3_384withDSAinP1363Format() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-384"), true); + } + } + + /** + * Standard SHA3-512withDSA implementation. + */ + public static final class SHA3_512withDSA extends DSA { + public SHA3_512withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-512")); + } + } + + /** + * Standard SHA3-512withDSA implementation that uses the IEEE P1363 format. + */ + public static final class SHA3_512withDSAinP1363Format extends DSA { + public SHA3_512withDSAinP1363Format() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA3-512"), true); + } + } + /** * Standard SHA224withDSA implementation as defined in FIPS186-3. */ @@ -540,6 +617,42 @@ public SHA256withDSAinP1363Format() throws NoSuchAlgorithmException { } } + /** + * Standard SHA384withDSA implementation as defined in FIPS186-3. + */ + public static final class SHA384withDSA extends DSA { + public SHA384withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA-384")); + } + } + + /** + * SHA384withDSA implementation that uses the IEEE P1363 format. + */ + public static final class SHA384withDSAinP1363Format extends DSA { + public SHA384withDSAinP1363Format() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA-384"), true); + } + } + + /** + * Standard SHA512withDSA implementation as defined in FIPS186-3. + */ + public static final class SHA512withDSA extends DSA { + public SHA512withDSA() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA-512")); + } + } + + /** + * SHA512withDSA implementation that uses the IEEE P1363 format. + */ + public static final class SHA512withDSAinP1363Format extends DSA { + public SHA512withDSAinP1363Format() throws NoSuchAlgorithmException { + super(MessageDigest.getInstance("SHA-512"), true); + } + } + /** * Standard SHA1withDSA implementation. */ diff --git a/src/java.base/share/classes/sun/security/provider/SunEntries.java b/src/java.base/share/classes/sun/security/provider/SunEntries.java index 79007f4d8ef51..076c6e04f4f4f 100644 --- a/src/java.base/share/classes/sun/security/provider/SunEntries.java +++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java @@ -54,9 +54,13 @@ * SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384, * and SHA-512. * - * - SHA-224withDSA/SHA-256withDSA are the signature schemes + * - [SHA-224|SHA-256|SHA-384|SHA-512]withDSA are the signature schemes * described in FIPS 186-3. The associated object identifiers are - * "OID.2.16.840.1.101.3.4.3.1", and "OID.2.16.840.1.101.3.4.3.2". + * "OID.2.16.840.1.101.3.4.3.[1|2|3|4]" respectively. + * + * - [SHA3-224|SHA3-256|SHA3-384|SHA3-512]withDSA are the signature schemes + * using SHA-3 family of digests with DSA. The associated object identifiers + * are "OID.2.16.840.1.101.3.4.3.[5|6|7|8]" respectively. * * - DSA is the key generation scheme as described in FIPS 186. * Aliases for DSA include the OID strings "OID.1.3.14.3.2.12" @@ -127,13 +131,30 @@ public final class SunEntries { addWithAlias(p, "Signature", "NONEwithDSA", "sun.security.provider.DSA$RawDSA", attrs); - attrs.put("KeySize", "2048"); // for SHA224 and SHA256 DSA signatures + // for DSA signatures with 224/256-bit digests + attrs.put("KeySize", "2048"); addWithAlias(p, "Signature", "SHA224withDSA", "sun.security.provider.DSA$SHA224withDSA", attrs); addWithAlias(p, "Signature", "SHA256withDSA", "sun.security.provider.DSA$SHA256withDSA", attrs); + addWithAlias(p, "Signature", "SHA3-224withDSA", + "sun.security.provider.DSA$SHA3_224withDSA", attrs); + addWithAlias(p, "Signature", "SHA3-256withDSA", + "sun.security.provider.DSA$SHA3_256withDSA", attrs); + + attrs.put("KeySize", "3072"); // for DSA sig using 384/512-bit digests + + addWithAlias(p, "Signature", "SHA384withDSA", + "sun.security.provider.DSA$SHA384withDSA", attrs); + addWithAlias(p, "Signature", "SHA512withDSA", + "sun.security.provider.DSA$SHA512withDSA", attrs); + addWithAlias(p, "Signature", "SHA3-384withDSA", + "sun.security.provider.DSA$SHA3_384withDSA", attrs); + addWithAlias(p, "Signature", "SHA3-512withDSA", + "sun.security.provider.DSA$SHA3_512withDSA", attrs); + attrs.remove("KeySize"); add(p, "Signature", "SHA1withDSAinP1363Format", @@ -144,7 +165,18 @@ public final class SunEntries { "sun.security.provider.DSA$SHA224withDSAinP1363Format"); add(p, "Signature", "SHA256withDSAinP1363Format", "sun.security.provider.DSA$SHA256withDSAinP1363Format"); - + add(p, "Signature", "SHA384withDSAinP1363Format", + "sun.security.provider.DSA$SHA384withDSAinP1363Format"); + add(p, "Signature", "SHA512withDSAinP1363Format", + "sun.security.provider.DSA$SHA512withDSAinP1363Format"); + add(p, "Signature", "SHA3-224withDSAinP1363Format", + "sun.security.provider.DSA$SHA3_224withDSAinP1363Format"); + add(p, "Signature", "SHA3-256withDSAinP1363Format", + "sun.security.provider.DSA$SHA3_256withDSAinP1363Format"); + add(p, "Signature", "SHA3-384withDSAinP1363Format", + "sun.security.provider.DSA$SHA3_384withDSAinP1363Format"); + add(p, "Signature", "SHA3-512withDSAinP1363Format", + "sun.security.provider.DSA$SHA3_512withDSAinP1363Format"); /* * Key Pair Generator engines */ diff --git a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java index a4bdd4b5dca37..fef496ed50c88 100644 --- a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java +++ b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,7 +103,7 @@ protected void engineInit(byte[] encoded) throws IOException { throw new IOException("Only MGF1 mgf is supported"); } AlgorithmId params = AlgorithmId.parse( - new DerValue(val.getEncodedParams())); + new DerValue(val.getEncodedParams())); String mgfDigestName = params.getName(); switch (mgfDigestName) { case "SHA-1": @@ -127,6 +127,18 @@ protected void engineInit(byte[] encoded) throws IOException { case "SHA-512/256": mgfSpec = MGF1ParameterSpec.SHA512_256; break; + case "SHA3-224": + mgfSpec = MGF1ParameterSpec.SHA3_224; + break; + case "SHA3-256": + mgfSpec = MGF1ParameterSpec.SHA3_256; + break; + case "SHA3-384": + mgfSpec = MGF1ParameterSpec.SHA3_384; + break; + case "SHA3-512": + mgfSpec = MGF1ParameterSpec.SHA3_512; + break; default: throw new IOException ("Unrecognized message digest algorithm " + diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java index e95408b9f6253..85eb219a7d989 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java @@ -45,8 +45,8 @@ * PKCS#1 v2.2 RSASSA-PSS signatures with various message digest algorithms. * RSASSA-PSS implementation takes the message digest algorithm, MGF algorithm, * and salt length values through the required signature PSS parameters. - * We support SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and - * SHA-512/256 message digest algorithms and MGF1 mask generation function. + * We support SHA-1, SHA-2 family and SHA3 family of message digest algorithms, + * and MGF1 mask generation function. * * @since 11 */ @@ -81,24 +81,20 @@ private boolean isDigestEqual(String stdAlg, String givenAlg) { private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8]; - private static final Hashtable DIGEST_LENGTHS = - new Hashtable(); + private static final Hashtable DIGEST_LENGTHS = + new Hashtable(); static { - DIGEST_LENGTHS.put("SHA-1", 20); - DIGEST_LENGTHS.put("SHA", 20); - DIGEST_LENGTHS.put("SHA1", 20); - DIGEST_LENGTHS.put("SHA-224", 28); - DIGEST_LENGTHS.put("SHA224", 28); - DIGEST_LENGTHS.put("SHA-256", 32); - DIGEST_LENGTHS.put("SHA256", 32); - DIGEST_LENGTHS.put("SHA-384", 48); - DIGEST_LENGTHS.put("SHA384", 48); - DIGEST_LENGTHS.put("SHA-512", 64); - DIGEST_LENGTHS.put("SHA512", 64); - DIGEST_LENGTHS.put("SHA-512/224", 28); - DIGEST_LENGTHS.put("SHA512/224", 28); - DIGEST_LENGTHS.put("SHA-512/256", 32); - DIGEST_LENGTHS.put("SHA512/256", 32); + DIGEST_LENGTHS.put(KnownOIDs.SHA_1, 20); + DIGEST_LENGTHS.put(KnownOIDs.SHA_224, 28); + DIGEST_LENGTHS.put(KnownOIDs.SHA_256, 32); + DIGEST_LENGTHS.put(KnownOIDs.SHA_384, 48); + DIGEST_LENGTHS.put(KnownOIDs.SHA_512, 64); + DIGEST_LENGTHS.put(KnownOIDs.SHA_512$224, 28); + DIGEST_LENGTHS.put(KnownOIDs.SHA_512$256, 32); + DIGEST_LENGTHS.put(KnownOIDs.SHA3_224, 28); + DIGEST_LENGTHS.put(KnownOIDs.SHA3_256, 32); + DIGEST_LENGTHS.put(KnownOIDs.SHA3_384, 48); + DIGEST_LENGTHS.put(KnownOIDs.SHA3_512, 64); } // message digest implementation we use for hashing the data @@ -210,27 +206,33 @@ private static boolean isCompatible(AlgorithmParameterSpec keyParams, * internal signature parameters. */ private RSAKey isValid(RSAKey rsaKey) throws InvalidKeyException { - try { - AlgorithmParameterSpec keyParams = rsaKey.getParams(); - // validate key parameters - if (!isCompatible(rsaKey.getParams(), this.sigParams)) { - throw new InvalidKeyException - ("Key contains incompatible PSS parameter values"); - } - // validate key length - if (this.sigParams != null) { - Integer hLen = - DIGEST_LENGTHS.get(this.sigParams.getDigestAlgorithm()); - if (hLen == null) { - throw new ProviderException("Unsupported digest algo: " + - this.sigParams.getDigestAlgorithm()); + AlgorithmParameterSpec keyParams = rsaKey.getParams(); + // validate key parameters + if (!isCompatible(rsaKey.getParams(), this.sigParams)) { + throw new InvalidKeyException + ("Key contains incompatible PSS parameter values"); + } + // validate key length + if (this.sigParams != null) { + String digestAlgo = this.sigParams.getDigestAlgorithm(); + KnownOIDs ko = KnownOIDs.findMatch(digestAlgo); + if (ko != null) { + Integer hLen = DIGEST_LENGTHS.get(ko); + if (hLen != null) { + checkKeyLength(rsaKey, hLen, + this.sigParams.getSaltLength()); + } else { + // should never happen; checked in validateSigParams() + throw new ProviderException + ("Unsupported digest algo: " + digestAlgo); } - checkKeyLength(rsaKey, hLen, this.sigParams.getSaltLength()); + } else { + // should never happen; checked in validateSigParams() + throw new ProviderException + ("Unrecognized digest algo: " + digestAlgo); } - return rsaKey; - } catch (SignatureException e) { - throw new InvalidKeyException(e); } + return rsaKey; } /** @@ -268,14 +270,26 @@ private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p) ("Only supports TrailerFieldBC(1)"); } - String digestAlgo = params.getDigestAlgorithm(); + // check key length again if (key != null) { - try { - int hLen = DIGEST_LENGTHS.get(digestAlgo); - checkKeyLength(key, hLen, params.getSaltLength()); - } catch (SignatureException e) { - throw new InvalidAlgorithmParameterException(e); + String digestAlgo = params.getDigestAlgorithm(); + KnownOIDs ko = KnownOIDs.findMatch(digestAlgo); + if (ko != null) { + Integer hLen = DIGEST_LENGTHS.get(ko); + if (hLen != null) { + try { + checkKeyLength(key, hLen, params.getSaltLength()); + } catch (InvalidKeyException e) { + throw new InvalidAlgorithmParameterException(e); + } + } else { + throw new InvalidAlgorithmParameterException + ("Unsupported digest algo: " + digestAlgo); + } + } else { + throw new InvalidAlgorithmParameterException + ("Unrecognized digest algo: " + digestAlgo); } } return params; @@ -302,12 +316,12 @@ private void ensureInit() throws SignatureException { * salt length */ private static void checkKeyLength(RSAKey key, int digestLen, - int saltLen) throws SignatureException { + int saltLen) throws InvalidKeyException { if (key != null) { int keyLength = (getKeyLengthInBits(key) + 7) >> 3; int minLength = Math.addExact(Math.addExact(digestLen, saltLen), 2); if (keyLength < minLength) { - throw new SignatureException + throw new InvalidKeyException ("Key is too short, need min " + minLength + " bytes"); } } diff --git a/src/java.base/share/classes/sun/security/rsa/RSASignature.java b/src/java.base/share/classes/sun/security/rsa/RSASignature.java index ea2ef98508268..795d5c5902034 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSASignature.java +++ b/src/java.base/share/classes/sun/security/rsa/RSASignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,9 @@ * PKCS#1 v1.5 RSA signatures with the various message digest algorithms. * This file contains an abstract base class with all the logic plus * a nested static class for each of the message digest algorithms - * (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256, - * SHA-384, SHA-512, SHA-512/224, and SHA-512/256. + * (see end of the file). We support MD2, MD5, SHA-1, SHA2 family ( + * SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256), + * and SHA3 family (SHA3-224, SHA3-256, SHA3-384, SHA3-512) of digests. * * @since 1.5 * @author Andreas Sterbenz @@ -360,4 +361,32 @@ public SHA512_256withRSA() { super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11); } } + + // Nested class for SHA3-224withRSA signatures + public static final class SHA3_224withRSA extends RSASignature { + public SHA3_224withRSA() { + super("SHA3-224", AlgorithmId.SHA3_224_oid, 11); + } + } + + // Nested class for SHA3-256withRSA signatures + public static final class SHA3_256withRSA extends RSASignature { + public SHA3_256withRSA() { + super("SHA3-256", AlgorithmId.SHA3_256_oid, 11); + } + } + + // Nested class for SHA3-384withRSA signatures + public static final class SHA3_384withRSA extends RSASignature { + public SHA3_384withRSA() { + super("SHA3-384", AlgorithmId.SHA3_384_oid, 11); + } + } + + // Nested class for SHA3-512withRSA signatures + public static final class SHA3_512withRSA extends RSASignature { + public SHA3_512withRSA() { + super("SHA3-512", AlgorithmId.SHA3_512_oid, 11); + } + } } diff --git a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java index f3edf4f25e1ff..ca79f25cc4443 100644 --- a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java +++ b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java @@ -84,6 +84,14 @@ public SunRsaSignEntries(Provider p) { "sun.security.rsa.RSASignature$SHA512_224withRSA", attrs); addA(p, "Signature", "SHA512/256withRSA", "sun.security.rsa.RSASignature$SHA512_256withRSA", attrs); + addA(p, "Signature", "SHA3-224withRSA", + "sun.security.rsa.RSASignature$SHA3_224withRSA", attrs); + addA(p, "Signature", "SHA3-256withRSA", + "sun.security.rsa.RSASignature$SHA3_256withRSA", attrs); + addA(p, "Signature", "SHA3-384withRSA", + "sun.security.rsa.RSASignature$SHA3_384withRSA", attrs); + addA(p, "Signature", "SHA3-512withRSA", + "sun.security.rsa.RSASignature$SHA3_512withRSA", attrs); addA(p, "KeyFactory", "RSASSA-PSS", "sun.security.rsa.RSAKeyFactory$PSS", attrs); @@ -92,7 +100,7 @@ public SunRsaSignEntries(Provider p) { addA(p, "Signature", "RSASSA-PSS", "sun.security.rsa.RSAPSSSignature", attrs); addA(p, "AlgorithmParameters", "RSASSA-PSS", - "sun.security.rsa.PSSParameters", attrs); + "sun.security.rsa.PSSParameters", null); } public Iterator iterator() { diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java index f7eff259c4b42..ac519dc288661 100644 --- a/src/java.base/share/classes/sun/security/util/KnownOIDs.java +++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java @@ -154,6 +154,14 @@ public enum KnownOIDs { SHA256withDSA("2.16.840.1.101.3.4.3.2"), SHA384withDSA("2.16.840.1.101.3.4.3.3"), SHA512withDSA("2.16.840.1.101.3.4.3.4"), + SHA3_224withDSA("2.16.840.1.101.3.4.3.5", "SHA3-224withDSA"), + SHA3_256withDSA("2.16.840.1.101.3.4.3.6", "SHA3-256withDSA"), + SHA3_384withDSA("2.16.840.1.101.3.4.3.7", "SHA3-384withDSA"), + SHA3_512withDSA("2.16.840.1.101.3.4.3.8", "SHA3-512withDSA"), + SHA3_224withECDSA("2.16.840.1.101.3.4.3.9", "SHA3-224withECDSA"), + SHA3_256withECDSA("2.16.840.1.101.3.4.3.10", "SHA3-256withECDSA"), + SHA3_384withECDSA("2.16.840.1.101.3.4.3.11", "SHA3-384withECDSA"), + SHA3_512withECDSA("2.16.840.1.101.3.4.3.12", "SHA3-512withECDSA"), SHA3_224withRSA("2.16.840.1.101.3.4.3.13", "SHA3-224withRSA"), SHA3_256withRSA("2.16.840.1.101.3.4.3.14", "SHA3-256withRSA"), SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"), @@ -429,9 +437,9 @@ public static KnownOIDs findMatch(String s) { if (debug != null) { debug.println("Setting up name2enum:"); } - List.of(KnownOIDs.values()).forEach(o -> { + for (KnownOIDs o : KnownOIDs.values()) { register(o); - }); + }; } private static void register(KnownOIDs o) { diff --git a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java index 8351bfa8168b1..b9b96b31c918c 100644 --- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java +++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java @@ -196,6 +196,10 @@ public void derEncode (OutputStream out) throws IOException { algid.equals((Object)SHA512_oid) || algid.equals((Object)SHA512_224_oid) || algid.equals((Object)SHA512_256_oid) || + algid.equals((Object)SHA3_224_oid) || + algid.equals((Object)SHA3_256_oid) || + algid.equals((Object)SHA3_384_oid) || + algid.equals((Object)SHA3_512_oid) || algid.equals((Object)DSA_oid) || algid.equals((Object)sha1WithDSA_oid)) { ; // no parameter part encoded @@ -608,6 +612,18 @@ private static ConcurrentHashMap collectOIDAliases() { public static final ObjectIdentifier SHA512_256_oid = ObjectIdentifier.of(KnownOIDs.SHA_512$256); + public static final ObjectIdentifier SHA3_224_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_224); + + public static final ObjectIdentifier SHA3_256_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_256); + + public static final ObjectIdentifier SHA3_384_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_384); + + public static final ObjectIdentifier SHA3_512_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_512); + public static final ObjectIdentifier DSA_oid = ObjectIdentifier.of(KnownOIDs.DSA); diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java b/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java index 9270df3745f97..ac776f3f29040 100644 --- a/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java +++ b/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,17 +50,19 @@ public class ForwardingFileObject implements FileObject { protected final F fileObject; /** - * Creates a new instance of ForwardingFileObject. + * Creates a new instance of {@code ForwardingFileObject}. * @param fileObject delegate to this file object */ protected ForwardingFileObject(F fileObject) { this.fileObject = Objects.requireNonNull(fileObject); } + @Override public URI toUri() { return fileObject.toUri(); } + @Override public String getName() { return fileObject.getName(); } @@ -70,6 +72,7 @@ public String getName() { * @throws UnsupportedOperationException {@inheritDoc} * @throws IOException {@inheritDoc} */ + @Override public InputStream openInputStream() throws IOException { return fileObject.openInputStream(); } @@ -79,6 +82,7 @@ public InputStream openInputStream() throws IOException { * @throws UnsupportedOperationException {@inheritDoc} * @throws IOException {@inheritDoc} */ + @Override public OutputStream openOutputStream() throws IOException { return fileObject.openOutputStream(); } @@ -88,6 +92,7 @@ public OutputStream openOutputStream() throws IOException { * @throws UnsupportedOperationException {@inheritDoc} * @throws IOException {@inheritDoc} */ + @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException { return fileObject.openReader(ignoreEncodingErrors); } @@ -97,6 +102,7 @@ public Reader openReader(boolean ignoreEncodingErrors) throws IOException { * @throws UnsupportedOperationException {@inheritDoc} * @throws IOException {@inheritDoc} */ + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return fileObject.getCharContent(ignoreEncodingErrors); } @@ -106,14 +112,17 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept * @throws UnsupportedOperationException {@inheritDoc} * @throws IOException {@inheritDoc} */ + @Override public Writer openWriter() throws IOException { return fileObject.openWriter(); } + @Override public long getLastModified() { return fileObject.getLastModified(); } + @Override public boolean delete() { return fileObject.delete(); } diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java index 1a15c88c03281..479c90e9ba9f1 100644 --- a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java +++ b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ public class ForwardingJavaFileManager implements Jav protected final M fileManager; /** - * Creates a new instance of ForwardingJavaFileManager. + * Creates a new instance of {@code ForwardingJavaFileManager}. * @param fileManager delegate to this file manager */ protected ForwardingJavaFileManager(M fileManager) { @@ -60,6 +60,7 @@ protected ForwardingJavaFileManager(M fileManager) { * @throws SecurityException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @Override public ClassLoader getClassLoader(Location location) { return fileManager.getClassLoader(location); } @@ -68,6 +69,7 @@ public ClassLoader getClassLoader(Location location) { * @throws IOException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @Override public Iterable list(Location location, String packageName, Set kinds, @@ -80,6 +82,7 @@ public Iterable list(Location location, /** * @throws IllegalStateException {@inheritDoc} */ + @Override public String inferBinaryName(Location location, JavaFileObject file) { return fileManager.inferBinaryName(location, file); } @@ -87,6 +90,7 @@ public String inferBinaryName(Location location, JavaFileObject file) { /** * @throws IllegalArgumentException {@inheritDoc} */ + @Override public boolean isSameFile(FileObject a, FileObject b) { return fileManager.isSameFile(a, b); } @@ -95,14 +99,17 @@ public boolean isSameFile(FileObject a, FileObject b) { * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @Override public boolean handleOption(String current, Iterator remaining) { return fileManager.handleOption(current, remaining); } + @Override public boolean hasLocation(Location location) { return fileManager.hasLocation(location); } + @Override public int isSupportedOption(String option) { return fileManager.isSupportedOption(option); } @@ -111,6 +118,7 @@ public int isSupportedOption(String option) { * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @Override public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) @@ -123,6 +131,7 @@ public JavaFileObject getJavaFileForInput(Location location, * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @Override public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, @@ -136,6 +145,7 @@ public JavaFileObject getJavaFileForOutput(Location location, * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @Override public FileObject getFileForInput(Location location, String packageName, String relativeName) @@ -148,6 +158,7 @@ public FileObject getFileForInput(Location location, * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + @Override public FileObject getFileForOutput(Location location, String packageName, String relativeName, @@ -157,10 +168,12 @@ public FileObject getFileForOutput(Location location, return fileManager.getFileForOutput(location, packageName, relativeName, sibling); } + @Override public void flush() throws IOException { fileManager.flush(); } + @Override public void close() throws IOException { fileManager.close(); } @@ -169,6 +182,7 @@ public void close() throws IOException { * @since 9 * @spec JPMS */ + @Override public Location getLocationForModule(Location location, String moduleName) throws IOException { return fileManager.getLocationForModule(location, moduleName); } @@ -177,6 +191,7 @@ public Location getLocationForModule(Location location, String moduleName) throw * @since 9 * @spec JPMS */ + @Override public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException { return fileManager.getLocationForModule(location, fo); } @@ -185,6 +200,7 @@ public Location getLocationForModule(Location location, JavaFileObject fo) throw * @since 9 * @spec JPMS */ + @Override public ServiceLoader getServiceLoader(Location location, Class service) throws IOException { return fileManager.getServiceLoader(location, service); } @@ -193,6 +209,7 @@ public ServiceLoader getServiceLoader(Location location, Class service * @since 9 * @spec JPMS */ + @Override public String inferModuleName(Location location) throws IOException { return fileManager.inferModuleName(location); } @@ -201,6 +218,7 @@ public String inferModuleName(Location location) throws IOException { * @since 9 * @spec JPMS */ + @Override public Iterable> listLocationsForModules(Location location) throws IOException { return fileManager.listLocationsForModules(location); } @@ -208,6 +226,7 @@ public Iterable> listLocationsForModules(Location location) throws /** * @since 9 */ + @Override public boolean contains(Location location, FileObject fo) throws IOException { return fileManager.contains(location, fo); } diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java index b0b3e9d40fdca..bf7ad8f70addf 100644 --- a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java +++ b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,23 +43,27 @@ public class ForwardingJavaFileObject { /** - * Creates a new instance of ForwardingJavaFileObject. + * Creates a new instance of {@code ForwardingJavaFileObject}. * @param fileObject delegate to this file object */ protected ForwardingJavaFileObject(F fileObject) { super(fileObject); } + @Override public Kind getKind() { return fileObject.getKind(); } + @Override public boolean isNameCompatible(String simpleName, Kind kind) { return fileObject.isNameCompatible(simpleName, kind); } + @Override public NestingKind getNestingKind() { return fileObject.getNestingKind(); } + @Override public Modifier getAccessLevel() { return fileObject.getAccessLevel(); } } diff --git a/src/java.compiler/share/classes/javax/tools/JavaFileObject.java b/src/java.compiler/share/classes/javax/tools/JavaFileObject.java index 14a4fa9e698b8..48d6388df9e37 100644 --- a/src/java.compiler/share/classes/javax/tools/JavaFileObject.java +++ b/src/java.compiler/share/classes/javax/tools/JavaFileObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,8 +63,7 @@ enum Kind { CLASS(".class"), /** - * HTML files. For example, regular files ending with {@code - * .html}. + * HTML files. For example, regular files ending with {@code .html}. */ HTML(".html"), @@ -78,7 +77,7 @@ enum Kind { * empty string ({@code ""}) is used. */ public final String extension; - private Kind(String extension) { + Kind(String extension) { this.extension = Objects.requireNonNull(extension); } } @@ -94,12 +93,11 @@ private Kind(String extension) { * Checks if this file object is compatible with the specified * simple name and kind. A simple name is a single identifier * (not qualified) as defined in - * The Java Language Specification, - * section 6.2 "Names and Identifiers". + * The Java Language Specification, section {@jls 6.2}. * * @param simpleName a simple name of a class * @param kind a kind - * @return {@code true} if this file object is compatible; false + * @return {@code true} if this file object is compatible; {@code false} * otherwise */ boolean isNameCompatible(String simpleName, Kind kind); @@ -119,7 +117,7 @@ private Kind(String extension) { /** * Provides a hint about the access level of the class represented - * by this file object. If the access level is not known or if + * by this file object. If the access level is not known or * this file object does not represent a class file this method * returns {@code null}. * diff --git a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java index a2905b91356b9..9c8d491996aac 100644 --- a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java +++ b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ import java.util.Objects; import javax.lang.model.element.Modifier; import javax.lang.model.element.NestingKind; -import javax.tools.JavaFileObject.Kind; /** * Provides simple implementations for most methods in JavaFileObject. diff --git a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java index ab04e8597958b..2fee7e2673a09 100644 --- a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java +++ b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ import java.util.List; /** - * File manager based on {@linkplain File java.io.File} and {@linkplain Path java.nio.file.Path}. + * File manager based on {@link File java.io.File} and {@link Path java.nio.file.Path}. * * A common way to obtain an instance of this class is using * {@linkplain JavaCompiler#getStandardFileManager getStandardFileManager}, for example: @@ -363,7 +363,7 @@ default void setLocationFromPaths(Location location, Collection * * All such module-specific associations will be cancelled if a * new search path is associated with the location by calling - * {@linkplain #setLocation setLocation } or + * {@linkplain #setLocation setLocation} or * {@linkplain #setLocationFromPaths setLocationFromPaths}. * * @throws IllegalStateException if the location is not a module-oriented @@ -377,8 +377,8 @@ default void setLocationFromPaths(Location location, Collection * @param moduleName the name of the module * @param paths the search path to associate with the location and module. * - * @see setLocation - * @see setLocationFromPaths + * @see #setLocation + * @see #setLocationFromPaths * * @since 9 */ @@ -480,8 +480,8 @@ default void setPathFactory(PathFactory f) { } private static Iterable asPaths(final Iterable files) { - return () -> new Iterator() { - Iterator iter = files.iterator(); + return () -> new Iterator<>() { + final Iterator iter = files.iterator(); @Override public boolean hasNext() { @@ -496,8 +496,8 @@ public Path next() { } private static Iterable asFiles(final Iterable paths) { - return () -> new Iterator() { - Iterator iter = paths.iterator(); + return () -> new Iterator<>() { + final Iterator iter = paths.iterator(); @Override public boolean hasNext() { diff --git a/src/java.compiler/share/classes/javax/tools/package-info.java b/src/java.compiler/share/classes/javax/tools/package-info.java index e7883f9be74e0..c5ec54e7871e0 100644 --- a/src/java.compiler/share/classes/javax/tools/package-info.java +++ b/src/java.compiler/share/classes/javax/tools/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,25 +32,25 @@ * but there is no requirement to provide any tools implementing them. * *

Unless explicitly allowed, all methods in this package might - * throw a {@linkplain java.lang.NullPointerException} if given a + * throw a {@link java.lang.NullPointerException} if given a * {@code null} argument or if given a * {@linkplain java.lang.Iterable list or collection} containing * {@code null} elements. Similarly, no method may return * {@code null} unless explicitly allowed. * - *

This package is the home of the Java programming language compiler framework. This - * framework allows clients of the framework to locate and run + *

This package is the home of the Java programming language compiler framework. + * This framework allows clients of the framework to locate and run * compilers from programs. The framework also provides Service * Provider Interfaces (SPI) for structured access to diagnostics - * ({@linkplain javax.tools.DiagnosticListener}) as well as a file - * abstraction for overriding file access ({@linkplain - * javax.tools.JavaFileManager} and {@linkplain - * javax.tools.JavaFileObject}). See {@linkplain + * ({@link javax.tools.DiagnosticListener}) as well as a file + * abstraction for overriding file access ({@link + * javax.tools.JavaFileManager} and {@link + * javax.tools.JavaFileObject}). See {@link * javax.tools.JavaCompiler} for more details on using the SPI. * *

There is no requirement for a compiler at runtime. However, if * a default compiler is provided, it can be located using the - * {@linkplain javax.tools.ToolProvider}, for example: + * {@link javax.tools.ToolProvider}, for example: * *

{@code JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();} * diff --git a/src/java.desktop/share/classes/javax/swing/Box.java b/src/java.desktop/share/classes/javax/swing/Box.java index 9db52ce9a0e28..85983abddc1d6 100644 --- a/src/java.desktop/share/classes/javax/swing/Box.java +++ b/src/java.desktop/share/classes/javax/swing/Box.java @@ -316,6 +316,7 @@ public Filler(Dimension min, Dimension pref, Dimension max) { setMinimumSize(min); setPreferredSize(pref); setMaximumSize(max); + setFocusable(false); } /** diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java b/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java index cdb771283577f..ef587bca480e4 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,14 +25,14 @@ package com.sun.jndi.ldap; -import javax.naming.NamingException; -import javax.naming.ldap.spi.LdapDnsProvider; -import javax.naming.ldap.spi.LdapDnsProviderResult; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; +import javax.naming.NamingException; +import javax.naming.ldap.spi.LdapDnsProviderResult; + public class DefaultLdapDnsProvider { public Optional lookupEndpoints(String url, @@ -82,5 +82,4 @@ public Optional lookupEndpoints(String url, return Optional.of(res); } } - } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java index 1d6ac817f0bda..b5f6fd05c11d9 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,7 @@ static LdapDnsProviderService getInstance() { * subclasses of {@code LdapDnsProvider} then this method will fall back * to the {@code DefaultLdapDnsProvider}. * - * @throws NamingException if the {@code url} in not valid or an error + * @throws NamingException if the {@code url} is not valid or an error * occurred while performing the lookup. */ LdapDnsProviderResult lookupEndpoints(String url, Hashtable env) @@ -110,5 +110,4 @@ LdapDnsProviderResult lookupEndpoints(String url, Hashtable env) } return result; } - } diff --git a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java index abafef646855c..d89436f188a23 100644 --- a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java +++ b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,5 +105,4 @@ private static Void checkPermission() { */ public abstract Optional lookupEndpoints( String url, Map env) throws NamingException; - } diff --git a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java index d28326bb7e7db..9427c256c26e1 100644 --- a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java +++ b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ * *

This class is used by an {@link LdapDnsProvider} to return the result * of a DNS lookup for a given LDAP URL. The result consists of a domain name - * and its associated ldap server endpoints. + * and its associated LDAP server endpoints. * *

A {@code null} {@code domainName} is equivalent to and represented * by an empty string. @@ -46,10 +46,10 @@ public final class LdapDnsProviderResult { /** * Construct an LdapDnsProviderResult consisting of a resolved domain name - * and the ldap server endpoints that serve the domain. + * and the LDAP server endpoints that serve the domain. * * @param domainName the resolved domain name; can be null. - * @param endpoints the possibly empty list of resolved ldap server + * @param endpoints the possibly empty list of resolved LDAP server * endpoints * * @throws NullPointerException if {@code endpoints} contains {@code null} @@ -63,7 +63,7 @@ public LdapDnsProviderResult(String domainName, List endpoints) { } /** - * Returns the domain name resolved from the ldap URL. This method returns + * Returns the domain name resolved from the LDAP URL. This method returns * the empty string if the {@code LdapDnsProviderResult} is created with a * null domain name. * @@ -75,13 +75,12 @@ public String getDomainName() { /** * Returns the possibly empty list of individual server endpoints resolved - * from the ldap URL. + * from the LDAP URL. * * @return a possibly empty unmodifiable {@link List} containing the - * resolved ldap server endpoints + * resolved LDAP server endpoints */ public List getEndpoints() { return endpoints; } - } diff --git a/src/java.xml/share/classes/org/w3c/dom/package-info.java b/src/java.xml/share/classes/org/w3c/dom/package-info.java index 8d08de006fd8f..10f081415ede3 100644 --- a/src/java.xml/share/classes/org/w3c/dom/package-info.java +++ b/src/java.xml/share/classes/org/w3c/dom/package-info.java @@ -42,31 +42,6 @@ * {@link org.w3c.dom.Node#setTextContent(String) setTextContent} shared the same * content that defined the TextContent property itself. * - * @implNote - * The JDK implementation of {@link org.w3c.dom.ls.LSSerializer LSSerializer} - * follows the Characters section - * of the XML Specification in handling characters output. In particular, the - * specification defined a character range that excluded the surrogate blocks. - * As a result, the JDK LSSerializer writes characters in the surrogate blocks - * as Character References. Character {@code 0xf0 0x9f 0x9a 0xa9} - * (Unicode code point U+1F6A9) for example will be written as {@code 🚩}. - * - *

- * This behavior is different from what was in the class description of - * {@link org.w3c.dom.ls.LSSerializer LSSerializer}. The relevant section is quoted - * below: - * - *

- * {@code Within the character data of a document (outside of markup), any characters - * that cannot be represented directly are replaced with character references... - * Any characters that cannot be represented directly in the output character encoding - * are serialized as numeric character references } - * - *

- * The JDK implementation does not follow this definition because it is not consistent - * with the XML Specification that defined an explicit character range with no - * association to the setting of the output character encoding. - * * * @since 1.4 */ diff --git a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java index 4565cefd70b1c..427425a526e91 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java @@ -26,10 +26,10 @@ package com.sun.source.doctree; /** - * A tree node for an {@code @docroot} inline tag. + * A tree node for an {@code @docRoot} inline tag. * *

- *    {@docroot}
+ *    {@docRoot}
  * 
* * @since 1.8 diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java index 8878486b99da4..54dc3d259bde5 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java @@ -137,7 +137,7 @@ DocCommentTree newDocCommentTree(List fullBody, List preamble, List postamble); /** - * Creates a new {@code DocRootTree} object, to represent an {@code {@docroot}} tag. + * Creates a new {@code DocRootTree} object, to represent an {@code {@docRoot}} tag. * @return a {@code DocRootTree} object */ DocRootTree newDocRootTree(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java index f43484bb3b147..aebbc78da3685 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java @@ -220,7 +220,11 @@ public static EnumSet asFlagSet(long flags) { */ public static final long UNION = 1L<<39; - // Flag bit (1L << 40) is available. + /** + * Flags an erroneous TypeSymbol as viable for recovery. + * TypeSymbols only. + */ + public static final long RECOVERABLE = 1L<<40; /** * Flag that marks an 'effectively final' local variable. @@ -508,6 +512,7 @@ public enum Flag { MATCH_BINDING(Flags.MATCH_BINDING), MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER), RECORD(Flags.RECORD), + RECOVERABLE(Flags.RECOVERABLE), SEALED(Flags.SEALED), NON_SEALED(Flags.NON_SEALED) { @Override diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index cf26504dfa989..b5cae83e3f47c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -120,6 +120,7 @@ public class Attr extends JCTree.Visitor { final Annotate annotate; final ArgumentAttr argumentAttr; final MatchBindingsComputer matchBindingsComputer; + final AttrRecover attrRecover; public static Attr instance(Context context) { Attr instance = context.get(attrKey); @@ -157,6 +158,7 @@ protected Attr(Context context) { dependencies = Dependencies.instance(context); argumentAttr = ArgumentAttr.instance(context); matchBindingsComputer = MatchBindingsComputer.instance(context); + attrRecover = AttrRecover.instance(context); Options options = Options.instance(context); @@ -419,8 +421,9 @@ private Env attribToTree(JCTree root, Env env, JCTree JavaFileObject prev = log.useSource(env.toplevel.sourcefile); try { deferredAttr.attribSpeculative(root, env, resultInfo, - null, DeferredAttr.AttributionMode.ANALYZER, + null, DeferredAttr.AttributionMode.ATTRIB_TO_TREE, argumentAttr.withLocalCacheContext()); + attrRecover.doRecovery(); } catch (BreakAttr b) { return b.env; } catch (AssertionError ae) { @@ -738,6 +741,7 @@ public Type attribStat(JCTree tree, Env env) { Env analyzeEnv = analyzer.copyEnvIfNeeded(tree, env); Type result = attribTree(tree, env, statInfo); analyzer.analyzeIfNeeded(tree, analyzeEnv); + attrRecover.doRecovery(); return result; } @@ -2092,6 +2096,7 @@ public void visitIf(JCIf tree) { } void preFlow(JCTree tree) { + attrRecover.doRecovery(); new PostAttrAnalyzer() { @Override public void scan(JCTree tree) { @@ -3114,6 +3119,7 @@ TargetInfo getTargetInfo(JCPolyExpression that, ResultInfo resultInfo, List env, ResultInfo resultInfo) { if (resultInfo.pkind.contains(KindSelector.POLY)) { - Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)); - Type owntype = checkIdInternal(tree, site, sym, pt, env, resultInfo); - resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); - return owntype; + return attrRecover.recoverMethodInvocation(tree, site, sym, env, resultInfo); } else { return checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo); } @@ -4916,9 +4919,12 @@ public void visitAnnotatedType(JCAnnotatedType tree) { } public void visitErroneous(JCErroneous tree) { - if (tree.errs != null) + if (tree.errs != null) { + Env errEnv = env.dup(env.tree); + errEnv.info.returnResult = unknownExprInfo; for (JCTree err : tree.errs) - attribTree(err, env, new ResultInfo(KindSelector.ERR, pt())); + attribTree(err, errEnv, new ResultInfo(KindSelector.ERR, pt())); + } result = tree.type = syms.errType; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java new file mode 100644 index 0000000000000..8fd09501717ca --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.tools.javac.comp; + +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.TypeSymbol; +import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Type.ArrayType; +import com.sun.tools.javac.code.Type.ErrorType; +import com.sun.tools.javac.code.TypeTag; +import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.comp.Attr.ResultInfo; +import com.sun.tools.javac.comp.DeferredAttr.AttrMode; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCErroneous; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCLambda; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCReturn; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.JCTree.Tag; +import com.sun.tools.javac.tree.TreeInfo; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.tree.TreeTranslator; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Names; + +/** This is an error recovery addon for Attr. Currently, it recovers + * method invocations with lambdas, that require type inference. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class AttrRecover { + protected static final Context.Key attrRepairKey = new Context.Key<>(); + + final Attr attr; + final DeferredAttr deferredAttr; + final Names names; + final TreeMaker make; + final Symtab syms; + final Types types; + + public static AttrRecover instance(Context context) { + AttrRecover instance = context.get(attrRepairKey); + if (instance == null) + instance = new AttrRecover(context); + return instance; + } + + protected AttrRecover(Context context) { + context.put(attrRepairKey, this); + + attr = Attr.instance(context); + deferredAttr = DeferredAttr.instance(context); + names = Names.instance(context); + make = TreeMaker.instance(context); + syms = Symtab.instance(context); + types = Types.instance(context); + } + + private final ListBuffer recoveryTodo = new ListBuffer<>(); + + public void doRecovery() { + while (recoveryTodo.nonEmpty()) { + RecoverTodo todo = recoveryTodo.remove(); + ListBuffer rollback = new ListBuffer<>(); + boolean repaired = false; + RECOVER: if (todo.env.tree.hasTag(Tag.APPLY)) { + JCMethodInvocation mit = (JCMethodInvocation) todo.env.tree; + boolean vararg = (todo.candSym.flags() & Flags.VARARGS) != 0; + if (!vararg && + mit.args.length() > todo.candSym.type.getParameterTypes().length()) { + break RECOVER; //too many actual parameters, skip + } + List args = mit.args; + List formals = todo.candSym.type.getParameterTypes(); + while (args.nonEmpty() && formals.nonEmpty()) { + JCExpression arg = args.head; + Type formal = formals.tail.nonEmpty() || !vararg + ? formals.head : ((ArrayType) formals.head).elemtype; + if (arg.hasTag(JCTree.Tag.LAMBDA)) { + final JCTree.JCLambda lambda = (JCLambda) arg; + if (lambda.paramKind == JCLambda.ParameterKind.IMPLICIT) { + for (JCVariableDecl var : lambda.params) { + var.vartype = null; //reset type + } + } + if (types.isFunctionalInterface(formal)) { + Type functionalType = types.findDescriptorType(formal); + boolean voidCompatible = functionalType.getReturnType().hasTag(TypeTag.VOID); + lambda.body = new TreeTranslator() { + @Override + public void visitReturn(JCReturn tree) { + result = tree; + if (voidCompatible) { + if (tree.expr != null) { + JCErroneous err = make.Erroneous(List.of(tree)); + result = err; + rollback.append(() -> { + lambda.body = new TreeTranslator() { + @SuppressWarnings("unchecked") + public T translate(T t) { + if (t == err) return (T) tree; + else return super.translate(t); + } + }.translate(lambda.body); + }); + } + } else { + if (tree.expr == null) { + tree.expr = make.Erroneous().setType(syms.errType); + rollback.append(() -> { + tree.expr = null; + }); + } + } + } + @Override + public void visitLambda(JCLambda tree) { + //do not touch nested lambdas + } + @Override + public void visitClassDef(JCClassDecl tree) { + //do not touch nested classes + } + }.translate(lambda.body); + if (!voidCompatible) { + JCReturn ret = make.Return(make.Erroneous().setType(syms.errType)); + ((JCBlock) lambda.body).stats = ((JCBlock) lambda.body).stats.append(ret); + rollback.append(() -> { + ((JCBlock) lambda.body).stats = List.filter(((JCBlock) lambda.body).stats, ret); + }); + } + } + repaired = true; + } + args = args.tail; + if (formals.tail.nonEmpty() || !vararg) { + formals = formals.tail; + } + } + List prevArgs = mit.args; + while (formals.nonEmpty()) { + mit.args = mit.args.append(make.Erroneous().setType(syms.errType)); + formals = formals.tail; + repaired = true; + } + rollback.append(() -> { + mit.args = prevArgs; + }); + } + + Type owntype; + if (repaired) { + List args = TreeInfo.args(todo.env.tree); + List pats = todo.resultInfo.pt.getParameterTypes(); + while (pats.length() < args.length()) { + pats = pats.append(syms.errType); + } + owntype = attr.checkMethod(todo.site, todo.candSym, + attr.new ResultInfo(todo.resultInfo.pkind, todo.resultInfo.pt.getReturnType(), todo.resultInfo.checkContext, todo.resultInfo.checkMode), + todo.env, args, pats, + todo.resultInfo.pt.getTypeArguments()); + rollback.stream().forEach(Runnable::run); + } else { + owntype = basicMethodInvocationRecovery(todo.tree, todo.site, todo.errSym, todo.env, todo.resultInfo); + } + todo.tree.type = owntype; + } + } + + Type recoverMethodInvocation(JCTree tree, + Type site, + Symbol sym, + Env env, + ResultInfo resultInfo) { + if ((sym.flags_field & Flags.RECOVERABLE) != 0 && env.info.attributionMode.recover()) { + recoveryTodo.append(new RecoverTodo(tree, site, sym, ((RecoveryErrorType) sym.type).candidateSymbol, attr.copyEnv(env), resultInfo)); + return syms.errType; + } else { + return basicMethodInvocationRecovery(tree, site, sym, env, resultInfo); + } + } + + private Type basicMethodInvocationRecovery(JCTree tree, + Type site, + Symbol sym, + Env env, + ResultInfo resultInfo) { + Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)); + Type owntype = attr.checkIdInternal(tree, site, sym, pt, env, resultInfo); + resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); + return owntype; + } + + void wrongMethodSymbolCandidate(TypeSymbol errSymbol, Symbol candSym, JCDiagnostic diag) { + List diags = List.of(diag); + boolean recoverable = false; + while (!recoverable && diags.nonEmpty()) { + JCDiagnostic d = diags.head; + diags = diags.tail; + switch (d.getCode()) { + case "compiler.misc.missing.ret.val": + case "compiler.misc.unexpected.ret.val": + case "compiler.misc.infer.arg.length.mismatch": + case "compiler.misc.arg.length.mismatch": + errSymbol.type = new RecoveryErrorType((Type.ErrorType) errSymbol.type, candSym); + errSymbol.flags_field |= Flags.RECOVERABLE; + return ; + default: + break; + } + for (Object a : d.getArgs()) { + if (a instanceof JCDiagnostic) { + diags = diags.prepend((JCDiagnostic) a); + } + } + } + } + + private static class RecoveryErrorType extends ErrorType { + public final Symbol candidateSymbol; + + public RecoveryErrorType(ErrorType original, Symbol candidateSymbol) { + super(original.getOriginalType(), original.tsym); + this.candidateSymbol = candidateSymbol; + } + + } + + private static class RecoverTodo { + public final JCTree tree; + public final Type site; + public final Symbol errSym; + public final Symbol candSym; + public final Env env; + public final ResultInfo resultInfo; + + public RecoverTodo(JCTree tree, Type site, Symbol errSym, Symbol candSym, + Env env, Attr.ResultInfo resultInfo) { + this.tree = tree; + this.site = site; + this.errSym = errSym; + this.candSym = candSym; + this.env = env; + this.resultInfo = resultInfo; + } + + } +} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 66ed1834179a9..f64274ca4de38 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -1329,20 +1329,28 @@ public void visitReference(JCMemberReference tree) { */ enum AttributionMode { /**Normal, non-speculative, attribution.*/ - FULL(false), + FULL(false, true), /**Speculative attribution on behalf of an Analyzer.*/ - ANALYZER(true), + ATTRIB_TO_TREE(true, true), + /**Speculative attribution on behalf of an Analyzer.*/ + ANALYZER(true, false), /**Speculative attribution.*/ - SPECULATIVE(true); + SPECULATIVE(true, false); - AttributionMode(boolean isSpeculative) { + AttributionMode(boolean isSpeculative, boolean recover) { this.isSpeculative = isSpeculative; + this.recover = recover; } boolean isSpeculative() { return isSpeculative; } + boolean recover() { + return recover; + } + final boolean isSpeculative; + final boolean recover; } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index e855c24036043..6fd598340b7a1 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -96,6 +96,7 @@ public class Resolve { Log log; Symtab syms; Attr attr; + AttrRecover attrRecover; DeferredAttr deferredAttr; Check chk; Infer infer; @@ -126,6 +127,7 @@ protected Resolve(Context context) { names = Names.instance(context); log = Log.instance(context); attr = Attr.instance(context); + attrRecover = AttrRecover.instance(context); deferredAttr = DeferredAttr.instance(context); chk = Check.instance(context); infer = Infer.instance(context); @@ -4043,12 +4045,12 @@ JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, @Override public Symbol access(Name name, TypeSymbol location) { - Symbol sym = bestCandidate(); - return types.createErrorType(name, location, sym != null ? sym.type : syms.errSymbol.type).tsym; - } - - protected Symbol bestCandidate() { - return errCandidate().fst; + Pair cand = errCandidate(); + TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym; + if (cand != null) { + attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd); + } + return errSymbol; } protected Pair errCandidate() { @@ -4181,11 +4183,12 @@ private List candidateDetails(Map candidates } @Override - protected Symbol bestCandidate() { + protected Pair errCandidate() { Map candidatesMap = mapCandidates(); Map filteredCandidates = filterCandidates(candidatesMap); if (filteredCandidates.size() == 1) { - return filteredCandidates.keySet().iterator().next(); + return Pair.of(filteredCandidates.keySet().iterator().next(), + filteredCandidates.values().iterator().next()); } return null; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java index 9480947520073..440df2a35fa98 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java @@ -248,7 +248,7 @@ protected List blockContent(Phase phase) { */ protected List blockTags() { ListBuffer tags = new ListBuffer<>(); - while (ch == '@') + while (bp < buflen && ch == '@') tags.add(blockTag()); return tags.toList(); } @@ -354,7 +354,7 @@ private enum WhitespaceRetentionPolicy { * Matching pairs of { } are skipped; the text is terminated by the first * unmatched }. It is an error if the beginning of the next tag is detected. */ - private DCTree inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException { + private DCText inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException { switch (whitespacePolicy) { case REMOVE_ALL: skipWhitespace(); @@ -663,14 +663,14 @@ protected DCTree entity() { nextChar(); if (isDecimalDigit(ch)) { nextChar(); - while (isDecimalDigit(ch)) + while (bp < buflen && isDecimalDigit(ch)) nextChar(); name = names.fromChars(buf, namep, bp - namep); } else if (ch == 'x' || ch == 'X') { nextChar(); if (isHexDigit(ch)) { nextChar(); - while (isHexDigit(ch)) + while (bp < buflen && isHexDigit(ch)) nextChar(); name = names.fromChars(buf, namep, bp - namep); } @@ -843,7 +843,7 @@ private DCTree html() { nextChar(); while (bp < buflen) { int dash = 0; - while (ch == '-') { + while (bp < buflen && ch == '-') { dash++; nextChar(); } @@ -890,7 +890,7 @@ protected List htmlAttrs() { skipWhitespace(); loop: - while (isIdentifierStart(ch)) { + while (bp < buflen && isIdentifierStart(ch)) { int namePos = bp; Name name = readAttributeName(); skipWhitespace(); @@ -1057,7 +1057,7 @@ protected boolean isWhitespace(char ch) { } protected void skipWhitespace() { - while (isWhitespace(ch)) { + while (bp < buflen && isWhitespace(ch)) { nextChar(); } } @@ -1118,9 +1118,9 @@ public DCTree parse(int pos) { new TagParser(TagParser.Kind.INLINE, DCTree.Kind.CODE, true) { @Override public DCTree parse(int pos) throws ParseException { - DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE); + DCText text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE); nextChar(); - return m.at(pos).newCodeTree((DCText) text); + return m.at(pos).newCodeTree(text); } }, @@ -1228,9 +1228,9 @@ public DCTree parse(int pos) throws ParseException { new TagParser(TagParser.Kind.INLINE, DCTree.Kind.LITERAL, true) { @Override public DCTree parse(int pos) throws ParseException { - DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE); + DCText text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE); nextChar(); - return m.at(pos).newLiteralTree((DCText) text); + return m.at(pos).newLiteralTree(text); } }, diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java index 7a237840852a5..b786f4cfd5169 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java @@ -161,14 +161,14 @@ public DocTreeMaker at(DiagnosticPosition pos) { } @Override @DefinedBy(Api.COMPILER_TREE) - public DCAttribute newAttributeTree(javax.lang.model.element.Name name, ValueKind vkind, java.util.List value) { + public DCAttribute newAttributeTree(Name name, ValueKind vkind, List value) { DCAttribute tree = new DCAttribute(name, vkind, cast(value)); tree.pos = pos; return tree; } @Override @DefinedBy(Api.COMPILER_TREE) - public DCAuthor newAuthorTree(java.util.List name) { + public DCAuthor newAuthorTree(List name) { DCAuthor tree = new DCAuthor(cast(name)); tree.pos = pos; return tree; @@ -197,11 +197,7 @@ public DCDeprecated newDeprecatedTree(List text) { @Override @DefinedBy(Api.COMPILER_TREE) public DCDocComment newDocCommentTree(List fullBody, List tags) { - Pair, List> pair = splitBody(fullBody); - List preamble = Collections.emptyList(); - List postamble = Collections.emptyList(); - - return newDocCommentTree(fullBody, tags, preamble, postamble); + return newDocCommentTree(fullBody, tags, Collections.emptyList(), Collections.emptyList()); } public DCDocComment newDocCommentTree(Comment comment, @@ -503,7 +499,7 @@ public DCVersion newVersionTree(List text) { } @Override @DefinedBy(Api.COMPILER_TREE) - public java.util.List getFirstSentence(java.util.List list) { + public List getFirstSentence(List list) { Pair, List> pair = splitBody(list); return new ArrayList<>(pair.fst); } @@ -693,7 +689,7 @@ private int getSentenceBreak(String s, DocTree dt) { return -1; // indeterminate at this time } - private boolean isSentenceBreak(javax.lang.model.element.Name tagName) { + private boolean isSentenceBreak(Name tagName) { return sentenceBreakTags.contains(get(tagName)); } diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java index 5f34d123a4a52..41c18e91f7b32 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java @@ -46,12 +46,20 @@ * . "SHA256withECDSA" * . "SHA384withECDSA" * . "SHA512withECDSA" + * . "SHA3-224withECDSA" + * . "SHA3-256withECDSA" + * . "SHA3-384withECDSA" + * . "SHA3-512withECDSA" * . "NONEwithECDSAinP1363Format" * . "SHA1withECDSAinP1363Format" * . "SHA224withECDSAinP1363Format" * . "SHA256withECDSAinP1363Format" * . "SHA384withECDSAinP1363Format" * . "SHA512withECDSAinP1363Format" + * . "SHA3-224withECDSAinP1363Format" + * . "SHA3-256withECDSAinP1363Format" + * . "SHA3-384withECDSAinP1363Format" + * . "SHA3-512withECDSAinP1363Format" * * @since 1.7 */ @@ -278,6 +286,62 @@ public SHA512inP1363Format() { } } + // Nested class for SHA3_224withECDSA signatures + public static final class SHA3_224 extends ECDSASignature { + public SHA3_224() { + super("SHA3-224"); + } + } + + // Nested class for SHA3_224withECDSAinP1363Format signatures + public static final class SHA3_224inP1363Format extends ECDSASignature { + public SHA3_224inP1363Format() { + super("SHA3-224", true); + } + } + + // Nested class for SHA3_256withECDSA signatures + public static final class SHA3_256 extends ECDSASignature { + public SHA3_256() { + super("SHA3-256"); + } + } + + // Nested class for SHA3_256withECDSAinP1363Format signatures + public static final class SHA3_256inP1363Format extends ECDSASignature { + public SHA3_256inP1363Format() { + super("SHA3-256", true); + } + } + + // Nested class for SHA3_384withECDSA signatures + public static final class SHA3_384 extends ECDSASignature { + public SHA3_384() { + super("SHA3-384"); + } + } + + // Nested class for SHA3_384withECDSAinP1363Format signatures + public static final class SHA3_384inP1363Format extends ECDSASignature { + public SHA3_384inP1363Format() { + super("SHA3-384", true); + } + } + + // Nested class for SHA3_512withECDSA signatures + public static final class SHA3_512 extends ECDSASignature { + public SHA3_512() { + super("SHA3-512"); + } + } + + // Nested class for SHA3_512withECDSAinP1363Format signatures + public static final class SHA3_512inP1363Format extends ECDSASignature { + public SHA3_512inP1363Format() { + super("SHA3-512", true); + } + } + // initialize for verification. See JCA doc @Override protected void engineInitVerify(PublicKey publicKey) diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java index d84ffaa815c75..e5c7d404c533c 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java @@ -157,8 +157,20 @@ public Object newInstance(Object ctrParamObj) } else if (algo.equals("NONEwithECDSA")) { return (inP1363? new ECDSASignature.RawinP1363Format() : new ECDSASignature.Raw()); - } - } else if (type.equals("KeyFactory")) { + } else if (algo.equals("SHA3-224withECDSA")) { + return (inP1363? new ECDSASignature.SHA3_224inP1363Format() : + new ECDSASignature.SHA3_224()); + } else if (algo.equals("SHA3-256withECDSA")) { + return (inP1363? new ECDSASignature.SHA3_256inP1363Format() : + new ECDSASignature.SHA3_256()); + } else if (algo.equals("SHA3-384withECDSA")) { + return (inP1363? new ECDSASignature.SHA3_384inP1363Format() : + new ECDSASignature.SHA3_384()); + } else if (algo.equals("SHA3-512withECDSA")) { + return (inP1363? new ECDSASignature.SHA3_512inP1363Format() : + new ECDSASignature.SHA3_512()); + } + } else if (type.equals("KeyFactory")) { if (algo.equals("EC")) { return new ECKeyFactory(); } else if (algo.equals("XDH")) { @@ -304,6 +316,18 @@ void putEntries() { putService(new ProviderServiceA(this, "Signature", "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512", ATTRS)); + putService(new ProviderServiceA(this, "Signature", + "SHA3-224withECDSA", "sun.security.ec.ECDSASignature$SHA3_224", + ATTRS)); + putService(new ProviderServiceA(this, "Signature", + "SHA3-256withECDSA", "sun.security.ec.ECDSASignature$SHA3_256", + ATTRS)); + putService(new ProviderServiceA(this, "Signature", + "SHA3-384withECDSA", "sun.security.ec.ECDSASignature$SHA3_384", + ATTRS)); + putService(new ProviderServiceA(this, "Signature", + "SHA3-512withECDSA", "sun.security.ec.ECDSASignature$SHA3_512", + ATTRS)); putService(new ProviderService(this, "Signature", "NONEwithECDSAinP1363Format", @@ -324,6 +348,19 @@ void putEntries() { "SHA512withECDSAinP1363Format", "sun.security.ec.ECDSASignature$SHA512inP1363Format")); + putService(new ProviderService(this, "Signature", + "SHA3-224withECDSAinP1363Format", + "sun.security.ec.ECDSASignature$SHA3_224inP1363Format")); + putService(new ProviderService(this, "Signature", + "SHA3-256withECDSAinP1363Format", + "sun.security.ec.ECDSASignature$SHA3_256inP1363Format")); + putService(new ProviderService(this, "Signature", + "SHA3-384withECDSAinP1363Format", + "sun.security.ec.ECDSASignature$SHA3_384inP1363Format")); + putService(new ProviderService(this, "Signature", + "SHA3-512withECDSAinP1363Format", + "sun.security.ec.ECDSASignature$SHA3_512inP1363Format")); + /* * Key Pair Generator engine */ diff --git a/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp b/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp index 43d45eba025aa..69d3c30ae0129 100644 --- a/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp +++ b/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp @@ -44,8 +44,6 @@ size_t hash(const std::string& str) { } void launchApp() { - setlocale(LC_ALL, "en_US.utf8"); - const tstring launcherPath = SysInfo::getProcessModulePath(); const Package ownerPackage = Package::findOwnerOfFile(launcherPath); diff --git a/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp b/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp index b9f8f17d5d80d..3949716e51418 100644 --- a/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp +++ b/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp @@ -67,7 +67,6 @@ void initJvmLauncher() { int main(int argc, char *argv[]) { - setlocale(LC_ALL, "en_US.utf8"); if (jvmLauncher) { // This is the call from the thread spawned by JVM. // Skip initialization phase as we have done this already in the first diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java index 7a6d56e7f63ca..b323b69ea5252 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java @@ -999,9 +999,9 @@ HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean com /** * Adds phases in HotSpot JFR. * - * @see JFR.CompilerPhaseEvent#registerPhases and JFR.CompilerPhaseEvent#write + * @see JFR.CompilerPhaseEvent#write */ - native int registerCompilerPhases(String[] phases); + native int registerCompilerPhase(String phaseName); /** * @see JFR.CompilerPhaseEvent#write diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java index 29fc59111df45..7f6b99a2f43f9 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java @@ -21,7 +21,6 @@ * questions. */ - package jdk.vm.ci.hotspot; import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; @@ -33,8 +32,9 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; /** - * Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify it when events occur. - * The JFR events are defined in {see @code src/share/jfr/metadata/metadata.xml}. + * Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify + * it when events occur. The JFR events are defined in {see @code + * src/share/jfr/metadata/metadata.xml}. */ public final class JFR { @@ -60,22 +60,7 @@ public static final class CompilerPhaseEvent { private static final ConcurrentHashMap phaseToId = new ConcurrentHashMap<>(); private static int getPhaseToId(String phaseName) { - String[] phaseNames = { phaseName }; - return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhases(phaseNames)); - } - - /** - * Registers new compiler phases with JFR. This should be called during compiler initialization. - * - * @param phaseNames compiler phase names - */ - public static synchronized void registerPhases(String[] phaseNames) { - ArrayList toProcess = new ArrayList<>(Arrays.asList(phaseNames)); - toProcess.removeAll(phaseToId.keySet()); - int pid = compilerToVM().registerCompilerPhases(toProcess.toArray(new String[toProcess.size()])); - for (String phase : toProcess) { - phaseToId.put(phase, pid++); - } + return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhase(phaseName)); } /** @@ -92,8 +77,8 @@ public static void write(long startTime, String phaseName, int compileId, int ph } /** - * Helper methods for managing JFR CompilerInlining events. - * The events are defined in {see @code src/share/jfr/metadata/metadata.xml}. + * Helper methods for managing JFR CompilerInlining events. The events are defined in {see @code + * src/share/jfr/metadata/metadata.xml}. */ public static final class CompilerInliningEvent { @@ -112,4 +97,3 @@ public static void write(int compileId, ResolvedJavaMethod caller, ResolvedJavaM } } } - diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java index 8c64732eae2a2..893f3e358bbd6 100644 --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java @@ -84,7 +84,7 @@ public final class AMD64ArrayCompareToOp extends AMD64LIRInstruction { public AMD64ArrayCompareToOp(LIRGeneratorTool tool, int useAVX3Threshold, JavaKind kind1, JavaKind kind2, Value result, Value array1, Value array2, Value length1, Value length2) { super(TYPE); - assert CodeUtil.isPowerOf2(useAVX3Threshold) : "AVX3Threshold must be power of 2"; + assert useAVX3Threshold == 0 || CodeUtil.isPowerOf2(useAVX3Threshold) : "AVX3Threshold must be power of 2"; this.useAVX3Threshold = useAVX3Threshold; this.kind1 = kind1; this.kind2 = kind2; diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java index 6c82fb2e7e848..dcfeb9419381e 100644 --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java @@ -71,7 +71,7 @@ public final class AMD64StringLatin1InflateOp extends AMD64LIRInstruction { public AMD64StringLatin1InflateOp(LIRGeneratorTool tool, int useAVX3Threshold, Value src, Value dst, Value len) { super(TYPE); - assert CodeUtil.isPowerOf2(useAVX3Threshold) : "AVX3Threshold must be power of 2"; + assert useAVX3Threshold == 0 || CodeUtil.isPowerOf2(useAVX3Threshold) : "AVX3Threshold must be power of 2"; this.useAVX3Threshold = useAVX3Threshold; assert asRegister(src).equals(rsi); diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java index 8b04f272b70ea..da6ac047008f7 100644 --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java @@ -76,7 +76,7 @@ public final class AMD64StringUTF16CompressOp extends AMD64LIRInstruction { public AMD64StringUTF16CompressOp(LIRGeneratorTool tool, int useAVX3Threshold, Value res, Value src, Value dst, Value len) { super(TYPE); - assert CodeUtil.isPowerOf2(useAVX3Threshold) : "AVX3Threshold must be power of 2"; + assert useAVX3Threshold == 0 || CodeUtil.isPowerOf2(useAVX3Threshold) : "AVX3Threshold must be power of 2"; this.useAVX3Threshold = useAVX3Threshold; assert asRegister(src).equals(rsi); diff --git a/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java b/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java index f714e22a529fc..31ad7e483208d 100644 --- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java +++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java @@ -586,12 +586,14 @@ void validateAssignment(ValueContainer destination) */ JNITypeParser destSig = new JNITypeParser(destination.signature()); - JNITypeParser sourceSig = new JNITypeParser(type().signature()); if (destSig.isPrimitive()) { throw new InvalidTypeException("Can't assign object value to primitive"); } - if (destSig.isArray() && !sourceSig.isArray()) { - throw new InvalidTypeException("Can't assign non-array value to an array"); + if (destSig.isArray()) { + JNITypeParser sourceSig = new JNITypeParser(type().signature()); + if (!sourceSig.isArray()) { + throw new InvalidTypeException("Can't assign non-array value to an array"); + } } if (destSig.isVoid()) { throw new InvalidTypeException("Can't assign object value to a void"); diff --git a/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp b/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp index 448295122bde3..f143e28feee87 100644 --- a/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp +++ b/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp @@ -95,6 +95,51 @@ TEST(PrimitiveConversionsTest, round_trip_int) { EXPECT_EQ(ufive, PrimitiveConversions::cast(PrimitiveConversions::cast(ufive))); } +TEST(PrimitiveConversionsTest, round_trip_int_constexpr) { + constexpr int sfive = 5; + constexpr int mfive = -5; + constexpr uint ufive = 5u; + + typedef PrimitiveConversionsTestSupport::Signed::type SI; + typedef PrimitiveConversionsTestSupport::Unsigned::type UI; + + { + constexpr SI i = PrimitiveConversions::cast(sfive); + constexpr int r = PrimitiveConversions::cast(i); + EXPECT_EQ(sfive, r); + } + + { + constexpr UI i = PrimitiveConversions::cast(sfive); + constexpr int r = PrimitiveConversions::cast(i); + EXPECT_EQ(sfive, r); + } + + { + constexpr SI i = PrimitiveConversions::cast(mfive); + constexpr int r = PrimitiveConversions::cast(i); + EXPECT_EQ(mfive, r); + } + + { + constexpr UI i = PrimitiveConversions::cast(mfive); + constexpr int r = PrimitiveConversions::cast(i); + EXPECT_EQ(mfive, r); + } + + { + constexpr SI i = PrimitiveConversions::cast(ufive); + constexpr uint r = PrimitiveConversions::cast(i); + EXPECT_EQ(ufive, r); + } + + { + constexpr UI i = PrimitiveConversions::cast(ufive); + constexpr uint r = PrimitiveConversions::cast(i); + EXPECT_EQ(ufive, r); + } +} + TEST(PrimitiveConversionsTest, round_trip_float) { float ffive = 5.0f; double dfive = 5.0; diff --git a/test/hotspot/gtest/runtime/test_arguments.cpp b/test/hotspot/gtest/runtime/test_arguments.cpp index b6121ba3abaab..81bae6c468aec 100644 --- a/test/hotspot/gtest/runtime/test_arguments.cpp +++ b/test/hotspot/gtest/runtime/test_arguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -153,7 +153,7 @@ static intx calc_expected(julong small_xss_input) { assert(small_xss_input <= max_julong / 2, "Sanity"); // Match code in arguments.cpp - julong julong_ret = align_up_(small_xss_input, K) / K; + julong julong_ret = align_up(small_xss_input, K) / K; assert(julong_ret <= (julong)max_intx, "Overflow: " JULONG_FORMAT, julong_ret); return (intx)julong_ret; } diff --git a/test/hotspot/gtest/utilities/test_align.cpp b/test/hotspot/gtest/utilities/test_align.cpp index e522acc5f012c..1097dd6c4f7ca 100644 --- a/test/hotspot/gtest/utilities/test_align.cpp +++ b/test/hotspot/gtest/utilities/test_align.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,82 @@ #include "utilities/align.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/globalDefinitions.hpp" -#include "unittest.hpp" - #include +#include "unittest.hpp" // A few arbitrarily chosen values to test the align functions on. -static uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, uint64_t(-1)}; +static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, uint64_t(-1)}; template -static T max_alignment() { +static constexpr T max_alignment() { T max = std::numeric_limits::max(); return max ^ (max >> 1); } #define log(...) SCOPED_TRACE(err_msg(__VA_ARGS__).buffer()) +struct StaticTestAlignmentsResult { + uint64_t _value; + uint64_t _alignment; + int _status; // 0: success, > 0 indicates which failure case + constexpr StaticTestAlignmentsResult(uint64_t value, uint64_t alignment, int status) : + _value(value), _alignment(alignment), _status(status) {} +}; + +// Structure copied from test_alignments runtime test (below). +template +static constexpr StaticTestAlignmentsResult +static_test_alignments_aux(A alignment) { + using Result = StaticTestAlignmentsResult; + + for ( ; alignment > 0; alignment >>= 1) { + for (size_t i = 0; i < ARRAY_SIZE(values); ++i) { + // Test align up + uint64_t up = align_up(values[i], alignment); + if (0 < up && up < uint64_t(std::numeric_limits::max())) { + T value = T(values[i]); + if (align_up(uint64_t(value), alignment) != up) { + return Result(values[i], alignment, 1); + } else if (align_up(value, alignment) < value) { + return Result(values[i], alignment, 2); + } + } + + // Test align down + uint64_t down = align_down(values[i], alignment); + if (down <= uint64_t(std::numeric_limits::max())) { + T value = T(values[i]); + if (uint64_t(align_down(value, alignment)) != down) { + return Result(values[i], alignment, 3); + } else if (align_down(value, alignment) > value) { + return Result(values[i], alignment, 4); + } + } + + // Test is aligned + bool is = is_aligned(values[i], alignment); + if (values[i] <= uint64_t(std::numeric_limits::max())) { + T value = T(values[i]); + if (is_aligned(value, alignment) != is) { + return Result(values[i], alignment, 5); + } + } + } + } + return Result(T(), A(), 0); +} + +template +static void static_test_alignments() { + constexpr StaticTestAlignmentsResult result + = static_test_alignments_aux(max_alignment()); + + EXPECT_EQ(0, result._status) + << "value = " << result._value + << ", alignment = " << result._alignment + << ", status = " << result._status; +} + template static void test_alignments() { log("### Test: %c" SIZE_FORMAT " " UINT64_FORMAT " : %c" SIZE_FORMAT " " UINT64_FORMAT " ###\n", @@ -54,7 +115,7 @@ static void test_alignments() { log("--- Value: " UINT64_FORMAT "\n", values[i]); // Test align up - const uint64_t up = align_up_(values[i], (uint64_t)alignment); + const uint64_t up = align_up(values[i], alignment); if (0 < up && up <= (uint64_t)std::numeric_limits::max()) { log("Testing align_up: alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: 0x" UINT64_FORMAT_X "\n", (uint64_t)alignment, values[i], up); @@ -62,14 +123,12 @@ static void test_alignments() { // Check against uint64_t version ASSERT_EQ(align_up((uint64_t)value, alignment), up); - // Check inline function vs macro - ASSERT_EQ(align_up(value, alignment), align_up_(value, alignment)); // Sanity check ASSERT_GE(align_up(value, alignment), value); } // Test align down - const uint64_t down = align_down_(values[i], (uint64_t)alignment); + const uint64_t down = align_down(values[i], alignment); if (down <= (uint64_t)std::numeric_limits::max()) { log("Testing align_down: alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: 0x" UINT64_FORMAT_X "\n", (uint64_t)alignment, values[i], down); @@ -77,14 +136,12 @@ static void test_alignments() { // Check against uint64_t version ASSERT_EQ((uint64_t)align_down(value, alignment), down); - // Check inline function vs macro - ASSERT_EQ(align_down(value, alignment), align_down_(value, alignment)); // Sanity check ASSERT_LE(align_down(value, alignment), value); } // Test is aligned - const bool is = is_aligned_(values[i], (uint64_t)alignment); + const bool is = is_aligned(values[i], alignment); if (values[i] <= (uint64_t)std::numeric_limits::max()) { log("Testing is_aligned: alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: %s\n", (uint64_t)alignment, values[i], is ? "true" : "false"); @@ -92,14 +149,14 @@ static void test_alignments() { // Check against uint64_t version ASSERT_EQ(is_aligned(value, alignment), is); - // Check inline function vs macro - ASSERT_EQ(is_aligned(value, alignment), is_aligned_(value, alignment)); } } } + + static_test_alignments(); } -TEST(Align, functions_and_macros) { +TEST(Align, alignments) { // Test the alignment functions with different type combinations. test_alignments(); diff --git a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp index a920351ee789b..e82eea051aed3 100644 --- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp +++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp @@ -23,9 +23,10 @@ #include "precompiled.hpp" #include "runtime/os.hpp" -#include "unittest.hpp" #include "utilities/align.hpp" #include "utilities/globalDefinitions.hpp" +#include +#include "unittest.hpp" static ::testing::AssertionResult testPageAddress( const char* expected_addr_expr, @@ -192,7 +193,7 @@ TEST(globalDefinitions, byte_size_in_exact_unit) { #define EXPECT_EQ_LOG2(fn, type) \ { \ int limit = sizeof (type) * BitsPerByte; \ - if (IsSigned::value) { \ + if (std::is_signed::value) { \ EXPECT_EQ(limit - 1, fn(std::numeric_limits::min())); \ EXPECT_EQ(limit - 1, fn((type)-1)); \ limit--; \ diff --git a/test/hotspot/gtest/utilities/test_population_count.cpp b/test/hotspot/gtest/utilities/test_population_count.cpp index a5320817ac258..4ed6513ec1364 100644 --- a/test/hotspot/gtest/utilities/test_population_count.cpp +++ b/test/hotspot/gtest/utilities/test_population_count.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "utilities/population_count.hpp" #include "utilities/powerOfTwo.hpp" #include "utilities/globalDefinitions.hpp" +#include #include "unittest.hpp" #define BITS_IN_BYTE_ARRAY_SIZE 256 @@ -51,8 +52,8 @@ const uint8_t test_popcnt_bitsInByte[BITS_IN_BYTE_ARRAY_SIZE] = { }; template -void sparse() { - const T max_val = max_value(); +static void sparse() { + const T max_val = std::numeric_limits::max(); // Step through the entire input range from a random starting point, // verify population_count return values against the lookup table @@ -95,4 +96,4 @@ TEST(population_count, sparse32) { } TEST(population_count, sparse64) { sparse(); -} \ No newline at end of file +} diff --git a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp index 795918d144fdd..54802a37b7b5a 100644 --- a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp +++ b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,20 +25,57 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/powerOfTwo.hpp" +#include +#include #include "unittest.hpp" -template T max_pow2() { - T max_val = max_value(); +template static constexpr T max_pow2() { + T max_val = std::numeric_limits::max(); return max_val - (max_val >> 1); } +struct StaticTestIsPowerOf2Result { + uint64_t _value; + int _status; // 0: success, > 0 indicates which failure case + constexpr StaticTestIsPowerOf2Result(uint64_t value, int status) : + _value(value), _status(status) {} +}; + +// Structure copied from test_is_power_of_2 runtime test (below). +template +static constexpr StaticTestIsPowerOf2Result static_test_is_power_of_2_aux(T v) { + using Result = StaticTestIsPowerOf2Result; + for ( ; v > 0; v >>= 1) { + if (!is_power_of_2(v)) { + return Result(v, 1); + } else if ((v > 2) && is_power_of_2(T(v - 1))) { + return Result(v, 2); + } else if ((v > 1) && is_power_of_2(T(v + 1))) { + return Result(v, 3); + } + } + return Result(v, 0); +} + +template +static void static_test_is_power_of_2() { + constexpr StaticTestIsPowerOf2Result result + = static_test_is_power_of_2_aux(max_pow2()); + + EXPECT_EQ(0, result._status) + << "value = " << result._value << ", status = " << result._status; +} + template static void test_is_power_of_2() { EXPECT_FALSE(is_power_of_2(T(0))); EXPECT_FALSE(is_power_of_2(~T(0))); - if (IsSigned::value) { - EXPECT_FALSE(is_power_of_2(std::numeric_limits::min())); - } + static_assert(!is_power_of_2(T(0)), ""); + static_assert(!is_power_of_2(~T(0)), ""); + + // Should be false regardless of whether T is signed or unsigned. + EXPECT_FALSE(is_power_of_2(std::numeric_limits::min())); + static_assert(!is_power_of_2(std::numeric_limits::min()), ""); // Test true for (T i = max_pow2(); i > 0; i = (i >> 1)) { @@ -54,6 +91,8 @@ template static void test_is_power_of_2() { for (T i = max_pow2(); i > 1; i = (i >> 1)) { EXPECT_FALSE(is_power_of_2(i + 1)) << "value = " << T(i + 1); } + + static_test_is_power_of_2(); } TEST(power_of_2, is_power_of_2) { diff --git a/test/jdk/java/awt/ColorClass/AlphaColorTest.java b/test/jdk/java/awt/ColorClass/AlphaColorTest.java index b26bb0616f4b3..e3478c961fc02 100644 --- a/test/jdk/java/awt/ColorClass/AlphaColorTest.java +++ b/test/jdk/java/awt/ColorClass/AlphaColorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,8 +84,8 @@ public void paint(Graphics g) { Color color = new Color(255, 255, 255, 127); frame.add("Center", new AlphaColorTest(color)); frame.setUndecorated(true); - frame.setLocationRelativeTo(null); frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); } } diff --git a/test/jdk/java/security/SignedObject/Chain.java b/test/jdk/java/security/SignedObject/Chain.java index 71fd79dd4c3ee..b4a5ea794e6bc 100644 --- a/test/jdk/java/security/SignedObject/Chain.java +++ b/test/jdk/java/security/SignedObject/Chain.java @@ -1,5 +1,5 @@ -/** - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. +/* + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,6 +71,13 @@ static enum SigAlg { SHA1withDSA("SHA1withDSA"), SHA224withDSA("SHA224withDSA"), SHA256withDSA("SHA256withDSA"), + SHA384withDSA("SHA384withDSA"), + SHA512withDSA("SHA512withDSA"), + + SHA3_224withDSA("SHA3-224withDSA"), + SHA3_256withDSA("SHA3-256withDSA"), + SHA3_384withDSA("SHA3-384withDSA"), + SHA3_512withDSA("SHA3-512withDSA"), SHA1withRSA("Sha1withrSA"), SHA224withRSA("SHA224withRSA"), @@ -79,12 +86,20 @@ static enum SigAlg { SHA512withRSA("SHA512withRSA"), SHA512_224withRSA("SHA512/224withRSA"), SHA512_256withRSA("SHA512/256withRSA"), + SHA3_224withRSA("SHA3-224withRSA"), + SHA3_256withRSA("SHA3-256withRSA"), + SHA3_384withRSA("SHA3-384withRSA"), + SHA3_512withRSA("SHA3-512withRSA"), SHA1withECDSA("SHA1withECDSA"), - SHA256withECDSA("SHA256withECDSA"), SHA224withECDSA("SHA224withECDSA"), + SHA256withECDSA("SHA256withECDSA"), SHA384withECDSA("SHA384withECDSA"), SHA512withECDSA("SHA512withECDSA"), + SHA3_224withECDSA("SHA3-224withECDSA"), + SHA3_256withECDSA("SHA3-256withECDSA"), + SHA3_384withECDSA("SHA3-384withECDSA"), + SHA3_512withECDSA("SHA3-512withECDSA"), MD5andSHA1withRSA("MD5andSHA1withRSA"), @@ -147,7 +162,10 @@ public String toString() { new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default, 1024), new Test(SigAlg.MD2withRSA, KeyAlg.RSA, Provider.Default), new Test(SigAlg.MD5withRSA, KeyAlg.RSA, Provider.Default), - new Test(SigAlg.SHA1withRSA, KeyAlg.RSA, Provider.Default), + new Test(SigAlg.SHA3_224withRSA, KeyAlg.RSA, Provider.Default), + new Test(SigAlg.SHA3_256withRSA, KeyAlg.RSA, Provider.Default), + new Test(SigAlg.SHA3_384withRSA, KeyAlg.RSA, Provider.Default), + new Test(SigAlg.SHA3_512withRSA, KeyAlg.RSA, Provider.Default), new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun, 1024), new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun, 2048), new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun, 2048), diff --git a/test/jdk/javax/swing/Box/TestBoxFiller.java b/test/jdk/javax/swing/Box/TestBoxFiller.java new file mode 100644 index 0000000000000..e1dd269be0cc4 --- /dev/null +++ b/test/jdk/javax/swing/Box/TestBoxFiller.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 8253016 + @key headful + @summary Verifies Box.Filler components should be unfocusable by default + @run main TestBoxFiller + */ +import java.awt.ContainerOrderFocusTraversalPolicy; +import java.awt.KeyboardFocusManager; +import java.beans.PropertyChangeEvent; +import javax.swing.Box; +import javax.swing.JFrame; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import java.awt.Robot; +import java.awt.event.KeyEvent; + +public class TestBoxFiller +{ + private static JFrame frame; + private static void showFocusOwner(PropertyChangeEvent e) + { + Object c = e.getNewValue(); + if (c instanceof Box.Filler) { + throw new RuntimeException("Box.Filler having focus"); + } + } + + public static void main(String[] args) throws Exception + { + try { + Robot robot = new Robot(); + robot.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + KeyboardFocusManager m = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + m.addPropertyChangeListener("focusOwner", TestBoxFiller::showFocusOwner); + + Box box = Box.createHorizontalBox(); + JTextField tf1 = new JTextField("Test"); + tf1.setColumns(40); + JTextField tf2 = new JTextField("Test"); + tf2.setColumns(40); + box.add(tf1); + box.add(Box.createHorizontalStrut(20)); + box.add(tf2); + frame.setContentPane(box); + frame.setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy()); + frame.pack(); + frame.setVisible(true); + frame.setLocationRelativeTo(null); + tf1.requestFocusInWindow(); + }); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java b/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java index 69508b93a3c81..b7a7494c9924e 100644 --- a/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java +++ b/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ public class bug7154841 { private static void initAndShowUI() { popupMenu = new JPopupMenu(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 400; i++) { JRadioButtonMenuItem item = new JRadioButtonMenuItem(" Test " + i); item.addMouseMotionListener(new MouseMotionAdapter() { @Override diff --git a/test/jdk/sun/security/ec/SignatureKAT.java b/test/jdk/sun/security/ec/SignatureKAT.java new file mode 100644 index 0000000000000..d1fa6f702cfa6 --- /dev/null +++ b/test/jdk/sun/security/ec/SignatureKAT.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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.Convert; + +import java.security.*; +import java.security.spec.*; +import java.math.*; +import java.util.*; + +/* + * @test + * @bug 8172366 + * @summary Known Answer Test for ECDSA signature + * @library /test/lib + * @build jdk.test.lib.Convert + * @run main/othervm SignatureKAT + */ +public class SignatureKAT { + + private static String checkHex(String hex) { + // if hex length is odd, need to prepend 0 + if (hex.length() % 2 != 0) { + hex = "0" + hex; + } + return hex; + } + + private static class CurveData { + private String name; + private byte[] msgBytes; + private BigInteger priv; + private BigInteger pubX; + private BigInteger pubY; + + private static BigInteger toBigInteger(String hex) { + byte[] bytes = Convert.hexStringToByteArray(checkHex(hex)); + return new BigInteger(1, bytes); + } + CurveData(String name, String msg, String priv, String pubX, + String pubY) { + this.name = name; + this.msgBytes = msg.getBytes(); + this.priv = toBigInteger(priv); + this.pubX = toBigInteger(pubX); + this.pubY = toBigInteger(pubY); + } + } + + private static class TestData { + private String sigName; + private CurveData cd; + private byte[] expSig; + + TestData(String sigName, CurveData cd, String r, String s) { + this.sigName = sigName; + this.cd = cd; + if (r.length() != s.length() || r != checkHex(r) || + s != checkHex(s)) { + throw new RuntimeException("Error: invalid r, s"); + } + this.expSig = Convert.hexStringToByteArray(r + s); + } + } + + // These test values are from the examples shown in the page below: + // https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values + private static final CurveData P_256 = new CurveData( + "secp256r1", "Example of ECDSA with P-256", + "C477F9F65C22CCE20657FAA5B2D1D8122336F851A508A1ED04E479C34985BF96", + "B7E08AFDFE94BAD3F1DC8C734798BA1C62B3A0AD1E9EA2A38201CD0889BC7A19", + "3603F747959DBF7A4BB226E41928729063ADC7AE43529E61B563BBC606CC5E09" + ); + + private static final CurveData P_384 = new CurveData( + "secp384r1", "Example of ECDSA with P-384", + "F92C02ED629E4B48C0584B1C6CE3A3E3B4FAAE4AFC6ACB0455E73DFC392E6A0AE393A8565E6B9714D1224B57D83F8A08", + "3BF701BC9E9D36B4D5F1455343F09126F2564390F2B487365071243C61E6471FB9D2AB74657B82F9086489D9EF0F5CB5", + "D1A358EAFBF952E68D533855CCBDAA6FF75B137A5101443199325583552A6295FFE5382D00CFCDA30344A9B5B68DB855" + ); + + private static final CurveData P_521 = new CurveData( + "secp521r1", "Example of ECDSA with P-521", + "100085F47B8E1B8B11B7EB33028C0B2888E304BFC98501955B45BBA1478DC184EEEDF09B86A5F7C21994406072787205E69A63709FE35AA93BA333514B24F961722", + "98E91EEF9A68452822309C52FAB453F5F117C1DA8ED796B255E9AB8F6410CCA16E59DF403A6BDC6CA467A37056B1E54B3005D8AC030DECFEB68DF18B171885D5C4", + "164350C321AECFC1CCA1BA4364C9B15656150B4B78D6A48D7D28E7F31985EF17BE8554376B72900712C4B83AD668327231526E313F5F092999A4632FD50D946BC2E" + ); + + private static TestData[] TEST_DATUM = { + // secp256r1, secp384r1, and secp521r1 remain enabled + new TestData("SHA256withECDSAinP1363Format", P_256, + "2B42F576D07F4165FF65D1F3B1500F81E44C316F1F0B3EF57325B69ACA46104F", + "DC42C2122D6392CD3E3A993A89502A8198C1886FE69D262C4B329BDB6B63FAF1"), + new TestData("SHA3-256withECDSAinP1363Format", P_256, + "2B42F576D07F4165FF65D1F3B1500F81E44C316F1F0B3EF57325B69ACA46104F", + "0A861C2526900245C73BACB9ADAEC1A5ACB3BA1F7114A3C334FDCD5B7690DADD"), + new TestData("SHA384withECDSAinP1363Format", P_384, + "30EA514FC0D38D8208756F068113C7CADA9F66A3B40EA3B313D040D9B57DD41A332795D02CC7D507FCEF9FAF01A27088", + "CC808E504BE414F46C9027BCBF78ADF067A43922D6FCAA66C4476875FBB7B94EFD1F7D5DBE620BFB821C46D549683AD8"), + new TestData("SHA3-384withECDSAinP1363Format", P_384, + "30EA514FC0D38D8208756F068113C7CADA9F66A3B40EA3B313D040D9B57DD41A332795D02CC7D507FCEF9FAF01A27088", + "691B9D4969451A98036D53AA725458602125DE74881BBC333012CA4FA55BDE39D1BF16A6AAE3FE4992C567C6E7892337"), + new TestData("SHA512withECDSAinP1363Format", P_521, + "0140C8EDCA57108CE3F7E7A240DDD3AD74D81E2DE62451FC1D558FDC79269ADACD1C2526EEEEF32F8C0432A9D56E2B4A8A732891C37C9B96641A9254CCFE5DC3E2BA", + "00D72F15229D0096376DA6651D9985BFD7C07F8D49583B545DB3EAB20E0A2C1E8615BD9E298455BDEB6B61378E77AF1C54EEE2CE37B2C61F5C9A8232951CB988B5B1"), + new TestData("SHA3-512withECDSAinP1363Format", P_521, + "0140C8EDCA57108CE3F7E7A240DDD3AD74D81E2DE62451FC1D558FDC79269ADACD1C2526EEEEF32F8C0432A9D56E2B4A8A732891C37C9B96641A9254CCFE5DC3E2BA", + "00B25188492D58E808EDEBD7BF440ED20DB771CA7C618595D5398E1B1C0098E300D8C803EC69EC5F46C84FC61967A302D366C627FCFA56F87F241EF921B6E627ADBF"), + }; + + private static void runTest(TestData td) throws Exception { + System.out.println("Testing " + td.sigName + " with " + td.cd.name); + + AlgorithmParameters params = + AlgorithmParameters.getInstance("EC", "SunEC"); + params.init(new ECGenParameterSpec(td.cd.name)); + ECParameterSpec ecParams = + params.getParameterSpec(ECParameterSpec.class); + + KeyFactory kf = KeyFactory.getInstance("EC", "SunEC"); + PrivateKey privKey = kf.generatePrivate + (new ECPrivateKeySpec(td.cd.priv, ecParams)); + + Signature sig = Signature.getInstance(td.sigName, "SunEC"); + sig.initSign(privKey); + sig.update(td.cd.msgBytes); + // NOTE: there is no way to set the nonce value into current SunEC + // ECDSA signature, thus the output signature bytes likely won't + // match the expected signature bytes + byte[] ov = sig.sign(); + + ECPublicKeySpec pubKeySpec = new ECPublicKeySpec + (new ECPoint(td.cd.pubX, td.cd.pubY), ecParams); + PublicKey pubKey = kf.generatePublic(pubKeySpec); + + sig.initVerify(pubKey); + sig.update(td.cd.msgBytes); + if (!sig.verify(ov)) { + throw new RuntimeException("Error verifying actual sig bytes"); + } + + sig.update(td.cd.msgBytes); + if (!sig.verify(td.expSig)) { + throw new RuntimeException("Error verifying expected sig bytes"); + } + } + + public static void main(String[] args) throws Exception { + for (TestData td : TEST_DATUM) { + runTest(td); + } + } +} diff --git a/test/jdk/sun/security/ec/SignatureOffsets.java b/test/jdk/sun/security/ec/SignatureOffsets.java index 3570258c861b2..3ea886a3f2aa2 100644 --- a/test/jdk/sun/security/ec/SignatureOffsets.java +++ b/test/jdk/sun/security/ec/SignatureOffsets.java @@ -43,6 +43,10 @@ * @run main SignatureOffsets SunEC SHA224withECDSA * @run main SignatureOffsets SunEC SHA384withECDSA * @run main SignatureOffsets SunEC SHA512withECDSA + * @run main SignatureOffsets SunEC SHA3-256withECDSA + * @run main SignatureOffsets SunEC SHA3-224withECDSA + * @run main SignatureOffsets SunEC SHA3-384withECDSA + * @run main SignatureOffsets SunEC SHA3-512withECDSA */ public class SignatureOffsets { diff --git a/test/jdk/sun/security/ec/SignedObjectChain.java b/test/jdk/sun/security/ec/SignedObjectChain.java index 6a5b7c93f6640..cfeff8c1ad587 100644 --- a/test/jdk/sun/security/ec/SignedObjectChain.java +++ b/test/jdk/sun/security/ec/SignedObjectChain.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8050374 8146293 + * @bug 8050374 8146293 8172366 * @summary Verify a chain of signed objects * @library /test/lib * @build jdk.test.lib.SigTestUtil @@ -41,10 +41,14 @@ public Test(Chain.SigAlg sigAlg) { private static final Test[] tests = { new Test(Chain.SigAlg.SHA1withECDSA), - new Test(Chain.SigAlg.SHA256withECDSA), new Test(Chain.SigAlg.SHA224withECDSA), + new Test(Chain.SigAlg.SHA256withECDSA), new Test(Chain.SigAlg.SHA384withECDSA), new Test(Chain.SigAlg.SHA512withECDSA), + new Test(Chain.SigAlg.SHA3_224withECDSA), + new Test(Chain.SigAlg.SHA3_256withECDSA), + new Test(Chain.SigAlg.SHA3_384withECDSA), + new Test(Chain.SigAlg.SHA3_512withECDSA), }; public static void main(String argv[]) { diff --git a/test/jdk/sun/security/rsa/SignatureOffsets.java b/test/jdk/sun/security/rsa/SignatureOffsets.java index 1db628cac3112..15df99c466502 100644 --- a/test/jdk/sun/security/rsa/SignatureOffsets.java +++ b/test/jdk/sun/security/rsa/SignatureOffsets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ /* * @test - * @bug 8050374 8146293 + * @bug 8050374 8146293 8172366 * @key randomness * @summary This test validates signature verification * Signature.verify(byte[], int, int). The test uses RandomFactory to @@ -46,6 +46,10 @@ * @run main SignatureOffsets SunRsaSign SHA512withRSA * @run main SignatureOffsets SunRsaSign SHA512/224withRSA * @run main SignatureOffsets SunRsaSign SHA512/256withRSA + * @run main SignatureOffsets SunRsaSign SHA3-224withRSA + * @run main SignatureOffsets SunRsaSign SHA3-256withRSA + * @run main SignatureOffsets SunRsaSign SHA3-384withRSA + * @run main SignatureOffsets SunRsaSign SHA3-512withRSA */ public class SignatureOffsets { diff --git a/test/jdk/sun/security/rsa/pss/PSSParametersTest.java b/test/jdk/sun/security/rsa/pss/PSSParametersTest.java index 2fde948fdc91a..c71e5bb34a4d2 100644 --- a/test/jdk/sun/security/rsa/pss/PSSParametersTest.java +++ b/test/jdk/sun/security/rsa/pss/PSSParametersTest.java @@ -31,7 +31,7 @@ /** * @test - * @bug 8146293 8242556 + * @bug 8146293 8242556 8172366 * @summary Test RSASSA-PSS AlgorithmParameters impl of SunRsaSign provider. * @run main PSSParametersTest */ @@ -50,6 +50,8 @@ public static void main(String[] args) throws Exception { System.out.println("Testing against custom parameters"); test(new PSSParameterSpec("SHA-512/224", "MGF1", MGF1ParameterSpec.SHA384, 100, 1)); + test(new PSSParameterSpec("SHA3-256", "MGF1", + new MGF1ParameterSpec("SHA3-256"), 256>>3, 1)); System.out.println("Test Passed"); } @@ -57,6 +59,7 @@ public static void main(String[] args) throws Exception { // bytes, then initialize w/ the DER bytes, retrieve the spec. // compare both spec for equality and throw exception if the check failed. private static void test(PSSParameterSpec spec) throws Exception { + System.out.println("Testing PSS spec: " + spec); String ALGORITHMS[] = { PSS_ALGO, PSS_OID }; for (String alg : ALGORITHMS) { AlgorithmParameters params = AlgorithmParameters.getInstance @@ -67,9 +70,9 @@ private static void test(PSSParameterSpec spec) throws Exception { (alg, PROVIDER); params2.init(encoded); PSSParameterSpec spec2 = params2.getParameterSpec - (PSSParameterSpec.class); + (PSSParameterSpec.class); if (!isEqual(spec, spec2)) { - throw new RuntimeException("Spec check Failed for " + alg); + throw new RuntimeException("Spec check Failed for " + alg); } } } diff --git a/test/jdk/sun/security/rsa/pss/SignatureTest2.java b/test/jdk/sun/security/rsa/pss/SignatureTest2.java index f510484200130..ea548d04dad09 100644 --- a/test/jdk/sun/security/rsa/pss/SignatureTest2.java +++ b/test/jdk/sun/security/rsa/pss/SignatureTest2.java @@ -31,7 +31,7 @@ /** * @test - * @bug 8146293 8238448 + * @bug 8146293 8238448 8172366 * @summary Create a signature for RSASSA-PSS and get its signed data. * re-initiate the signature with the public key. The signature * can be verified by acquired signed data. @@ -68,7 +68,8 @@ public class SignatureTest2 { */ private static final String[] DIGEST_ALG = { "SHA-1", "SHA-224", "SHA-256", "SHA-384", - "SHA-512", "SHA-512/224", "SHA-512/256" + "SHA-512", "SHA-512/224", "SHA-512/256", + "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512" }; private static final String SIG_ALG = "RSASSA-PSS"; diff --git a/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java b/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java index c9c7a27e186ec..7db7774870caa 100644 --- a/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java +++ b/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8146293 8242556 + * @bug 8146293 8242556 8172366 * @summary Test RSASSA-PSS Key related support such as KeyPairGenerator * and KeyFactory of the SunRsaSign provider */ @@ -145,11 +145,18 @@ public static void main(String[] args) throws Exception { KeyPair kp2 = kpg.generateKeyPair(); checkKeyPair(kp2); + params = new PSSParameterSpec("SHA3-256", "MGF1", + new MGF1ParameterSpec("SHA3-256"), 32, 1); + kpg.initialize(new RSAKeyGenParameterSpec(2048, pubExp, params)); + KeyPair kp3 = kpg.generateKeyPair(); + checkKeyPair(kp3); + KeyFactory kf = KeyFactory.getInstance(ALGO, "SunRsaSign"); test(kf, kp.getPublic()); test(kf, kp.getPrivate()); test(kf, kp2.getPublic()); test(kf, kp2.getPrivate()); - + test(kf, kp3.getPublic()); + test(kf, kp3.getPrivate()); } } diff --git a/test/langtools/jdk/jshell/CompletionSuggestionTest.java b/test/langtools/jdk/jshell/CompletionSuggestionTest.java index b78b25e33dfc8..1a024e298878f 100644 --- a/test/langtools/jdk/jshell/CompletionSuggestionTest.java +++ b/test/langtools/jdk/jshell/CompletionSuggestionTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8131025 8141092 8153761 8145263 8131019 8175886 8176184 8176241 8176110 8177466 8197439 8221759 8234896 + * @bug 8131025 8141092 8153761 8145263 8131019 8175886 8176184 8176241 8176110 8177466 8197439 8221759 8234896 8240658 * @summary Test Completion and Documentation * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -698,6 +698,27 @@ public void testMemberReferences() { assertCompletion("FI2 fi = C::|", true, "statConvert1", "statConvert3"); } + public void testBrokenLambdaCompletion() { + assertEval("interface Consumer { public void consume(T t); }"); + assertEval("interface Function { public R convert(T t); }"); + assertEval(" void m1(T t, Consumer f) { }"); + assertCompletion("m1(\"\", x -> {x.tri|", "trim()"); + assertEval(" void m2(T t, Function f) { }"); + assertCompletion("m2(\"\", x -> {x.tri|", "trim()"); + assertEval(" void m3(T t, Consumer f, int i) { }"); + assertCompletion("m3(\"\", x -> {x.tri|", "trim()"); + assertEval(" void m4(T t, Function f, int i) { }"); + assertCompletion("m4(\"\", x -> {x.tri|", "trim()"); + assertEval(" T m5(Consumer f) { return null; }"); + assertCompletion("String s = m5(x -> {x.tri|", "trim()"); + assertEval(" T m6(Function f) { return null; }"); + assertCompletion("String s = m6(x -> {x.tri|", "trim()"); + assertEval(" T m7(Consumer f, int i) { return null; }"); + assertCompletion("String s = m7(x -> {x.tri|", "trim()"); + assertEval(" T m8(Function f, int i) { return null; }"); + assertCompletion("String s = m8(x -> {x.tri|", "trim()"); + } + @BeforeMethod public void setUp() { super.setUp(); diff --git a/test/langtools/tools/javac/api/TestGetScopeResult.java b/test/langtools/tools/javac/api/TestGetScopeResult.java index 8f32df197d912..b2a2e500e0320 100644 --- a/test/langtools/tools/javac/api/TestGetScopeResult.java +++ b/test/langtools/tools/javac/api/TestGetScopeResult.java @@ -23,12 +23,13 @@ /* * @test - * @bug 8205418 8207229 8207230 8230847 8245786 8247334 8248641 + * @bug 8205418 8207229 8207230 8230847 8245786 8247334 8248641 8240658 * @summary Test the outcomes from Trees.getScope * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.util + * @compile TestGetScopeResult.java */ import java.io.IOException; @@ -62,6 +63,7 @@ import com.sun.source.util.TreePathScanner; import com.sun.source.util.Trees; import com.sun.tools.javac.api.JavacScope; +import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.comp.Analyzer; @@ -192,6 +194,19 @@ static interface BiFunction { } }""", invocationInMethodInvocation); + + String[] infer = { + "c:java.lang.String", + "super:java.lang.Object", + "this:Test" + }; + + doTest("class Test { void test() { cand(\"\", c -> { }); } void cand(T t, I i) { } interface I { public String test(T s); } }", + infer); + doTest("class Test { void test() { cand(\"\", c -> { }); } void cand(T t, I i, int j) { } interface I { public void test(T s); } }", + infer); + doTest("class Test { void test() { cand(\"\", c -> { }); } void cand(T t, I i, int j) { } interface I { public String test(T s); } }", + infer); } public void doTest(String code, String... expected) throws IOException { @@ -208,24 +223,29 @@ public String getCharContent(boolean ignoreEncodingErrors) { } JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, List.of(new MyFileObject())); CompilationUnitTree cut = t.parse().iterator().next(); - t.analyze(); - List actual = new ArrayList<>(); + ((JavacTaskImpl)t).enter(); - new TreePathScanner() { - @Override - public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { - Scope scope = Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getBody())); - actual.addAll(dumpScope(scope)); - return super.visitLambdaExpression(node, p); - } - }.scan(cut, null); + for (int r = 0; r < 2; r++) { + List actual = new ArrayList<>(); - List expectedList = List.of(expected); + new TreePathScanner() { + @Override + public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + Scope scope = Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getBody())); + actual.addAll(dumpScope(scope)); + return super.visitLambdaExpression(node, p); + } + }.scan(cut, null); + + List expectedList = List.of(expected); - if (!expectedList.equals(actual)) { - throw new IllegalStateException("Unexpected scope content: " + actual + "\n" + - "expected: " + expectedList); + if (!expectedList.equals(actual)) { + throw new IllegalStateException("Unexpected scope content: " + actual + "\n" + + "expected: " + expectedList); + } + + t.analyze(); } } } diff --git a/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReference.java b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReference.java new file mode 100644 index 0000000000000..741835a0a4fb9 --- /dev/null +++ b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReference.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 8240658 + * @summary Verify that broken method invocations with lambdas get type inference done + * @modules jdk.compiler + * @compile --enable-preview -source ${jdk.version} TestGetTypeMirrorReference.java + * @run main/othervm --enable-preview TestGetTypeMirrorReference + */ + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.*; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import javax.lang.model.type.TypeMirror; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/* + * This test verifies proper error recovery for method invocations which need + * type inference, and have lambdas as arguments. + * + * The test will read the adjacent TestGetTypeMirrorReferenceData.java, parse and + * attribute it, and call Trees.getTypeMirror on each place marked, in a block + * comment, with: + * getTypeMirror:: + * The actual retrieved TypeMirror will be checked against the provided description, + * verifying the return value of TypeMirror.getKind and TypeMirror.toString(). + * + * The AST for TestGetTypeMirrorReferenceData.java will also be printed using + * Tree.toString(), and compared to the expected AST form. + */ +public class TestGetTypeMirrorReference { + + private static final String JDK_VERSION = + Integer.toString(Runtime.version().feature()); + + public static void main(String... args) throws IOException { + analyze("TestGetTypeMirrorReferenceData.java", + """ + package test; + + public class TestGetTypeMirrorReferenceData { + + public TestGetTypeMirrorReferenceData() { + super(); + } + + private static void test() { + Test.of(1).convert((c1)->{ + Object o = c1; + }); + Test.of(1).consume((c2)->{ + Object o = c2; + return null; + }); + Test.of(1).consumeWithParam((c3)->{ + Object o = c3; + }); + convert(0, (c4)->{ + Object o = c4; + }); + consume(0, (c5)->{ + Object o = c5; + }); + convertVarArgs(0, (c6)->{ + Object o = c6; + }, 1, 2, 3, 4); + consumeVarArgs(0, (c7)->{ + Object o = c7; + }, 1, 2, 3, 4); + convertVarArgs2(0, (c8)->{ + Object o = c8; + }, (c8)->{ + Object o = c8; + }); + consumeVarArgs2(0, (c9)->{ + Object o = c9; + }, (c9)->{ + Object o = c9; + }); + } + + public R convert(T t, Function f, int i) { + return null; + } + + public void consume(T t, Consumer c, int i) { + } + + public R convertVarArgs(T t, Function c, int... i) { + return null; + } + + public void consumeVarArgs(T t, Consumer c, int... i) { + } + + public R convertVarArgs2(T t, Function... c) { + return null; + } + + public void consumeVarArgs2(T t, Consumer... c) { + } + + public static class Test { + + public Test() { + super(); + } + + public static Test of(T t) { + return new Test<>(); + } + + public Test convert(Function c) { + return null; + } + + public void consume(Consumer c) { + } + + public void consumeWithParam(Consumer c, int i) { + } + } + + public interface Function { + + public R map(T t); + } + + public interface Consumer { + + public void run(T t); + } + }"""); + } + + private static void analyze(String fileName, String expectedAST) throws IOException { + try (StandardJavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) { + List files = new ArrayList<>(); + File source = new File(System.getProperty("test.src", "."), fileName.replace('/', File.separatorChar)).getAbsoluteFile(); + for (JavaFileObject f : fm.getJavaFileObjects(source)) { + files.add(f); + } + DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + List options = List.of("-source", JDK_VERSION, + "-XDshould-stop.at=FLOW"); + JavacTask ct = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, null, diagnostics, options, null, files); + Trees trees = Trees.instance(ct); + CompilationUnitTree cut = ct.parse().iterator().next(); + + ct.analyze(); + + String actualAST = Arrays.stream(cut.toString().split("\n")) + .map(l -> l.stripTrailing()) + .collect(Collectors.joining("\n")); + + if (!expectedAST.equals(actualAST)) { + throw new AssertionError("Unexpected AST shape!\n" + actualAST); + } + + Pattern p = Pattern.compile("/\\*getTypeMirror:(.*?)\\*/"); + Matcher m = p.matcher(cut.getSourceFile().getCharContent(false)); + + while (m.find()) { + TreePath tp = pathFor(trees, cut, m.start() - 1); + String expected = m.group(1); + if (expected.startsWith("getParentPath:")) { + tp = tp.getParentPath(); + expected = expected.substring("getParentPath:".length()); + } + TypeMirror found = trees.getTypeMirror(tp); + String actual = found != null ? found.getKind() + ":" + typeToString(found) : ""; + + if (!expected.equals(actual)) { + throw new IllegalStateException("expected=" + expected + "; actual=" + actual + "; tree: " + tp.getLeaf()); + } + } + } + } + + private static TreePath pathFor(final Trees trees, final CompilationUnitTree cut, final int pos) { + final TreePath[] result = new TreePath[1]; + + new TreePathScanner() { + @Override public Void scan(Tree node, Void p) { + if ( node != null + && trees.getSourcePositions().getStartPosition(cut, node) <= pos + && pos <= trees.getSourcePositions().getEndPosition(cut, node)) { + result[0] = new TreePath(getCurrentPath(), node); + return super.scan(node, p); + } + return null; + } + }.scan(cut, null); + + return result[0]; + } + + private static String typeToString(TypeMirror type) { + return type.toString(); + } + + static class TestFileObject extends SimpleJavaFileObject { + private final String text; + public TestFileObject(String text) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.text = text; + } + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return text; + } + } + +} diff --git a/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReferenceData.java b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReferenceData.java new file mode 100644 index 0000000000000..28e62147bdfde --- /dev/null +++ b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReferenceData.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 test; + +public class TestGetTypeMirrorReferenceData { + + private static void test() { + Test.of(1).convert(c1 -> {Object o = c1/*getTypeMirror:DECLARED:java.lang.Integer*/;}); + Test.of(1).consume(c2 -> {Object o = c2/*getTypeMirror:DECLARED:java.lang.Integer*/; return null;}); + Test.of(1).consumeWithParam(c3 -> {Object o = c3/*getTypeMirror:DECLARED:java.lang.Integer*/;}); + convert(0, c4 -> {Object o = c4/*getTypeMirror:DECLARED:java.lang.Integer*/;}); + consume(0, c5 -> {Object o = c5/*getTypeMirror:DECLARED:java.lang.Integer*/;}); + convertVarArgs(0, c6 -> {Object o = c6/*getTypeMirror:DECLARED:java.lang.Integer*/;}, 1, 2, 3, 4); + consumeVarArgs(0, c7 -> {Object o = c7/*getTypeMirror:DECLARED:java.lang.Integer*/;}, 1, 2, 3, 4); + convertVarArgs2(0, c8 -> {Object o = c8/*getTypeMirror:DECLARED:java.lang.Integer*/;}, c8 -> {Object o = c8/*getTypeMirror:DECLARED:java.lang.Integer*/;}); + consumeVarArgs2(0, c9 -> {Object o = c9/*getTypeMirror:DECLARED:java.lang.Integer*/;}, c9 -> {Object o = c9/*getTypeMirror:DECLARED:java.lang.Integer*/;}); + } + public R convert(T t, Function f, int i) { + return null; + } + public void consume(T t, Consumer c, int i) { + } + public R convertVarArgs(T t, Function c, int... i) { + return null; + } + public void consumeVarArgs(T t, Consumer c, int... i) { + } + public R convertVarArgs2(T t, Function... c) { + return null; + } + public void consumeVarArgs2(T t, Consumer... c) { + } + public static class Test { + public static Test of(T t) { + return new Test<>(); + } + public Test convert(Function c) { + return null; + } + public void consume(Consumer c) {} + public void consumeWithParam(Consumer c, int i) {} + } + public interface Function { + public R map(T t); + } + public interface Consumer { + public void run(T t); + } +} diff --git a/test/lib/jdk/test/lib/SigTestUtil.java b/test/lib/jdk/test/lib/SigTestUtil.java index f6775cda37d95..b04f2215f8a1a 100644 --- a/test/lib/jdk/test/lib/SigTestUtil.java +++ b/test/lib/jdk/test/lib/SigTestUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * 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,10 +54,14 @@ public String toString() { // collection of all supported digest algorithms // note that the entries are ordered by required key sizes private static final String[] DIGEST_ALGS = { + "SHA3-512", "SHA-512", + "SHA3-384", "SHA-384", + "SHA3-256", "SHA-256", "SHA-512/256", + "SHA3-224", "SHA-224", "SHA-512/224", "SHA-1", @@ -66,14 +70,14 @@ public String toString() { // indice for message digest algorithms lookup // may need to be adjusted if new algorithms are added - private static final int PKCS1_5_INDEX_768 = 0; - private static final int PKCS1_5_INDEX_512 = 2; + private static final int PKCS1_5_INDEX_768 = 0; // 512, 384-bit digests + private static final int PKCS1_5_INDEX_512 = 4; // 256-bit digests private static final int PKCS1_5_INDEX_END = DIGEST_ALGS.length; - private static final int PSS_INDEX_2048 = 0; - private static final int PSS_INDEX_1024 = 1; - private static final int PSS_INDEX_768 = 2; - private static final int PSS_INDEX_512 = 4; - private static final int PSS_INDEX_END = 7; + private static final int PSS_INDEX_2048 = 0; // 512-bit digests + private static final int PSS_INDEX_1024 = 2; // 384-bit digests + private static final int PSS_INDEX_768 = 4; // 256-bit digests + private static final int PSS_INDEX_512 = 7; // 224-bit digests + private static final int PSS_INDEX_END = DIGEST_ALGS.length - 2; public static Iterable getDigestAlgorithms(SignatureType type, int keysize) throws RuntimeException { @@ -135,9 +139,8 @@ public static String generateSigAlg(SignatureType type, String mdAlg) throws RuntimeException { switch (type) { case RSA: - int idx = mdAlg.indexOf("-"); - if (idx != -1) { - mdAlg = mdAlg.substring(0, idx) + mdAlg.substring(idx+1); + if (mdAlg.startsWith("SHA-")) { + mdAlg = mdAlg.substring(0, 3) + mdAlg.substring(4); } return mdAlg + "with" + type.toString(); case RSASSA_PSS: diff --git a/test/micro/org/openjdk/bench/java/net/ThreadLocalParseUtil.java b/test/micro/org/openjdk/bench/java/net/ThreadLocalParseUtil.java new file mode 100644 index 0000000000000..1bdcefbef7d98 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/net/ThreadLocalParseUtil.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 org.openjdk.bench.java.net; + +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.CompilerControl; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Setup; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.net.URI; +import java.net.URL; +import java.util.concurrent.TimeUnit; + +import static java.lang.invoke.MethodType.methodType; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Fork(value = 1, jvmArgsAppend = "--add-exports=java.base/sun.net.www=ALL-UNNAMED") +public class ThreadLocalParseUtil { + + private static final MethodHandle MH_DECODE; + private static final MethodHandle MH_TO_URI; + + static { + final MethodHandles.Lookup lookup = MethodHandles.lookup(); + try { + Class c = Class.forName("sun.net.www.ParseUtil"); + MH_DECODE = lookup.findStatic(c, "decode", methodType(String.class, String.class)); + MH_TO_URI = lookup.findStatic(c, "toURI", methodType(URI.class, URL.class)); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { + throw new ExceptionInInitializerError(e); + } + } + + @Benchmark + public String decodeTest() throws Throwable { + return (String) MH_DECODE.invokeExact("/xyz/\u00A0\u00A0"); + } + + @Benchmark + public URI appendEncodedTest() throws Throwable { + URL url = new URL("https://example.com/xyz/abc/def?query=#30"); + return (URI) MH_TO_URI.invokeExact(url); + } +}