8176054: [BACKOUT][REDO] G1 Needs pre barrier on dereference of weak JNI handles
Reviewed-by: kbarrett, mgerdin
--- a/hotspot/make/test/JtregNative.gmk Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/make/test/JtregNative.gmk Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, 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
@@ -48,8 +48,6 @@
$(HOTSPOT_TOPDIR)/test/runtime/jni/PrivateInterfaceMethods \
$(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
$(HOTSPOT_TOPDIR)/test/runtime/jni/CalleeSavedRegisters \
- $(HOTSPOT_TOPDIR)/test/runtime/jni/CallWithJNIWeak \
- $(HOTSPOT_TOPDIR)/test/runtime/jni/ReturnJNIWeak \
$(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \
$(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \
--- a/hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -82,11 +82,6 @@
__ eor(robj, robj, rcounter); // obj, since
// robj ^ rcounter ^ rcounter == robj
// robj is address dependent on rcounter.
-
- // If mask changes we need to ensure that the inverse is still encodable as an immediate
- STATIC_ASSERT(JNIHandles::weak_tag_mask == 1);
- __ andr(robj, robj, ~JNIHandles::weak_tag_mask);
-
__ ldr(robj, Address(robj, 0)); // *obj
__ lsr(roffset, c_rarg2, 2); // offset
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -2052,31 +2052,13 @@
__ reset_last_Java_frame(false);
- // Unbox oop result, e.g. JNIHandles::resolve result.
+ // Unpack oop result
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label done, not_weak;
- __ cbz(r0, done); // Use NULL as-is.
- STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
- __ tbz(r0, 0, not_weak); // Test for jweak tag.
- // Resolve jweak.
- __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value));
- __ verify_oop(r0);
-#if INCLUDE_ALL_GCS
- if (UseG1GC) {
- __ g1_write_barrier_pre(noreg /* obj */,
- r0 /* pre_val */,
- rthread /* thread */,
- rscratch1 /* tmp */,
- true /* tosca_live */,
- true /* expand_call */);
- }
-#endif // INCLUDE_ALL_GCS
- __ b(done);
- __ bind(not_weak);
- // Resolve (untagged) jobject.
- __ ldr(r0, Address(r0, 0));
- __ verify_oop(r0);
- __ bind(done);
+ Label L;
+ __ cbz(r0, L);
+ __ ldr(r0, Address(r0, 0));
+ __ bind(L);
+ __ verify_oop(r0);
}
if (CheckJNICalls) {
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -1399,32 +1399,13 @@
// and result handler will pick it up
{
- Label no_oop, not_weak, store_result;
+ Label no_oop, store_result;
__ adr(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
__ cmp(t, result_handler);
__ br(Assembler::NE, no_oop);
- // Unbox oop result, e.g. JNIHandles::resolve result.
+ // retrieve result
__ pop(ltos);
- __ cbz(r0, store_result); // Use NULL as-is.
- STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
- __ tbz(r0, 0, not_weak); // Test for jweak tag.
- // Resolve jweak.
- __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value));
-#if INCLUDE_ALL_GCS
- if (UseG1GC) {
- __ enter(); // Barrier may call runtime.
- __ g1_write_barrier_pre(noreg /* obj */,
- r0 /* pre_val */,
- rthread /* thread */,
- t /* tmp */,
- true /* tosca_live */,
- true /* expand_call */);
- __ leave();
- }
-#endif // INCLUDE_ALL_GCS
- __ b(store_result);
- __ bind(not_weak);
- // Resolve (untagged) jobject.
+ __ cbz(r0, store_result);
__ ldr(r0, Address(r0, 0));
__ bind(store_result);
__ str(r0, Address(rfp, frame::interpreter_frame_oop_temp_offset*wordSize));
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -476,6 +476,185 @@
}
//////////////////////////////////////////////////////////////////////////////////
+#if INCLUDE_ALL_GCS
+
+// G1 pre-barrier.
+// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+// If store_addr != noreg, then previous value is loaded from [store_addr];
+// in such case store_addr and new_val registers are preserved;
+// otherwise pre_val register is preserved.
+void InterpreterMacroAssembler::g1_write_barrier_pre(Register store_addr,
+ Register new_val,
+ Register pre_val,
+ Register tmp1,
+ Register tmp2) {
+ Label done;
+ Label runtime;
+
+ if (store_addr != noreg) {
+ assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
+ } else {
+ assert (new_val == noreg, "should be");
+ assert_different_registers(pre_val, tmp1, tmp2, noreg);
+ }
+
+ Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_active()));
+ Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_index()));
+ Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_buf()));
+
+ // Is marking active?
+ assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
+ ldrb(tmp1, in_progress);
+ cbz(tmp1, done);
+
+ // Do we need to load the previous value?
+ if (store_addr != noreg) {
+ load_heap_oop(pre_val, Address(store_addr, 0));
+ }
+
+ // Is the previous value null?
+ cbz(pre_val, done);
+
+ // Can we store original value in the thread's buffer?
+ // Is index == 0?
+ // (The index field is typed as size_t.)
+
+ ldr(tmp1, index); // tmp1 := *index_adr
+ ldr(tmp2, buffer);
+
+ subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize
+ b(runtime, lt); // If negative, goto runtime
+
+ str(tmp1, index); // *index_adr := tmp1
+
+ // Record the previous value
+ str(pre_val, Address(tmp2, tmp1));
+ b(done);
+
+ bind(runtime);
+
+ // save the live input values
+#ifdef AARCH64
+ if (store_addr != noreg) {
+ raw_push(store_addr, new_val);
+ } else {
+ raw_push(pre_val, ZR);
+ }
+#else
+ if (store_addr != noreg) {
+ // avoid raw_push to support any ordering of store_addr and new_val
+ push(RegisterSet(store_addr) | RegisterSet(new_val));
+ } else {
+ push(pre_val);
+ }
+#endif // AARCH64
+
+ if (pre_val != R0) {
+ mov(R0, pre_val);
+ }
+ mov(R1, Rthread);
+
+ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1);
+
+#ifdef AARCH64
+ if (store_addr != noreg) {
+ raw_pop(store_addr, new_val);
+ } else {
+ raw_pop(pre_val, ZR);
+ }
+#else
+ if (store_addr != noreg) {
+ pop(RegisterSet(store_addr) | RegisterSet(new_val));
+ } else {
+ pop(pre_val);
+ }
+#endif // AARCH64
+
+ bind(done);
+}
+
+// G1 post-barrier.
+// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+void InterpreterMacroAssembler::g1_write_barrier_post(Register store_addr,
+ Register new_val,
+ Register tmp1,
+ Register tmp2,
+ Register tmp3) {
+
+ Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
+ DirtyCardQueue::byte_offset_of_index()));
+ Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
+ DirtyCardQueue::byte_offset_of_buf()));
+
+ BarrierSet* bs = Universe::heap()->barrier_set();
+ CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+ Label done;
+ Label runtime;
+
+ // Does store cross heap regions?
+
+ eor(tmp1, store_addr, new_val);
+#ifdef AARCH64
+ logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
+ cbz(tmp1, done);
+#else
+ movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
+ b(done, eq);
+#endif
+
+ // crosses regions, storing NULL?
+
+ cbz(new_val, done);
+
+ // storing region crossing non-NULL, is card already dirty?
+ const Register card_addr = tmp1;
+ assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+
+ mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
+ add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
+
+ ldrb(tmp2, Address(card_addr));
+ cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ b(done, eq);
+
+ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
+
+ assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
+ ldrb(tmp2, Address(card_addr));
+ cbz(tmp2, done);
+
+ // storing a region crossing, non-NULL oop, card is clean.
+ // dirty card and log.
+
+ strb(zero_register(tmp2), Address(card_addr));
+
+ ldr(tmp2, queue_index);
+ ldr(tmp3, buffer);
+
+ subs(tmp2, tmp2, wordSize);
+ b(runtime, lt); // go to runtime if now negative
+
+ str(tmp2, queue_index);
+
+ str(card_addr, Address(tmp3, tmp2));
+ b(done);
+
+ bind(runtime);
+
+ if (card_addr != R0) {
+ mov(R0, card_addr);
+ }
+ mov(R1, Rthread);
+ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1);
+
+ bind(done);
+}
+
+#endif // INCLUDE_ALL_GCS
+//////////////////////////////////////////////////////////////////////////////////
// Java Expression Stack
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.hpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.hpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -146,6 +146,27 @@
void set_card(Register card_table_base, Address card_table_addr, Register tmp);
+#if INCLUDE_ALL_GCS
+ // G1 pre-barrier.
+ // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+ // If store_addr != noreg, then previous value is loaded from [store_addr];
+ // in such case store_addr and new_val registers are preserved;
+ // otherwise pre_val register is preserved.
+ void g1_write_barrier_pre(Register store_addr,
+ Register new_val,
+ Register pre_val,
+ Register tmp1,
+ Register tmp2);
+
+ // G1 post-barrier.
+ // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+ void g1_write_barrier_post(Register store_addr,
+ Register new_val,
+ Register tmp1,
+ Register tmp2,
+ Register tmp3);
+#endif // INCLUDE_ALL_GCS
+
void pop_ptr(Register r);
void pop_i(Register r = R0_tos);
#ifdef AARCH64
--- a/hotspot/src/cpu/arm/vm/jniFastGetField_arm.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/arm/vm/jniFastGetField_arm.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -119,14 +119,6 @@
__ ldr_s32(Rsafept_cnt, Address(Rsafepoint_counter_addr));
__ tbnz(Rsafept_cnt, 0, slow_case);
-#ifdef AARCH64
- // If mask changes we need to ensure that the inverse is still encodable as an immediate
- STATIC_ASSERT(JNIHandles::weak_tag_mask == 1);
- __ andr(R1, R1, ~JNIHandles::weak_tag_mask);
-#else
- __ bic(R1, R1, JNIHandles::weak_tag_mask);
-#endif
-
if (os::is_MP()) {
// Address dependency restricts memory access ordering. It's cheaper than explicit LoadLoad barrier
__ andr(Rtmp1, Rsafept_cnt, (unsigned)1);
--- a/hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -2211,219 +2211,6 @@
b(done, eq);
}
-
-void MacroAssembler::resolve_jobject(Register value,
- Register tmp1,
- Register tmp2) {
- assert_different_registers(value, tmp1, tmp2);
- Label done, not_weak;
- cbz(value, done); // Use NULL as-is.
- STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
- tbz(value, 0, not_weak); // Test for jweak tag.
- // Resolve jweak.
- ldr(value, Address(value, -JNIHandles::weak_tag_value));
- verify_oop(value);
-#if INCLUDE_ALL_GCS
- if (UseG1GC) {
- g1_write_barrier_pre(noreg, // store_addr
- noreg, // new_val
- value, // pre_val
- tmp1, // tmp1
- tmp2); // tmp2
- }
-#endif // INCLUDE_ALL_GCS
- b(done);
- bind(not_weak);
- // Resolve (untagged) jobject.
- ldr(value, Address(value));
- verify_oop(value);
- bind(done);
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////
-
-#if INCLUDE_ALL_GCS
-
-// G1 pre-barrier.
-// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
-// If store_addr != noreg, then previous value is loaded from [store_addr];
-// in such case store_addr and new_val registers are preserved;
-// otherwise pre_val register is preserved.
-void MacroAssembler::g1_write_barrier_pre(Register store_addr,
- Register new_val,
- Register pre_val,
- Register tmp1,
- Register tmp2) {
- Label done;
- Label runtime;
-
- if (store_addr != noreg) {
- assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
- } else {
- assert (new_val == noreg, "should be");
- assert_different_registers(pre_val, tmp1, tmp2, noreg);
- }
-
- Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_active()));
- Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_index()));
- Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_buf()));
-
- // Is marking active?
- assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
- ldrb(tmp1, in_progress);
- cbz(tmp1, done);
-
- // Do we need to load the previous value?
- if (store_addr != noreg) {
- load_heap_oop(pre_val, Address(store_addr, 0));
- }
-
- // Is the previous value null?
- cbz(pre_val, done);
-
- // Can we store original value in the thread's buffer?
- // Is index == 0?
- // (The index field is typed as size_t.)
-
- ldr(tmp1, index); // tmp1 := *index_adr
- ldr(tmp2, buffer);
-
- subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize
- b(runtime, lt); // If negative, goto runtime
-
- str(tmp1, index); // *index_adr := tmp1
-
- // Record the previous value
- str(pre_val, Address(tmp2, tmp1));
- b(done);
-
- bind(runtime);
-
- // save the live input values
-#ifdef AARCH64
- if (store_addr != noreg) {
- raw_push(store_addr, new_val);
- } else {
- raw_push(pre_val, ZR);
- }
-#else
- if (store_addr != noreg) {
- // avoid raw_push to support any ordering of store_addr and new_val
- push(RegisterSet(store_addr) | RegisterSet(new_val));
- } else {
- push(pre_val);
- }
-#endif // AARCH64
-
- if (pre_val != R0) {
- mov(R0, pre_val);
- }
- mov(R1, Rthread);
-
- call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1);
-
-#ifdef AARCH64
- if (store_addr != noreg) {
- raw_pop(store_addr, new_val);
- } else {
- raw_pop(pre_val, ZR);
- }
-#else
- if (store_addr != noreg) {
- pop(RegisterSet(store_addr) | RegisterSet(new_val));
- } else {
- pop(pre_val);
- }
-#endif // AARCH64
-
- bind(done);
-}
-
-// G1 post-barrier.
-// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
-void MacroAssembler::g1_write_barrier_post(Register store_addr,
- Register new_val,
- Register tmp1,
- Register tmp2,
- Register tmp3) {
-
- Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
- DirtyCardQueue::byte_offset_of_index()));
- Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
- DirtyCardQueue::byte_offset_of_buf()));
-
- BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
- Label done;
- Label runtime;
-
- // Does store cross heap regions?
-
- eor(tmp1, store_addr, new_val);
-#ifdef AARCH64
- logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
- cbz(tmp1, done);
-#else
- movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
- b(done, eq);
-#endif
-
- // crosses regions, storing NULL?
-
- cbz(new_val, done);
-
- // storing region crossing non-NULL, is card already dirty?
- const Register card_addr = tmp1;
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-
- mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
- add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
-
- ldrb(tmp2, Address(card_addr));
- cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
- b(done, eq);
-
- membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
-
- assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
- ldrb(tmp2, Address(card_addr));
- cbz(tmp2, done);
-
- // storing a region crossing, non-NULL oop, card is clean.
- // dirty card and log.
-
- strb(zero_register(tmp2), Address(card_addr));
-
- ldr(tmp2, queue_index);
- ldr(tmp3, buffer);
-
- subs(tmp2, tmp2, wordSize);
- b(runtime, lt); // go to runtime if now negative
-
- str(tmp2, queue_index);
-
- str(card_addr, Address(tmp3, tmp2));
- b(done);
-
- bind(runtime);
-
- if (card_addr != R0) {
- mov(R0, card_addr);
- }
- mov(R1, Rthread);
- call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1);
-
- bind(done);
-}
-
-#endif // INCLUDE_ALL_GCS
-
-//////////////////////////////////////////////////////////////////////////////////
-
#ifdef AARCH64
void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed) {
--- a/hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -402,29 +402,6 @@
void biased_locking_enter_with_cas(Register obj_reg, Register old_mark_reg, Register new_mark_reg,
Register tmp, Label& slow_case, int* counter_addr);
- void resolve_jobject(Register value, Register tmp1, Register tmp2);
-
-#if INCLUDE_ALL_GCS
- // G1 pre-barrier.
- // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
- // If store_addr != noreg, then previous value is loaded from [store_addr];
- // in such case store_addr and new_val registers are preserved;
- // otherwise pre_val register is preserved.
- void g1_write_barrier_pre(Register store_addr,
- Register new_val,
- Register pre_val,
- Register tmp1,
- Register tmp2);
-
- // G1 post-barrier.
- // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
- void g1_write_barrier_post(Register store_addr,
- Register new_val,
- Register tmp1,
- Register tmp2,
- Register tmp3);
-#endif // INCLUDE_ALL_GCS
-
#ifndef AARCH64
void nop() {
mov(R0, R0);
--- a/hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -1732,7 +1732,14 @@
case T_FLOAT : // fall through
case T_DOUBLE : /* nothing to do */ break;
case T_OBJECT : // fall through
- case T_ARRAY : break; // See JNIHandles::resolve below
+ case T_ARRAY : {
+ Label L;
+ __ cbz(R0, L);
+ __ ldr(R0, Address(R0));
+ __ verify_oop(R0);
+ __ bind(L);
+ break;
+ }
default:
ShouldNotReachHere();
}
@@ -1741,14 +1748,13 @@
if (CheckJNICalls) {
__ str(__ zero_register(Rtemp), Address(Rthread, JavaThread::pending_jni_exception_check_fn_offset()));
}
-#endif // AARCH64
- // Unbox oop result, e.g. JNIHandles::resolve value in R0.
+ // Unhandle the result
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- __ resolve_jobject(R0, // value
- Rtemp, // tmp1
- R1_tmp); // tmp2
+ __ cmp(R0, 0);
+ __ ldr(R0, Address(R0), ne);
}
+#endif // AARCH64
// Any exception pending?
__ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
--- a/hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -1240,25 +1240,28 @@
__ str(__ zero_register(Rtemp), Address(Rthread, JavaThread::pending_jni_exception_check_fn_offset()));
}
- // Unbox oop result, e.g. JNIHandles::resolve result if it's an oop.
+ // Unbox if the result is non-zero object
+#ifdef AARCH64
{
- Label Lnot_oop;
-#ifdef AARCH64
+ Label L, Lnull;
__ mov_slow(Rtemp, AbstractInterpreter::result_handler(T_OBJECT));
__ cmp(Rresult_handler, Rtemp);
- __ b(Lnot_oop, ne);
-#else // !AARCH64
- // For ARM32, Rresult_handler is -1 for oop result, 0 otherwise.
- __ cbz(Rresult_handler, Lnot_oop);
-#endif // !AARCH64
- Register value = AARCH64_ONLY(Rsaved_result) NOT_AARCH64(Rsaved_result_lo);
- __ resolve_jobject(value, // value
- Rtemp, // tmp1
- R1_tmp); // tmp2
- // Store resolved result in frame for GC visibility.
- __ str(value, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
- __ bind(Lnot_oop);
+ __ b(L, ne);
+ __ cbz(Rsaved_result, Lnull);
+ __ ldr(Rsaved_result, Address(Rsaved_result));
+ __ bind(Lnull);
+ // Store oop on the stack for GC
+ __ str(Rsaved_result, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
+ __ bind(L);
}
+#else
+ __ tst(Rsaved_result_lo, Rresult_handler);
+ __ ldr(Rsaved_result_lo, Address(Rsaved_result_lo), ne);
+
+ // Store oop on the stack for GC
+ __ cmp(Rresult_handler, 0);
+ __ str(Rsaved_result_lo, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize), ne);
+#endif // AARCH64
#ifdef AARCH64
// Restore SP (drop native parameters area), to keep SP in sync with extended_sp in frame
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015 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
@@ -171,7 +171,10 @@
switch (method->result_type()) {
case T_OBJECT:
case T_ARRAY: {
- *oop_result = JNIHandles::resolve(*(jobject*)lresult);
+ 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;
break;
}
// We use std/stfd to store the values.
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 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
@@ -3033,34 +3033,6 @@
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.
@@ -3122,7 +3094,7 @@
bind(runtime);
- // May need to preserve LR. Also needed if current frame is not compatible with C calling convention.
+ // VM call need frame to access(write) O register.
if (needs_frame) {
save_LR_CR(Rtmp1);
push_frame_reg_args(0, Rtmp2);
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 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
@@ -649,8 +649,6 @@
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,
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 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
@@ -2477,11 +2477,16 @@
__ reset_last_Java_frame();
- // Unbox oop result, e.g. JNIHandles::resolve value.
+ // Unpack oop result.
// --------------------------------------------------------------------------
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- __ resolve_jobject(R3_RET, r_temp_1, r_temp_2, /* needs_frame */ false); // kills R31
+ 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);
}
if (CheckJNICalls) {
--- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 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
@@ -401,8 +401,11 @@
case T_LONG:
break;
case T_OBJECT:
- // JNIHandles::resolve result.
- __ resolve_jobject(R3_RET, R11_scratch1, R12_scratch2, /* needs_frame */ true); // kills R31
+ // unbox result if not null
+ __ cmpdi(CCR0, R3_RET, 0);
+ __ beq(CCR0, done);
+ __ ld(R3_RET, 0, R3_RET);
+ __ verify_oop(R3_RET);
break;
case T_FLOAT:
break;
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -3439,34 +3439,6 @@
z_mvi(0, store_addr, 0); // Store byte 0.
}
-void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2) {
- NearLabel Ldone;
- z_ltgr(tmp1, value);
- z_bre(Ldone); // Use NULL result as-is.
-
- z_nill(value, ~JNIHandles::weak_tag_mask);
- z_lg(value, 0, value); // Resolve (untagged) jobject.
-
-#if INCLUDE_ALL_GCS
- if (UseG1GC) {
- NearLabel Lnot_weak;
- z_tmll(tmp1, JNIHandles::weak_tag_mask); // Test for jweak tag.
- z_braz(Lnot_weak);
- verify_oop(value);
- g1_write_barrier_pre(noreg /* obj */,
- noreg /* offset */,
- value /* pre_val */,
- noreg /* val */,
- tmp1 /* tmp1 */,
- tmp2 /* tmp2 */,
- true /* pre_val_needed */);
- bind(Lnot_weak);
- }
-#endif // INCLUDE_ALL_GCS
- verify_oop(value);
- bind(Ldone);
-}
-
#if INCLUDE_ALL_GCS
//------------------------------------------------------
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp Thu Mar 02 17:46:59 2017 +0100
@@ -726,8 +726,6 @@
// Write to card table for modification at store_addr - register is destroyed afterwards.
void card_write_barrier_post(Register store_addr, Register tmp);
- void resolve_jobject(Register value, Register tmp1, Register tmp2);
-
#if INCLUDE_ALL_GCS
// General G1 pre-barrier generator.
// Purpose: record the previous value if it is not null.
--- a/hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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
@@ -2272,9 +2272,13 @@
__ reset_last_Java_frame();
- // Unpack oop result, e.g. JNIHandles::resolve result.
+ // Unpack oop result
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- __ resolve_jobject(Z_RET, /* tmp1 */ Z_R13, /* tmp2 */ Z_R7);
+ NearLabel L;
+ __ compare64_and_branch(Z_RET, (RegisterOrConstant)0L, Assembler::bcondEqual, L);
+ __ z_lg(Z_RET, 0, Z_RET);
+ __ bind(L);
+ __ verify_oop(Z_RET);
}
if (CheckJNICalls) {
--- a/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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
@@ -1695,11 +1695,14 @@
// from the jni handle to z_ijava_state.oop_temp. This is
// necessary, because we reset the jni handle block below.
// NOTE: frame::interpreter_frame_result() depends on this, too.
- { NearLabel no_oop_result;
+ { NearLabel no_oop_result, store_oop_result;
__ load_absolute_address(Z_R1, AbstractInterpreter::result_handler(T_OBJECT));
__ compareU64_and_branch(Z_R1, Rresult_handler, Assembler::bcondNotEqual, no_oop_result);
- __ resolve_jobject(Rlresult, /* tmp1 */ Rmethod, /* tmp2 */ Z_R1);
+ __ compareU64_and_branch(Rlresult, (intptr_t)0L, Assembler::bcondEqual, store_oop_result);
+ __ z_lg(Rlresult, 0, Rlresult); // unbox
+ __ bind(store_oop_result);
__ z_stg(Rlresult, oop_tmp_offset, Z_fp);
+ __ verify_oop(Rlresult);
__ bind(no_oop_result);
}
--- a/hotspot/src/cpu/sparc/vm/jniFastGetField_sparc.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/sparc/vm/jniFastGetField_sparc.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2010, 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,7 +68,6 @@
__ 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");
@@ -148,7 +147,6 @@
__ 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);
@@ -221,7 +219,6 @@
__ 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");
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -2754,30 +2754,15 @@
__ verify_thread(); // G2_thread must be correct
__ reset_last_Java_frame();
- // Unbox oop result, e.g. JNIHandles::resolve value in I0.
+ // Unpack oop result
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- 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);
+ 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);
}
if (CheckJNICalls) {
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -1516,23 +1516,11 @@
__ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
__ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop);
- // 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
+ __ 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);
+
__ 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);
--- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2010, 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
@@ -85,9 +85,6 @@
__ 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
@@ -205,9 +202,6 @@
__ 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
@@ -297,9 +291,6 @@
__ 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
--- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2010, 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
@@ -80,9 +80,6 @@
// robj ^ rcounter ^ rcounter == robj
// robj is data dependent on rcounter.
}
-
- __ clear_jweak_tag(robj);
-
__ movptr(robj, Address(robj, 0)); // *obj
__ mov (roffset, c_rarg2);
__ shrptr(roffset, 2); // offset
@@ -181,9 +178,6 @@
// robj ^ rcounter ^ rcounter == robj
// robj is data dependent on rcounter.
}
-
- __ clear_jweak_tag(robj);
-
__ movptr(robj, Address(robj, 0)); // *obj
__ mov (roffset, c_rarg2);
__ shrptr(roffset, 2); // offset
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -5129,43 +5129,6 @@
}
-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
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -297,9 +297,6 @@
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,
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -2226,11 +2226,14 @@
__ reset_last_Java_frame(thread, false);
- // Unbox oop result, e.g. JNIHandles::resolve value.
+ // Unpack oop result
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- __ resolve_jobject(rax /* value */,
- thread /* thread */,
- rcx /* tmp */);
+ Label L;
+ __ cmpptr(rax, (int32_t)NULL_WORD);
+ __ jcc(Assembler::equal, L);
+ __ movptr(rax, Address(rax, 0));
+ __ bind(L);
+ __ verify_oop(rax);
}
if (CheckJNICalls) {
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -2579,11 +2579,14 @@
__ reset_last_Java_frame(false);
- // Unbox oop result, e.g. JNIHandles::resolve value.
+ // Unpack oop result
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- __ resolve_jobject(rax /* value */,
- r15_thread /* thread */,
- rcx /* tmp */);
+ Label L;
+ __ testptr(rax, rax);
+ __ jcc(Assembler::zero, L);
+ __ movptr(rax, Address(rax, 0));
+ __ bind(L);
+ __ verify_oop(rax);
}
if (CheckJNICalls) {
--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -1193,16 +1193,16 @@
// and result handler will pick it up
{
- Label no_oop, not_weak, store_result;
+ Label no_oop, store_result;
__ 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);
- // Unbox oop result, e.g. JNIHandles::resolve value.
- __ resolve_jobject(rax /* value */,
- thread /* thread */,
- t /* tmp */);
+ __ testptr(rax, rax);
+ __ jcc(Assembler::zero, store_result);
+ __ movptr(rax, Address(rax, 0));
+ __ bind(store_result);
__ 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);
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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.
*
@@ -406,12 +406,10 @@
// 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] == 0) {
+ if (result[0])
+ istate->set_oop_temp(*(oop *) result[0]);
+ else
istate->set_oop_temp(NULL);
- } else {
- jobject handle = reinterpret_cast<jobject>(result[0]);
- istate->set_oop_temp(JNIHandles::resolve(handle));
- }
}
// Reset handle block
--- a/hotspot/src/share/vm/prims/jni.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/share/vm/prims/jni.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -935,7 +935,8 @@
inline void get_long() { _arguments->push_long(va_arg(_ap, jlong)); }
inline void get_float() { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
- inline void get_object() { _arguments->push_jobject(va_arg(_ap, jobject)); }
+ inline void get_object() { jobject l = va_arg(_ap, jobject);
+ _arguments->push_oop(Handle((oop *)l, false)); }
inline void set_ap(va_list rap) {
va_copy(_ap, rap);
@@ -1024,7 +1025,7 @@
inline void get_long() { _arguments->push_long((_ap++)->j); }
inline void get_float() { _arguments->push_float((_ap++)->f); }
inline void get_double() { _arguments->push_double((_ap++)->d);}
- inline void get_object() { _arguments->push_jobject((_ap++)->l); }
+ inline void get_object() { _arguments->push_oop(Handle((oop *)(_ap++)->l, false)); }
inline void set_ap(const jvalue *rap) { _ap = rap; }
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -1796,13 +1796,6 @@
}
}
- if (initial_object != NULL) {
- oop init_obj = JNIHandles::resolve_external_guard(initial_object);
- if (init_obj == NULL) {
- return JVMTI_ERROR_INVALID_OBJECT;
- }
- }
-
Thread *thread = Thread::current();
HandleMark hm(thread);
KlassHandle kh (thread, k_oop);
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -328,9 +328,9 @@
// Verify the arguments
if (CheckJNICalls) {
- args->verify(method, result->get_type());
+ args->verify(method, result->get_type(), thread);
}
- else debug_only(args->verify(method, result->get_type()));
+ else debug_only(args->verify(method, result->get_type(), thread));
#if INCLUDE_JVMCI
}
#else
@@ -442,43 +442,12 @@
//--------------------------------------------------------------------------------------
// Implementation of JavaCallArguments
-inline bool is_value_state_indirect_oop(uint state) {
- assert(state != JavaCallArguments::value_state_oop,
- "Checking for handles after removal");
- assert(state < JavaCallArguments::value_state_limit,
- "Invalid value state %u", state);
- return state != JavaCallArguments::value_state_primitive;
-}
-
-inline oop resolve_indirect_oop(intptr_t value, uint state) {
- switch (state) {
- case JavaCallArguments::value_state_handle:
- {
- oop* ptr = reinterpret_cast<oop*>(value);
- return Handle::raw_resolve(ptr);
- }
-
- case JavaCallArguments::value_state_jobject:
- {
- jobject obj = reinterpret_cast<jobject>(value);
- return JNIHandles::resolve(obj);
- }
-
- default:
- ShouldNotReachHere();
- return NULL;
- }
-}
-
intptr_t* JavaCallArguments::parameters() {
// First convert all handles to oops
for(int i = 0; i < _size; i++) {
- uint state = _value_state[i];
- assert(state != value_state_oop, "Multiple handle conversions");
- if (is_value_state_indirect_oop(state)) {
- oop obj = resolve_indirect_oop(_value[i], state);
- _value[i] = cast_from_oop<intptr_t>(obj);
- _value_state[i] = value_state_oop;
+ if (_is_oop[i]) {
+ // Handle conversion
+ _value[i] = cast_from_oop<intptr_t>(Handle::raw_resolve((oop *)_value[i]));
}
}
// Return argument vector
@@ -488,42 +457,30 @@
class SignatureChekker : public SignatureIterator {
private:
- int _pos;
+ bool *_is_oop;
+ int _pos;
BasicType _return_type;
- u_char* _value_state;
- intptr_t* _value;
+ intptr_t* _value;
+ Thread* _thread;
public:
bool _is_return;
- SignatureChekker(Symbol* signature,
- BasicType return_type,
- bool is_static,
- u_char* value_state,
- intptr_t* value) :
- SignatureIterator(signature),
- _pos(0),
- _return_type(return_type),
- _value_state(value_state),
- _value(value),
- _is_return(false)
- {
+ SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
+ _is_oop = is_oop;
+ _is_return = false;
+ _return_type = return_type;
+ _pos = 0;
+ _value = value;
+ _thread = thread;
+
if (!is_static) {
check_value(true); // Receiver must be an oop
}
}
void check_value(bool type) {
- uint state = _value_state[_pos++];
- if (type) {
- guarantee(is_value_state_indirect_oop(state),
- "signature does not match pushed arguments: %u at %d",
- state, _pos - 1);
- } else {
- guarantee(state == JavaCallArguments::value_state_primitive,
- "signature does not match pushed arguments: %u at %d",
- state, _pos - 1);
- }
+ guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments");
}
void check_doing_return(bool state) { _is_return = state; }
@@ -558,20 +515,24 @@
return;
}
- intptr_t v = _value[_pos];
- if (v != 0) {
- // v is a "handle" referring to an oop, cast to integral type.
- // There shouldn't be any handles in very low memory.
- guarantee((size_t)v >= (size_t)os::vm_page_size(),
- "Bad JNI oop argument %d: " PTR_FORMAT, _pos, v);
- // Verify the pointee.
- oop vv = resolve_indirect_oop(v, _value_state[_pos]);
- guarantee(vv->is_oop_or_null(true),
- "Bad JNI oop argument %d: " PTR_FORMAT " -> " PTR_FORMAT,
- _pos, v, p2i(vv));
+ // verify handle and the oop pointed to by handle
+ int p = _pos;
+ bool bad = false;
+ // If argument is oop
+ if (_is_oop[p]) {
+ intptr_t v = _value[p];
+ if (v != 0 ) {
+ size_t t = (size_t)v;
+ bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true);
+ if (CheckJNICalls && bad) {
+ ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
+ }
+ }
+ // for the regular debug case.
+ assert(!bad, "Bad JNI oop argument");
}
- check_value(true); // Verify value state.
+ check_value(true);
}
void do_bool() { check_int(T_BOOLEAN); }
@@ -588,7 +549,8 @@
};
-void JavaCallArguments::verify(const methodHandle& method, BasicType return_type) {
+void JavaCallArguments::verify(const methodHandle& method, BasicType return_type,
+ Thread *thread) {
guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
// Treat T_OBJECT and T_ARRAY as the same
@@ -597,11 +559,7 @@
// Check that oop information is correct
Symbol* signature = method->signature();
- SignatureChekker sc(signature,
- return_type,
- method->is_static(),
- _value_state,
- _value);
+ SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
sc.iterate_parameters();
sc.check_doing_return(true);
sc.iterate_returntype();
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -80,11 +80,11 @@
_default_size = 8 // Must be at least # of arguments in JavaCalls methods
};
- intptr_t _value_buffer [_default_size + 1];
- u_char _value_state_buffer[_default_size + 1];
+ intptr_t _value_buffer [_default_size + 1];
+ bool _is_oop_buffer[_default_size + 1];
intptr_t* _value;
- u_char* _value_state;
+ bool* _is_oop;
int _size;
int _max_size;
bool _start_at_zero; // Support late setting of receiver
@@ -92,8 +92,8 @@
void initialize() {
// Starts at first element to support set_receiver.
- _value = &_value_buffer[1];
- _value_state = &_value_state_buffer[1];
+ _value = &_value_buffer[1];
+ _is_oop = &_is_oop_buffer[1];
_max_size = _default_size;
_size = 0;
@@ -101,23 +101,6 @@
JVMCI_ONLY(_alternative_target = NULL;)
}
- // Helper for push_oop and the like. The value argument is a
- // "handle" that refers to an oop. We record the address of the
- // handle rather than the designated oop. The handle is later
- // resolved to the oop by parameters(). This delays the exposure of
- // naked oops until it is GC-safe.
- template<typename T>
- inline int push_oop_impl(T handle, int size) {
- // JNITypes::put_obj expects an oop value, so we play fast and
- // loose with the type system. The cast from handle type to oop
- // *must* use a C-style cast. In a product build it performs a
- // reinterpret_cast. In a debug build (more accurately, in a
- // CHECK_UNHANDLED_OOPS build) it performs a static_cast, invoking
- // the debug-only oop class's conversion from void* constructor.
- JNITypes::put_obj((oop)handle, _value, size); // Updates size.
- return size; // Return the updated size.
- }
-
public:
JavaCallArguments() { initialize(); }
@@ -128,12 +111,11 @@
JavaCallArguments(int max_size) {
if (max_size > _default_size) {
- _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
- _value_state = NEW_RESOURCE_ARRAY(u_char, max_size + 1);
+ _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
+ _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1);
- // Reserve room for potential receiver in value and state
- _value++;
- _value_state++;
+ // Reserve room for potential receiver in value and is_oop
+ _value++; _is_oop++;
_max_size = max_size;
_size = 0;
@@ -154,52 +136,25 @@
}
#endif
- // The possible values for _value_state elements.
- enum {
- value_state_primitive,
- value_state_oop,
- value_state_handle,
- value_state_jobject,
- value_state_limit
- };
+ inline void push_oop(Handle h) { _is_oop[_size] = true;
+ JNITypes::put_obj((oop)h.raw_value(), _value, _size); }
- inline void push_oop(Handle h) {
- _value_state[_size] = value_state_handle;
- _size = push_oop_impl(h.raw_value(), _size);
- }
-
- inline void push_jobject(jobject h) {
- _value_state[_size] = value_state_jobject;
- _size = push_oop_impl(h, _size);
- }
+ inline void push_int(int i) { _is_oop[_size] = false;
+ JNITypes::put_int(i, _value, _size); }
- inline void push_int(int i) {
- _value_state[_size] = value_state_primitive;
- JNITypes::put_int(i, _value, _size);
- }
-
- inline void push_double(double d) {
- _value_state[_size] = value_state_primitive;
- _value_state[_size + 1] = value_state_primitive;
- JNITypes::put_double(d, _value, _size);
- }
+ inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
+ JNITypes::put_double(d, _value, _size); }
- inline void push_long(jlong l) {
- _value_state[_size] = value_state_primitive;
- _value_state[_size + 1] = value_state_primitive;
- JNITypes::put_long(l, _value, _size);
- }
+ inline void push_long(jlong l) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
+ JNITypes::put_long(l, _value, _size); }
- inline void push_float(float f) {
- _value_state[_size] = value_state_primitive;
- JNITypes::put_float(f, _value, _size);
- }
+ inline void push_float(float f) { _is_oop[_size] = false;
+ JNITypes::put_float(f, _value, _size); }
// receiver
Handle receiver() {
assert(_size > 0, "must at least be one argument");
- assert(_value_state[0] == value_state_handle,
- "first argument must be an oop");
+ assert(_is_oop[0], "first argument must be an oop");
assert(_value[0] != 0, "receiver must be not-null");
return Handle((oop*)_value[0], false);
}
@@ -207,11 +162,11 @@
void set_receiver(Handle h) {
assert(_start_at_zero == false, "can only be called once");
_start_at_zero = true;
- _value_state--;
+ _is_oop--;
_value--;
_size++;
- _value_state[0] = value_state_handle;
- push_oop_impl(h.raw_value(), 0);
+ _is_oop[0] = true;
+ _value[0] = (intptr_t)h.raw_value();
}
// Converts all Handles to oops, and returns a reference to parameter vector
@@ -219,7 +174,7 @@
int size_of_parameters() const { return _size; }
// Verify that pushed arguments fits a given method
- void verify(const methodHandle& method, BasicType return_type);
+ void verify(const methodHandle& method, BasicType return_type, Thread *thread);
};
// All calls to Java have to go via JavaCalls. Sets up the stack frame
--- a/hotspot/src/share/vm/runtime/jniHandles.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -31,9 +31,6 @@
#include "runtime/jniHandles.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.inline.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1SATBCardTableModRefBS.hpp"
-#endif
JNIHandleBlock* JNIHandles::_global_handles = NULL;
JNIHandleBlock* JNIHandles::_weak_global_handles = NULL;
@@ -95,48 +92,28 @@
jobject res = NULL;
if (!obj.is_null()) {
// ignore null handles
- {
- MutexLocker ml(JNIGlobalHandle_lock);
- assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
- res = _weak_global_handles->allocate_handle(obj());
- }
- // Add weak tag.
- assert(is_ptr_aligned(res, weak_tag_alignment), "invariant");
- char* tptr = reinterpret_cast<char*>(res) + weak_tag_value;
- res = reinterpret_cast<jobject>(tptr);
+ MutexLocker ml(JNIGlobalHandle_lock);
+ assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
+ res = _weak_global_handles->allocate_handle(obj());
} else {
CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
}
return res;
}
-template<bool external_guard>
-oop JNIHandles::resolve_jweak(jweak handle) {
- assert(is_jweak(handle), "precondition");
- oop result = jweak_ref(handle);
- result = guard_value<external_guard>(result);
-#if INCLUDE_ALL_GCS
- if (result != NULL && UseG1GC) {
- G1SATBCardTableModRefBS::enqueue(result);
- }
-#endif // INCLUDE_ALL_GCS
- return result;
-}
-
-template oop JNIHandles::resolve_jweak<true>(jweak);
-template oop JNIHandles::resolve_jweak<false>(jweak);
void JNIHandles::destroy_global(jobject handle) {
if (handle != NULL) {
assert(is_global_handle(handle), "Invalid delete of global JNI handle");
- jobject_ref(handle) = deleted_handle();
+ *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
}
}
void JNIHandles::destroy_weak_global(jobject handle) {
if (handle != NULL) {
- jweak_ref(handle) = deleted_handle();
+ assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle");
+ *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
}
}
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, 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
@@ -40,28 +40,7 @@
static JNIHandleBlock* _weak_global_handles; // First weak global handle block
static oop _deleted_handle; // Sentinel marking deleted handles
- inline static bool is_jweak(jobject handle);
- inline static oop& jobject_ref(jobject handle); // NOT jweak!
- inline static oop& jweak_ref(jobject handle);
-
- template<bool external_guard> inline static oop guard_value(oop value);
- template<bool external_guard> inline static oop resolve_impl(jobject handle);
- template<bool external_guard> static oop resolve_jweak(jweak handle);
-
public:
- // Low tag bit in jobject used to distinguish a jweak. jweak is
- // type equivalent to jobject, but there are places where we need to
- // be able to distinguish jweak values from other jobjects, and
- // is_weak_global_handle is unsuitable for performance reasons. To
- // provide such a test we add weak_tag_value to the (aligned) byte
- // address designated by the jobject to produce the corresponding
- // jweak. Accessing the value of a jobject must account for it
- // being a possibly offset jweak.
- static const uintptr_t weak_tag_size = 1;
- static const uintptr_t weak_tag_alignment = (1u << weak_tag_size);
- static const uintptr_t weak_tag_mask = weak_tag_alignment - 1;
- static const int weak_tag_value = 1;
-
// Resolve handle into oop
inline static oop resolve(jobject handle);
// Resolve externally provided handle into oop with some guards
@@ -197,85 +176,36 @@
#endif
};
-inline bool JNIHandles::is_jweak(jobject handle) {
- STATIC_ASSERT(weak_tag_size == 1);
- STATIC_ASSERT(weak_tag_value == 1);
- return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0;
-}
-
-inline oop& JNIHandles::jobject_ref(jobject handle) {
- assert(!is_jweak(handle), "precondition");
- return *reinterpret_cast<oop*>(handle);
-}
-
-inline oop& JNIHandles::jweak_ref(jobject handle) {
- assert(is_jweak(handle), "precondition");
- char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value;
- return *reinterpret_cast<oop*>(ptr);
-}
-
-// external_guard is true if called from resolve_external_guard.
-// Treat deleted (and possibly zapped) as NULL for external_guard,
-// else as (asserted) error.
-template<bool external_guard>
-inline oop JNIHandles::guard_value(oop value) {
- if (!external_guard) {
- assert(value != badJNIHandle, "Pointing to zapped jni handle area");
- assert(value != deleted_handle(), "Used a deleted global handle");
- } else if ((value == badJNIHandle) || (value == deleted_handle())) {
- value = NULL;
- }
- return value;
-}
-
-// external_guard is true if called from resolve_external_guard.
-template<bool external_guard>
-inline oop JNIHandles::resolve_impl(jobject handle) {
- assert(handle != NULL, "precondition");
- oop result;
- if (is_jweak(handle)) { // Unlikely
- result = resolve_jweak<external_guard>(handle);
- } else {
- result = jobject_ref(handle);
- // Construction of jobjects canonicalize a null value into a null
- // jobject, so for non-jweak the pointee should never be null.
- assert(external_guard || result != NULL,
- "Invalid value read from jni handle");
- result = guard_value<external_guard>(result);
- }
- return result;
-}
inline oop JNIHandles::resolve(jobject handle) {
- oop result = NULL;
- if (handle != NULL) {
- result = resolve_impl<false /* external_guard */ >(handle);
- }
+ oop result = (handle == NULL ? (oop)NULL : *(oop*)handle);
+ assert(result != NULL || (handle == NULL || !CheckJNICalls || is_weak_global_handle(handle)), "Invalid value read from jni handle");
+ assert(result != badJNIHandle, "Pointing to zapped jni handle area");
return result;
-}
+};
+
-// Resolve some erroneous cases to NULL, rather than treating them as
-// possibly unchecked errors. In particular, deleted handles are
-// treated as NULL (though a deleted and later reallocated handle
-// isn't detected).
inline oop JNIHandles::resolve_external_guard(jobject handle) {
- oop result = NULL;
- if (handle != NULL) {
- result = resolve_impl<true /* external_guard */ >(handle);
- }
+ if (handle == NULL) return NULL;
+ oop result = *(oop*)handle;
+ if (result == NULL || result == badJNIHandle) return NULL;
return result;
-}
+};
+
inline oop JNIHandles::resolve_non_null(jobject handle) {
assert(handle != NULL, "JNI handle should not be null");
- oop result = resolve_impl<false /* external_guard */ >(handle);
- assert(result != NULL, "NULL read from jni handle");
+ oop result = *(oop*)handle;
+ assert(result != NULL, "Invalid value read from jni handle");
+ assert(result != badJNIHandle, "Pointing to zapped jni handle area");
+ // Don't let that private _deleted_handle object escape into the wild.
+ assert(result != deleted_handle(), "Used a deleted global handle.");
return result;
-}
+};
inline void JNIHandles::destroy_local(jobject handle) {
if (handle != NULL) {
- jobject_ref(handle) = deleted_handle();
+ *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
}
}
--- a/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Mon Feb 27 17:36:36 2017 +0100
+++ b/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Thu Mar 02 17:46:59 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -300,7 +300,6 @@
not_null, merge);
builder()->SetInsertPoint(not_null);
-#error Needs to be updated for tagged jweak; see JNIHandles.
Value *unboxed_result = builder()->CreateLoad(result);
builder()->CreateBr(merge);
--- a/hotspot/test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.java Mon Feb 27 17:36:36 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8166188
- * @summary Test call of native function with JNI weak global ref.
- * @modules java.base
- * @run main/othervm/native CallWithJNIWeak
- */
-
-public class CallWithJNIWeak {
- static {
- System.loadLibrary("CallWithJNIWeak");
- }
-
- private static native void testJNIFieldAccessors(CallWithJNIWeak o);
-
- // The field initializations must be kept in sync with the JNI code
- // which reads verifies the values of these fields.
- private int i = 1;
- private long j = 2;
- private boolean z = true;
- private char c = 'a';
- private short s = 3;
- private float f = 1.0f;
- private double d = 2.0;
- private Object l;
-
- private CallWithJNIWeak() {
- this.l = this;
- }
-
- private native void weakReceiverTest0();
- private void weakReceiverTest() {
- weakReceiverTest0();
- }
-
- private synchronized void synchonizedWeakReceiverTest() {
- this.notifyAll();
- }
-
-
- private static native void runTests(CallWithJNIWeak o);
-
- public static void main(String[] args) {
- CallWithJNIWeak w = new CallWithJNIWeak();
- for (int i = 0; i < 20000; i++) {
- runTests(w);
- }
- }
-}
--- a/hotspot/test/runtime/jni/CallWithJNIWeak/libCallWithJNIWeak.c Mon Feb 27 17:36:36 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-
-/*
- * Class: CallWithJNIWeak
- * Method: testJNIFieldAccessors
- * Signature: (LCallWithJNIWeak;)V
- */
-JNIEXPORT void JNICALL
-Java_CallWithJNIWeak_testJNIFieldAccessors(JNIEnv *env, jclass clazz, jobject this) {
- // Make sure that we have a weak reference to the receiver
-
- jweak self = (*env)->NewWeakGlobalRef(env, this);
-
- jclass this_class = (*env)->GetObjectClass(env, self);
-
- jclass exception = (*env)->FindClass(env, "java/lang/RuntimeException");
-
- jfieldID id_i = (*env)->GetFieldID(env, this_class, "i", "I");
- jfieldID id_j = (*env)->GetFieldID(env, this_class, "j", "J");
- jfieldID id_z = (*env)->GetFieldID(env, this_class, "z", "Z");
- jfieldID id_c = (*env)->GetFieldID(env, this_class, "c", "C");
- jfieldID id_s = (*env)->GetFieldID(env, this_class, "s", "S");
- jfieldID id_f = (*env)->GetFieldID(env, this_class, "f", "F");
- jfieldID id_d = (*env)->GetFieldID(env, this_class, "d", "D");
- jfieldID id_l = (*env)->GetFieldID(env, this_class, "l", "Ljava/lang/Object;");
- jvalue v;
-
-#define CHECK(variable, expected) \
- do { \
- if ((variable) != (expected)) { \
- (*env)->ThrowNew(env, exception, #variable" != " #expected); \
- return; \
- } \
- } while(0)
-
- // The values checked below must be kept in sync with the Java source file.
-
- v.i = (*env)->GetIntField(env, self, id_i);
- CHECK(v.i, 1);
-
- v.j = (*env)->GetLongField(env, self, id_j);
- CHECK(v.j, 2);
-
- v.z = (*env)->GetBooleanField(env, self, id_z);
- CHECK(v.z, JNI_TRUE);
-
- v.c = (*env)->GetCharField(env, self, id_c);
- CHECK(v.c, 'a');
-
- v.s = (*env)->GetShortField(env, self, id_s);
- CHECK(v.s, 3);
-
- v.f = (*env)->GetFloatField(env, self, id_f);
- CHECK(v.f, 1.0f);
-
- v.d = (*env)->GetDoubleField(env, self, id_d);
- CHECK(v.d, 2.0);
-
-#undef CHECK
-
- v.l = (*env)->GetObjectField(env, self, id_l);
- if (v.l == NULL) {
- (*env)->ThrowNew(env, exception, "Object field was null");
- return;
- }
- {
- jclass clz = (*env)->GetObjectClass(env, v.l);
- if (!(*env)->IsSameObject(env, clazz, clz)) {
- (*env)->ThrowNew(env, exception, "Bad object class");
- }
- }
-
- (*env)->DeleteWeakGlobalRef(env, self);
-}
-
-/*
- * Class: CallWithJNIWeak
- * Method: runTests
- * Signature: (LCallWithJNIWeak;)V
- */
-JNIEXPORT void JNICALL
-Java_CallWithJNIWeak_runTests(JNIEnv *env, jclass clazz, jobject this) {
- jweak that = (*env)->NewWeakGlobalRef(env, this);
- {
- jmethodID method = (*env)->GetStaticMethodID(env,
- clazz, "testJNIFieldAccessors", "(LCallWithJNIWeak;)V");
- (*env)->CallStaticVoidMethod(env, clazz, method, that);
- if ((*env)->ExceptionCheck(env)) {
- return;
- }
- }
-
- {
- jmethodID method = (*env)->GetMethodID(env, clazz, "weakReceiverTest", "()V");
- (*env)->CallVoidMethod(env, that, method);
- if ((*env)->ExceptionCheck(env)) {
- return;
- }
- }
-
- {
- jmethodID method = (*env)->GetMethodID(env, clazz, "synchonizedWeakReceiverTest", "()V");
- (*env)->CallVoidMethod(env, that, method);
- if ((*env)->ExceptionCheck(env)) {
- return;
- }
- }
- (*env)->DeleteWeakGlobalRef(env, that);
-}
-
-/*
- * Class: CallWithJNIWeak
- * Method: weakReceiverTest0
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_CallWithJNIWeak_weakReceiverTest0(JNIEnv *env, jobject obj) {
- (*env)->GetObjectClass(env, obj);
-}
--- a/hotspot/test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.java Mon Feb 27 17:36:36 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 8166188
- * @requires vm.opt.ExplicitGCInvokesConcurrent != true
- * @summary Test return of JNI weak global refs from native calls.
- * @modules java.base
- * @run main/othervm/native -Xint ReturnJNIWeak
- * @run main/othervm/native -Xcomp ReturnJNIWeak
- */
-
-public final class ReturnJNIWeak {
-
- static {
- System.loadLibrary("ReturnJNIWeak");
- }
-
- private static final class TestObject {
- public final int value;
-
- public TestObject(int value) {
- this.value = value;
- }
- }
-
- private static volatile TestObject testObject = null;
-
- private static native void registerObject(Object o);
- private static native void unregisterObject();
- private static native Object getObject();
-
- // Create the test object and record it both strongly and weakly.
- private static void remember(int value) {
- TestObject o = new TestObject(value);
- registerObject(o);
- testObject = o;
- }
-
- // Remove both strong and weak references to the current test object.
- private static void forget() {
- unregisterObject();
- testObject = null;
- }
-
- // Verify the weakly recorded object
- private static void checkValue(int value) throws Exception {
- Object o = getObject();
- if (o == null) {
- throw new RuntimeException("Weak reference unexpectedly null");
- }
- TestObject t = (TestObject)o;
- if (t.value != value) {
- throw new RuntimeException("Incorrect value");
- }
- }
-
- // Verify we can create a weak reference and get it back.
- private static void testSanity() throws Exception {
- System.out.println("running testSanity");
- int value = 5;
- try {
- remember(value);
- checkValue(value);
- } finally {
- forget();
- }
- }
-
- // Verify weak ref value survives across collection if strong ref exists.
- private static void testSurvival() throws Exception {
- System.out.println("running testSurvival");
- int value = 10;
- try {
- remember(value);
- checkValue(value);
- System.gc();
- // Verify weak ref still has expected value.
- checkValue(value);
- } finally {
- forget();
- }
- }
-
- // Verify weak ref cleared if no strong ref exists.
- private static void testClear() throws Exception {
- System.out.println("running testClear");
- int value = 15;
- try {
- remember(value);
- checkValue(value);
- // Verify still good.
- checkValue(value);
- // Drop reference.
- testObject = null;
- System.gc();
- // Verify weak ref cleared as expected.
- Object recorded = getObject();
- if (recorded != null) {
- throw new RuntimeException("expected clear");
- }
- } finally {
- forget();
- }
- }
-
- public static void main(String[] args) throws Exception {
- testSanity();
- testSurvival();
- testClear();
- }
-}
--- a/hotspot/test/runtime/jni/ReturnJNIWeak/libReturnJNIWeak.c Mon Feb 27 17:36:36 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Native support for ReturnJNIWeak test.
- */
-
-#include "jni.h"
-
-static jweak registered = NULL;
-
-JNIEXPORT void JNICALL
-Java_ReturnJNIWeak_registerObject(JNIEnv* env,
- jclass jclazz,
- jobject value) {
- // assert registered == NULL
- registered = (*env)->NewWeakGlobalRef(env, value);
-}
-
-JNIEXPORT void JNICALL
-Java_ReturnJNIWeak_unregisterObject(JNIEnv* env, jclass jclazz) {
- if (registered != NULL) {
- (*env)->DeleteWeakGlobalRef(env, registered);
- registered = NULL;
- }
-}
-
-JNIEXPORT jobject JNICALL
-Java_ReturnJNIWeak_getObject(JNIEnv* env, jclass jclazz) {
- // assert registered != NULL
- return registered;
-}