Tue, 07 May 2019 20:38:26 +0000
8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
Summary: Add tag bit to all JNI weak handles
Reviewed-by: kbarrett, coleenp, tschatzl
1.1 --- a/src/cpu/ppc/vm/frame_ppc.cpp Thu Nov 05 11:42:42 2015 +0100 1.2 +++ b/src/cpu/ppc/vm/frame_ppc.cpp Tue May 07 20:38:26 2019 +0000 1.3 @@ -1,6 +1,6 @@ 1.4 /* 1.5 - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 - * Copyright 2012, 2014 SAP AG. All rights reserved. 1.7 + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. 1.8 + * Copyright (c) 2012, 2017 SAP AG. All rights reserved. 1.9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.10 * 1.11 * This code is free software; you can redistribute it and/or modify it 1.12 @@ -190,10 +190,7 @@ 1.13 switch (method->result_type()) { 1.14 case T_OBJECT: 1.15 case T_ARRAY: { 1.16 - oop* obj_p = *(oop**)lresult; 1.17 - oop obj = (obj_p == NULL) ? (oop)NULL : *obj_p; 1.18 - assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); 1.19 - *oop_result = obj; 1.20 + *oop_result = JNIHandles::resolve(*(jobject*)lresult); 1.21 break; 1.22 } 1.23 // We use std/stfd to store the values.
2.1 --- a/src/cpu/ppc/vm/interpreter_ppc.cpp Thu Nov 05 11:42:42 2015 +0100 2.2 +++ b/src/cpu/ppc/vm/interpreter_ppc.cpp Tue May 07 20:38:26 2019 +0000 2.3 @@ -1,6 +1,6 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 2.6 - * Copyright 2012, 2015 SAP AG. All rights reserved. 2.7 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 2.8 + * Copyright (c) 2012, 2017 SAP AG. All rights reserved. 2.9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.10 * 2.11 * This code is free software; you can redistribute it and/or modify it 2.12 @@ -413,11 +413,8 @@ 2.13 case T_LONG: 2.14 break; 2.15 case T_OBJECT: 2.16 - // unbox result if not null 2.17 - __ cmpdi(CCR0, R3_RET, 0); 2.18 - __ beq(CCR0, done); 2.19 - __ ld(R3_RET, 0, R3_RET); 2.20 - __ verify_oop(R3_RET); 2.21 + // JNIHandles::resolve result. 2.22 + __ resolve_jobject(R3_RET, R11_scratch1, R12_scratch2, /* needs_frame */ true); // kills R31 2.23 break; 2.24 case T_FLOAT: 2.25 break;
3.1 --- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp Thu Nov 05 11:42:42 2015 +0100 3.2 +++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp Tue May 07 20:38:26 2019 +0000 3.3 @@ -1,6 +1,6 @@ 3.4 /* 3.5 - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 3.6 - * Copyright (c) 2012, 2018, SAP SE. All rights reserved. 3.7 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 3.8 + * Copyright (c) 2012, 2017, SAP SE. All rights reserved. 3.9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.10 * 3.11 * This code is free software; you can redistribute it and/or modify it 3.12 @@ -2220,6 +2220,34 @@ 3.13 stbx(R0, Rtmp, Robj); 3.14 } 3.15 3.16 +// Kills R31 if value is a volatile register. 3.17 +void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2, bool needs_frame) { 3.18 + Label done; 3.19 + cmpdi(CCR0, value, 0); 3.20 + beq(CCR0, done); // Use NULL as-is. 3.21 + 3.22 + clrrdi(tmp1, value, JNIHandles::weak_tag_size); 3.23 +#if INCLUDE_ALL_GCS 3.24 + if (UseG1GC) { andi_(tmp2, value, JNIHandles::weak_tag_mask); } 3.25 +#endif 3.26 + ld(value, 0, tmp1); // Resolve (untagged) jobject. 3.27 + 3.28 +#if INCLUDE_ALL_GCS 3.29 + if (UseG1GC) { 3.30 + Label not_weak; 3.31 + beq(CCR0, not_weak); // Test for jweak tag. 3.32 + verify_oop(value); 3.33 + g1_write_barrier_pre(noreg, // obj 3.34 + noreg, // offset 3.35 + value, // pre_val 3.36 + tmp1, tmp2, needs_frame); 3.37 + bind(not_weak); 3.38 + } 3.39 +#endif // INCLUDE_ALL_GCS 3.40 + verify_oop(value); 3.41 + bind(done); 3.42 +} 3.43 + 3.44 #if INCLUDE_ALL_GCS 3.45 // General G1 pre-barrier generator. 3.46 // Goal: record the previous value if it is not null. 3.47 @@ -2281,7 +2309,7 @@ 3.48 3.49 bind(runtime); 3.50 3.51 - // VM call need frame to access(write) O register. 3.52 + // May need to preserve LR. Also needed if current frame is not compatible with C calling convention. 3.53 if (needs_frame) { 3.54 save_LR_CR(Rtmp1); 3.55 push_frame_reg_args(0, Rtmp2);
4.1 --- a/src/cpu/ppc/vm/macroAssembler_ppc.hpp Thu Nov 05 11:42:42 2015 +0100 4.2 +++ b/src/cpu/ppc/vm/macroAssembler_ppc.hpp Tue May 07 20:38:26 2019 +0000 4.3 @@ -1,6 +1,6 @@ 4.4 /* 4.5 * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. 4.6 - * Copyright 2012, 2017 SAP AG. All rights reserved. 4.7 + * Copyright (c) 2012, 2017 SAP AG. All rights reserved. 4.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.9 * 4.10 * This code is free software; you can redistribute it and/or modify it 4.11 @@ -516,6 +516,8 @@ 4.12 void card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp); 4.13 void card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj); 4.14 4.15 + void resolve_jobject(Register value, Register tmp1, Register tmp2, bool needs_frame); 4.16 + 4.17 #if INCLUDE_ALL_GCS 4.18 // General G1 pre-barrier generator. 4.19 void g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val,
5.1 --- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Nov 05 11:42:42 2015 +0100 5.2 +++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Tue May 07 20:38:26 2019 +0000 5.3 @@ -1,6 +1,6 @@ 5.4 /* 5.5 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 5.6 - * Copyright 2012, 2014 SAP AG. All rights reserved. 5.7 + * Copyright (c) 2012, 2017 SAP AG. All rights reserved. 5.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.9 * 5.10 * This code is free software; you can redistribute it and/or modify it 5.11 @@ -2513,16 +2513,11 @@ 5.12 5.13 __ reset_last_Java_frame(); 5.14 5.15 - // Unpack oop result. 5.16 + // Unbox oop result, e.g. JNIHandles::resolve value. 5.17 // -------------------------------------------------------------------------- 5.18 5.19 if (ret_type == T_OBJECT || ret_type == T_ARRAY) { 5.20 - Label skip_unboxing; 5.21 - __ cmpdi(CCR0, R3_RET, 0); 5.22 - __ beq(CCR0, skip_unboxing); 5.23 - __ ld(R3_RET, 0, R3_RET); 5.24 - __ bind(skip_unboxing); 5.25 - __ verify_oop(R3_RET); 5.26 + __ resolve_jobject(R3_RET, r_temp_1, r_temp_2, /* needs_frame */ false); // kills R31 5.27 } 5.28 5.29
6.1 --- a/src/cpu/sparc/vm/jniFastGetField_sparc.cpp Thu Nov 05 11:42:42 2015 +0100 6.2 +++ b/src/cpu/sparc/vm/jniFastGetField_sparc.cpp Tue May 07 20:38:26 2019 +0000 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -68,6 +68,7 @@ 6.11 __ andcc (G4, 1, G0); 6.12 __ br (Assembler::notZero, false, Assembler::pn, label1); 6.13 __ delayed()->srl (O2, 2, O4); 6.14 + __ andn (O1, JNIHandles::weak_tag_mask, O1); 6.15 __ ld_ptr (O1, 0, O5); 6.16 6.17 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 6.18 @@ -147,6 +148,7 @@ 6.19 __ andcc (G4, 1, G0); 6.20 __ br (Assembler::notZero, false, Assembler::pn, label1); 6.21 __ delayed()->srl (O2, 2, O4); 6.22 + __ andn (O1, JNIHandles::weak_tag_mask, O1); 6.23 __ ld_ptr (O1, 0, O5); 6.24 __ add (O5, O4, O5); 6.25 6.26 @@ -219,6 +221,7 @@ 6.27 __ andcc (G4, 1, G0); 6.28 __ br (Assembler::notZero, false, Assembler::pn, label1); 6.29 __ delayed()->srl (O2, 2, O4); 6.30 + __ andn (O1, JNIHandles::weak_tag_mask, O1); 6.31 __ ld_ptr (O1, 0, O5); 6.32 6.33 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
7.1 --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Nov 05 11:42:42 2015 +0100 7.2 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Tue May 07 20:38:26 2019 +0000 7.3 @@ -2706,15 +2706,30 @@ 7.4 __ verify_thread(); // G2_thread must be correct 7.5 __ reset_last_Java_frame(); 7.6 7.7 - // Unpack oop result 7.8 + // Unbox oop result, e.g. JNIHandles::resolve value in I0. 7.9 if (ret_type == T_OBJECT || ret_type == T_ARRAY) { 7.10 - Label L; 7.11 - __ addcc(G0, I0, G0); 7.12 - __ brx(Assembler::notZero, true, Assembler::pt, L); 7.13 - __ delayed()->ld_ptr(I0, 0, I0); 7.14 - __ mov(G0, I0); 7.15 - __ bind(L); 7.16 - __ verify_oop(I0); 7.17 + Label done, not_weak; 7.18 + __ br_null(I0, false, Assembler::pn, done); // Use NULL as-is. 7.19 + __ delayed()->andcc(I0, JNIHandles::weak_tag_mask, G0); // Test for jweak 7.20 + __ brx(Assembler::zero, true, Assembler::pt, not_weak); 7.21 + __ delayed()->ld_ptr(I0, 0, I0); // Maybe resolve (untagged) jobject. 7.22 + // Resolve jweak. 7.23 + __ ld_ptr(I0, -JNIHandles::weak_tag_value, I0); 7.24 +#if INCLUDE_ALL_GCS 7.25 + if (UseG1GC) { 7.26 + // Copy to O0 because macro doesn't allow pre_val in input reg. 7.27 + __ mov(I0, O0); 7.28 + __ g1_write_barrier_pre(noreg /* obj */, 7.29 + noreg /* index */, 7.30 + 0 /* offset */, 7.31 + O0 /* pre_val */, 7.32 + G3_scratch /* tmp */, 7.33 + true /* preserve_o_regs */); 7.34 + } 7.35 +#endif // INCLUDE_ALL_GCS 7.36 + __ bind(not_weak); 7.37 + __ verify_oop(I0); 7.38 + __ bind(done); 7.39 } 7.40 7.41 if (!is_critical_native) {
8.1 --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Nov 05 11:42:42 2015 +0100 8.2 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Tue May 07 20:38:26 2019 +0000 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -1160,11 +1160,23 @@ 8.11 8.12 __ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch); 8.13 __ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop); 8.14 - __ addcc(G0, O0, O0); 8.15 - __ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL: 8.16 - __ delayed()->ld_ptr(O0, 0, O0); // unbox it 8.17 - __ mov(G0, O0); 8.18 - 8.19 + // Unbox oop result, e.g. JNIHandles::resolve value in O0. 8.20 + __ br_null(O0, false, Assembler::pn, store_result); // Use NULL as-is. 8.21 + __ delayed()->andcc(O0, JNIHandles::weak_tag_mask, G0); // Test for jweak 8.22 + __ brx(Assembler::zero, true, Assembler::pt, store_result); 8.23 + __ delayed()->ld_ptr(O0, 0, O0); // Maybe resolve (untagged) jobject. 8.24 + // Resolve jweak. 8.25 + __ ld_ptr(O0, -JNIHandles::weak_tag_value, O0); 8.26 +#if INCLUDE_ALL_GCS 8.27 + if (UseG1GC) { 8.28 + __ g1_write_barrier_pre(noreg /* obj */, 8.29 + noreg /* index */, 8.30 + 0 /* offset */, 8.31 + O0 /* pre_val */, 8.32 + G3_scratch /* tmp */, 8.33 + true /* preserve_o_regs */); 8.34 + } 8.35 +#endif // INCLUDE_ALL_GCS 8.36 __ bind(store_result); 8.37 // Store it where gc will look for it and result handler expects it. 8.38 __ st_ptr(O0, FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS);
9.1 --- a/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Thu Nov 05 11:42:42 2015 +0100 9.2 +++ b/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Tue May 07 20:38:26 2019 +0000 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -79,14 +79,17 @@ 9.11 __ mov(rax, rcx); 9.12 __ andptr(rax, 1); // rax, must end up 0 9.13 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); 9.14 - // obj, notice rax, is 0. 9.15 - // rdx is data dependent on rcx. 9.16 + // obj, notice rax, is 0. 9.17 + // rdx is data dependent on rcx. 9.18 } else { 9.19 - __ movptr (rdx, Address(rsp, 2*wordSize)); // obj 9.20 + __ movptr (rdx, Address(rsp, 2*wordSize)); // obj 9.21 } 9.22 __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID 9.23 + 9.24 + __ clear_jweak_tag(rdx); 9.25 + 9.26 __ movptr(rdx, Address(rdx, 0)); // *obj 9.27 - __ shrptr (rax, 2); // offset 9.28 + __ shrptr (rax, 2); // offset 9.29 9.30 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 9.31 speculative_load_pclist[count] = __ pc(); 9.32 @@ -194,14 +197,17 @@ 9.33 __ jcc (Assembler::notZero, slow); 9.34 if (os::is_MP()) { 9.35 __ mov(rax, rcx); 9.36 - __ andptr(rax, 1); // rax, must end up 0 9.37 + __ andptr(rax, 1); // rax, must end up 0 9.38 __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); 9.39 // obj, notice rax, is 0. 9.40 // rdx is data dependent on rcx. 9.41 } else { 9.42 - __ movptr(rdx, Address(rsp, 3*wordSize)); // obj 9.43 + __ movptr(rdx, Address(rsp, 3*wordSize)); // obj 9.44 } 9.45 __ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID 9.46 + 9.47 + __ clear_jweak_tag(rdx); 9.48 + 9.49 __ movptr(rdx, Address(rdx, 0)); // *obj 9.50 __ shrptr(rsi, 2); // offset 9.51 9.52 @@ -283,7 +289,7 @@ 9.53 __ jcc (Assembler::notZero, slow); 9.54 if (os::is_MP()) { 9.55 __ mov(rax, rcx); 9.56 - __ andptr(rax, 1); // rax, must end up 0 9.57 + __ andptr(rax, 1); // rax, must end up 0 9.58 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); 9.59 // obj, notice rax, is 0. 9.60 // rdx is data dependent on rcx. 9.61 @@ -291,6 +297,9 @@ 9.62 __ movptr(rdx, Address(rsp, 2*wordSize)); // obj 9.63 } 9.64 __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID 9.65 + 9.66 + __ clear_jweak_tag(rdx); 9.67 + 9.68 __ movptr(rdx, Address(rdx, 0)); // *obj 9.69 __ shrptr(rax, 2); // offset 9.70
10.1 --- a/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Thu Nov 05 11:42:42 2015 +0100 10.2 +++ b/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Tue May 07 20:38:26 2019 +0000 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -76,13 +76,16 @@ 10.11 __ jcc (Assembler::notZero, slow); 10.12 if (os::is_MP()) { 10.13 __ xorptr(robj, rcounter); 10.14 - __ xorptr(robj, rcounter); // obj, since 10.15 + __ xorptr(robj, rcounter); // obj, since 10.16 // robj ^ rcounter ^ rcounter == robj 10.17 // robj is data dependent on rcounter. 10.18 } 10.19 - __ movptr(robj, Address(robj, 0)); // *obj 10.20 + 10.21 + __ clear_jweak_tag(robj); 10.22 + 10.23 + __ movptr(robj, Address(robj, 0)); // *obj 10.24 __ mov (roffset, c_rarg2); 10.25 - __ shrptr(roffset, 2); // offset 10.26 + __ shrptr(roffset, 2); // offset 10.27 10.28 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 10.29 speculative_load_pclist[count] = __ pc(); 10.30 @@ -174,13 +177,16 @@ 10.31 __ jcc (Assembler::notZero, slow); 10.32 if (os::is_MP()) { 10.33 __ xorptr(robj, rcounter); 10.34 - __ xorptr(robj, rcounter); // obj, since 10.35 + __ xorptr(robj, rcounter); // obj, since 10.36 // robj ^ rcounter ^ rcounter == robj 10.37 // robj is data dependent on rcounter. 10.38 } 10.39 - __ movptr(robj, Address(robj, 0)); // *obj 10.40 + 10.41 + __ clear_jweak_tag(robj); 10.42 + 10.43 + __ movptr(robj, Address(robj, 0)); // *obj 10.44 __ mov (roffset, c_rarg2); 10.45 - __ shrptr(roffset, 2); // offset 10.46 + __ shrptr(roffset, 2); // offset 10.47 10.48 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 10.49 speculative_load_pclist[count] = __ pc();
11.1 --- a/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Nov 05 11:42:42 2015 +0100 11.2 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp Tue May 07 20:38:26 2019 +0000 11.3 @@ -4119,6 +4119,42 @@ 11.4 } 11.5 } 11.6 11.7 +void MacroAssembler::resolve_jobject(Register value, 11.8 + Register thread, 11.9 + Register tmp) { 11.10 + assert_different_registers(value, thread, tmp); 11.11 + Label done, not_weak; 11.12 + testptr(value, value); 11.13 + jcc(Assembler::zero, done); // Use NULL as-is. 11.14 + testptr(value, JNIHandles::weak_tag_mask); // Test for jweak tag. 11.15 + jcc(Assembler::zero, not_weak); 11.16 + // Resolve jweak. 11.17 + movptr(value, Address(value, -JNIHandles::weak_tag_value)); 11.18 + verify_oop(value); 11.19 +#if INCLUDE_ALL_GCS 11.20 + if (UseG1GC) { 11.21 + g1_write_barrier_pre(noreg /* obj */, 11.22 + value /* pre_val */, 11.23 + thread /* thread */, 11.24 + tmp /* tmp */, 11.25 + true /* tosca_live */, 11.26 + true /* expand_call */); 11.27 + } 11.28 +#endif // INCLUDE_ALL_GCS 11.29 + jmp(done); 11.30 + bind(not_weak); 11.31 + // Resolve (untagged) jobject. 11.32 + movptr(value, Address(value, 0)); 11.33 + verify_oop(value); 11.34 + bind(done); 11.35 +} 11.36 + 11.37 +void MacroAssembler::clear_jweak_tag(Register possibly_jweak) { 11.38 + const int32_t inverted_jweak_mask = ~static_cast<int32_t>(JNIHandles::weak_tag_mask); 11.39 + STATIC_ASSERT(inverted_jweak_mask == -2); // otherwise check this code 11.40 + // The inverted mask is sign-extended 11.41 + andptr(possibly_jweak, inverted_jweak_mask); 11.42 +} 11.43 11.44 ////////////////////////////////////////////////////////////////////////////////// 11.45 #if INCLUDE_ALL_GCS
12.1 --- a/src/cpu/x86/vm/macroAssembler_x86.hpp Thu Nov 05 11:42:42 2015 +0100 12.2 +++ b/src/cpu/x86/vm/macroAssembler_x86.hpp Tue May 07 20:38:26 2019 +0000 12.3 @@ -298,6 +298,9 @@ 12.4 void store_check(Register obj); // store check for obj - register is destroyed afterwards 12.5 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) 12.6 12.7 + void resolve_jobject(Register value, Register thread, Register tmp); 12.8 + void clear_jweak_tag(Register possibly_jweak); 12.9 + 12.10 #if INCLUDE_ALL_GCS 12.11 12.12 void g1_write_barrier_pre(Register obj,
13.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Nov 05 11:42:42 2015 +0100 13.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue May 07 20:38:26 2019 +0000 13.3 @@ -2253,14 +2253,11 @@ 13.4 13.5 __ reset_last_Java_frame(thread, false); 13.6 13.7 - // Unpack oop result 13.8 + // Unbox oop result, e.g. JNIHandles::resolve value. 13.9 if (ret_type == T_OBJECT || ret_type == T_ARRAY) { 13.10 - Label L; 13.11 - __ cmpptr(rax, (int32_t)NULL_WORD); 13.12 - __ jcc(Assembler::equal, L); 13.13 - __ movptr(rax, Address(rax, 0)); 13.14 - __ bind(L); 13.15 - __ verify_oop(rax); 13.16 + __ resolve_jobject(rax /* value */, 13.17 + thread /* thread */, 13.18 + rcx /* tmp */); 13.19 } 13.20 13.21 if (!is_critical_native) {
14.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Nov 05 11:42:42 2015 +0100 14.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue May 07 20:38:26 2019 +0000 14.3 @@ -2499,14 +2499,11 @@ 14.4 14.5 __ reset_last_Java_frame(false); 14.6 14.7 - // Unpack oop result 14.8 + // Unbox oop result, e.g. JNIHandles::resolve value. 14.9 if (ret_type == T_OBJECT || ret_type == T_ARRAY) { 14.10 - Label L; 14.11 - __ testptr(rax, rax); 14.12 - __ jcc(Assembler::zero, L); 14.13 - __ movptr(rax, Address(rax, 0)); 14.14 - __ bind(L); 14.15 - __ verify_oop(rax); 14.16 + __ resolve_jobject(rax /* value */, 14.17 + r15_thread /* thread */, 14.18 + rcx /* tmp */); 14.19 } 14.20 14.21 if (!is_critical_native) {
15.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Nov 05 11:42:42 2015 +0100 15.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue May 07 20:38:26 2019 +0000 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -1296,19 +1296,18 @@ 15.11 __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); 15.12 15.13 // If result was an oop then unbox and save it in the frame 15.14 - { Label L; 15.15 - Label no_oop, store_result; 15.16 + { 15.17 + Label no_oop; 15.18 ExternalAddress handler(AbstractInterpreter::result_handler(T_OBJECT)); 15.19 __ cmpptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), 15.20 handler.addr()); 15.21 __ jcc(Assembler::notEqual, no_oop); 15.22 __ cmpptr(Address(rsp, 0), (int32_t)NULL_WORD); 15.23 __ pop(ltos); 15.24 - __ testptr(rax, rax); 15.25 - __ jcc(Assembler::zero, store_result); 15.26 - // unbox 15.27 - __ movptr(rax, Address(rax, 0)); 15.28 - __ bind(store_result); 15.29 + // Unbox oop result, e.g. JNIHandles::resolve value. 15.30 + __ resolve_jobject(rax /* value */, 15.31 + thread /* thread */, 15.32 + t /* tmp */); 15.33 __ movptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset)*wordSize), rax); 15.34 // keep stack depth as expected by pushing oop which will eventually be discarded 15.35 __ push(ltos);
16.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Nov 05 11:42:42 2015 +0100 16.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Tue May 07 20:38:26 2019 +0000 16.3 @@ -1,5 +1,5 @@ 16.4 /* 16.5 - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 16.6 + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 16.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.8 * 16.9 * This code is free software; you can redistribute it and/or modify it 16.10 @@ -1272,16 +1272,16 @@ 16.11 // and result handler will pick it up 16.12 16.13 { 16.14 - Label no_oop, store_result; 16.15 + Label no_oop; 16.16 __ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); 16.17 __ cmpptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); 16.18 __ jcc(Assembler::notEqual, no_oop); 16.19 // retrieve result 16.20 __ pop(ltos); 16.21 - __ testptr(rax, rax); 16.22 - __ jcc(Assembler::zero, store_result); 16.23 - __ movptr(rax, Address(rax, 0)); 16.24 - __ bind(store_result); 16.25 + // Unbox oop result, e.g. JNIHandles::resolve value. 16.26 + __ resolve_jobject(rax /* value */, 16.27 + r15_thread /* thread */, 16.28 + t /* tmp */); 16.29 __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); 16.30 // keep stack depth as expected by pushing oop which will eventually be discarde 16.31 __ push(ltos);
17.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Nov 05 11:42:42 2015 +0100 17.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Tue May 07 20:38:26 2019 +0000 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 17.7 * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. 17.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.9 * 17.10 @@ -405,10 +405,12 @@ 17.11 // oop_temp where the garbage collector can see it before 17.12 // we release the handle it might be protected by. 17.13 if (handler->result_type() == &ffi_type_pointer) { 17.14 - if (result[0]) 17.15 - istate->set_oop_temp(*(oop *) result[0]); 17.16 - else 17.17 + if (result[0] == 0) { 17.18 istate->set_oop_temp(NULL); 17.19 + } else { 17.20 + jobject handle = reinterpret_cast<jobject>(result[0]); 17.21 + istate->set_oop_temp(JNIHandles::resolve(handle)); 17.22 + } 17.23 } 17.24 17.25 // Reset handle block
18.1 --- a/src/share/vm/prims/jni.cpp Thu Nov 05 11:42:42 2015 +0100 18.2 +++ b/src/share/vm/prims/jni.cpp Tue May 07 20:38:26 2019 +0000 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 18.7 * Copyright (c) 2012 Red Hat, Inc. 18.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.9 * 18.10 @@ -709,6 +709,7 @@ 18.11 18.12 THROW_OOP_(JNIHandles::resolve(obj), JNI_OK); 18.13 ShouldNotReachHere(); 18.14 + return 0; // Mute compiler. 18.15 JNI_END 18.16 18.17 #ifndef USDT2 18.18 @@ -735,6 +736,7 @@ 18.19 Handle protection_domain (THREAD, k->protection_domain()); 18.20 THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK); 18.21 ShouldNotReachHere(); 18.22 + return 0; // Mute compiler. 18.23 JNI_END 18.24 18.25 18.26 @@ -1140,8 +1142,7 @@ 18.27 inline void get_long() { _arguments->push_long(va_arg(_ap, jlong)); } 18.28 inline void get_float() { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg 18.29 inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); } 18.30 - inline void get_object() { jobject l = va_arg(_ap, jobject); 18.31 - _arguments->push_oop(Handle((oop *)l, false)); } 18.32 + inline void get_object() { _arguments->push_jobject(va_arg(_ap, jobject)); } 18.33 18.34 inline void set_ap(va_list rap) { 18.35 #ifdef va_copy 18.36 @@ -1235,7 +1236,7 @@ 18.37 inline void get_long() { _arguments->push_long((_ap++)->j); } 18.38 inline void get_float() { _arguments->push_float((_ap++)->f); } 18.39 inline void get_double() { _arguments->push_double((_ap++)->d);} 18.40 - inline void get_object() { _arguments->push_oop(Handle((oop *)(_ap++)->l, false)); } 18.41 + inline void get_object() { _arguments->push_jobject((_ap++)->l); } 18.42 18.43 inline void set_ap(const jvalue *rap) { _ap = rap; } 18.44
19.1 --- a/src/share/vm/prims/jvmtiEnv.cpp Thu Nov 05 11:42:42 2015 +0100 19.2 +++ b/src/share/vm/prims/jvmtiEnv.cpp Tue May 07 20:38:26 2019 +0000 19.3 @@ -1,5 +1,5 @@ 19.4 /* 19.5 - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 19.6 + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. 19.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 * 19.9 * This code is free software; you can redistribute it and/or modify it 19.10 @@ -1621,6 +1621,13 @@ 19.11 } 19.12 } 19.13 19.14 + if (initial_object != NULL) { 19.15 + oop init_obj = JNIHandles::resolve_external_guard(initial_object); 19.16 + if (init_obj == NULL) { 19.17 + return JVMTI_ERROR_INVALID_OBJECT; 19.18 + } 19.19 + } 19.20 + 19.21 Thread *thread = Thread::current(); 19.22 HandleMark hm(thread); 19.23 KlassHandle kh (thread, k_oop);
20.1 --- a/src/share/vm/runtime/javaCalls.cpp Thu Nov 05 11:42:42 2015 +0100 20.2 +++ b/src/share/vm/runtime/javaCalls.cpp Tue May 07 20:38:26 2019 +0000 20.3 @@ -1,5 +1,5 @@ 20.4 /* 20.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 20.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 20.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.8 * 20.9 * This code is free software; you can redistribute it and/or modify it 20.10 @@ -325,9 +325,9 @@ 20.11 // Verify the arguments 20.12 20.13 if (CheckJNICalls) { 20.14 - args->verify(method, result->get_type(), thread); 20.15 + args->verify(method, result->get_type()); 20.16 } 20.17 - else debug_only(args->verify(method, result->get_type(), thread)); 20.18 + else debug_only(args->verify(method, result->get_type())); 20.19 20.20 // Ignore call if method is empty 20.21 if (method->is_empty_method()) { 20.22 @@ -429,12 +429,42 @@ 20.23 //-------------------------------------------------------------------------------------- 20.24 // Implementation of JavaCallArguments 20.25 20.26 +inline bool is_value_state_indirect_oop(uint state) { 20.27 + assert(state != JavaCallArguments::value_state_oop, 20.28 + "Checking for handles after removal"); 20.29 + assert(state < JavaCallArguments::value_state_limit, "Invalid value state"); 20.30 + return state != JavaCallArguments::value_state_primitive; 20.31 +} 20.32 + 20.33 +inline oop resolve_indirect_oop(intptr_t value, uint state) { 20.34 + switch (state) { 20.35 + case JavaCallArguments::value_state_handle: 20.36 + { 20.37 + oop* ptr = reinterpret_cast<oop*>(value); 20.38 + return Handle::raw_resolve(ptr); 20.39 + } 20.40 + 20.41 + case JavaCallArguments::value_state_jobject: 20.42 + { 20.43 + jobject obj = reinterpret_cast<jobject>(value); 20.44 + return JNIHandles::resolve(obj); 20.45 + } 20.46 + 20.47 + default: 20.48 + ShouldNotReachHere(); 20.49 + return NULL; 20.50 + } 20.51 +} 20.52 + 20.53 intptr_t* JavaCallArguments::parameters() { 20.54 // First convert all handles to oops 20.55 for(int i = 0; i < _size; i++) { 20.56 - if (_is_oop[i]) { 20.57 - // Handle conversion 20.58 - _value[i] = cast_from_oop<intptr_t>(Handle::raw_resolve((oop *)_value[i])); 20.59 + uint state = _value_state[i]; 20.60 + assert(state != value_state_oop, "Multiple handle conversions"); 20.61 + if (is_value_state_indirect_oop(state)) { 20.62 + oop obj = resolve_indirect_oop(_value[i], state); 20.63 + _value[i] = cast_from_oop<intptr_t>(obj); 20.64 + _value_state[i] = value_state_oop; 20.65 } 20.66 } 20.67 // Return argument vector 20.68 @@ -444,30 +474,40 @@ 20.69 20.70 class SignatureChekker : public SignatureIterator { 20.71 private: 20.72 - bool *_is_oop; 20.73 - int _pos; 20.74 - BasicType _return_type; 20.75 - intptr_t* _value; 20.76 - Thread* _thread; 20.77 + int _pos; 20.78 + BasicType _return_type; 20.79 + u_char* _value_state; 20.80 + intptr_t* _value; 20.81 20.82 public: 20.83 bool _is_return; 20.84 20.85 - SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { 20.86 - _is_oop = is_oop; 20.87 - _is_return = false; 20.88 - _return_type = return_type; 20.89 - _pos = 0; 20.90 - _value = value; 20.91 - _thread = thread; 20.92 - 20.93 + SignatureChekker(Symbol* signature, 20.94 + BasicType return_type, 20.95 + bool is_static, 20.96 + u_char* value_state, 20.97 + intptr_t* value) : 20.98 + SignatureIterator(signature), 20.99 + _pos(0), 20.100 + _return_type(return_type), 20.101 + _value_state(value_state), 20.102 + _value(value), 20.103 + _is_return(false) 20.104 + { 20.105 if (!is_static) { 20.106 check_value(true); // Receiver must be an oop 20.107 } 20.108 } 20.109 20.110 void check_value(bool type) { 20.111 - guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments"); 20.112 + uint state = _value_state[_pos++]; 20.113 + if (type) { 20.114 + guarantee(is_value_state_indirect_oop(state), 20.115 + "signature does not match pushed arguments"); 20.116 + } else { 20.117 + guarantee(state == JavaCallArguments::value_state_primitive, 20.118 + "signature does not match pushed arguments"); 20.119 + } 20.120 } 20.121 20.122 void check_doing_return(bool state) { _is_return = state; } 20.123 @@ -502,24 +542,19 @@ 20.124 return; 20.125 } 20.126 20.127 - // verify handle and the oop pointed to by handle 20.128 - int p = _pos; 20.129 - bool bad = false; 20.130 - // If argument is oop 20.131 - if (_is_oop[p]) { 20.132 - intptr_t v = _value[p]; 20.133 - if (v != 0 ) { 20.134 - size_t t = (size_t)v; 20.135 - bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true); 20.136 - if (CheckJNICalls && bad) { 20.137 - ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); 20.138 - } 20.139 - } 20.140 - // for the regular debug case. 20.141 - assert(!bad, "Bad JNI oop argument"); 20.142 + intptr_t v = _value[_pos]; 20.143 + if (v != 0) { 20.144 + // v is a "handle" referring to an oop, cast to integral type. 20.145 + // There shouldn't be any handles in very low memory. 20.146 + guarantee((size_t)v >= (size_t)os::vm_page_size(), 20.147 + "Bad JNI oop argument"); 20.148 + // Verify the pointee. 20.149 + oop vv = resolve_indirect_oop(v, _value_state[_pos]); 20.150 + guarantee(vv->is_oop_or_null(true), 20.151 + "Bad JNI oop argument"); 20.152 } 20.153 20.154 - check_value(true); 20.155 + check_value(true); // Verify value state. 20.156 } 20.157 20.158 void do_bool() { check_int(T_BOOLEAN); } 20.159 @@ -536,8 +571,7 @@ 20.160 }; 20.161 20.162 20.163 -void JavaCallArguments::verify(methodHandle method, BasicType return_type, 20.164 - Thread *thread) { 20.165 +void JavaCallArguments::verify(methodHandle method, BasicType return_type) { 20.166 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); 20.167 20.168 // Treat T_OBJECT and T_ARRAY as the same 20.169 @@ -546,7 +580,11 @@ 20.170 // Check that oop information is correct 20.171 Symbol* signature = method->signature(); 20.172 20.173 - SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); 20.174 + SignatureChekker sc(signature, 20.175 + return_type, 20.176 + method->is_static(), 20.177 + _value_state, 20.178 + _value); 20.179 sc.iterate_parameters(); 20.180 sc.check_doing_return(true); 20.181 sc.iterate_returntype();
21.1 --- a/src/share/vm/runtime/javaCalls.hpp Thu Nov 05 11:42:42 2015 +0100 21.2 +++ b/src/share/vm/runtime/javaCalls.hpp Tue May 07 20:38:26 2019 +0000 21.3 @@ -1,5 +1,5 @@ 21.4 /* 21.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 21.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.8 * 21.9 * This code is free software; you can redistribute it and/or modify it 21.10 @@ -92,25 +92,42 @@ 21.11 _default_size = 8 // Must be at least # of arguments in JavaCalls methods 21.12 }; 21.13 21.14 - intptr_t _value_buffer [_default_size + 1]; 21.15 - bool _is_oop_buffer[_default_size + 1]; 21.16 + intptr_t _value_buffer [_default_size + 1]; 21.17 + u_char _value_state_buffer[_default_size + 1]; 21.18 21.19 intptr_t* _value; 21.20 - bool* _is_oop; 21.21 + u_char* _value_state; 21.22 int _size; 21.23 int _max_size; 21.24 bool _start_at_zero; // Support late setting of receiver 21.25 21.26 void initialize() { 21.27 // Starts at first element to support set_receiver. 21.28 - _value = &_value_buffer[1]; 21.29 - _is_oop = &_is_oop_buffer[1]; 21.30 + _value = &_value_buffer[1]; 21.31 + _value_state = &_value_state_buffer[1]; 21.32 21.33 _max_size = _default_size; 21.34 _size = 0; 21.35 _start_at_zero = false; 21.36 } 21.37 21.38 + // Helper for push_oop and the like. The value argument is a 21.39 + // "handle" that refers to an oop. We record the address of the 21.40 + // handle rather than the designated oop. The handle is later 21.41 + // resolved to the oop by parameters(). This delays the exposure of 21.42 + // naked oops until it is GC-safe. 21.43 + template<typename T> 21.44 + inline int push_oop_impl(T handle, int size) { 21.45 + // JNITypes::put_obj expects an oop value, so we play fast and 21.46 + // loose with the type system. The cast from handle type to oop 21.47 + // *must* use a C-style cast. In a product build it performs a 21.48 + // reinterpret_cast. In a debug build (more accurately, in a 21.49 + // CHECK_UNHANDLED_OOPS build) it performs a static_cast, invoking 21.50 + // the debug-only oop class's conversion from void* constructor. 21.51 + JNITypes::put_obj((oop)handle, _value, size); // Updates size. 21.52 + return size; // Return the updated size. 21.53 + } 21.54 + 21.55 public: 21.56 JavaCallArguments() { initialize(); } 21.57 21.58 @@ -121,11 +138,12 @@ 21.59 21.60 JavaCallArguments(int max_size) { 21.61 if (max_size > _default_size) { 21.62 - _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1); 21.63 - _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1); 21.64 + _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1); 21.65 + _value_state = NEW_RESOURCE_ARRAY(u_char, max_size + 1); 21.66 21.67 - // Reserve room for potential receiver in value and is_oop 21.68 - _value++; _is_oop++; 21.69 + // Reserve room for potential receiver in value and state 21.70 + _value++; 21.71 + _value_state++; 21.72 21.73 _max_size = max_size; 21.74 _size = 0; 21.75 @@ -135,25 +153,52 @@ 21.76 } 21.77 } 21.78 21.79 - inline void push_oop(Handle h) { _is_oop[_size] = true; 21.80 - JNITypes::put_obj((oop)h.raw_value(), _value, _size); } 21.81 + // The possible values for _value_state elements. 21.82 + enum { 21.83 + value_state_primitive, 21.84 + value_state_oop, 21.85 + value_state_handle, 21.86 + value_state_jobject, 21.87 + value_state_limit 21.88 + }; 21.89 21.90 - inline void push_int(int i) { _is_oop[_size] = false; 21.91 - JNITypes::put_int(i, _value, _size); } 21.92 + inline void push_oop(Handle h) { 21.93 + _value_state[_size] = value_state_handle; 21.94 + _size = push_oop_impl(h.raw_value(), _size); 21.95 + } 21.96 21.97 - inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false; 21.98 - JNITypes::put_double(d, _value, _size); } 21.99 + inline void push_jobject(jobject h) { 21.100 + _value_state[_size] = value_state_jobject; 21.101 + _size = push_oop_impl(h, _size); 21.102 + } 21.103 21.104 - inline void push_long(jlong l) { _is_oop[_size] = false; _is_oop[_size + 1] = false; 21.105 - JNITypes::put_long(l, _value, _size); } 21.106 + inline void push_int(int i) { 21.107 + _value_state[_size] = value_state_primitive; 21.108 + JNITypes::put_int(i, _value, _size); 21.109 + } 21.110 21.111 - inline void push_float(float f) { _is_oop[_size] = false; 21.112 - JNITypes::put_float(f, _value, _size); } 21.113 + inline void push_double(double d) { 21.114 + _value_state[_size] = value_state_primitive; 21.115 + _value_state[_size + 1] = value_state_primitive; 21.116 + JNITypes::put_double(d, _value, _size); 21.117 + } 21.118 + 21.119 + inline void push_long(jlong l) { 21.120 + _value_state[_size] = value_state_primitive; 21.121 + _value_state[_size + 1] = value_state_primitive; 21.122 + JNITypes::put_long(l, _value, _size); 21.123 + } 21.124 + 21.125 + inline void push_float(float f) { 21.126 + _value_state[_size] = value_state_primitive; 21.127 + JNITypes::put_float(f, _value, _size); 21.128 + } 21.129 21.130 // receiver 21.131 Handle receiver() { 21.132 assert(_size > 0, "must at least be one argument"); 21.133 - assert(_is_oop[0], "first argument must be an oop"); 21.134 + assert(_value_state[0] == value_state_handle, 21.135 + "first argument must be an oop"); 21.136 assert(_value[0] != 0, "receiver must be not-null"); 21.137 return Handle((oop*)_value[0], false); 21.138 } 21.139 @@ -161,11 +206,11 @@ 21.140 void set_receiver(Handle h) { 21.141 assert(_start_at_zero == false, "can only be called once"); 21.142 _start_at_zero = true; 21.143 - _is_oop--; 21.144 + _value_state--; 21.145 _value--; 21.146 _size++; 21.147 - _is_oop[0] = true; 21.148 - _value[0] = (intptr_t)h.raw_value(); 21.149 + _value_state[0] = value_state_handle; 21.150 + push_oop_impl(h.raw_value(), 0); 21.151 } 21.152 21.153 // Converts all Handles to oops, and returns a reference to parameter vector 21.154 @@ -173,7 +218,7 @@ 21.155 int size_of_parameters() const { return _size; } 21.156 21.157 // Verify that pushed arguments fits a given method 21.158 - void verify(methodHandle method, BasicType return_type, Thread *thread); 21.159 + void verify(methodHandle method, BasicType return_type); 21.160 }; 21.161 21.162 // All calls to Java have to go via JavaCalls. Sets up the stack frame
22.1 --- a/src/share/vm/runtime/jniHandles.cpp Thu Nov 05 11:42:42 2015 +0100 22.2 +++ b/src/share/vm/runtime/jniHandles.cpp Tue May 07 20:38:26 2019 +0000 22.3 @@ -30,6 +30,9 @@ 22.4 #include "runtime/jniHandles.hpp" 22.5 #include "runtime/mutexLocker.hpp" 22.6 #include "runtime/thread.inline.hpp" 22.7 +#if INCLUDE_ALL_GCS 22.8 +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" 22.9 +#endif 22.10 22.11 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 22.12 22.13 @@ -87,34 +90,52 @@ 22.14 return res; 22.15 } 22.16 22.17 - 22.18 jobject JNIHandles::make_weak_global(Handle obj) { 22.19 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); 22.20 jobject res = NULL; 22.21 if (!obj.is_null()) { 22.22 // ignore null handles 22.23 - MutexLocker ml(JNIGlobalHandle_lock); 22.24 - assert(Universe::heap()->is_in_reserved(obj()), "sanity check"); 22.25 - res = _weak_global_handles->allocate_handle(obj()); 22.26 + { 22.27 + MutexLocker ml(JNIGlobalHandle_lock); 22.28 + assert(Universe::heap()->is_in_reserved(obj()), "sanity check"); 22.29 + res = _weak_global_handles->allocate_handle(obj()); 22.30 + } 22.31 + // Add weak tag. 22.32 + assert(is_ptr_aligned(res, weak_tag_alignment), "invariant"); 22.33 + char* tptr = reinterpret_cast<char*>(res) + weak_tag_value; 22.34 + res = reinterpret_cast<jobject>(tptr); 22.35 } else { 22.36 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 22.37 } 22.38 return res; 22.39 } 22.40 22.41 +template<bool external_guard> 22.42 +oop JNIHandles::resolve_jweak(jweak handle) { 22.43 + assert(is_jweak(handle), "precondition"); 22.44 + oop result = jweak_ref(handle); 22.45 + result = guard_value<external_guard>(result); 22.46 +#if INCLUDE_ALL_GCS 22.47 + if (result != NULL && UseG1GC) { 22.48 + G1SATBCardTableModRefBS::enqueue(result); 22.49 + } 22.50 +#endif // INCLUDE_ALL_GCS 22.51 + return result; 22.52 +} 22.53 + 22.54 +template oop JNIHandles::resolve_jweak<true>(jweak); 22.55 +template oop JNIHandles::resolve_jweak<false>(jweak); 22.56 22.57 void JNIHandles::destroy_global(jobject handle) { 22.58 if (handle != NULL) { 22.59 assert(is_global_handle(handle), "Invalid delete of global JNI handle"); 22.60 - *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 22.61 + jobject_ref(handle) = deleted_handle(); 22.62 } 22.63 } 22.64 22.65 - 22.66 void JNIHandles::destroy_weak_global(jobject handle) { 22.67 if (handle != NULL) { 22.68 - assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle"); 22.69 - *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 22.70 + jweak_ref(handle) = deleted_handle(); 22.71 } 22.72 } 22.73
23.1 --- a/src/share/vm/runtime/jniHandles.hpp Thu Nov 05 11:42:42 2015 +0100 23.2 +++ b/src/share/vm/runtime/jniHandles.hpp Tue May 07 20:38:26 2019 +0000 23.3 @@ -1,5 +1,5 @@ 23.4 /* 23.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 23.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. 23.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.8 * 23.9 * This code is free software; you can redistribute it and/or modify it 23.10 @@ -40,7 +40,28 @@ 23.11 static JNIHandleBlock* _weak_global_handles; // First weak global handle block 23.12 static oop _deleted_handle; // Sentinel marking deleted handles 23.13 23.14 + inline static bool is_jweak(jobject handle); 23.15 + inline static oop& jobject_ref(jobject handle); // NOT jweak! 23.16 + inline static oop& jweak_ref(jobject handle); 23.17 + 23.18 + template<bool external_guard> inline static oop guard_value(oop value); 23.19 + template<bool external_guard> inline static oop resolve_impl(jobject handle); 23.20 + template<bool external_guard> static oop resolve_jweak(jweak handle); 23.21 + 23.22 public: 23.23 + // Low tag bit in jobject used to distinguish a jweak. jweak is 23.24 + // type equivalent to jobject, but there are places where we need to 23.25 + // be able to distinguish jweak values from other jobjects, and 23.26 + // is_weak_global_handle is unsuitable for performance reasons. To 23.27 + // provide such a test we add weak_tag_value to the (aligned) byte 23.28 + // address designated by the jobject to produce the corresponding 23.29 + // jweak. Accessing the value of a jobject must account for it 23.30 + // being a possibly offset jweak. 23.31 + static const uintptr_t weak_tag_size = 1; 23.32 + static const uintptr_t weak_tag_alignment = (1u << weak_tag_size); 23.33 + static const uintptr_t weak_tag_mask = weak_tag_alignment - 1; 23.34 + static const int weak_tag_value = 1; 23.35 + 23.36 // Resolve handle into oop 23.37 inline static oop resolve(jobject handle); 23.38 // Resolve externally provided handle into oop with some guards 23.39 @@ -173,36 +194,85 @@ 23.40 #endif 23.41 }; 23.42 23.43 +inline bool JNIHandles::is_jweak(jobject handle) { 23.44 + STATIC_ASSERT(weak_tag_size == 1); 23.45 + STATIC_ASSERT(weak_tag_value == 1); 23.46 + return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0; 23.47 +} 23.48 + 23.49 +inline oop& JNIHandles::jobject_ref(jobject handle) { 23.50 + assert(!is_jweak(handle), "precondition"); 23.51 + return *reinterpret_cast<oop*>(handle); 23.52 +} 23.53 + 23.54 +inline oop& JNIHandles::jweak_ref(jobject handle) { 23.55 + assert(is_jweak(handle), "precondition"); 23.56 + char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value; 23.57 + return *reinterpret_cast<oop*>(ptr); 23.58 +} 23.59 + 23.60 +// external_guard is true if called from resolve_external_guard. 23.61 +// Treat deleted (and possibly zapped) as NULL for external_guard, 23.62 +// else as (asserted) error. 23.63 +template<bool external_guard> 23.64 +inline oop JNIHandles::guard_value(oop value) { 23.65 + if (!external_guard) { 23.66 + assert(value != badJNIHandle, "Pointing to zapped jni handle area"); 23.67 + assert(value != deleted_handle(), "Used a deleted global handle"); 23.68 + } else if ((value == badJNIHandle) || (value == deleted_handle())) { 23.69 + value = NULL; 23.70 + } 23.71 + return value; 23.72 +} 23.73 + 23.74 +// external_guard is true if called from resolve_external_guard. 23.75 +template<bool external_guard> 23.76 +inline oop JNIHandles::resolve_impl(jobject handle) { 23.77 + assert(handle != NULL, "precondition"); 23.78 + oop result; 23.79 + if (is_jweak(handle)) { // Unlikely 23.80 + result = resolve_jweak<external_guard>(handle); 23.81 + } else { 23.82 + result = jobject_ref(handle); 23.83 + // Construction of jobjects canonicalize a null value into a null 23.84 + // jobject, so for non-jweak the pointee should never be null. 23.85 + assert(external_guard || result != NULL, 23.86 + "Invalid value read from jni handle"); 23.87 + result = guard_value<external_guard>(result); 23.88 + } 23.89 + return result; 23.90 +} 23.91 23.92 inline oop JNIHandles::resolve(jobject handle) { 23.93 - oop result = (handle == NULL ? (oop)NULL : *(oop*)handle); 23.94 - assert(result != NULL || (handle == NULL || !CheckJNICalls || is_weak_global_handle(handle)), "Invalid value read from jni handle"); 23.95 - assert(result != badJNIHandle, "Pointing to zapped jni handle area"); 23.96 + oop result = NULL; 23.97 + if (handle != NULL) { 23.98 + result = resolve_impl<false /* external_guard */ >(handle); 23.99 + } 23.100 return result; 23.101 -}; 23.102 +} 23.103 23.104 - 23.105 +// Resolve some erroneous cases to NULL, rather than treating them as 23.106 +// possibly unchecked errors. In particular, deleted handles are 23.107 +// treated as NULL (though a deleted and later reallocated handle 23.108 +// isn't detected). 23.109 inline oop JNIHandles::resolve_external_guard(jobject handle) { 23.110 - if (handle == NULL) return NULL; 23.111 - oop result = *(oop*)handle; 23.112 - if (result == NULL || result == badJNIHandle) return NULL; 23.113 + oop result = NULL; 23.114 + if (handle != NULL) { 23.115 + result = resolve_impl<true /* external_guard */ >(handle); 23.116 + } 23.117 return result; 23.118 -}; 23.119 - 23.120 +} 23.121 23.122 inline oop JNIHandles::resolve_non_null(jobject handle) { 23.123 assert(handle != NULL, "JNI handle should not be null"); 23.124 - oop result = *(oop*)handle; 23.125 - assert(result != NULL, "Invalid value read from jni handle"); 23.126 - assert(result != badJNIHandle, "Pointing to zapped jni handle area"); 23.127 - // Don't let that private _deleted_handle object escape into the wild. 23.128 - assert(result != deleted_handle(), "Used a deleted global handle."); 23.129 + oop result = resolve_impl<false /* external_guard */ >(handle); 23.130 + assert(result != NULL, "NULL read from jni handle"); 23.131 return result; 23.132 -}; 23.133 +} 23.134 23.135 inline void JNIHandles::destroy_local(jobject handle) { 23.136 if (handle != NULL) { 23.137 - *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 23.138 + jobject_ref(handle) = deleted_handle(); 23.139 } 23.140 } 23.141
24.1 --- a/src/share/vm/shark/sharkNativeWrapper.cpp Thu Nov 05 11:42:42 2015 +0100 24.2 +++ b/src/share/vm/shark/sharkNativeWrapper.cpp Tue May 07 20:38:26 2019 +0000 24.3 @@ -1,5 +1,5 @@ 24.4 /* 24.5 - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 24.6 + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. 24.7 * Copyright 2009, 2010 Red Hat, Inc. 24.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.9 * 24.10 @@ -50,6 +50,7 @@ 24.11 24.12 // Create and push our stack frame 24.13 builder()->SetInsertPoint(CreateBlock()); 24.14 +#error Needs to be updated for tagged jweak; see JNIHandles. 24.15 _stack = SharkStack::CreateBuildAndPushFrame(this, method); 24.16 NOT_PRODUCT(method = NULL); 24.17