# HG changeset patch # User huangjia # Date 1569555073 -28800 # Node ID 0b27fc8adf1bb6db9b1a87c9ceb52fe67eebed8d # Parent 02fc94107aa23a4d66e883c6ac230fdc9391f99a #10071 MIPS Port of 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles Summary: runtime/jni/CallWithJNIWeak/test.sh runtime/jni/ReturnJNIWeak/test.sh crash Reviewed-by: aoqi diff -r 02fc94107aa2 -r 0b27fc8adf1b src/cpu/mips/vm/jniFastGetField_mips_64.cpp --- a/src/cpu/mips/vm/jniFastGetField_mips_64.cpp Wed Sep 11 12:40:06 2019 +0800 +++ b/src/cpu/mips/vm/jniFastGetField_mips_64.cpp Fri Sep 27 11:31:13 2019 +0800 @@ -1,6 +1,6 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2015, 2018, Loongson Technology. All rights reserved. + * Copyright (c) 2015, 2019, Loongson Technology. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,13 +65,15 @@ __ set64(AT, (long)counter_addr); __ lw(T1, AT, 0); - /* 2012/4/28 Jin: the parameters(A0~A3) should not be modified, since - * they will be used in slow path. */ + // Parameters(A0~A3) should not be modified, since they will be used in slow path __ andi(AT, T1, 1); __ bne(AT, R0, slow); __ delayed()->nop(); - __ ld(T0, A1, 0); // unbox, *obj + __ move(T0, A1); + __ clear_jweak_tag(T0); + + __ ld(T0, T0, 0); // unbox, *obj __ move(T2, A2); __ shr(T2, 2); // offset __ dadd(T0, T0, T2); @@ -171,11 +173,14 @@ __ bne(AT, R0, slow); __ delayed()->nop(); + __ clear_jweak_tag(A1); + #ifdef _LP64 __ ld(A1, A1, 0); // unbox, *obj #else __ lw(A1, A1, 0); // unbox, *obj #endif + __ shr(A2, 2); // offset __ add(A1, A1, A2); diff -r 02fc94107aa2 -r 0b27fc8adf1b src/cpu/mips/vm/macroAssembler_mips.cpp --- a/src/cpu/mips/vm/macroAssembler_mips.cpp Wed Sep 11 12:40:06 2019 +0800 +++ b/src/cpu/mips/vm/macroAssembler_mips.cpp Fri Sep 27 11:31:13 2019 +0800 @@ -4241,3 +4241,44 @@ return code_offset; } + +void MacroAssembler::clear_jweak_tag(Register possibly_jweak) { + const int32_t inverted_jweak_mask = ~static_cast(JNIHandles::weak_tag_mask); + STATIC_ASSERT(inverted_jweak_mask == -2); // otherwise check this code + // The inverted mask is sign-extended + move(AT, inverted_jweak_mask); + andr(possibly_jweak, AT, possibly_jweak); +} + +void MacroAssembler::resolve_jobject(Register value, + Register thread, + Register tmp) { + assert_different_registers(value, thread, tmp); + Label done, not_weak; + beq(value, R0, done); // Use NULL as-is. + delayed()->nop(); + move(AT, JNIHandles::weak_tag_mask); // Test for jweak tag. + andr(AT, value, AT); + beq(AT, R0, not_weak); + delayed()->nop(); + // Resolve jweak. + ld(value, value, -JNIHandles::weak_tag_value); + verify_oop(value); + #if INCLUDE_ALL_GCS + if (UseG1GC) { + g1_write_barrier_pre(noreg /* obj */, + value /* pre_val */, + thread /* thread */, + tmp /* tmp */, + true /* tosca_live */, + true /* expand_call */); + } + #endif // INCLUDE_ALL_GCS + b(done); + delayed()->nop(); + bind(not_weak); + // Resolve (untagged) jobject. + ld(value, value, 0); + verify_oop(value); + bind(done); +} diff -r 02fc94107aa2 -r 0b27fc8adf1b src/cpu/mips/vm/macroAssembler_mips.hpp --- a/src/cpu/mips/vm/macroAssembler_mips.hpp Wed Sep 11 12:40:06 2019 +0800 +++ b/src/cpu/mips/vm/macroAssembler_mips.hpp Fri Sep 27 11:31:13 2019 +0800 @@ -217,6 +217,9 @@ void store_check(Register obj); // store check for obj - register is destroyed afterwards void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) + void resolve_jobject(Register value, Register thread, Register tmp); + void clear_jweak_tag(Register possibly_jweak); + #if INCLUDE_ALL_GCS void g1_write_barrier_pre(Register obj, diff -r 02fc94107aa2 -r 0b27fc8adf1b src/cpu/mips/vm/sharedRuntime_mips_64.cpp --- a/src/cpu/mips/vm/sharedRuntime_mips_64.cpp Wed Sep 11 12:40:06 2019 +0800 +++ b/src/cpu/mips/vm/sharedRuntime_mips_64.cpp Fri Sep 27 11:31:13 2019 +0800 @@ -2254,14 +2254,9 @@ __ reset_last_Java_frame(false); - // Unpack oop result + // Unpack oop result, e.g. JNIHandles::resolve value. if (ret_type == T_OBJECT || ret_type == T_ARRAY) { - Label L; - __ beq(V0, R0, L); - __ delayed()->nop(); - __ ld(V0, V0, 0); - __ bind(L); - __ verify_oop(V0); + __ resolve_jobject(V0, thread, T9); } if (!is_critical_native) { diff -r 02fc94107aa2 -r 0b27fc8adf1b src/cpu/mips/vm/templateInterpreter_mips_64.cpp --- a/src/cpu/mips/vm/templateInterpreter_mips_64.cpp Wed Sep 11 12:40:06 2019 +0800 +++ b/src/cpu/mips/vm/templateInterpreter_mips_64.cpp Fri Sep 27 11:31:13 2019 +0800 @@ -1303,19 +1303,16 @@ __ sw(R0, t, JNIHandleBlock::top_offset_in_bytes()); // If result was an oop then unbox and save it in the frame - { Label L; - Label no_oop, store_result; + { + Label no_oop; //FIXME, addi only support 16-bit imeditate __ ld(AT, FP, frame::interpreter_frame_result_handler_offset*wordSize); __ li(T0, AbstractInterpreter::result_handler(T_OBJECT)); __ bne(AT, T0, no_oop); __ delayed()->nop(); __ pop(ltos); - __ beq(V0, R0, store_result); - __ delayed()->nop(); - // unbox - __ ld(V0, V0, 0); - __ bind(store_result); + // Unbox oop result, e.g. JNIHandles::resolve value. + __ resolve_jobject(V0, thread, T9); __ sd(V0, FP, (frame::interpreter_frame_oop_temp_offset)*wordSize); // keep stack depth as expected by pushing oop which will eventually be discarded __ push(ltos);