8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles jdk8u222-b02

Tue, 07 May 2019 20:38:26 +0000

author
phh
date
Tue, 07 May 2019 20:38:26 +0000
changeset 9669
32bc598624bd
parent 9668
acb9351e3a29
child 9670
884a9feb3bb8
child 9671
e86bc9786d83

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

src/cpu/ppc/vm/frame_ppc.cpp file | annotate | diff | comparison | revisions
src/cpu/ppc/vm/interpreter_ppc.cpp file | annotate | diff | comparison | revisions
src/cpu/ppc/vm/macroAssembler_ppc.cpp file | annotate | diff | comparison | revisions
src/cpu/ppc/vm/macroAssembler_ppc.hpp file | annotate | diff | comparison | revisions
src/cpu/ppc/vm/sharedRuntime_ppc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/jniFastGetField_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/sharedRuntime_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/templateInterpreter_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/jniFastGetField_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/jniFastGetField_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/macroAssembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/macroAssembler_x86.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/sharedRuntime_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/sharedRuntime_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateInterpreter_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateInterpreter_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/zero/vm/cppInterpreter_zero.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jni.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jvmtiEnv.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/javaCalls.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/javaCalls.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/jniHandles.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/jniHandles.hpp file | annotate | diff | comparison | revisions
src/share/vm/shark/sharkNativeWrapper.cpp file | annotate | diff | comparison | revisions
     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  

mercurial