aboutsummaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorphh <unknown>2019-05-07 20:38:26 +0000
committerbell-sw <liberica@bell-sw.com>2019-07-22 19:21:53 +0300
commit83e032cae4741976cbbc69f574bc115ad44fbcdf (patch)
treee93f9c982aba5d92402105a695e81855cf3195e7 /src/cpu
parent8f2abffb4feefd6382c387979a901899acbac916 (diff)
downloadjdk8u_hotspot-83e032cae4741976cbbc69f574bc115ad44fbcdf.tar.gz
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
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/ppc/vm/frame_ppc.cpp9
-rw-r--r--src/cpu/ppc/vm/interpreter_ppc.cpp11
-rw-r--r--src/cpu/ppc/vm/macroAssembler_ppc.cpp34
-rw-r--r--src/cpu/ppc/vm/macroAssembler_ppc.hpp4
-rw-r--r--src/cpu/ppc/vm/sharedRuntime_ppc.cpp11
-rw-r--r--src/cpu/sparc/vm/jniFastGetField_sparc.cpp5
-rw-r--r--src/cpu/sparc/vm/sharedRuntime_sparc.cpp31
-rw-r--r--src/cpu/sparc/vm/templateInterpreter_sparc.cpp24
-rw-r--r--src/cpu/x86/vm/jniFastGetField_x86_32.cpp25
-rw-r--r--src/cpu/x86/vm/jniFastGetField_x86_64.cpp20
-rw-r--r--src/cpu/x86/vm/macroAssembler_x86.cpp36
-rw-r--r--src/cpu/x86/vm/macroAssembler_x86.hpp3
-rw-r--r--src/cpu/x86/vm/sharedRuntime_x86_32.cpp11
-rw-r--r--src/cpu/x86/vm/sharedRuntime_x86_64.cpp11
-rw-r--r--src/cpu/x86/vm/templateInterpreter_x86_32.cpp15
-rw-r--r--src/cpu/x86/vm/templateInterpreter_x86_64.cpp12
-rw-r--r--src/cpu/zero/vm/cppInterpreter_zero.cpp10
17 files changed, 185 insertions, 87 deletions
diff --git a/src/cpu/ppc/vm/frame_ppc.cpp b/src/cpu/ppc/vm/frame_ppc.cpp
index a4f7bedb0..d56eeb2b3 100644
--- a/src/cpu/ppc/vm/frame_ppc.cpp
+++ b/src/cpu/ppc/vm/frame_ppc.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -190,10 +190,7 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result)
switch (method->result_type()) {
case T_OBJECT:
case T_ARRAY: {
- oop* obj_p = *(oop**)lresult;
- oop obj = (obj_p == NULL) ? (oop)NULL : *obj_p;
- assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
- *oop_result = obj;
+ *oop_result = JNIHandles::resolve(*(jobject*)lresult);
break;
}
// We use std/stfd to store the values.
diff --git a/src/cpu/ppc/vm/interpreter_ppc.cpp b/src/cpu/ppc/vm/interpreter_ppc.cpp
index b6b9907df..3505ce734 100644
--- a/src/cpu/ppc/vm/interpreter_ppc.cpp
+++ b/src/cpu/ppc/vm/interpreter_ppc.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2015 SAP AG. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -413,11 +413,8 @@ address AbstractInterpreterGenerator::generate_result_handler_for(BasicType type
case T_LONG:
break;
case T_OBJECT:
- // unbox result if not null
- __ cmpdi(CCR0, R3_RET, 0);
- __ beq(CCR0, done);
- __ ld(R3_RET, 0, R3_RET);
- __ verify_oop(R3_RET);
+ // JNIHandles::resolve result.
+ __ resolve_jobject(R3_RET, R11_scratch1, R12_scratch2, /* needs_frame */ true); // kills R31
break;
case T_FLOAT:
break;
diff --git a/src/cpu/ppc/vm/macroAssembler_ppc.cpp b/src/cpu/ppc/vm/macroAssembler_ppc.cpp
index a140b36bd..d70312706 100644
--- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp
+++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2018, SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2220,6 +2220,34 @@ void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Regis
stbx(R0, Rtmp, Robj);
}
+// Kills R31 if value is a volatile register.
+void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2, bool needs_frame) {
+ Label done;
+ cmpdi(CCR0, value, 0);
+ beq(CCR0, done); // Use NULL as-is.
+
+ clrrdi(tmp1, value, JNIHandles::weak_tag_size);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) { andi_(tmp2, value, JNIHandles::weak_tag_mask); }
+#endif
+ ld(value, 0, tmp1); // Resolve (untagged) jobject.
+
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ Label not_weak;
+ beq(CCR0, not_weak); // Test for jweak tag.
+ verify_oop(value);
+ g1_write_barrier_pre(noreg, // obj
+ noreg, // offset
+ value, // pre_val
+ tmp1, tmp2, needs_frame);
+ bind(not_weak);
+ }
+#endif // INCLUDE_ALL_GCS
+ verify_oop(value);
+ bind(done);
+}
+
#if INCLUDE_ALL_GCS
// General G1 pre-barrier generator.
// Goal: record the previous value if it is not null.
@@ -2281,7 +2309,7 @@ void MacroAssembler::g1_write_barrier_pre(Register Robj, RegisterOrConstant offs
bind(runtime);
- // VM call need frame to access(write) O register.
+ // May need to preserve LR. Also needed if current frame is not compatible with C calling convention.
if (needs_frame) {
save_LR_CR(Rtmp1);
push_frame_reg_args(0, Rtmp2);
diff --git a/src/cpu/ppc/vm/macroAssembler_ppc.hpp b/src/cpu/ppc/vm/macroAssembler_ppc.hpp
index 0f4e8da72..3c6cea51b 100644
--- a/src/cpu/ppc/vm/macroAssembler_ppc.hpp
+++ b/src/cpu/ppc/vm/macroAssembler_ppc.hpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2017 SAP AG. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -516,6 +516,8 @@ class MacroAssembler: public Assembler {
void card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp);
void card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj);
+ void resolve_jobject(Register value, Register tmp1, Register tmp2, bool needs_frame);
+
#if INCLUDE_ALL_GCS
// General G1 pre-barrier generator.
void g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val,
diff --git a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp
index 047779e38..404670547 100644
--- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp
+++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2513,16 +2513,11 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
__ reset_last_Java_frame();
- // Unpack oop result.
+ // Unbox oop result, e.g. JNIHandles::resolve value.
// --------------------------------------------------------------------------
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label skip_unboxing;
- __ cmpdi(CCR0, R3_RET, 0);
- __ beq(CCR0, skip_unboxing);
- __ ld(R3_RET, 0, R3_RET);
- __ bind(skip_unboxing);
- __ verify_oop(R3_RET);
+ __ resolve_jobject(R3_RET, r_temp_1, r_temp_2, /* needs_frame */ false); // kills R31
}
diff --git a/src/cpu/sparc/vm/jniFastGetField_sparc.cpp b/src/cpu/sparc/vm/jniFastGetField_sparc.cpp
index 6d3f05a2a..ff9fcd694 100644
--- a/src/cpu/sparc/vm/jniFastGetField_sparc.cpp
+++ b/src/cpu/sparc/vm/jniFastGetField_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
__ andcc (G4, 1, G0);
__ br (Assembler::notZero, false, Assembler::pn, label1);
__ delayed()->srl (O2, 2, O4);
+ __ andn (O1, JNIHandles::weak_tag_mask, O1);
__ ld_ptr (O1, 0, O5);
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
@@ -147,6 +148,7 @@ address JNI_FastGetField::generate_fast_get_long_field() {
__ andcc (G4, 1, G0);
__ br (Assembler::notZero, false, Assembler::pn, label1);
__ delayed()->srl (O2, 2, O4);
+ __ andn (O1, JNIHandles::weak_tag_mask, O1);
__ ld_ptr (O1, 0, O5);
__ add (O5, O4, O5);
@@ -219,6 +221,7 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
__ andcc (G4, 1, G0);
__ br (Assembler::notZero, false, Assembler::pn, label1);
__ delayed()->srl (O2, 2, O4);
+ __ andn (O1, JNIHandles::weak_tag_mask, O1);
__ ld_ptr (O1, 0, O5);
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
diff --git a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
index 7e72da895..1cea35f57 100644
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
@@ -2706,15 +2706,30 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
__ verify_thread(); // G2_thread must be correct
__ reset_last_Java_frame();
- // Unpack oop result
+ // Unbox oop result, e.g. JNIHandles::resolve value in I0.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label L;
- __ addcc(G0, I0, G0);
- __ brx(Assembler::notZero, true, Assembler::pt, L);
- __ delayed()->ld_ptr(I0, 0, I0);
- __ mov(G0, I0);
- __ bind(L);
- __ verify_oop(I0);
+ Label done, not_weak;
+ __ br_null(I0, false, Assembler::pn, done); // Use NULL as-is.
+ __ delayed()->andcc(I0, JNIHandles::weak_tag_mask, G0); // Test for jweak
+ __ brx(Assembler::zero, true, Assembler::pt, not_weak);
+ __ delayed()->ld_ptr(I0, 0, I0); // Maybe resolve (untagged) jobject.
+ // Resolve jweak.
+ __ ld_ptr(I0, -JNIHandles::weak_tag_value, I0);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ // Copy to O0 because macro doesn't allow pre_val in input reg.
+ __ mov(I0, O0);
+ __ g1_write_barrier_pre(noreg /* obj */,
+ noreg /* index */,
+ 0 /* offset */,
+ O0 /* pre_val */,
+ G3_scratch /* tmp */,
+ true /* preserve_o_regs */);
+ }
+#endif // INCLUDE_ALL_GCS
+ __ bind(not_weak);
+ __ verify_oop(I0);
+ __ bind(done);
}
if (!is_critical_native) {
diff --git a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index 5ffaf2faf..83d40496c 100644
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1160,11 +1160,23 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
__ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
__ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop);
- __ addcc(G0, O0, O0);
- __ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL:
- __ delayed()->ld_ptr(O0, 0, O0); // unbox it
- __ mov(G0, O0);
-
+ // Unbox oop result, e.g. JNIHandles::resolve value in O0.
+ __ br_null(O0, false, Assembler::pn, store_result); // Use NULL as-is.
+ __ delayed()->andcc(O0, JNIHandles::weak_tag_mask, G0); // Test for jweak
+ __ brx(Assembler::zero, true, Assembler::pt, store_result);
+ __ delayed()->ld_ptr(O0, 0, O0); // Maybe resolve (untagged) jobject.
+ // Resolve jweak.
+ __ ld_ptr(O0, -JNIHandles::weak_tag_value, O0);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ __ g1_write_barrier_pre(noreg /* obj */,
+ noreg /* index */,
+ 0 /* offset */,
+ O0 /* pre_val */,
+ G3_scratch /* tmp */,
+ true /* preserve_o_regs */);
+ }
+#endif // INCLUDE_ALL_GCS
__ bind(store_result);
// Store it where gc will look for it and result handler expects it.
__ st_ptr(O0, FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS);
diff --git a/src/cpu/x86/vm/jniFastGetField_x86_32.cpp b/src/cpu/x86/vm/jniFastGetField_x86_32.cpp
index a45e0eb9a..48c4400e2 100644
--- a/src/cpu/x86/vm/jniFastGetField_x86_32.cpp
+++ b/src/cpu/x86/vm/jniFastGetField_x86_32.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,14 +79,17 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
__ mov(rax, rcx);
__ andptr(rax, 1); // rax, must end up 0
__ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize));
- // obj, notice rax, is 0.
- // rdx is data dependent on rcx.
+ // obj, notice rax, is 0.
+ // rdx is data dependent on rcx.
} else {
- __ movptr (rdx, Address(rsp, 2*wordSize)); // obj
+ __ movptr (rdx, Address(rsp, 2*wordSize)); // obj
}
__ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID
+
+ __ clear_jweak_tag(rdx);
+
__ movptr(rdx, Address(rdx, 0)); // *obj
- __ shrptr (rax, 2); // offset
+ __ shrptr (rax, 2); // offset
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
speculative_load_pclist[count] = __ pc();
@@ -194,14 +197,17 @@ address JNI_FastGetField::generate_fast_get_long_field() {
__ jcc (Assembler::notZero, slow);
if (os::is_MP()) {
__ mov(rax, rcx);
- __ andptr(rax, 1); // rax, must end up 0
+ __ andptr(rax, 1); // rax, must end up 0
__ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize));
// obj, notice rax, is 0.
// rdx is data dependent on rcx.
} else {
- __ movptr(rdx, Address(rsp, 3*wordSize)); // obj
+ __ movptr(rdx, Address(rsp, 3*wordSize)); // obj
}
__ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID
+
+ __ clear_jweak_tag(rdx);
+
__ movptr(rdx, Address(rdx, 0)); // *obj
__ shrptr(rsi, 2); // offset
@@ -283,7 +289,7 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
__ jcc (Assembler::notZero, slow);
if (os::is_MP()) {
__ mov(rax, rcx);
- __ andptr(rax, 1); // rax, must end up 0
+ __ andptr(rax, 1); // rax, must end up 0
__ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize));
// obj, notice rax, is 0.
// rdx is data dependent on rcx.
@@ -291,6 +297,9 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
__ movptr(rdx, Address(rsp, 2*wordSize)); // obj
}
__ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID
+
+ __ clear_jweak_tag(rdx);
+
__ movptr(rdx, Address(rdx, 0)); // *obj
__ shrptr(rax, 2); // offset
diff --git a/src/cpu/x86/vm/jniFastGetField_x86_64.cpp b/src/cpu/x86/vm/jniFastGetField_x86_64.cpp
index 7286fd124..9b538002f 100644
--- a/src/cpu/x86/vm/jniFastGetField_x86_64.cpp
+++ b/src/cpu/x86/vm/jniFastGetField_x86_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,13 +76,16 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
__ jcc (Assembler::notZero, slow);
if (os::is_MP()) {
__ xorptr(robj, rcounter);
- __ xorptr(robj, rcounter); // obj, since
+ __ xorptr(robj, rcounter); // obj, since
// robj ^ rcounter ^ rcounter == robj
// robj is data dependent on rcounter.
}
- __ movptr(robj, Address(robj, 0)); // *obj
+
+ __ clear_jweak_tag(robj);
+
+ __ movptr(robj, Address(robj, 0)); // *obj
__ mov (roffset, c_rarg2);
- __ shrptr(roffset, 2); // offset
+ __ shrptr(roffset, 2); // offset
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
speculative_load_pclist[count] = __ pc();
@@ -174,13 +177,16 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
__ jcc (Assembler::notZero, slow);
if (os::is_MP()) {
__ xorptr(robj, rcounter);
- __ xorptr(robj, rcounter); // obj, since
+ __ xorptr(robj, rcounter); // obj, since
// robj ^ rcounter ^ rcounter == robj
// robj is data dependent on rcounter.
}
- __ movptr(robj, Address(robj, 0)); // *obj
+
+ __ clear_jweak_tag(robj);
+
+ __ movptr(robj, Address(robj, 0)); // *obj
__ mov (roffset, c_rarg2);
- __ shrptr(roffset, 2); // offset
+ __ shrptr(roffset, 2); // offset
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
speculative_load_pclist[count] = __ pc();
diff --git a/src/cpu/x86/vm/macroAssembler_x86.cpp b/src/cpu/x86/vm/macroAssembler_x86.cpp
index 0e757f29c..1b09514c9 100644
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp
@@ -4119,6 +4119,42 @@ void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src
}
}
+void MacroAssembler::resolve_jobject(Register value,
+ Register thread,
+ Register tmp) {
+ assert_different_registers(value, thread, tmp);
+ Label done, not_weak;
+ testptr(value, value);
+ jcc(Assembler::zero, done); // Use NULL as-is.
+ testptr(value, JNIHandles::weak_tag_mask); // Test for jweak tag.
+ jcc(Assembler::zero, not_weak);
+ // Resolve jweak.
+ movptr(value, Address(value, -JNIHandles::weak_tag_value));
+ verify_oop(value);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ g1_write_barrier_pre(noreg /* obj */,
+ value /* pre_val */,
+ thread /* thread */,
+ tmp /* tmp */,
+ true /* tosca_live */,
+ true /* expand_call */);
+ }
+#endif // INCLUDE_ALL_GCS
+ jmp(done);
+ bind(not_weak);
+ // Resolve (untagged) jobject.
+ movptr(value, Address(value, 0));
+ verify_oop(value);
+ bind(done);
+}
+
+void MacroAssembler::clear_jweak_tag(Register possibly_jweak) {
+ const int32_t inverted_jweak_mask = ~static_cast<int32_t>(JNIHandles::weak_tag_mask);
+ STATIC_ASSERT(inverted_jweak_mask == -2); // otherwise check this code
+ // The inverted mask is sign-extended
+ andptr(possibly_jweak, inverted_jweak_mask);
+}
//////////////////////////////////////////////////////////////////////////////////
#if INCLUDE_ALL_GCS
diff --git a/src/cpu/x86/vm/macroAssembler_x86.hpp b/src/cpu/x86/vm/macroAssembler_x86.hpp
index c3c0a7911..e94fdd7d7 100644
--- a/src/cpu/x86/vm/macroAssembler_x86.hpp
+++ b/src/cpu/x86/vm/macroAssembler_x86.hpp
@@ -298,6 +298,9 @@ class MacroAssembler: public Assembler {
void store_check(Register obj); // store check for obj - register is destroyed afterwards
void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)
+ void resolve_jobject(Register value, Register thread, Register tmp);
+ void clear_jweak_tag(Register possibly_jweak);
+
#if INCLUDE_ALL_GCS
void g1_write_barrier_pre(Register obj,
diff --git a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
index 9debbc118..d701d4495 100644
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
@@ -2253,14 +2253,11 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
__ reset_last_Java_frame(thread, false);
- // Unpack oop result
+ // Unbox oop result, e.g. JNIHandles::resolve value.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label L;
- __ cmpptr(rax, (int32_t)NULL_WORD);
- __ jcc(Assembler::equal, L);
- __ movptr(rax, Address(rax, 0));
- __ bind(L);
- __ verify_oop(rax);
+ __ resolve_jobject(rax /* value */,
+ thread /* thread */,
+ rcx /* tmp */);
}
if (!is_critical_native) {
diff --git a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
index e50c72218..c2f69f7c3 100644
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
@@ -2499,14 +2499,11 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
__ reset_last_Java_frame(false);
- // Unpack oop result
+ // Unbox oop result, e.g. JNIHandles::resolve value.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label L;
- __ testptr(rax, rax);
- __ jcc(Assembler::zero, L);
- __ movptr(rax, Address(rax, 0));
- __ bind(L);
- __ verify_oop(rax);
+ __ resolve_jobject(rax /* value */,
+ r15_thread /* thread */,
+ rcx /* tmp */);
}
if (!is_critical_native) {
diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
index 4d94902ee..b7c515031 100644
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1296,19 +1296,18 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
__ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
// If result was an oop then unbox and save it in the frame
- { Label L;
- Label no_oop, store_result;
+ {
+ Label no_oop;
ExternalAddress handler(AbstractInterpreter::result_handler(T_OBJECT));
__ cmpptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize),
handler.addr());
__ jcc(Assembler::notEqual, no_oop);
__ cmpptr(Address(rsp, 0), (int32_t)NULL_WORD);
__ pop(ltos);
- __ testptr(rax, rax);
- __ jcc(Assembler::zero, store_result);
- // unbox
- __ movptr(rax, Address(rax, 0));
- __ bind(store_result);
+ // Unbox oop result, e.g. JNIHandles::resolve value.
+ __ resolve_jobject(rax /* value */,
+ thread /* thread */,
+ t /* tmp */);
__ movptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset)*wordSize), rax);
// keep stack depth as expected by pushing oop which will eventually be discarded
__ push(ltos);
diff --git a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
index 121738292..209a3f676 100644
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1272,16 +1272,16 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
// and result handler will pick it up
{
- Label no_oop, store_result;
+ Label no_oop;
__ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
__ cmpptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize));
__ jcc(Assembler::notEqual, no_oop);
// retrieve result
__ pop(ltos);
- __ testptr(rax, rax);
- __ jcc(Assembler::zero, store_result);
- __ movptr(rax, Address(rax, 0));
- __ bind(store_result);
+ // Unbox oop result, e.g. JNIHandles::resolve value.
+ __ resolve_jobject(rax /* value */,
+ r15_thread /* thread */,
+ t /* tmp */);
__ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax);
// keep stack depth as expected by pushing oop which will eventually be discarde
__ push(ltos);
diff --git a/src/cpu/zero/vm/cppInterpreter_zero.cpp b/src/cpu/zero/vm/cppInterpreter_zero.cpp
index 242ce1cfd..525031eb9 100644
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -405,10 +405,12 @@ int CppInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
// oop_temp where the garbage collector can see it before
// we release the handle it might be protected by.
if (handler->result_type() == &ffi_type_pointer) {
- if (result[0])
- istate->set_oop_temp(*(oop *) result[0]);
- else
+ if (result[0] == 0) {
istate->set_oop_temp(NULL);
+ } else {
+ jobject handle = reinterpret_cast<jobject>(result[0]);
+ istate->set_oop_temp(JNIHandles::resolve(handle));
+ }
}
// Reset handle block