diff --git a/.hgtags b/.hgtags index 186dfdb09c2..f90e093b502 100644 --- a/.hgtags +++ b/.hgtags @@ -603,3 +603,6 @@ c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21 2069b4bfd23b56b6fc659fba8b75aaaa23debbe0 jdk-14+28 563fa900fa17c290ae516c7a3a69e8c069dde304 jdk-14+29 d54ce919da90dab361995bb4d87be9851f00537a jdk-14+30 +d54ce919da90dab361995bb4d87be9851f00537a jdk-14+31 +d54ce919da90dab361995bb4d87be9851f00537a jdk-14+31 +decd3d2953b640f1043ee76953ff89238bff92e8 jdk-14+31 diff --git a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp index b461affefe2..4257e3445ea 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp @@ -49,6 +49,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index f9a96e04de7..45632635f44 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp @@ -759,7 +759,7 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po if (is_reference_type(type)) { __ str(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix())); __ verify_oop(src->as_register()); - } else if (type == T_METADATA || type == T_DOUBLE) { + } else if (type == T_METADATA || type == T_DOUBLE || type == T_ADDRESS) { __ str(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix())); } else { __ strw(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix())); @@ -872,7 +872,7 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (is_reference_type(type)) { __ ldr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); __ verify_oop(dest->as_register()); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ ldr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); } else { __ ldrw(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); diff --git a/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp b/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp index cb234675241..bd74c3f83b4 100644 --- a/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp +++ b/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp @@ -80,10 +80,12 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { Register reg = r_1->as_Register(); if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { opr = as_long_opr(reg, r_2->as_Register()); - } else if (type == T_OBJECT || type == T_ARRAY) { + } else if (is_reference_type(type)) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { // PreferInterpreterNativeStubs should ensure we never need to // handle a long opr passed as R3+stack_slot diff --git a/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp b/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp index f73e6b1be5f..7de34093cfe 100644 --- a/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp @@ -54,6 +54,10 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) { opr = as_long_opr(reg); } else if (is_reference_type(type)) { opr = as_oop_opr(reg); + } else if (type == T_METADATA) { + opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp index 42815aadebb..7fe43487325 100644 --- a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp +++ b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp @@ -294,7 +294,7 @@ void PatchingStub::align_patch_site(MacroAssembler* masm) { void PatchingStub::emit_code(LIR_Assembler* ce) { // Copy original code here. assert(NativeGeneralJump::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF, - "not enough room for call"); + "not enough room for call, need %d", _bytes_to_copy); NearLabel call_patch; @@ -331,7 +331,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { } #endif } else { - // Make a copy the code which is going to be patched. + // Make a copy of the code which is going to be patched. for (int i = 0; i < _bytes_to_copy; i++) { address ptr = (address)(_pc_start + i); int a_byte = (*ptr) & 0xFF; diff --git a/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp b/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp index 12dda5e344e..d639de695b3 100644 --- a/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp +++ b/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp @@ -50,6 +50,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index afacc715bde..262474bf621 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -897,7 +897,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_P bool needs_patching = (patch_code != lir_patch_none); if (addr->base()->type() == T_OBJECT) { - __ verify_oop(src); + __ verify_oop(src, FILE_AND_LINE); } PatchingStub* patch = NULL; @@ -972,7 +972,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_P } else { __ z_lg(dest->as_register(), disp_value, disp_reg, src); } - __ verify_oop(dest->as_register()); + __ verify_oop(dest->as_register(), FILE_AND_LINE); break; } case T_FLOAT: @@ -1006,8 +1006,8 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (dest->is_single_cpu()) { if (is_reference_type(type)) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); - __ verify_oop(dest->as_register()); - } else if (type == T_METADATA) { + __ verify_oop(dest->as_register(), FILE_AND_LINE); + } else if (type == T_METADATA || type == T_ADDRESS) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); } else { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), false); @@ -1033,9 +1033,9 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po if (src->is_single_cpu()) { const Address dst = frame_map()->address_for_slot(dest->single_stack_ix()); if (is_reference_type(type)) { - __ verify_oop(src->as_register()); + __ verify_oop(src->as_register(), FILE_AND_LINE); __ reg2mem_opt(src->as_register(), dst, true); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ reg2mem_opt(src->as_register(), dst, true); } else { __ reg2mem_opt(src->as_register(), dst, false); @@ -1079,7 +1079,7 @@ void LIR_Assembler::reg2reg(LIR_Opr from_reg, LIR_Opr to_reg) { ShouldNotReachHere(); } if (is_reference_type(to_reg->type())) { - __ verify_oop(to_reg->as_register()); + __ verify_oop(to_reg->as_register(), FILE_AND_LINE); } } @@ -1095,7 +1095,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, bool needs_patching = (patch_code != lir_patch_none); if (addr->base()->is_oop_register()) { - __ verify_oop(dest); + __ verify_oop(dest, FILE_AND_LINE); } PatchingStub* patch = NULL; @@ -1130,7 +1130,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, assert(disp_reg != Z_R0 || Immediate::is_simm20(disp_value), "should have set this up"); if (is_reference_type(type)) { - __ verify_oop(from->as_register()); + __ verify_oop(from->as_register(), FILE_AND_LINE); } bool short_disp = Immediate::is_uimm12(disp_value); @@ -2412,7 +2412,7 @@ void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { op->klass()->as_register(), *op->stub()->entry()); __ bind(*op->stub()->continuation()); - __ verify_oop(op->obj()->as_register()); + __ verify_oop(op->obj()->as_register(), FILE_AND_LINE); } void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { @@ -2548,7 +2548,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } assert(obj != k_RInfo, "must be different"); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); // Get object class. // Not a safepoint as obj null check happens earlier. @@ -3009,7 +3009,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { assert(do_null || do_update, "why are we here?"); assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); if (do_null || tmp1 != obj DEBUG_ONLY(|| true)) { __ z_ltgr(tmp1, obj); diff --git a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp index b2680769dcf..a357f79ffcc 100644 --- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp @@ -40,7 +40,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { Label ic_miss, ic_hit; - verify_oop(receiver); + verify_oop(receiver, FILE_AND_LINE); int klass_offset = oopDesc::klass_offset_in_bytes(); if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) { @@ -83,7 +83,7 @@ void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hd assert_different_registers(hdr, obj, disp_hdr); NearLabel done; - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); // Load object header. z_lg(hdr, Address(obj, hdr_offset)); @@ -158,7 +158,7 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_ // Load object. z_lg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); } - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); // Test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object. If the object header is not pointing to // the displaced header, get the object header instead. @@ -278,7 +278,7 @@ void C1_MacroAssembler::initialize_object( // call(RuntimeAddress(Runtime1::entry_for (Runtime1::dtrace_object_alloc_id))); // } - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); } void C1_MacroAssembler::allocate_array( @@ -336,16 +336,15 @@ void C1_MacroAssembler::allocate_array( // call(RuntimeAddress(Runtime1::entry_for (Runtime1::dtrace_object_alloc_id))); // } - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); } #ifndef PRODUCT void C1_MacroAssembler::verify_stack_oop(int stack_offset) { - Unimplemented(); - // if (!VerifyOops) return; - // verify_oop_addr(Address(SP, stack_offset + STACK_BIAS)); + if (!VerifyOops) return; + verify_oop_addr(Address(Z_SP, stack_offset), FILE_AND_LINE); } void C1_MacroAssembler::verify_not_null_oop(Register r) { @@ -354,7 +353,7 @@ void C1_MacroAssembler::verify_not_null_oop(Register r) { compareU64_and_branch(r, (intptr_t)0, bcondNotEqual, not_null); stop("non-null oop required"); bind(not_null); - verify_oop(r); + verify_oop(r, FILE_AND_LINE); } void C1_MacroAssembler::invalidate_registers(Register preserve1, diff --git a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp index eeb934bfdaa..e7526d17c6d 100644 --- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp +++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp @@ -339,7 +339,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { oop_maps->add_gc_map(call_offset, map); restore_live_registers_except_r2(sasm); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); __ z_br(Z_R14); } break; @@ -405,7 +405,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { oop_maps->add_gc_map(call_offset, map); restore_live_registers_except_r2(sasm); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); __ z_br(Z_R14); } break; @@ -423,7 +423,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { restore_live_registers_except_r2(sasm); // Z_R2,: new multi array - __ verify_oop(Z_R2); + __ verify_oop(Z_R2, FILE_AND_LINE); __ z_br(Z_R14); } break; diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp index d0bb0c0e41c..2bdfa801053 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp @@ -400,11 +400,11 @@ void G1BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value __ z_tmll(tmp1, JNIHandles::weak_tag_mask); // Test for jweak tag. __ z_braz(Lnot_weak); - __ verify_oop(value); + __ verify_oop(value, FILE_AND_LINE); DecoratorSet decorators = IN_NATIVE | ON_PHANTOM_OOP_REF; g1_write_barrier_pre(masm, decorators, (const Address*)NULL, value, noreg, tmp1, tmp2, true); __ bind(Lnot_weak); - __ verify_oop(value); + __ verify_oop(value, FILE_AND_LINE); __ bind(Ldone); } diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp index f99100dcb6d..2fce9a4589b 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp @@ -108,7 +108,7 @@ void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, __ z_nill(value, ~JNIHandles::weak_tag_mask); __ z_lg(value, 0, value); // Resolve (untagged) jobject. - __ verify_oop(value); + __ verify_oop(value, FILE_AND_LINE); __ bind(Ldone); } diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index 48af3cf0cf3..cbee39e3eae 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -1664,7 +1664,7 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, Address mdo_addr, compareU64_and_branch(obj, (intptr_t)0, Assembler::bcondEqual, null_seen); } - verify_oop(obj); + MacroAssembler::verify_oop(obj, FILE_AND_LINE); load_klass(klass, obj); // Klass seen before, nothing to do (regardless of unknown bit). @@ -2073,7 +2073,7 @@ void InterpreterMacroAssembler::access_local_int(Register index, Register dst) { } void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { - if (state == atos) { MacroAssembler::verify_oop(reg); } + if (state == atos) { MacroAssembler::verify_oop(reg, FILE_AND_LINE); } } // Inline assembly for: diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index 49fb3492783..e774e0a9748 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -3587,7 +3587,7 @@ void MacroAssembler::get_vm_result(Register oop_result) { z_lg(oop_result, Address(Z_thread, JavaThread::vm_result_offset())); clear_mem(Address(Z_thread, JavaThread::vm_result_offset()), sizeof(void*)); - verify_oop(oop_result); + verify_oop(oop_result, FILE_AND_LINE); } void MacroAssembler::get_vm_result_2(Register result) { @@ -6813,26 +6813,94 @@ void MacroAssembler::verify_thread() { } } +// Save and restore functions: Exclude Z_R0. +void MacroAssembler::save_volatile_regs(Register dst, int offset, bool include_fp, bool include_flags) { + z_stmg(Z_R1, Z_R5, offset, dst); offset += 5 * BytesPerWord; + if (include_fp) { + z_std(Z_F0, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F1, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F2, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F3, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F4, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F5, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F6, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F7, Address(dst, offset)); offset += BytesPerWord; + } + if (include_flags) { + Label done; + z_mvi(Address(dst, offset), 2); // encoding: equal + z_bre(done); + z_mvi(Address(dst, offset), 4); // encoding: higher + z_brh(done); + z_mvi(Address(dst, offset), 1); // encoding: lower + bind(done); + } +} +void MacroAssembler::restore_volatile_regs(Register src, int offset, bool include_fp, bool include_flags) { + z_lmg(Z_R1, Z_R5, offset, src); offset += 5 * BytesPerWord; + if (include_fp) { + z_ld(Z_F0, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F1, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F2, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F3, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F4, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F5, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F6, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F7, Address(src, offset)); offset += BytesPerWord; + } + if (include_flags) { + z_cli(Address(src, offset), 2); // see encoding above + } +} + // Plausibility check for oops. void MacroAssembler::verify_oop(Register oop, const char* msg) { if (!VerifyOops) return; BLOCK_COMMENT("verify_oop {"); - Register tmp = Z_R0; - unsigned int nbytes_save = 5*BytesPerWord; - address entry = StubRoutines::verify_oop_subroutine_entry_address(); + unsigned int nbytes_save = (5 + 8 + 1) * BytesPerWord; + address entry_addr = StubRoutines::verify_oop_subroutine_entry_address(); save_return_pc(); - push_frame_abi160(nbytes_save); - z_stmg(Z_R1, Z_R5, frame::z_abi_160_size, Z_SP); - z_lgr(Z_ARG2, oop); - load_const(Z_ARG1, (address) msg); - load_const(Z_R1, entry); + // Push frame, but preserve flags + z_lgr(Z_R0, Z_SP); + z_lay(Z_SP, -((int64_t)nbytes_save + frame::z_abi_160_size), Z_SP); + z_stg(Z_R0, _z_abi(callers_sp), Z_SP); + + save_volatile_regs(Z_SP, frame::z_abi_160_size, true, true); + + lgr_if_needed(Z_ARG2, oop); + load_const_optimized(Z_ARG1, (address)msg); + load_const_optimized(Z_R1, entry_addr); z_lg(Z_R1, 0, Z_R1); call_c(Z_R1); - z_lmg(Z_R1, Z_R5, frame::z_abi_160_size, Z_SP); + restore_volatile_regs(Z_SP, frame::z_abi_160_size, true, true); + pop_frame(); + restore_return_pc(); + + BLOCK_COMMENT("} verify_oop "); +} + +void MacroAssembler::verify_oop_addr(Address addr, const char* msg) { + if (!VerifyOops) return; + + BLOCK_COMMENT("verify_oop {"); + unsigned int nbytes_save = (5 + 8) * BytesPerWord; + address entry_addr = StubRoutines::verify_oop_subroutine_entry_address(); + + save_return_pc(); + unsigned int frame_size = push_frame_abi160(nbytes_save); // kills Z_R0 + save_volatile_regs(Z_SP, frame::z_abi_160_size, true, false); + + z_lg(Z_ARG2, addr.plus_disp(frame_size)); + load_const_optimized(Z_ARG1, (address)msg); + load_const_optimized(Z_R1, entry_addr); + z_lg(Z_R1, 0, Z_R1); + call_c(Z_R1); + + restore_volatile_regs(Z_SP, frame::z_abi_160_size, true, false); pop_frame(); restore_return_pc(); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index 8600c78a608..fb20b51ed29 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -973,8 +973,15 @@ class MacroAssembler: public Assembler { // Verify Z_thread contents. void verify_thread(); + // Save and restore functions: Exclude Z_R0. + void save_volatile_regs( Register dst, int offset, bool include_fp, bool include_flags); + void restore_volatile_regs(Register src, int offset, bool include_fp, bool include_flags); + // Only if +VerifyOops. + // Kills Z_R0. void verify_oop(Register reg, const char* s = "broken oop"); + // Kills Z_R0, condition code. + void verify_oop_addr(Address addr, const char* msg = "contains broken oop"); // TODO: verify_method and klass metadata (compare against vptr?). void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {} diff --git a/src/hotspot/cpu/s390/methodHandles_s390.cpp b/src/hotspot/cpu/s390/methodHandles_s390.cpp index bb456117a1c..ca93ef3f136 100644 --- a/src/hotspot/cpu/s390/methodHandles_s390.cpp +++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp @@ -85,7 +85,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm, BLOCK_COMMENT("verify_klass {"); - __ verify_oop(obj_reg); + __ verify_oop(obj_reg, FILE_AND_LINE); __ compareU64_and_branch(obj_reg, (intptr_t)0L, Assembler::bcondEqual, L_bad); __ load_klass(temp_reg, obj_reg); // klass_addr is a klass in allstatic SystemDictionaryHandles. Can't get GCed. @@ -194,22 +194,22 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, BLOCK_COMMENT("jump_to_lambda_form {"); // Load the invoker, as MH -> MH.form -> LF.vmentry - __ verify_oop(recv); + __ verify_oop(recv, FILE_AND_LINE); __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), noreg, noreg, IS_NOT_NULL); - __ verify_oop(method_temp); + __ verify_oop(method_temp, FILE_AND_LINE); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), noreg, noreg, IS_NOT_NULL); - __ verify_oop(method_temp); + __ verify_oop(method_temp, FILE_AND_LINE); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), noreg, noreg, IS_NOT_NULL); - __ verify_oop(method_temp); + __ verify_oop(method_temp, FILE_AND_LINE); __ z_lg(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()))); @@ -385,7 +385,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, Register temp1_recv_klass = temp1; if (iid != vmIntrinsics::_linkToStatic) { - __ verify_oop(receiver_reg); + __ verify_oop(receiver_reg, FILE_AND_LINE); if (iid == vmIntrinsics::_linkToSpecial) { // Don't actually load the klass; just null-check the receiver. __ null_check(receiver_reg); diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index dae5d46a8cc..54beb8263ea 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -892,9 +892,9 @@ static void verify_oop_args(MacroAssembler *masm, if (r->is_stack()) { __ z_lg(Z_R0_scratch, Address(Z_SP, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); - __ verify_oop(Z_R0_scratch); + __ verify_oop(Z_R0_scratch, FILE_AND_LINE); } else { - __ verify_oop(r->as_Register()); + __ verify_oop(r->as_Register(), FILE_AND_LINE); } } } @@ -2686,7 +2686,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm __ z_ltgr(Z_ARG1, Z_ARG1); __ z_bre(ic_miss); } - __ verify_oop(Z_ARG1); + __ verify_oop(Z_ARG1, FILE_AND_LINE); // Check ic: object class <-> cached class // Compress cached class for comparison. That's more efficient. @@ -2955,7 +2955,7 @@ void SharedRuntime::generate_deopt_blob() { #ifdef ASSERT // verify that there is really an exception oop in JavaThread __ z_lg(Z_ARG1, Address(Z_thread, JavaThread::exception_oop_offset())); - __ verify_oop(Z_ARG1); + __ MacroAssembler::verify_oop(Z_ARG1, FILE_AND_LINE); // verify that there is no pending exception __ asm_assert_mem8_is_zero(in_bytes(Thread::pending_exception_offset()), Z_thread, diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 419f6832ad5..4a2e28b9569 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -667,6 +667,17 @@ class StubGenerator: public StubCodeGenerator { return start; } +#if !defined(PRODUCT) + // Wrapper which calls oopDesc::is_oop_or_null() + // Only called by MacroAssembler::verify_oop + static void verify_oop_helper(const char* message, oopDesc* o) { + if (!oopDesc::is_oop_or_null(o)) { + fatal("%s. oop: " PTR_FORMAT, message, p2i(o)); + } + ++ StubRoutines::_verify_oop_count; + } +#endif + // Return address of code to be called from code generated by // MacroAssembler::verify_oop. // @@ -679,6 +690,11 @@ class StubGenerator: public StubCodeGenerator { // StubCodeMark mark(this, "StubRoutines", "verify_oop_stub"); address start = 0; + +#if !defined(PRODUCT) + start = CAST_FROM_FN_PTR(address, verify_oop_helper); +#endif + return start; } diff --git a/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp b/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp index 22d980aba76..2e2e737d850 100644 --- a/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp +++ b/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp @@ -55,6 +55,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp b/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp index 958065f3521..f25cefb8a44 100644 --- a/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp +++ b/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp @@ -54,6 +54,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index b508084ad6b..4fb9dd1bb27 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -935,7 +935,7 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po if (is_reference_type(type)) { __ verify_oop(src->as_register()); __ movptr (dst, src->as_register()); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ movptr (dst, src->as_register()); } else { __ movl (dst, src->as_register()); @@ -1116,7 +1116,7 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (is_reference_type(type)) { __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); __ verify_oop(dest->as_register()); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); } else { __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp index 993addd3a35..97609ef0e2a 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp @@ -30,6 +30,8 @@ #include "code/nativeInst.hpp" #include "code/vtableStubs.hpp" #include "gc/shared/gcLocker.hpp" +#include "gc/shared/barrierSet.hpp" +#include "gc/shared/barrierSetAssembler.hpp" #include "interpreter/interpreter.hpp" #include "logging/log.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 25bcb617211..62e677d2de9 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -2143,7 +2143,7 @@ operand vecZ() %{ // Replaces legVec during post-selection cleanup. See above. operand legVecZ() %{ - constraint(ALLOC_IN_RC(vectorz_reg_vl)); + constraint(ALLOC_IN_RC(vectorz_reg_legacy)); match(VecZ); format %{ %} diff --git a/src/hotspot/share/c1/c1_FrameMap.hpp b/src/hotspot/share/c1/c1_FrameMap.hpp index b993e231fa8..eca2460ee3a 100644 --- a/src/hotspot/share/c1/c1_FrameMap.hpp +++ b/src/hotspot/share/c1/c1_FrameMap.hpp @@ -185,6 +185,10 @@ class FrameMap : public CompilationResourceObj { return LIR_OprFact::single_cpu_metadata(cpu_reg2rnr(r)); } + static LIR_Opr as_address_opr(Register r) { + return LIR_OprFact::single_cpu_address(cpu_reg2rnr(r)); + } + FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size); bool finalize_frame(int nof_slots); diff --git a/src/hotspot/share/code/debugInfo.cpp b/src/hotspot/share/code/debugInfo.cpp index 245774ee633..ebb5dd6258f 100644 --- a/src/hotspot/share/code/debugInfo.cpp +++ b/src/hotspot/share/code/debugInfo.cpp @@ -51,7 +51,15 @@ void DebugInfoWriteStream::write_metadata(Metadata* h) { } oop DebugInfoReadStream::read_oop() { - oop o = code()->oop_at(read_int()); + nmethod* nm = const_cast(code())->as_nmethod_or_null(); + oop o; + if (nm != NULL) { + // Despite these oops being found inside nmethods that are on-stack, + // they are not kept alive by all GCs (e.g. G1 and Shenandoah). + o = nm->oop_at_phantom(read_int()); + } else { + o = code()->oop_at(read_int()); + } assert(oopDesc::is_oop_or_null(o), "oop only"); return o; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index bc227b965d2..e2ad72d656a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -199,12 +199,8 @@ oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) { _heap->in_collection_set(obj) && obj == fwd) { Thread *t = Thread::current(); - if (t->is_GC_task_thread()) { - return _heap->evacuate_object(obj, t); - } else { - ShenandoahEvacOOMScope oom_evac_scope; - return _heap->evacuate_object(obj, t); - } + ShenandoahEvacOOMScope oom_evac_scope; + return _heap->evacuate_object(obj, t); } else { return fwd; } @@ -252,9 +248,7 @@ oop ShenandoahBarrierSet::load_reference_barrier_native(oop obj, oop* load_addr) } oop ShenandoahBarrierSet::load_reference_barrier_native(oop obj, narrowOop* load_addr) { - // Assumption: narrow oop version should not be used anywhere. - ShouldNotReachHere(); - return NULL; + return load_reference_barrier_native_impl(obj, load_addr); } template @@ -264,7 +258,7 @@ oop ShenandoahBarrierSet::load_reference_barrier_native_impl(oop obj, T* load_ad } ShenandoahMarkingContext* const marking_context = _heap->marking_context(); - if (_heap->is_evacuation_in_progress() && !marking_context->is_marked(obj)) { + if (_heap->is_concurrent_root_in_progress() && !marking_context->is_marked(obj)) { Thread* thr = Thread::current(); if (thr->is_Java_thread()) { return NULL; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp index 300b04303e5..65938aad6dc 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp @@ -57,7 +57,6 @@ bool ShenandoahBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { } // Heal oops and disarm - ShenandoahEvacOOMScope scope; ShenandoahNMethod::heal_nmethod(nm); ShenandoahNMethod::disarm_nmethod(nm); return true; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp index 7f8809a07ac..ab61567c4be 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp @@ -111,12 +111,13 @@ ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() : template void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) { - assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); T o = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); if (_heap->in_collection_set(obj)) { + assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); shenandoah_assert_marked(p, obj); oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (resolved == obj) { @@ -139,11 +140,12 @@ ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsC } void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) { - assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); oop obj = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(obj)) { if (_heap->in_collection_set(obj)) { + assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); shenandoah_assert_marked(p, obj); oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (resolved == obj) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 7829bfb6d84..46c9ee45eae 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -155,7 +155,7 @@ void ShenandoahCodeRoots::flush_nmethod(nmethod* nm) { } } -void ShenandoahCodeRoots::prepare_concurrent_unloading() { +void ShenandoahCodeRoots::arm_nmethods() { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); _disarmed_value ++; // 0 is reserved for new nmethod @@ -215,7 +215,6 @@ public: if (nm->is_unloading()) { ShenandoahReentrantLocker locker(nm_data->lock()); - ShenandoahEvacOOMScope evac_scope; unlink(nm); return; } @@ -223,8 +222,9 @@ public: ShenandoahReentrantLocker locker(nm_data->lock()); // Heal oops and disarm - ShenandoahEvacOOMScope evac_scope; - ShenandoahNMethod::heal_nmethod(nm); + if (_heap->is_evacuation_in_progress()) { + ShenandoahNMethod::heal_nmethod(nm); + } ShenandoahNMethod::disarm_nmethod(nm); // Clear compiled ICs and exception caches diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp index 42661f4f870..4347192a578 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp @@ -109,7 +109,7 @@ public: // Concurrent nmethod unloading support static void unlink(WorkGang* workers, bool unloading_occurred); static void purge(WorkGang* workers); - static void prepare_concurrent_unloading(); + static void arm_nmethods(); static int disarmed_value() { return _disarmed_value; } static int* disarmed_value_address() { return &_disarmed_value; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp index 2d8478f262b..a04b7e1642b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2020, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as @@ -47,6 +47,8 @@ bool ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() { } bool ShenandoahConcurrentRoots::should_do_concurrent_class_unloading() { + ShenandoahHeap* const heap = ShenandoahHeap::heap(); return can_do_concurrent_class_unloading() && - !ShenandoahHeap::heap()->is_stw_gc_in_progress(); + heap->unload_classes() && + !heap->is_stw_gc_in_progress(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp index 64944d9974b..55bf51c5bd7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp @@ -123,11 +123,3 @@ ShenandoahEvacOOMScope::ShenandoahEvacOOMScope() { ShenandoahEvacOOMScope::~ShenandoahEvacOOMScope() { ShenandoahHeap::heap()->leave_evacuation(); } - -ShenandoahEvacOOMScopeLeaver::ShenandoahEvacOOMScopeLeaver() { - ShenandoahHeap::heap()->leave_evacuation(); -} - -ShenandoahEvacOOMScopeLeaver::~ShenandoahEvacOOMScopeLeaver() { - ShenandoahHeap::heap()->enter_evacuation(); -} diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp index b81b45cc7e6..19305a8bb17 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp @@ -119,10 +119,4 @@ public: ~ShenandoahEvacOOMScope(); }; -class ShenandoahEvacOOMScopeLeaver : public StackObj { -public: - ShenandoahEvacOOMScopeLeaver(); - ~ShenandoahEvacOOMScopeLeaver(); -}; - #endif // SHARE_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 4b7b58d7ef6..3f2d4412068 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -542,6 +542,7 @@ void ShenandoahHeap::print_on(outputStream* st) const { if (is_degenerated_gc_in_progress()) st->print("degenerated gc, "); if (is_full_gc_in_progress()) st->print("full gc, "); if (is_full_gc_move_in_progress()) st->print("full gc move, "); + if (is_concurrent_root_in_progress()) st->print("concurrent roots, "); if (cancelled_gc()) { st->print("cancelled"); @@ -1540,6 +1541,11 @@ void ShenandoahHeap::op_final_mark() { _free_set->rebuild(); } + if (!is_degenerated_gc_in_progress()) { + prepare_concurrent_roots(); + prepare_concurrent_unloading(); + } + // If collection set has candidates, start evacuation. // Otherwise, bypass the rest of the cycle. if (!collection_set()->is_empty()) { @@ -1554,8 +1560,9 @@ void ShenandoahHeap::op_final_mark() { set_has_forwarded_objects(true); if (!is_degenerated_gc_in_progress()) { - prepare_concurrent_roots(); - prepare_concurrent_unloading(); + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + ShenandoahCodeRoots::arm_nmethods(); + } evacuate_and_update_roots(); } @@ -1669,7 +1676,7 @@ public: }; void ShenandoahHeap::op_roots() { - if (is_evacuation_in_progress()) { + if (is_concurrent_root_in_progress()) { if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { _unloader.unload(); } @@ -2235,7 +2242,6 @@ void ShenandoahHeap::prepare_concurrent_roots() { void ShenandoahHeap::prepare_concurrent_unloading() { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { - ShenandoahCodeRoots::prepare_concurrent_unloading(); _unloader.prepare(); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp index ff30be1b1bb..27b34b5d4fb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp @@ -174,6 +174,7 @@ void ShenandoahNMethod::heal_nmethod(nmethod* nm) { assert(data != NULL, "Sanity"); assert(data->lock()->owned_by_self(), "Must hold the lock"); + ShenandoahEvacOOMScope evac_scope; ShenandoahEvacuateUpdateRootsClosure cl; data->oops_do(&cl, true /*fix relocation*/); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp b/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp index 4fef09ddbd3..08b750dd611 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp @@ -41,7 +41,6 @@ ShenandoahClassUnloadingTask::ShenandoahClassUnloadingTask(BoolObjectClosure* is } void ShenandoahClassUnloadingTask::work(uint worker_id) { - ShenandoahEvacOOMScope scope; _code_cache_task.work(worker_id); // Clean all klasses that were not unloaded. // The weak metadata in klass doesn't need to be diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp index 5702f33dce1..a56d1230d1f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2015, 2020, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as @@ -226,6 +226,7 @@ private: ShenandoahThreadRoots _thread_roots; ShenandoahCodeCacheRoots _code_roots; ShenandoahVMRoots _vm_roots; + ShenandoahStringDedupRoots _dedup_roots; ShenandoahClassLoaderDataRoots _cld_roots; public: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp index 67669c16194..5be19fd5cdb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2020, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as @@ -250,6 +250,9 @@ void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDC if (code != NULL && !ShenandoahConcurrentScanCodeRoots) { _code_roots.code_blobs_do(code, worker_id); } + + AlwaysTrueClosure always_true; + _dedup_roots.oops_do(&always_true, oops, worker_id); } template diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp index 205d1b4bc86..9ebe130e230 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as @@ -173,7 +173,6 @@ public: void work(uint worker_id) { ShenandoahParallelWorkerSession worker_session(worker_id); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahObjToScanQueueSet* queues = _heap->traversal_gc()->task_queues(); ShenandoahObjToScanQueue* q = queues->queue(worker_id); @@ -194,9 +193,6 @@ public: } else { _rp->roots_do(worker_id, &roots_cl, &cld_cl, &code_cl); } - - AlwaysTrueClosure is_alive; - _dedup_roots.oops_do(&is_alive, &roots_cl, worker_id); } } }; @@ -214,7 +210,6 @@ public: void work(uint worker_id) { ShenandoahConcurrentWorkerSession worker_session(worker_id); ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc(); // Drain all outstanding work in queues. @@ -237,7 +232,6 @@ public: void work(uint worker_id) { ShenandoahParallelWorkerSession worker_session(worker_id); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc(); ShenandoahObjToScanQueueSet* queues = traversal_gc->task_queues(); @@ -542,7 +536,6 @@ void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worke if (work == 0) { // No more work, try to terminate - ShenandoahEvacOOMScopeLeaver oom_scope_leaver; ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield && ShenandoahSuspendibleWorkers); ShenandoahTerminationTimingsTracker term_tracker(worker_id); ShenandoahTerminatorTerminator tt(_heap); @@ -811,7 +804,6 @@ private: template inline void do_oop_work(T* p) { - ShenandoahEvacOOMScope evac_scope; _traversal_gc->process_oop(p, _thread, _queue, _mark_context); } @@ -834,7 +826,6 @@ private: template inline void do_oop_work(T* p) { - ShenandoahEvacOOMScope evac_scope; _traversal_gc->process_oop(p, _thread, _queue, _mark_context); } @@ -861,7 +852,6 @@ public: assert(worker_id == 0, "The code below is single-threaded, only one worker is expected"); ShenandoahParallelWorkerSession worker_session(worker_id); ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahHeap* sh = ShenandoahHeap::heap(); @@ -968,7 +958,6 @@ public: assert(sh->process_references(), "why else would we be here?"); shenandoah_assert_rp_isalive_installed(); - ShenandoahEvacOOMScope evac_scope; traversal_gc->main_loop(_worker_id, _terminator, false); if (_reset_terminator) { @@ -1010,7 +999,6 @@ public: } void work(uint worker_id) { - ShenandoahEvacOOMScope oom_evac_scope; assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); ShenandoahHeap* heap = ShenandoahHeap::heap(); ShenandoahTraversalDrainMarkingStackClosure complete_gc(worker_id, _terminator); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp index d1506194fa5..86c36238ddf 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp @@ -51,6 +51,7 @@ void ShenandoahTraversalGC::process_oop(T* p, Thread* thread, ShenandoahObjToSca } else if (_heap->in_collection_set(obj)) { oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (obj == forw) { + ShenandoahEvacOOMScope evac_scope; forw = _heap->evacuate_object(obj, thread); } shenandoah_assert_forwarded_except(p, obj, _heap->cancelled_gc()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index 1022cdd5b90..3d2dc79e2de 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -79,7 +79,7 @@ class ShenandoahIsUnloadingBehaviour : public IsUnloadingBehaviour { public: virtual bool is_unloading(CompiledMethod* method) const { nmethod* const nm = method->as_nmethod(); - guarantee(ShenandoahHeap::heap()->is_evacuation_in_progress(), "Only this phase"); + guarantee(ShenandoahHeap::heap()->is_concurrent_root_in_progress(), "Only this phase"); ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); ShenandoahReentrantLocker locker(data->lock()); ShenandoahIsUnloadingOopClosure cl; @@ -166,7 +166,7 @@ public: void ShenandoahUnload::unload() { assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?"); - if (!ShenandoahHeap::heap()->is_evacuation_in_progress()) { + if (!ShenandoahHeap::heap()->is_concurrent_root_in_progress()) { return; } diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index cd9705f71c7..f69330dea2e 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -1,7 +1,7 @@