Fri, 27 Sep 2019 11:31:13 +0800
#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
1.1 --- a/src/cpu/mips/vm/jniFastGetField_mips_64.cpp Wed Sep 11 12:40:06 2019 +0800 1.2 +++ b/src/cpu/mips/vm/jniFastGetField_mips_64.cpp Fri Sep 27 11:31:13 2019 +0800 1.3 @@ -1,6 +1,6 @@ 1.4 /* 1.5 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 - * Copyright (c) 2015, 2018, Loongson Technology. All rights reserved. 1.7 + * Copyright (c) 2015, 2019, Loongson Technology. All rights reserved. 1.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.9 * 1.10 * This code is free software; you can redistribute it and/or modify it 1.11 @@ -65,13 +65,15 @@ 1.12 __ set64(AT, (long)counter_addr); 1.13 __ lw(T1, AT, 0); 1.14 1.15 - /* 2012/4/28 Jin: the parameters(A0~A3) should not be modified, since 1.16 - * they will be used in slow path. */ 1.17 + // Parameters(A0~A3) should not be modified, since they will be used in slow path 1.18 __ andi(AT, T1, 1); 1.19 __ bne(AT, R0, slow); 1.20 __ delayed()->nop(); 1.21 1.22 - __ ld(T0, A1, 0); // unbox, *obj 1.23 + __ move(T0, A1); 1.24 + __ clear_jweak_tag(T0); 1.25 + 1.26 + __ ld(T0, T0, 0); // unbox, *obj 1.27 __ move(T2, A2); 1.28 __ shr(T2, 2); // offset 1.29 __ dadd(T0, T0, T2); 1.30 @@ -171,11 +173,14 @@ 1.31 __ bne(AT, R0, slow); 1.32 __ delayed()->nop(); 1.33 1.34 + __ clear_jweak_tag(A1); 1.35 + 1.36 #ifdef _LP64 1.37 __ ld(A1, A1, 0); // unbox, *obj 1.38 #else 1.39 __ lw(A1, A1, 0); // unbox, *obj 1.40 #endif 1.41 + 1.42 __ shr(A2, 2); // offset 1.43 __ add(A1, A1, A2); 1.44
2.1 --- a/src/cpu/mips/vm/macroAssembler_mips.cpp Wed Sep 11 12:40:06 2019 +0800 2.2 +++ b/src/cpu/mips/vm/macroAssembler_mips.cpp Fri Sep 27 11:31:13 2019 +0800 2.3 @@ -4241,3 +4241,44 @@ 2.4 2.5 return code_offset; 2.6 } 2.7 + 2.8 +void MacroAssembler::clear_jweak_tag(Register possibly_jweak) { 2.9 + const int32_t inverted_jweak_mask = ~static_cast<int32_t>(JNIHandles::weak_tag_mask); 2.10 + STATIC_ASSERT(inverted_jweak_mask == -2); // otherwise check this code 2.11 + // The inverted mask is sign-extended 2.12 + move(AT, inverted_jweak_mask); 2.13 + andr(possibly_jweak, AT, possibly_jweak); 2.14 +} 2.15 + 2.16 +void MacroAssembler::resolve_jobject(Register value, 2.17 + Register thread, 2.18 + Register tmp) { 2.19 + assert_different_registers(value, thread, tmp); 2.20 + Label done, not_weak; 2.21 + beq(value, R0, done); // Use NULL as-is. 2.22 + delayed()->nop(); 2.23 + move(AT, JNIHandles::weak_tag_mask); // Test for jweak tag. 2.24 + andr(AT, value, AT); 2.25 + beq(AT, R0, not_weak); 2.26 + delayed()->nop(); 2.27 + // Resolve jweak. 2.28 + ld(value, value, -JNIHandles::weak_tag_value); 2.29 + verify_oop(value); 2.30 + #if INCLUDE_ALL_GCS 2.31 + if (UseG1GC) { 2.32 + g1_write_barrier_pre(noreg /* obj */, 2.33 + value /* pre_val */, 2.34 + thread /* thread */, 2.35 + tmp /* tmp */, 2.36 + true /* tosca_live */, 2.37 + true /* expand_call */); 2.38 + } 2.39 + #endif // INCLUDE_ALL_GCS 2.40 + b(done); 2.41 + delayed()->nop(); 2.42 + bind(not_weak); 2.43 + // Resolve (untagged) jobject. 2.44 + ld(value, value, 0); 2.45 + verify_oop(value); 2.46 + bind(done); 2.47 +}
3.1 --- a/src/cpu/mips/vm/macroAssembler_mips.hpp Wed Sep 11 12:40:06 2019 +0800 3.2 +++ b/src/cpu/mips/vm/macroAssembler_mips.hpp Fri Sep 27 11:31:13 2019 +0800 3.3 @@ -217,6 +217,9 @@ 3.4 void store_check(Register obj); // store check for obj - register is destroyed afterwards 3.5 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) 3.6 3.7 + void resolve_jobject(Register value, Register thread, Register tmp); 3.8 + void clear_jweak_tag(Register possibly_jweak); 3.9 + 3.10 #if INCLUDE_ALL_GCS 3.11 3.12 void g1_write_barrier_pre(Register obj,
4.1 --- a/src/cpu/mips/vm/sharedRuntime_mips_64.cpp Wed Sep 11 12:40:06 2019 +0800 4.2 +++ b/src/cpu/mips/vm/sharedRuntime_mips_64.cpp Fri Sep 27 11:31:13 2019 +0800 4.3 @@ -2254,14 +2254,9 @@ 4.4 4.5 __ reset_last_Java_frame(false); 4.6 4.7 - // Unpack oop result 4.8 + // Unpack oop result, e.g. JNIHandles::resolve value. 4.9 if (ret_type == T_OBJECT || ret_type == T_ARRAY) { 4.10 - Label L; 4.11 - __ beq(V0, R0, L); 4.12 - __ delayed()->nop(); 4.13 - __ ld(V0, V0, 0); 4.14 - __ bind(L); 4.15 - __ verify_oop(V0); 4.16 + __ resolve_jobject(V0, thread, T9); 4.17 } 4.18 4.19 if (!is_critical_native) {
5.1 --- a/src/cpu/mips/vm/templateInterpreter_mips_64.cpp Wed Sep 11 12:40:06 2019 +0800 5.2 +++ b/src/cpu/mips/vm/templateInterpreter_mips_64.cpp Fri Sep 27 11:31:13 2019 +0800 5.3 @@ -1303,19 +1303,16 @@ 5.4 __ sw(R0, t, JNIHandleBlock::top_offset_in_bytes()); 5.5 5.6 // If result was an oop then unbox and save it in the frame 5.7 - { Label L; 5.8 - Label no_oop, store_result; 5.9 + { 5.10 + Label no_oop; 5.11 //FIXME, addi only support 16-bit imeditate 5.12 __ ld(AT, FP, frame::interpreter_frame_result_handler_offset*wordSize); 5.13 __ li(T0, AbstractInterpreter::result_handler(T_OBJECT)); 5.14 __ bne(AT, T0, no_oop); 5.15 __ delayed()->nop(); 5.16 __ pop(ltos); 5.17 - __ beq(V0, R0, store_result); 5.18 - __ delayed()->nop(); 5.19 - // unbox 5.20 - __ ld(V0, V0, 0); 5.21 - __ bind(store_result); 5.22 + // Unbox oop result, e.g. JNIHandles::resolve value. 5.23 + __ resolve_jobject(V0, thread, T9); 5.24 __ sd(V0, FP, (frame::interpreter_frame_oop_temp_offset)*wordSize); 5.25 // keep stack depth as expected by pushing oop which will eventually be discarded 5.26 __ push(ltos);