8175086: [BACKOUT] fix for JDK-8166188
authordcubed
Thu, 16 Feb 2017 10:41:19 -0800
changeset 43969 ae5c415036b0
parent 43964 2f5e556a6037
child 43970 d731100c45a7
8175086: [BACKOUT] fix for JDK-8166188 Reviewed-by: kbarrett, jwilhelm, dcubed
hotspot/make/test/JtregNative.gmk
hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp
hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
hotspot/src/cpu/arm/vm/interp_masm_arm.cpp
hotspot/src/cpu/arm/vm/interp_masm_arm.hpp
hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp
hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp
hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp
hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp
hotspot/src/cpu/ppc/vm/frame_ppc.cpp
hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp
hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp
hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp
hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp
hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp
hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp
hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp
hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp
hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
hotspot/src/share/vm/prims/jni.cpp
hotspot/src/share/vm/prims/jvmtiEnv.cpp
hotspot/src/share/vm/runtime/javaCalls.cpp
hotspot/src/share/vm/runtime/javaCalls.hpp
hotspot/src/share/vm/runtime/jniHandles.cpp
hotspot/src/share/vm/runtime/jniHandles.hpp
hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
hotspot/test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.java
hotspot/test/runtime/jni/CallWithJNIWeak/libCallWithJNIWeak.c
hotspot/test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.java
hotspot/test/runtime/jni/ReturnJNIWeak/libReturnJNIWeak.c
--- a/hotspot/make/test/JtregNative.gmk	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/make/test/JtregNative.gmk	Thu Feb 16 10:41:19 2017 -0800
@@ -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/sharedRuntime_aarch64.cpp	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.hpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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/macroAssembler_arm.cpp	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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/sharedRuntime_sparc.cpp	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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/macroAssembler_x86.cpp	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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,36 +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);
-}
-
 //////////////////////////////////////////////////////////////////////////////////
 #if INCLUDE_ALL_GCS
 
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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,8 +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);
-
 #if INCLUDE_ALL_GCS
 
   void g1_write_barrier_pre(Register obj,
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/share/vm/prims/jni.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ b/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp	Thu Feb 16 10:41:19 2017 -0800
@@ -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	Wed Feb 15 22:19:13 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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");
-  }
-
-  static native Object doStuff(Object o);
-  static native Object doWithWeak(Object o);
-
-  public static void main(String[] args) {
-    Object o = doStuff(Thread.currentThread());
-    System.out.println(o);
-  }
-}
-
--- a/hotspot/test/runtime/jni/CallWithJNIWeak/libCallWithJNIWeak.c	Wed Feb 15 22:19:13 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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:    doStuff
- * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
- */
-JNIEXPORT jobject JNICALL
-Java_CallWithJNIWeak_doStuff(JNIEnv *env, jclass c, jobject o) {
-  jmethodID id = (*env)->GetStaticMethodID(
-    env, c, "doWithWeak", "(Ljava/lang/Object;)Ljava/lang/Object;");
-  jweak w = (*env)->NewWeakGlobalRef(env, o);
-  jobject param = w;
-  (*env)->CallStaticVoidMethod(env, c, id, param);
-  return param;
-}
-
-/*
- * Class:     CallWithJNIWeak
- * Method:    doWithWeak
- * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
- */
-JNIEXPORT jobject JNICALL
-Java_CallWithJNIWeak_doWithWeak(JNIEnv *env, jclass c, jobject o) {
-  jclass thr_class = (*env)->GetObjectClass(env, o); // o is java.lang.Thread
-  jmethodID id = (*env)->GetMethodID(env, thr_class, "isInterrupted", "()Z");
-  jboolean b = (*env)->CallBooleanMethod(env, o, id);
-  return o;
-}
-
--- a/hotspot/test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.java	Wed Feb 15 22:19:13 2017 -0500
+++ /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	Wed Feb 15 22:19:13 2017 -0500
+++ /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;
-}