changeset 11191:011616fee690

Merge
author vlivanov
date Mon, 09 May 2016 13:13:07 +0300
parents 2f835b9637ee 54d0862c0773
children e0fb424caaf7
files src/cpu/sparc/vm/stubGenerator_sparc.cpp src/cpu/x86/vm/stubGenerator_x86_64.cpp src/share/vm/c1/c1_Compiler.cpp src/share/vm/classfile/vmSymbols.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/opto/c2compiler.cpp src/share/vm/opto/library_call.cpp
diffstat 38 files changed, 658 insertions(+), 863 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Mon May 09 13:13:07 2016 +0300
@@ -825,17 +825,6 @@
     return start;
   }
 
-  // The following routine generates a subroutine to throw an asynchronous
-  // UnknownError when an unsafe access gets a fault that could not be
-  // reasonably prevented by the programmer.  (Example: SIGBUS/OBJERR.)
-  //
-  address generate_handler_for_unsafe_access() {
-    StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
-    address start = __ function_entry();
-    __ unimplemented("StubRoutines::handler_for_unsafe_access", 93);
-    return start;
-  }
-
 #if !defined(PRODUCT)
   // Wrapper which calls oopDesc::is_oop_or_null()
   // Only called by MacroAssembler::verify_oop
@@ -3111,8 +3100,6 @@
     StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError),  false);
     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
 
-    StubRoutines::_handler_for_unsafe_access_entry         = generate_handler_for_unsafe_access();
-
     // support for verify_oop (must happen after universe_init)
     StubRoutines::_verify_oop_subroutine_entry             = generate_verify_oop();
 
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Mon May 09 13:13:07 2016 +0300
@@ -64,20 +64,6 @@
 // -------------------------------------------------------------------------------------------------------------------------
 // Stub Code definitions
 
-static address handle_unsafe_access() {
-  JavaThread* thread = JavaThread::current();
-  address pc  = thread->saved_exception_pc();
-  address npc = thread->saved_exception_npc();
-  // pc is the instruction which we must emulate
-  // doing a no-op is fine:  return garbage from the load
-
-  // request an async exception
-  thread->set_pending_unsafe_access_error();
-
-  // return address of next instruction to execute
-  return npc;
-}
-
 class StubGenerator: public StubCodeGenerator {
  private:
 
@@ -746,62 +732,6 @@
   Label _atomic_add_stub;  // called from other stubs
 
 
-  //------------------------------------------------------------------------------------------------------------------------
-  // The following routine generates a subroutine to throw an asynchronous
-  // UnknownError when an unsafe access gets a fault that could not be
-  // reasonably prevented by the programmer.  (Example: SIGBUS/OBJERR.)
-  //
-  // Arguments :
-  //
-  //      trapping PC:    O7
-  //
-  // Results:
-  //     posts an asynchronous exception, skips the trapping instruction
-  //
-
-  address generate_handler_for_unsafe_access() {
-    StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
-    address start = __ pc();
-
-    const int preserve_register_words = (64 * 2);
-    Address preserve_addr(FP, (-preserve_register_words * wordSize) + STACK_BIAS);
-
-    Register Lthread = L7_thread_cache;
-    int i;
-
-    __ save_frame(0);
-    __ mov(G1, L1);
-    __ mov(G2, L2);
-    __ mov(G3, L3);
-    __ mov(G4, L4);
-    __ mov(G5, L5);
-    for (i = 0; i < 64; i += 2) {
-      __ stf(FloatRegisterImpl::D, as_FloatRegister(i), preserve_addr, i * wordSize);
-    }
-
-    address entry_point = CAST_FROM_FN_PTR(address, handle_unsafe_access);
-    BLOCK_COMMENT("call handle_unsafe_access");
-    __ call(entry_point, relocInfo::runtime_call_type);
-    __ delayed()->nop();
-
-    __ mov(L1, G1);
-    __ mov(L2, G2);
-    __ mov(L3, G3);
-    __ mov(L4, G4);
-    __ mov(L5, G5);
-    for (i = 0; i < 64; i += 2) {
-      __ ldf(FloatRegisterImpl::D, preserve_addr, as_FloatRegister(i), i * wordSize);
-    }
-
-    __ verify_thread();
-
-    __ jmp(O0, 0);
-    __ delayed()->restore();
-
-    return start;
-  }
-
-
   // Support for uint StubRoutine::Sparc::partial_subtype_check( Klass sub, Klass super );
   // Arguments :
   //
@@ -5218,9 +5148,6 @@
     StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
 
-    StubRoutines::_handler_for_unsafe_access_entry =
-      generate_handler_for_unsafe_access();
-
     // support for verify_oop (must happen after universe_init)
     StubRoutines::_verify_oop_subroutine_entry     = generate_verify_oop_subroutine();
 
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -63,21 +63,6 @@
 // -------------------------------------------------------------------------------------------------------------------------
 // Stub Code definitions
 
-static address handle_unsafe_access() {
-  JavaThread* thread = JavaThread::current();
-  address pc  = thread->saved_exception_pc();
-  // pc is the instruction which we must emulate
-  // doing a no-op is fine:  return garbage from the load
-  // therefore, compute npc
-  address npc = Assembler::locate_next_instruction(pc);
-
-  // request an async exception
-  thread->set_pending_unsafe_access_error();
-
-  // return address of next instruction to execute
-  return npc;
-}
-
 class StubGenerator: public StubCodeGenerator {
  private:
 
@@ -623,27 +608,6 @@
   }
 
 
-  //---------------------------------------------------------------------------
-  // The following routine generates a subroutine to throw an asynchronous
-  // UnknownError when an unsafe access gets a fault that could not be
-  // reasonably prevented by the programmer.  (Example: SIGBUS/OBJERR.)
-  address generate_handler_for_unsafe_access() {
-    StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
-    address start = __ pc();
-
-    __ push(0);                       // hole for return address-to-be
-    __ pusha();                       // push registers
-    Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
-    BLOCK_COMMENT("call handle_unsafe_access");
-    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
-    __ movptr(next_pc, rax);          // stuff next address
-    __ popa();
-    __ ret(0);                        // jump to next address
-
-    return start;
-  }
-
-
   //----------------------------------------------------------------------------------------------------
   // Non-destructive plausibility checks for oops
 
@@ -3865,9 +3829,6 @@
     // These are currently used by Solaris/Intel
     StubRoutines::_atomic_xchg_entry            = generate_atomic_xchg();
 
-    StubRoutines::_handler_for_unsafe_access_entry =
-      generate_handler_for_unsafe_access();
-
     // platform dependent
     create_control_words();
 
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, 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
@@ -61,21 +61,6 @@
 
 // Stub Code definitions
 
-static address handle_unsafe_access() {
-  JavaThread* thread = JavaThread::current();
-  address pc = thread->saved_exception_pc();
-  // pc is the instruction which we must emulate
-  // doing a no-op is fine:  return garbage from the load
-  // therefore, compute npc
-  address npc = Assembler::locate_next_instruction(pc);
-
-  // request an async exception
-  thread->set_pending_unsafe_access_error();
-
-  // return address of next instruction to execute
-  return npc;
-}
-
 class StubGenerator: public StubCodeGenerator {
  private:
 
@@ -989,32 +974,6 @@
     return start;
   }
 
-  // The following routine generates a subroutine to throw an
-  // asynchronous UnknownError when an unsafe access gets a fault that
-  // could not be reasonably prevented by the programmer.  (Example:
-  // SIGBUS/OBJERR.)
-  address generate_handler_for_unsafe_access() {
-    StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
-    address start = __ pc();
-
-    __ push(0);                       // hole for return address-to-be
-    __ pusha();                       // push registers
-    Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
-
-    // FIXME: this probably needs alignment logic
-
-    __ subptr(rsp, frame::arg_reg_save_area_bytes);
-    BLOCK_COMMENT("call handle_unsafe_access");
-    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
-    __ addptr(rsp, frame::arg_reg_save_area_bytes);
-
-    __ movptr(next_pc, rax);          // stuff next address
-    __ popa();
-    __ ret(0);                        // jump to next address
-
-    return start;
-  }
-
   // Non-destructive plausibility checks for oops
   //
   // Arguments:
@@ -5139,9 +5098,6 @@
     StubRoutines::_atomic_add_ptr_entry      = generate_atomic_add_ptr();
     StubRoutines::_fence_entry               = generate_orderaccess_fence();
 
-    StubRoutines::_handler_for_unsafe_access_entry =
-      generate_handler_for_unsafe_access();
-
     // platform dependent
     StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
     StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
--- a/src/cpu/zero/vm/stubGenerator_zero.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/cpu/zero/vm/stubGenerator_zero.cpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010, 2015 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -261,10 +261,6 @@
     StubRoutines::_atomic_add_entry          = ShouldNotCallThisStub();
     StubRoutines::_atomic_add_ptr_entry      = ShouldNotCallThisStub();
     StubRoutines::_fence_entry               = ShouldNotCallThisStub();
-
-    // amd64 does this here, sparc does it in generate_all()
-    StubRoutines::_handler_for_unsafe_access_entry =
-      ShouldNotCallThisStub();
   }
 
   void generate_all() {
--- a/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Mon May 09 13:13:07 2016 +0300
@@ -392,11 +392,9 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = cb->as_compiled_method_or_null();
         if (nm != NULL && nm->has_unsafe_access()) {
-          // We don't really need a stub here! Just set the pending exeption and
-          // continue at the next instruction after the faulting read. Returning
-          // garbage from this read is ok.
-          thread->set_pending_unsafe_access_error();
-          os::Aix::ucontext_set_pc(uc, pc + 4);
+          address next_pc = pc + 4;
+          next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
+          os::Aix::ucontext_set_pc(uc, next_pc);
           return 1;
         }
       }
@@ -415,11 +413,9 @@
       }
       else if (thread->thread_state() == _thread_in_vm &&
                sig == SIGBUS && thread->doing_unsafe_access()) {
-        // We don't really need a stub here! Just set the pending exeption and
-        // continue at the next instruction after the faulting read. Returning
-        // garbage from this read is ok.
-        thread->set_pending_unsafe_access_error();
-        os::Aix::ucontext_set_pc(uc, pc + 4);
+        address next_pc = pc + 4;
+        next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
+        os::Aix::ucontext_set_pc(uc, next_pc);
         return 1;
       }
     }
--- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Mon May 09 13:13:07 2016 +0300
@@ -584,7 +584,8 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
-          stub = StubRoutines::handler_for_unsafe_access();
+          address next_pc = Assembler::locate_next_instruction(pc);
+          stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
         }
       }
       else
@@ -655,7 +656,8 @@
     } else if (thread->thread_state() == _thread_in_vm &&
                sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
                thread->doing_unsafe_access()) {
-        stub = StubRoutines::handler_for_unsafe_access();
+        address next_pc = Assembler::locate_next_instruction(pc);
+        stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
     }
 
     // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
--- a/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Mon May 09 13:13:07 2016 +0300
@@ -226,23 +226,6 @@
 extern "C" void FetchNResume () ;
 #endif
 
-// An operation in Unsafe has faulted.  We're going to return to the
-// instruction after the faulting load or store.  We also set
-// pending_unsafe_access_error so that at some point in the future our
-// user will get a helpful message.
-static address handle_unsafe_access(JavaThread* thread, address pc) {
-  // pc is the instruction which we must emulate
-  // doing a no-op is fine:  return garbage from the load
-  // therefore, compute npc
-  address npc = pc + NativeCall::instruction_size;
-
-  // request an async exception
-  thread->set_pending_unsafe_access_error();
-
-  // return address of next instruction to execute
-  return npc;
-}
-
 extern "C" JNIEXPORT int
 JVM_handle_linux_signal(int sig,
                         siginfo_t* info,
@@ -387,7 +370,8 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
-          stub = handle_unsafe_access(thread, pc);
+          address next_pc = pc + NativeCall::instruction_size;
+          stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
         }
       }
       else
@@ -408,7 +392,8 @@
     } else if (thread->thread_state() == _thread_in_vm &&
                sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
                thread->doing_unsafe_access()) {
-        stub = handle_unsafe_access(thread, pc);
+      address next_pc = pc + NativeCall::instruction_size;
+      stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
     }
 
     // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
--- a/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Mon May 09 13:13:07 2016 +0300
@@ -366,11 +366,9 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
-          // We don't really need a stub here! Just set the pending exeption and
-          // continue at the next instruction after the faulting read. Returning
-          // garbage from this read is ok.
-          thread->set_pending_unsafe_access_error();
-          os::Linux::ucontext_set_pc(uc, pc + 4);
+          address next_pc = pc + 4;
+          next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
+          os::Linux::ucontext_set_pc(uc, next_pc);
           return true;
         }
       }
@@ -385,10 +383,8 @@
       }
       else if (thread->thread_state() == _thread_in_vm &&
                sig == SIGBUS && thread->doing_unsafe_access()) {
-        // We don't really need a stub here! Just set the pending exeption and
-        // continue at the next instruction after the faulting read. Returning
-        // garbage from this read is ok.
-        thread->set_pending_unsafe_access_error();
+        address next_pc = pc + 4;
+        next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
         os::Linux::ucontext_set_pc(uc, pc + 4);
         return true;
       }
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Mon May 09 13:13:07 2016 +0300
@@ -433,14 +433,14 @@
   return false;
 }
 
-inline static bool checkByteBuffer(address pc, address* stub) {
+inline static bool checkByteBuffer(address pc, address npc, address* stub) {
   // BugId 4454115: A read from a MappedByteBuffer can fault
   // here if the underlying file has been truncated.
   // Do not crash the VM in such a case.
   CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
   CompiledMethod* nm = cb->as_compiled_method_or_null();
   if (nm != NULL && nm->has_unsafe_access()) {
-    *stub = StubRoutines::handler_for_unsafe_access();
+    *stub = SharedRuntime::handle_unsafe_access(thread, npc);
     return true;
   }
   return false;
@@ -613,7 +613,7 @@
     if (sig == SIGBUS &&
         thread->thread_state() == _thread_in_vm &&
         thread->doing_unsafe_access()) {
-      stub = StubRoutines::handler_for_unsafe_access();
+      stub = SharedRuntime::handle_unsafe_access(thread, npc);
     }
 
     if (thread->thread_state() == _thread_in_Java) {
@@ -625,7 +625,7 @@
           break;
         }
 
-        if ((sig == SIGBUS) && checkByteBuffer(pc, &stub)) {
+        if ((sig == SIGBUS) && checkByteBuffer(pc, npc, &stub)) {
           break;
         }
 
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Mon May 09 13:13:07 2016 +0300
@@ -420,7 +420,8 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
-          stub = StubRoutines::handler_for_unsafe_access();
+          address next_pc = Assembler::locate_next_instruction(pc);
+          stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
         }
       }
       else
@@ -469,7 +470,8 @@
     } else if (thread->thread_state() == _thread_in_vm &&
                sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
                thread->doing_unsafe_access()) {
-        stub = StubRoutines::handler_for_unsafe_access();
+        address next_pc = Assembler::locate_next_instruction(pc);
+        stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
     }
 
     // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Mon May 09 13:13:07 2016 +0300
@@ -441,7 +441,7 @@
 
     if (thread->thread_state() == _thread_in_vm) {
       if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
-        stub = StubRoutines::handler_for_unsafe_access();
+        stub = SharedRuntime::handle_unsafe_access(thread, npc);
       }
     }
 
@@ -480,7 +480,7 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = cb->as_compiled_method_or_null();
         if (nm != NULL && nm->has_unsafe_access()) {
-          stub = StubRoutines::handler_for_unsafe_access();
+          stub = SharedRuntime::handle_unsafe_access(thread, npc);
         }
       }
 
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Mon May 09 13:13:07 2016 +0300
@@ -503,7 +503,8 @@
 
     if (thread->thread_state() == _thread_in_vm) {
       if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
-        stub = StubRoutines::handler_for_unsafe_access();
+        address next_pc = Assembler::locate_next_instruction(pc);
+        stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
       }
     }
 
@@ -520,7 +521,8 @@
         if (cb != NULL) {
           CompiledMethod* nm = cb->as_compiled_method_or_null();
           if (nm != NULL && nm->has_unsafe_access()) {
-            stub = StubRoutines::handler_for_unsafe_access();
+            address next_pc = Assembler::locate_next_instruction(pc);
+            stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
           }
         }
       }
--- a/src/share/vm/c1/c1_Compiler.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/c1/c1_Compiler.cpp	Mon May 09 13:13:07 2016 +0300
@@ -198,20 +198,6 @@
   case vmIntrinsics::_putLongVolatile:
   case vmIntrinsics::_putFloatVolatile:
   case vmIntrinsics::_putDoubleVolatile:
-  case vmIntrinsics::_getByte_raw:
-  case vmIntrinsics::_getShort_raw:
-  case vmIntrinsics::_getChar_raw:
-  case vmIntrinsics::_getInt_raw:
-  case vmIntrinsics::_getLong_raw:
-  case vmIntrinsics::_getFloat_raw:
-  case vmIntrinsics::_getDouble_raw:
-  case vmIntrinsics::_putByte_raw:
-  case vmIntrinsics::_putShort_raw:
-  case vmIntrinsics::_putChar_raw:
-  case vmIntrinsics::_putInt_raw:
-  case vmIntrinsics::_putLong_raw:
-  case vmIntrinsics::_putFloat_raw:
-  case vmIntrinsics::_putDouble_raw:
   case vmIntrinsics::_getShortUnaligned:
   case vmIntrinsics::_getCharUnaligned:
   case vmIntrinsics::_getIntUnaligned:
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Mon May 09 13:13:07 2016 +0300
@@ -3465,20 +3465,6 @@
   case vmIntrinsics::_putLongVolatile    : append_unsafe_put_obj(callee, T_LONG,    true); return;
   case vmIntrinsics::_putFloatVolatile   : append_unsafe_put_obj(callee, T_FLOAT,   true); return;
   case vmIntrinsics::_putDoubleVolatile  : append_unsafe_put_obj(callee, T_DOUBLE,  true); return;
-  case vmIntrinsics::_getByte_raw        : append_unsafe_get_raw(callee, T_BYTE  ); return;
-  case vmIntrinsics::_getShort_raw       : append_unsafe_get_raw(callee, T_SHORT ); return;
-  case vmIntrinsics::_getChar_raw        : append_unsafe_get_raw(callee, T_CHAR  ); return;
-  case vmIntrinsics::_getInt_raw         : append_unsafe_get_raw(callee, T_INT   ); return;
-  case vmIntrinsics::_getLong_raw        : append_unsafe_get_raw(callee, T_LONG  ); return;
-  case vmIntrinsics::_getFloat_raw       : append_unsafe_get_raw(callee, T_FLOAT ); return;
-  case vmIntrinsics::_getDouble_raw      : append_unsafe_get_raw(callee, T_DOUBLE); return;
-  case vmIntrinsics::_putByte_raw        : append_unsafe_put_raw(callee, T_BYTE  ); return;
-  case vmIntrinsics::_putShort_raw       : append_unsafe_put_raw(callee, T_SHORT ); return;
-  case vmIntrinsics::_putChar_raw        : append_unsafe_put_raw(callee, T_CHAR  ); return;
-  case vmIntrinsics::_putInt_raw         : append_unsafe_put_raw(callee, T_INT   ); return;
-  case vmIntrinsics::_putLong_raw        : append_unsafe_put_raw(callee, T_LONG  ); return;
-  case vmIntrinsics::_putFloat_raw       : append_unsafe_put_raw(callee, T_FLOAT ); return;
-  case vmIntrinsics::_putDouble_raw      : append_unsafe_put_raw(callee, T_DOUBLE);  return;
   case vmIntrinsics::_compareAndSwapLong:
   case vmIntrinsics::_compareAndSwapInt:
   case vmIntrinsics::_compareAndSwapObject: append_unsafe_CAS(callee); return;
--- a/src/share/vm/classfile/vmSymbols.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/classfile/vmSymbols.cpp	Mon May 09 13:13:07 2016 +0300
@@ -580,20 +580,6 @@
   case vmIntrinsics::_putLongOpaque:
   case vmIntrinsics::_putFloatOpaque:
   case vmIntrinsics::_putDoubleOpaque:
-  case vmIntrinsics::_getByte_raw:
-  case vmIntrinsics::_getShort_raw:
-  case vmIntrinsics::_getChar_raw:
-  case vmIntrinsics::_getInt_raw:
-  case vmIntrinsics::_getLong_raw:
-  case vmIntrinsics::_getFloat_raw:
-  case vmIntrinsics::_getDouble_raw:
-  case vmIntrinsics::_putByte_raw:
-  case vmIntrinsics::_putShort_raw:
-  case vmIntrinsics::_putChar_raw:
-  case vmIntrinsics::_putInt_raw:
-  case vmIntrinsics::_putLong_raw:
-  case vmIntrinsics::_putFloat_raw:
-  case vmIntrinsics::_putDouble_raw:
   case vmIntrinsics::_getAndAddInt:
   case vmIntrinsics::_getAndAddLong:
   case vmIntrinsics::_getAndSetInt:
@@ -634,8 +620,6 @@
   case vmIntrinsics::_putIntUnaligned:
   case vmIntrinsics::_putLongUnaligned:
   case vmIntrinsics::_allocateInstance:
-  case vmIntrinsics::_getAddress_raw:
-  case vmIntrinsics::_putAddress_raw:
     if (!InlineUnsafeOps || !UseUnalignedAccesses) return true;
     break;
   case vmIntrinsics::_hashCode:
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon May 09 13:13:07 2016 +0300
@@ -1232,43 +1232,6 @@
   do_intrinsic(_putIntUnaligned,           jdk_internal_misc_Unsafe,    putIntUnaligned_name, putInt_signature,         F_R)  \
   do_intrinsic(_putLongUnaligned,          jdk_internal_misc_Unsafe,    putLongUnaligned_name, putLong_signature,       F_R)  \
                                                                                                                         \
-  /* %%% these are redundant except perhaps for getAddress, but Unsafe has native methods for them */                   \
-  do_signature(getByte_raw_signature,     "(J)B")                                                                       \
-  do_signature(putByte_raw_signature,     "(JB)V")                                                                      \
-  do_signature(getShort_raw_signature,    "(J)S")                                                                       \
-  do_signature(putShort_raw_signature,    "(JS)V")                                                                      \
-  do_signature(getChar_raw_signature,     "(J)C")                                                                       \
-  do_signature(putChar_raw_signature,     "(JC)V")                                                                      \
-  do_signature(putInt_raw_signature,      "(JI)V")                                                                      \
-      do_alias(getLong_raw_signature,    /*(J)J*/ long_long_signature)                                                  \
-      do_alias(putLong_raw_signature,    /*(JJ)V*/ long_long_void_signature)                                            \
-  do_signature(getFloat_raw_signature,    "(J)F")                                                                       \
-  do_signature(putFloat_raw_signature,    "(JF)V")                                                                      \
-      do_alias(getDouble_raw_signature,  /*(J)D*/ long_double_signature)                                                \
-  do_signature(putDouble_raw_signature,   "(JD)V")                                                                      \
-      do_alias(getAddress_raw_signature, /*(J)J*/ long_long_signature)                                                  \
-      do_alias(putAddress_raw_signature, /*(JJ)V*/ long_long_void_signature)                                            \
-                                                                                                                        \
-   do_name(    getAddress_name,           "getAddress")                                                                 \
-   do_name(    putAddress_name,           "putAddress")                                                                 \
-                                                                                                                        \
-  do_intrinsic(_getByte_raw,              jdk_internal_misc_Unsafe,     getByte_name, getByte_raw_signature,           F_R)  \
-  do_intrinsic(_getShort_raw,             jdk_internal_misc_Unsafe,     getShort_name, getShort_raw_signature,         F_R)  \
-  do_intrinsic(_getChar_raw,              jdk_internal_misc_Unsafe,     getChar_name, getChar_raw_signature,           F_R)  \
-  do_intrinsic(_getInt_raw,               jdk_internal_misc_Unsafe,     getInt_name, long_int_signature,               F_R)  \
-  do_intrinsic(_getLong_raw,              jdk_internal_misc_Unsafe,     getLong_name, getLong_raw_signature,           F_R)  \
-  do_intrinsic(_getFloat_raw,             jdk_internal_misc_Unsafe,     getFloat_name, getFloat_raw_signature,         F_R)  \
-  do_intrinsic(_getDouble_raw,            jdk_internal_misc_Unsafe,     getDouble_name, getDouble_raw_signature,       F_R)  \
-  do_intrinsic(_getAddress_raw,           jdk_internal_misc_Unsafe,     getAddress_name, getAddress_raw_signature,     F_R)  \
-  do_intrinsic(_putByte_raw,              jdk_internal_misc_Unsafe,     putByte_name, putByte_raw_signature,           F_R)  \
-  do_intrinsic(_putShort_raw,             jdk_internal_misc_Unsafe,     putShort_name, putShort_raw_signature,         F_R)  \
-  do_intrinsic(_putChar_raw,              jdk_internal_misc_Unsafe,     putChar_name, putChar_raw_signature,           F_R)  \
-  do_intrinsic(_putInt_raw,               jdk_internal_misc_Unsafe,     putInt_name, putInt_raw_signature,             F_R)  \
-  do_intrinsic(_putLong_raw,              jdk_internal_misc_Unsafe,     putLong_name, putLong_raw_signature,           F_R)  \
-  do_intrinsic(_putFloat_raw,             jdk_internal_misc_Unsafe,     putFloat_name, putFloat_raw_signature,         F_R)  \
-  do_intrinsic(_putDouble_raw,            jdk_internal_misc_Unsafe,     putDouble_name, putDouble_raw_signature,       F_R)  \
-  do_intrinsic(_putAddress_raw,           jdk_internal_misc_Unsafe,     putAddress_name, putAddress_raw_signature,     F_R)  \
-                                                                                                                        \
   do_signature(compareAndSwapObject_signature,     "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z")        \
   do_signature(compareAndExchangeObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") \
   do_signature(compareAndSwapLong_signature,       "(Ljava/lang/Object;JJJ)Z")                                          \
--- a/src/share/vm/gc/parallel/gcTaskManager.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/parallel/gcTaskManager.cpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -25,8 +25,8 @@
 #include "precompiled.hpp"
 #include "gc/parallel/gcTaskManager.hpp"
 #include "gc/parallel/gcTaskThread.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcId.hpp"
+#include "gc/shared/workerManager.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
@@ -34,6 +34,7 @@
 #include "runtime/mutex.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/orderAccess.inline.hpp"
+#include "runtime/os.hpp"
 
 //
 // GCTask
@@ -372,10 +373,28 @@
 GCTaskManager::GCTaskManager(uint workers) :
   _workers(workers),
   _active_workers(0),
-  _idle_workers(0) {
+  _idle_workers(0),
+  _created_workers(0) {
   initialize();
 }
 
+GCTaskThread* GCTaskManager::install_worker(uint t) {
+  GCTaskThread* new_worker = GCTaskThread::create(this, t, _processor_assignment[t]);
+  set_thread(t, new_worker);
+  return new_worker;
+}
+
+void GCTaskManager::add_workers(bool initializing) {
+  os::ThreadType worker_type = os::pgc_thread;
+  _created_workers = WorkerManager::add_workers(this,
+                                                _active_workers,
+                                                (uint) _workers,
+                                                _created_workers,
+                                                worker_type,
+                                                initializing);
+  _active_workers = MIN2(_created_workers, _active_workers);
+}
+
 void GCTaskManager::initialize() {
   if (TraceGCTaskManager) {
     tty->print_cr("GCTaskManager::initialize: workers: %u", workers());
@@ -394,28 +413,30 @@
     // Set up worker threads.
     //     Distribute the workers among the available processors,
     //     unless we were told not to, or if the os doesn't want to.
-    uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
+    _processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
     if (!BindGCTaskThreadsToCPUs ||
-        !os::distribute_processes(workers(), processor_assignment)) {
+        !os::distribute_processes(workers(), _processor_assignment)) {
       for (uint a = 0; a < workers(); a += 1) {
-        processor_assignment[a] = sentinel_worker();
+        _processor_assignment[a] = sentinel_worker();
       }
     }
+
     _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC);
-    for (uint t = 0; t < workers(); t += 1) {
-      set_thread(t, GCTaskThread::create(this, t, processor_assignment[t]));
+    _active_workers = ParallelGCThreads;
+    if (UseDynamicNumberOfGCThreads && !FLAG_IS_CMDLINE(ParallelGCThreads)) {
+      _active_workers = 1U;
     }
+
     Log(gc, task, thread) log;
     if (log.is_trace()) {
       ResourceMark rm;
       outputStream* out = log.trace_stream();
       out->print("GCTaskManager::initialize: distribution:");
       for (uint t = 0; t < workers(); t += 1) {
-        out->print("  %u", processor_assignment[t]);
+        out->print("  %u", _processor_assignment[t]);
       }
       out->cr();
     }
-    FREE_C_HEAP_ARRAY(uint, processor_assignment);
   }
   reset_busy_workers();
   set_unblocked();
@@ -426,9 +447,8 @@
   reset_completed_tasks();
   reset_barriers();
   reset_emptied_queue();
-  for (uint s = 0; s < workers(); s += 1) {
-    thread(s)->start();
-  }
+
+  add_workers(true);
 }
 
 GCTaskManager::~GCTaskManager() {
@@ -437,13 +457,17 @@
   NoopGCTask::destroy(_noop_task);
   _noop_task = NULL;
   if (_thread != NULL) {
-    for (uint i = 0; i < workers(); i += 1) {
+    for (uint i = 0; i < created_workers(); i += 1) {
       GCTaskThread::destroy(thread(i));
       set_thread(i, NULL);
     }
     FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
     _thread = NULL;
   }
+  if (_processor_assignment != NULL) {
+    FREE_C_HEAP_ARRAY(uint, _processor_assignment);
+    _processor_assignment = NULL;
+  }
   if (_resource_flag != NULL) {
     FREE_C_HEAP_ARRAY(bool, _resource_flag);
     _resource_flag = NULL;
@@ -470,6 +494,9 @@
          "all_workers_active() is  incorrect: "
          "active %d  ParallelGCThreads %u", active_workers(),
          ParallelGCThreads);
+  _active_workers = MIN2(_active_workers, _workers);
+  // "add_workers" does not guarantee any additional workers
+  add_workers(false);
   log_trace(gc, task)("GCTaskManager::set_active_gang(): "
                       "all_workers_active()  %d  workers %d  "
                       "active  %d  ParallelGCThreads %u",
@@ -499,7 +526,7 @@
       // is starting).  Try later to release enough idle_workers
       // to allow the desired number of active_workers.
       more_inactive_workers =
-        workers() - active_workers() - idle_workers();
+        created_workers() - active_workers() - idle_workers();
       if (more_inactive_workers < 0) {
         int reduced_active_workers = active_workers() + more_inactive_workers;
         set_active_workers(reduced_active_workers);
@@ -507,7 +534,7 @@
       }
       log_trace(gc, task)("JT: %d  workers %d  active  %d  idle %d  more %d",
                           Threads::number_of_non_daemon_threads(),
-                          workers(),
+                          created_workers(),
                           active_workers(),
                           idle_workers(),
                           more_inactive_workers);
@@ -517,7 +544,7 @@
       q->enqueue(IdleGCTask::create_on_c_heap());
       increment_idle_workers();
     }
-    assert(workers() == active_workers() + idle_workers(),
+    assert(created_workers() == active_workers() + idle_workers(),
       "total workers should equal active + inactive");
     add_list(q);
     // GCTaskQueue* q was created in a ResourceArea so a
@@ -539,14 +566,15 @@
   if (!log_is_enabled(Debug, gc, task, time)) {
     return;
   }
-  for(uint i=0; i<ParallelGCThreads; i++) {
+  uint num_thr = created_workers();
+  for(uint i=0; i < num_thr; i++) {
     GCTaskThread* t = thread(i);
     t->print_task_time_stamps();
   }
 }
 
 void GCTaskManager::print_threads_on(outputStream* st) {
-  uint num_thr = workers();
+  uint num_thr = created_workers();
   for (uint i = 0; i < num_thr; i++) {
     thread(i)->print_on(st);
     st->cr();
@@ -555,19 +583,20 @@
 
 void GCTaskManager::threads_do(ThreadClosure* tc) {
   assert(tc != NULL, "Null ThreadClosure");
-  uint num_thr = workers();
+  uint num_thr = created_workers();
   for (uint i = 0; i < num_thr; i++) {
     tc->do_thread(thread(i));
   }
 }
 
 GCTaskThread* GCTaskManager::thread(uint which) {
-  assert(which < workers(), "index out of bounds");
+  assert(which < created_workers(), "index out of bounds");
   assert(_thread[which] != NULL, "shouldn't have null thread");
   return _thread[which];
 }
 
 void GCTaskManager::set_thread(uint which, GCTaskThread* value) {
+  // "_created_workers" may not have been updated yet so use workers()
   assert(which < workers(), "index out of bounds");
   assert(value != NULL, "shouldn't have null thread");
   _thread[which] = value;
@@ -728,7 +757,7 @@
 
 void GCTaskManager::release_all_resources() {
   // If you want this to be done atomically, do it in a WaitForBarrierGCTask.
-  for (uint i = 0; i < workers(); i += 1) {
+  for (uint i = 0; i < created_workers(); i += 1) {
     set_resource_flag(i, true);
   }
 }
--- a/src/share/vm/gc/parallel/gcTaskManager.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/parallel/gcTaskManager.hpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -370,6 +370,7 @@
   Monitor*                  _monitor;           // Notification of changes.
   SynchronizedGCTaskQueue*  _queue;             // Queue of tasks.
   GCTaskThread**            _thread;            // Array of worker threads.
+  uint                      _created_workers;   // Number of workers created.
   uint                      _active_workers;    // Number of active workers.
   uint                      _busy_workers;      // Number of busy workers.
   uint                      _blocking_worker;   // The worker that's blocking.
@@ -381,6 +382,8 @@
   NoopGCTask*               _noop_task;         // The NoopGCTask instance.
   WaitHelper                _wait_helper;       // Used by inactive worker
   volatile uint             _idle_workers;      // Number of idled workers
+  uint*                     _processor_assignment; // Worker to cpu mappings. May
+                                                   // be used lazily
 public:
   // Factory create and destroy methods.
   static GCTaskManager* create(uint workers) {
@@ -546,6 +549,13 @@
   uint active_workers() const {
     return _active_workers;
   }
+  uint created_workers() const {
+    return _created_workers;
+  }
+  // Create a GC worker and install into GCTaskManager
+  GCTaskThread* install_worker(uint worker_id);
+  // Add GC workers as needed.
+  void add_workers(bool initializing);
 };
 
 //
--- a/src/share/vm/gc/parallel/gcTaskThread.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/parallel/gcTaskThread.cpp	Mon May 09 13:13:07 2016 +0300
@@ -44,9 +44,6 @@
   _time_stamps(NULL),
   _time_stamp_index(0)
 {
-  if (!os::create_thread(this, os::pgc_thread))
-    vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GC thread. Out of system resources.");
-
   set_id(which);
   set_name("ParGC Thread#%d", which);
 }
@@ -57,10 +54,6 @@
   }
 }
 
-void GCTaskThread::start() {
-  os::start_thread(this);
-}
-
 GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) {
   guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
   if (_time_stamps == NULL) {
--- a/src/share/vm/gc/parallel/gcTaskThread.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/parallel/gcTaskThread.hpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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,13 +48,13 @@
 
   bool _is_working;                     // True if participating in GC tasks
 
- public:
   // Factory create and destroy methods.
   static GCTaskThread* create(GCTaskManager* manager,
                               uint           which,
                               uint           processor_id) {
     return new GCTaskThread(manager, which, processor_id);
   }
+ public:
   static void destroy(GCTaskThread* manager) {
     if (manager != NULL) {
       delete manager;
@@ -65,8 +65,6 @@
     return true;
   }
   virtual void run();
-  // Methods.
-  void start();
 
   void print_task_time_stamps();
 
--- a/src/share/vm/gc/shared/adaptiveSizePolicy.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/shared/adaptiveSizePolicy.cpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -130,10 +130,7 @@
   uintx max_active_workers =
     MAX2(active_workers_by_JT, active_workers_by_heap_size);
 
-  // Limit the number of workers to the the number created,
-  // (workers()).
-  new_active_workers = MIN2(max_active_workers,
-                                (uintx) total_workers);
+  new_active_workers = MIN2(max_active_workers, (uintx) total_workers);
 
   // Increase GC workers instantly but decrease them more
   // slowly.
@@ -167,7 +164,7 @@
       "Jiggled active workers too much");
   }
 
-   log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
+  log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
      "active_workers(): " UINTX_FORMAT "  new_active_workers: " UINTX_FORMAT "  "
      "prev_active_workers: " UINTX_FORMAT "\n"
      " active_workers_by_JT: " UINTX_FORMAT "  active_workers_by_heap_size: " UINTX_FORMAT,
--- a/src/share/vm/gc/shared/adaptiveSizePolicy.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/shared/adaptiveSizePolicy.hpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/shared/workerManager.hpp	Mon May 09 13:13:07 2016 +0300
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
+#define SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
+
+#include "gc/shared/adaptiveSizePolicy.hpp"
+
+class WorkerManager : public AllStatic {
+ public:
+  // Create additional workers as needed.
+  //   active_workers - number of workers being requested for an upcoming
+  // parallel task.
+  //   total_workers - total number of workers.  This is the maximum
+  // number possible.
+  //   created_workers - number of workers already created.  This maybe
+  // less than, equal to, or greater than active workers.  If greater than
+  // or equal to active_workers, nothing is done.
+  //   worker_type - type of thread.
+  //   initializing - true if this is called to get the initial number of
+  // GC workers.
+  // If initializing is true, do a vm exit if the workers cannot be created.
+  // The initializing = true case is for JVM start up and failing to
+  // create all the worker at start should considered a problem so exit.
+  // If initializing = false, there are already some number of worker
+  // threads and a failure would not be optimal but should not be fatal.
+  template <class WorkerType>
+  static uint add_workers (WorkerType* holder,
+                   uint active_workers,
+                   uint total_workers,
+                   uint created_workers,
+                   os::ThreadType worker_type,
+                   bool initializing) {
+    uint start = created_workers;
+    uint end = MIN2(active_workers, total_workers);
+    for (uint worker_id = start; worker_id < end; worker_id += 1) {
+      WorkerThread* new_worker = holder->install_worker(worker_id);
+      assert(new_worker != NULL, "Failed to allocate GangWorker");
+      if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
+        if(initializing) {
+          vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
+                  "Cannot create worker GC thread. Out of system resources.");
+        }
+      }
+      created_workers++;
+      os::start_thread(new_worker);
+    }
+
+    log_trace(gc, task)("AdaptiveSizePolicy::add_workers() : "
+       "active_workers: %u created_workers: %u",
+       active_workers, created_workers);
+
+    return created_workers;
+  }
+};
+#endif // SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
--- a/src/share/vm/gc/shared/workgroup.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/shared/workgroup.cpp	Mon May 09 13:13:07 2016 +0300
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/workgroup.hpp"
+#include "gc/shared/workerManager.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/atomic.inline.hpp"
@@ -35,37 +36,45 @@
 // Definitions of WorkGang methods.
 
 // The current implementation will exit if the allocation
-// of any worker fails.  Still, return a boolean so that
-// a future implementation can possibly do a partial
-// initialization of the workers and report such to the
-// caller.
-bool AbstractWorkGang::initialize_workers() {
+// of any worker fails.
+void  AbstractWorkGang::initialize_workers() {
   log_develop_trace(gc, workgang)("Constructing work gang %s with %u threads", name(), total_workers());
   _workers = NEW_C_HEAP_ARRAY(AbstractGangWorker*, total_workers(), mtInternal);
   if (_workers == NULL) {
     vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GangWorker array.");
-    return false;
   }
+
+  _active_workers = ParallelGCThreads;
+  if (UseDynamicNumberOfGCThreads && !FLAG_IS_CMDLINE(ParallelGCThreads)) {
+    _active_workers = 1U;
+  }
+
+  add_workers(true);
+}
+
+
+AbstractGangWorker* AbstractWorkGang::install_worker(uint worker_id) {
+  AbstractGangWorker* new_worker = allocate_worker(worker_id);
+  set_thread(worker_id, new_worker);
+  return new_worker;
+}
+
+void AbstractWorkGang::add_workers(bool initializing) {
+
   os::ThreadType worker_type;
   if (are_ConcurrentGC_threads()) {
     worker_type = os::cgc_thread;
   } else {
     worker_type = os::pgc_thread;
   }
-  for (uint worker = 0; worker < total_workers(); worker += 1) {
-    AbstractGangWorker* new_worker = allocate_worker(worker);
-    assert(new_worker != NULL, "Failed to allocate GangWorker");
-    _workers[worker] = new_worker;
-    if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
-      vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
-              "Cannot create worker GC thread. Out of system resources.");
-      return false;
-    }
-    if (!DisableStartThread) {
-      os::start_thread(new_worker);
-    }
-  }
-  return true;
+
+  _created_workers = WorkerManager::add_workers(this,
+                                                _active_workers,
+                                                _total_workers,
+                                                _created_workers,
+                                                worker_type,
+                                                initializing);
+  _active_workers = MIN2(_created_workers, _active_workers);
 }
 
 AbstractGangWorker* AbstractWorkGang::worker(uint i) const {
@@ -79,7 +88,7 @@
 }
 
 void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
-  uint workers = total_workers();
+  uint workers = created_workers();
   for (uint i = 0; i < workers; i++) {
     worker(i)->print_on(st);
     st->cr();
@@ -88,7 +97,7 @@
 
 void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
   assert(tc != NULL, "Null ThreadClosure");
-  uint workers = total_workers();
+  uint workers = created_workers();
   for (uint i = 0; i < workers; i++) {
     tc->do_thread(worker(i));
   }
--- a/src/share/vm/gc/shared/workgroup.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/gc/shared/workgroup.hpp	Mon May 09 13:13:07 2016 +0300
@@ -112,6 +112,8 @@
   uint _total_workers;
   // The currently active workers in this gang.
   uint _active_workers;
+  // The count of created workers in the gang.
+  uint _created_workers;
   // Printing support.
   const char* _name;
 
@@ -120,23 +122,32 @@
   const bool _are_GC_task_threads;
   const bool _are_ConcurrentGC_threads;
 
+  void set_thread(uint worker_id, AbstractGangWorker* worker) {
+    _workers[worker_id] = worker;
+  }
+
  public:
   AbstractWorkGang(const char* name, uint workers, bool are_GC_task_threads, bool are_ConcurrentGC_threads) :
       _name(name),
       _total_workers(workers),
       _active_workers(UseDynamicNumberOfGCThreads ? 1U : workers),
+      _created_workers(0),
       _are_GC_task_threads(are_GC_task_threads),
       _are_ConcurrentGC_threads(are_ConcurrentGC_threads)
   { }
 
   // Initialize workers in the gang.  Return true if initialization succeeded.
-  bool initialize_workers();
+  void initialize_workers();
 
   bool are_GC_task_threads()      const { return _are_GC_task_threads; }
   bool are_ConcurrentGC_threads() const { return _are_ConcurrentGC_threads; }
 
   uint total_workers() const { return _total_workers; }
 
+  uint created_workers() const {
+    return _created_workers;
+  }
+
   virtual uint active_workers() const {
     assert(_active_workers <= _total_workers,
            "_active_workers: %u > _total_workers: %u", _active_workers, _total_workers);
@@ -144,22 +155,29 @@
            "Unless dynamic should use total workers");
     return _active_workers;
   }
+
   void set_active_workers(uint v) {
     assert(v <= _total_workers,
            "Trying to set more workers active than there are");
     _active_workers = MIN2(v, _total_workers);
+    add_workers(false /* exit_on_failure */);
     assert(v != 0, "Trying to set active workers to 0");
-    _active_workers = MAX2(1U, _active_workers);
     assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
            "Unless dynamic should use total workers");
     log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
   }
 
+  // Add GC workers as needed.
+  void add_workers(bool initializing);
+
   // Return the Ith worker.
   AbstractGangWorker* worker(uint i) const;
 
   void threads_do(ThreadClosure* tc) const;
 
+  // Create a GC worker and install it into the work gang.
+  virtual AbstractGangWorker* install_worker(uint which);
+
   // Debugging.
   const char* name() const { return _name; }
 
--- a/src/share/vm/opto/c2compiler.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/opto/c2compiler.cpp	Mon May 09 13:13:07 2016 +0300
@@ -409,22 +409,6 @@
   case vmIntrinsics::_putLong:
   case vmIntrinsics::_putFloat:
   case vmIntrinsics::_putDouble:
-  case vmIntrinsics::_getByte_raw:
-  case vmIntrinsics::_getShort_raw:
-  case vmIntrinsics::_getChar_raw:
-  case vmIntrinsics::_getInt_raw:
-  case vmIntrinsics::_getLong_raw:
-  case vmIntrinsics::_getFloat_raw:
-  case vmIntrinsics::_getDouble_raw:
-  case vmIntrinsics::_getAddress_raw:
-  case vmIntrinsics::_putByte_raw:
-  case vmIntrinsics::_putShort_raw:
-  case vmIntrinsics::_putChar_raw:
-  case vmIntrinsics::_putInt_raw:
-  case vmIntrinsics::_putLong_raw:
-  case vmIntrinsics::_putFloat_raw:
-  case vmIntrinsics::_putDouble_raw:
-  case vmIntrinsics::_putAddress_raw:
   case vmIntrinsics::_getObjectVolatile:
   case vmIntrinsics::_getBooleanVolatile:
   case vmIntrinsics::_getByteVolatile:
--- a/src/share/vm/opto/library_call.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/opto/library_call.cpp	Mon May 09 13:13:07 2016 +0300
@@ -93,7 +93,7 @@
   Node*             _result;        // the result node, if any
   int               _reexecute_sp;  // the stack pointer when bytecode needs to be reexecuted
 
-  const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
+  const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type);
 
  public:
   LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic)
@@ -247,7 +247,7 @@
   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
 
   typedef enum { Relaxed, Opaque, Volatile, Acquire, Release } AccessKind;
-  bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, AccessKind kind, bool is_unaligned);
+  bool inline_unsafe_access(bool is_store, BasicType type, AccessKind kind, bool is_unaligned);
   static bool klass_needs_init_guard(Node* kls);
   bool inline_unsafe_allocate();
   bool inline_unsafe_newArray(bool uninitialized);
@@ -475,7 +475,6 @@
   // Handle symbolic names for otherwise undistinguished boolean switches:
   const bool is_store       = true;
   const bool is_compress    = true;
-  const bool is_native_ptr  = true;
   const bool is_static      = true;
   const bool is_volatile    = true;
 
@@ -555,113 +554,95 @@
   case vmIntrinsics::_inflateStringC:
   case vmIntrinsics::_inflateStringB:           return inline_string_copy(!is_compress);
 
-  case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,   Relaxed, false);
-  case vmIntrinsics::_getBoolean:               return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN,  Relaxed, false);
-  case vmIntrinsics::_getByte:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,     Relaxed, false);
-  case vmIntrinsics::_getShort:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,    Relaxed, false);
-  case vmIntrinsics::_getChar:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,     Relaxed, false);
-  case vmIntrinsics::_getInt:                   return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,      Relaxed, false);
-  case vmIntrinsics::_getLong:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,     Relaxed, false);
-  case vmIntrinsics::_getFloat:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,    Relaxed, false);
-  case vmIntrinsics::_getDouble:                return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,   Relaxed, false);
-
-  case vmIntrinsics::_putObject:                return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,   Relaxed, false);
-  case vmIntrinsics::_putBoolean:               return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN,  Relaxed, false);
-  case vmIntrinsics::_putByte:                  return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,     Relaxed, false);
-  case vmIntrinsics::_putShort:                 return inline_unsafe_access(!is_native_ptr,  is_store, T_SHORT,    Relaxed, false);
-  case vmIntrinsics::_putChar:                  return inline_unsafe_access(!is_native_ptr,  is_store, T_CHAR,     Relaxed, false);
-  case vmIntrinsics::_putInt:                   return inline_unsafe_access(!is_native_ptr,  is_store, T_INT,      Relaxed, false);
-  case vmIntrinsics::_putLong:                  return inline_unsafe_access(!is_native_ptr,  is_store, T_LONG,     Relaxed, false);
-  case vmIntrinsics::_putFloat:                 return inline_unsafe_access(!is_native_ptr,  is_store, T_FLOAT,    Relaxed, false);
-  case vmIntrinsics::_putDouble:                return inline_unsafe_access(!is_native_ptr,  is_store, T_DOUBLE,   Relaxed, false);
-
-  case vmIntrinsics::_getByte_raw:              return inline_unsafe_access( is_native_ptr, !is_store, T_BYTE,     Relaxed, false);
-  case vmIntrinsics::_getShort_raw:             return inline_unsafe_access( is_native_ptr, !is_store, T_SHORT,    Relaxed, false);
-  case vmIntrinsics::_getChar_raw:              return inline_unsafe_access( is_native_ptr, !is_store, T_CHAR,     Relaxed, false);
-  case vmIntrinsics::_getInt_raw:               return inline_unsafe_access( is_native_ptr, !is_store, T_INT,      Relaxed, false);
-  case vmIntrinsics::_getLong_raw:              return inline_unsafe_access( is_native_ptr, !is_store, T_LONG,     Relaxed, false);
-  case vmIntrinsics::_getFloat_raw:             return inline_unsafe_access( is_native_ptr, !is_store, T_FLOAT,    Relaxed, false);
-  case vmIntrinsics::_getDouble_raw:            return inline_unsafe_access( is_native_ptr, !is_store, T_DOUBLE,   Relaxed, false);
-  case vmIntrinsics::_getAddress_raw:           return inline_unsafe_access( is_native_ptr, !is_store, T_ADDRESS,  Relaxed, false);
-
-  case vmIntrinsics::_putByte_raw:              return inline_unsafe_access( is_native_ptr,  is_store, T_BYTE,     Relaxed, false);
-  case vmIntrinsics::_putShort_raw:             return inline_unsafe_access( is_native_ptr,  is_store, T_SHORT,    Relaxed, false);
-  case vmIntrinsics::_putChar_raw:              return inline_unsafe_access( is_native_ptr,  is_store, T_CHAR,     Relaxed, false);
-  case vmIntrinsics::_putInt_raw:               return inline_unsafe_access( is_native_ptr,  is_store, T_INT,      Relaxed, false);
-  case vmIntrinsics::_putLong_raw:              return inline_unsafe_access( is_native_ptr,  is_store, T_LONG,     Relaxed, false);
-  case vmIntrinsics::_putFloat_raw:             return inline_unsafe_access( is_native_ptr,  is_store, T_FLOAT,    Relaxed, false);
-  case vmIntrinsics::_putDouble_raw:            return inline_unsafe_access( is_native_ptr,  is_store, T_DOUBLE,   Relaxed, false);
-  case vmIntrinsics::_putAddress_raw:           return inline_unsafe_access( is_native_ptr,  is_store, T_ADDRESS,  Relaxed, false);
-
-  case vmIntrinsics::_getObjectVolatile:        return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,   Volatile, false);
-  case vmIntrinsics::_getBooleanVolatile:       return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN,  Volatile, false);
-  case vmIntrinsics::_getByteVolatile:          return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,     Volatile, false);
-  case vmIntrinsics::_getShortVolatile:         return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,    Volatile, false);
-  case vmIntrinsics::_getCharVolatile:          return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,     Volatile, false);
-  case vmIntrinsics::_getIntVolatile:           return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,      Volatile, false);
-  case vmIntrinsics::_getLongVolatile:          return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,     Volatile, false);
-  case vmIntrinsics::_getFloatVolatile:         return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,    Volatile, false);
-  case vmIntrinsics::_getDoubleVolatile:        return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,   Volatile, false);
-
-  case vmIntrinsics::_putObjectVolatile:        return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,   Volatile, false);
-  case vmIntrinsics::_putBooleanVolatile:       return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN,  Volatile, false);
-  case vmIntrinsics::_putByteVolatile:          return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,     Volatile, false);
-  case vmIntrinsics::_putShortVolatile:         return inline_unsafe_access(!is_native_ptr,  is_store, T_SHORT,    Volatile, false);
-  case vmIntrinsics::_putCharVolatile:          return inline_unsafe_access(!is_native_ptr,  is_store, T_CHAR,     Volatile, false);
-  case vmIntrinsics::_putIntVolatile:           return inline_unsafe_access(!is_native_ptr,  is_store, T_INT,      Volatile, false);
-  case vmIntrinsics::_putLongVolatile:          return inline_unsafe_access(!is_native_ptr,  is_store, T_LONG,     Volatile, false);
-  case vmIntrinsics::_putFloatVolatile:         return inline_unsafe_access(!is_native_ptr,  is_store, T_FLOAT,    Volatile, false);
-  case vmIntrinsics::_putDoubleVolatile:        return inline_unsafe_access(!is_native_ptr,  is_store, T_DOUBLE,   Volatile, false);
-
-  case vmIntrinsics::_getShortUnaligned:        return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,    Relaxed, true);
-  case vmIntrinsics::_getCharUnaligned:         return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,     Relaxed, true);
-  case vmIntrinsics::_getIntUnaligned:          return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,      Relaxed, true);
-  case vmIntrinsics::_getLongUnaligned:         return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,     Relaxed, true);
-
-  case vmIntrinsics::_putShortUnaligned:        return inline_unsafe_access(!is_native_ptr,  is_store, T_SHORT,    Relaxed, true);
-  case vmIntrinsics::_putCharUnaligned:         return inline_unsafe_access(!is_native_ptr,  is_store, T_CHAR,     Relaxed, true);
-  case vmIntrinsics::_putIntUnaligned:          return inline_unsafe_access(!is_native_ptr,  is_store, T_INT,      Relaxed, true);
-  case vmIntrinsics::_putLongUnaligned:         return inline_unsafe_access(!is_native_ptr,  is_store, T_LONG,     Relaxed, true);
-
-  case vmIntrinsics::_getObjectAcquire:         return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,   Acquire, false);
-  case vmIntrinsics::_getBooleanAcquire:        return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN,  Acquire, false);
-  case vmIntrinsics::_getByteAcquire:           return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,     Acquire, false);
-  case vmIntrinsics::_getShortAcquire:          return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,    Acquire, false);
-  case vmIntrinsics::_getCharAcquire:           return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,     Acquire, false);
-  case vmIntrinsics::_getIntAcquire:            return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,      Acquire, false);
-  case vmIntrinsics::_getLongAcquire:           return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,     Acquire, false);
-  case vmIntrinsics::_getFloatAcquire:          return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,    Acquire, false);
-  case vmIntrinsics::_getDoubleAcquire:         return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,   Acquire, false);
-
-  case vmIntrinsics::_putObjectRelease:         return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,   Release, false);
-  case vmIntrinsics::_putBooleanRelease:        return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN,  Release, false);
-  case vmIntrinsics::_putByteRelease:           return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,     Release, false);
-  case vmIntrinsics::_putShortRelease:          return inline_unsafe_access(!is_native_ptr,  is_store, T_SHORT,    Release, false);
-  case vmIntrinsics::_putCharRelease:           return inline_unsafe_access(!is_native_ptr,  is_store, T_CHAR,     Release, false);
-  case vmIntrinsics::_putIntRelease:            return inline_unsafe_access(!is_native_ptr,  is_store, T_INT,      Release, false);
-  case vmIntrinsics::_putLongRelease:           return inline_unsafe_access(!is_native_ptr,  is_store, T_LONG,     Release, false);
-  case vmIntrinsics::_putFloatRelease:          return inline_unsafe_access(!is_native_ptr,  is_store, T_FLOAT,    Release, false);
-  case vmIntrinsics::_putDoubleRelease:         return inline_unsafe_access(!is_native_ptr,  is_store, T_DOUBLE,   Release, false);
-
-  case vmIntrinsics::_getObjectOpaque:          return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,   Opaque, false);
-  case vmIntrinsics::_getBooleanOpaque:         return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN,  Opaque, false);
-  case vmIntrinsics::_getByteOpaque:            return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,     Opaque, false);
-  case vmIntrinsics::_getShortOpaque:           return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,    Opaque, false);
-  case vmIntrinsics::_getCharOpaque:            return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,     Opaque, false);
-  case vmIntrinsics::_getIntOpaque:             return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,      Opaque, false);
-  case vmIntrinsics::_getLongOpaque:            return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,     Opaque, false);
-  case vmIntrinsics::_getFloatOpaque:           return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,    Opaque, false);
-  case vmIntrinsics::_getDoubleOpaque:          return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,   Opaque, false);
-
-  case vmIntrinsics::_putObjectOpaque:          return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,   Opaque, false);
-  case vmIntrinsics::_putBooleanOpaque:         return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN,  Opaque, false);
-  case vmIntrinsics::_putByteOpaque:            return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,     Opaque, false);
-  case vmIntrinsics::_putShortOpaque:           return inline_unsafe_access(!is_native_ptr,  is_store, T_SHORT,    Opaque, false);
-  case vmIntrinsics::_putCharOpaque:            return inline_unsafe_access(!is_native_ptr,  is_store, T_CHAR,     Opaque, false);
-  case vmIntrinsics::_putIntOpaque:             return inline_unsafe_access(!is_native_ptr,  is_store, T_INT,      Opaque, false);
-  case vmIntrinsics::_putLongOpaque:            return inline_unsafe_access(!is_native_ptr,  is_store, T_LONG,     Opaque, false);
-  case vmIntrinsics::_putFloatOpaque:           return inline_unsafe_access(!is_native_ptr,  is_store, T_FLOAT,    Opaque, false);
-  case vmIntrinsics::_putDoubleOpaque:          return inline_unsafe_access(!is_native_ptr,  is_store, T_DOUBLE,   Opaque, false);
+  case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_store, T_OBJECT,   Relaxed, false);
+  case vmIntrinsics::_getBoolean:               return inline_unsafe_access(!is_store, T_BOOLEAN,  Relaxed, false);
+  case vmIntrinsics::_getByte:                  return inline_unsafe_access(!is_store, T_BYTE,     Relaxed, false);
+  case vmIntrinsics::_getShort:                 return inline_unsafe_access(!is_store, T_SHORT,    Relaxed, false);
+  case vmIntrinsics::_getChar:                  return inline_unsafe_access(!is_store, T_CHAR,     Relaxed, false);
+  case vmIntrinsics::_getInt:                   return inline_unsafe_access(!is_store, T_INT,      Relaxed, false);
+  case vmIntrinsics::_getLong:                  return inline_unsafe_access(!is_store, T_LONG,     Relaxed, false);
+  case vmIntrinsics::_getFloat:                 return inline_unsafe_access(!is_store, T_FLOAT,    Relaxed, false);
+  case vmIntrinsics::_getDouble:                return inline_unsafe_access(!is_store, T_DOUBLE,   Relaxed, false);
+
+  case vmIntrinsics::_putObject:                return inline_unsafe_access( is_store, T_OBJECT,   Relaxed, false);
+  case vmIntrinsics::_putBoolean:               return inline_unsafe_access( is_store, T_BOOLEAN,  Relaxed, false);
+  case vmIntrinsics::_putByte:                  return inline_unsafe_access( is_store, T_BYTE,     Relaxed, false);
+  case vmIntrinsics::_putShort:                 return inline_unsafe_access( is_store, T_SHORT,    Relaxed, false);
+  case vmIntrinsics::_putChar:                  return inline_unsafe_access( is_store, T_CHAR,     Relaxed, false);
+  case vmIntrinsics::_putInt:                   return inline_unsafe_access( is_store, T_INT,      Relaxed, false);
+  case vmIntrinsics::_putLong:                  return inline_unsafe_access( is_store, T_LONG,     Relaxed, false);
+  case vmIntrinsics::_putFloat:                 return inline_unsafe_access( is_store, T_FLOAT,    Relaxed, false);
+  case vmIntrinsics::_putDouble:                return inline_unsafe_access( is_store, T_DOUBLE,   Relaxed, false);
+
+  case vmIntrinsics::_getObjectVolatile:        return inline_unsafe_access(!is_store, T_OBJECT,   Volatile, false);
+  case vmIntrinsics::_getBooleanVolatile:       return inline_unsafe_access(!is_store, T_BOOLEAN,  Volatile, false);
+  case vmIntrinsics::_getByteVolatile:          return inline_unsafe_access(!is_store, T_BYTE,     Volatile, false);
+  case vmIntrinsics::_getShortVolatile:         return inline_unsafe_access(!is_store, T_SHORT,    Volatile, false);
+  case vmIntrinsics::_getCharVolatile:          return inline_unsafe_access(!is_store, T_CHAR,     Volatile, false);
+  case vmIntrinsics::_getIntVolatile:           return inline_unsafe_access(!is_store, T_INT,      Volatile, false);
+  case vmIntrinsics::_getLongVolatile:          return inline_unsafe_access(!is_store, T_LONG,     Volatile, false);
+  case vmIntrinsics::_getFloatVolatile:         return inline_unsafe_access(!is_store, T_FLOAT,    Volatile, false);
+  case vmIntrinsics::_getDoubleVolatile:        return inline_unsafe_access(!is_store, T_DOUBLE,   Volatile, false);
+
+  case vmIntrinsics::_putObjectVolatile:        return inline_unsafe_access( is_store, T_OBJECT,   Volatile, false);
+  case vmIntrinsics::_putBooleanVolatile:       return inline_unsafe_access( is_store, T_BOOLEAN,  Volatile, false);
+  case vmIntrinsics::_putByteVolatile:          return inline_unsafe_access( is_store, T_BYTE,     Volatile, false);
+  case vmIntrinsics::_putShortVolatile:         return inline_unsafe_access( is_store, T_SHORT,    Volatile, false);
+  case vmIntrinsics::_putCharVolatile:          return inline_unsafe_access( is_store, T_CHAR,     Volatile, false);
+  case vmIntrinsics::_putIntVolatile:           return inline_unsafe_access( is_store, T_INT,      Volatile, false);
+  case vmIntrinsics::_putLongVolatile:          return inline_unsafe_access( is_store, T_LONG,     Volatile, false);
+  case vmIntrinsics::_putFloatVolatile:         return inline_unsafe_access( is_store, T_FLOAT,    Volatile, false);
+  case vmIntrinsics::_putDoubleVolatile:        return inline_unsafe_access( is_store, T_DOUBLE,   Volatile, false);
+
+  case vmIntrinsics::_getShortUnaligned:        return inline_unsafe_access(!is_store, T_SHORT,    Relaxed, true);
+  case vmIntrinsics::_getCharUnaligned:         return inline_unsafe_access(!is_store, T_CHAR,     Relaxed, true);
+  case vmIntrinsics::_getIntUnaligned:          return inline_unsafe_access(!is_store, T_INT,      Relaxed, true);
+  case vmIntrinsics::_getLongUnaligned:         return inline_unsafe_access(!is_store, T_LONG,     Relaxed, true);
+
+  case vmIntrinsics::_putShortUnaligned:        return inline_unsafe_access( is_store, T_SHORT,    Relaxed, true);
+  case vmIntrinsics::_putCharUnaligned:         return inline_unsafe_access( is_store, T_CHAR,     Relaxed, true);
+  case vmIntrinsics::_putIntUnaligned:          return inline_unsafe_access( is_store, T_INT,      Relaxed, true);
+  case vmIntrinsics::_putLongUnaligned:         return inline_unsafe_access( is_store, T_LONG,     Relaxed, true);
+
+  case vmIntrinsics::_getObjectAcquire:         return inline_unsafe_access(!is_store, T_OBJECT,   Acquire, false);
+  case vmIntrinsics::_getBooleanAcquire:        return inline_unsafe_access(!is_store, T_BOOLEAN,  Acquire, false);
+  case vmIntrinsics::_getByteAcquire:           return inline_unsafe_access(!is_store, T_BYTE,     Acquire, false);
+  case vmIntrinsics::_getShortAcquire:          return inline_unsafe_access(!is_store, T_SHORT,    Acquire, false);
+  case vmIntrinsics::_getCharAcquire:           return inline_unsafe_access(!is_store, T_CHAR,     Acquire, false);
+  case vmIntrinsics::_getIntAcquire:            return inline_unsafe_access(!is_store, T_INT,      Acquire, false);
+  case vmIntrinsics::_getLongAcquire:           return inline_unsafe_access(!is_store, T_LONG,     Acquire, false);
+  case vmIntrinsics::_getFloatAcquire:          return inline_unsafe_access(!is_store, T_FLOAT,    Acquire, false);
+  case vmIntrinsics::_getDoubleAcquire:         return inline_unsafe_access(!is_store, T_DOUBLE,   Acquire, false);
+
+  case vmIntrinsics::_putObjectRelease:         return inline_unsafe_access( is_store, T_OBJECT,   Release, false);
+  case vmIntrinsics::_putBooleanRelease:        return inline_unsafe_access( is_store, T_BOOLEAN,  Release, false);
+  case vmIntrinsics::_putByteRelease:           return inline_unsafe_access( is_store, T_BYTE,     Release, false);
+  case vmIntrinsics::_putShortRelease:          return inline_unsafe_access( is_store, T_SHORT,    Release, false);
+  case vmIntrinsics::_putCharRelease:           return inline_unsafe_access( is_store, T_CHAR,     Release, false);
+  case vmIntrinsics::_putIntRelease:            return inline_unsafe_access( is_store, T_INT,      Release, false);
+  case vmIntrinsics::_putLongRelease:           return inline_unsafe_access( is_store, T_LONG,     Release, false);
+  case vmIntrinsics::_putFloatRelease:          return inline_unsafe_access( is_store, T_FLOAT,    Release, false);
+  case vmIntrinsics::_putDoubleRelease:         return inline_unsafe_access( is_store, T_DOUBLE,   Release, false);
+
+  case vmIntrinsics::_getObjectOpaque:          return inline_unsafe_access(!is_store, T_OBJECT,   Opaque, false);
+  case vmIntrinsics::_getBooleanOpaque:         return inline_unsafe_access(!is_store, T_BOOLEAN,  Opaque, false);
+  case vmIntrinsics::_getByteOpaque:            return inline_unsafe_access(!is_store, T_BYTE,     Opaque, false);
+  case vmIntrinsics::_getShortOpaque:           return inline_unsafe_access(!is_store, T_SHORT,    Opaque, false);
+  case vmIntrinsics::_getCharOpaque:            return inline_unsafe_access(!is_store, T_CHAR,     Opaque, false);
+  case vmIntrinsics::_getIntOpaque:             return inline_unsafe_access(!is_store, T_INT,      Opaque, false);
+  case vmIntrinsics::_getLongOpaque:            return inline_unsafe_access(!is_store, T_LONG,     Opaque, false);
+  case vmIntrinsics::_getFloatOpaque:           return inline_unsafe_access(!is_store, T_FLOAT,    Opaque, false);
+  case vmIntrinsics::_getDoubleOpaque:          return inline_unsafe_access(!is_store, T_DOUBLE,   Opaque, false);
+
+  case vmIntrinsics::_putObjectOpaque:          return inline_unsafe_access( is_store, T_OBJECT,   Opaque, false);
+  case vmIntrinsics::_putBooleanOpaque:         return inline_unsafe_access( is_store, T_BOOLEAN,  Opaque, false);
+  case vmIntrinsics::_putByteOpaque:            return inline_unsafe_access( is_store, T_BYTE,     Opaque, false);
+  case vmIntrinsics::_putShortOpaque:           return inline_unsafe_access( is_store, T_SHORT,    Opaque, false);
+  case vmIntrinsics::_putCharOpaque:            return inline_unsafe_access( is_store, T_CHAR,     Opaque, false);
+  case vmIntrinsics::_putIntOpaque:             return inline_unsafe_access( is_store, T_INT,      Opaque, false);
+  case vmIntrinsics::_putLongOpaque:            return inline_unsafe_access( is_store, T_LONG,     Opaque, false);
+  case vmIntrinsics::_putFloatOpaque:           return inline_unsafe_access( is_store, T_FLOAT,    Opaque, false);
+  case vmIntrinsics::_putDoubleOpaque:          return inline_unsafe_access( is_store, T_DOUBLE,   Opaque, false);
 
   case vmIntrinsics::_compareAndSwapObject:             return inline_unsafe_load_store(T_OBJECT, LS_cmp_swap,      Volatile);
   case vmIntrinsics::_compareAndSwapInt:                return inline_unsafe_load_store(T_INT,    LS_cmp_swap,      Volatile);
@@ -2196,8 +2177,6 @@
 
 //----------------------------inline_unsafe_access----------------------------
 
-const static BasicType T_ADDRESS_HOLDER = T_LONG;
-
 // Helper that guards and inserts a pre-barrier.
 void LibraryCallKit::insert_pre_barrier(Node* base_oop, Node* offset,
                                         Node* pre_val, bool need_mem_bar) {
@@ -2298,13 +2277,12 @@
 }
 
 
-const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr) {
+const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type) {
   // Attempt to infer a sharper value type from the offset and base type.
   ciKlass* sharpened_klass = NULL;
 
   // See if it is an instance field, with an object type.
   if (alias_type->field() != NULL) {
-    assert(!is_native_ptr, "native pointer op cannot use a java address");
     if (alias_type->field()->type()->is_klass()) {
       sharpened_klass = alias_type->field()->type()->as_klass();
     }
@@ -2337,7 +2315,7 @@
   return NULL;
 }
 
-bool LibraryCallKit::inline_unsafe_access(const bool is_native_ptr, bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) {
+bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) {
   if (callee()->is_static())  return false;  // caller must have the capability!
   guarantee(!is_store || kind != Acquire, "Acquire accesses can be produced only for loads");
   guarantee( is_store || kind != Release, "Release accesses can be produced only for stores");
@@ -2352,31 +2330,17 @@
     if (!is_store) {
       // Object getObject(Object base, int/long offset), etc.
       BasicType rtype = sig->return_type()->basic_type();
-      if (rtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::getAddress_name())
-          rtype = T_ADDRESS;  // it is really a C void*
       assert(rtype == type, "getter must return the expected value");
-      if (!is_native_ptr) {
-        assert(sig->count() == 2, "oop getter has 2 arguments");
-        assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object");
-        assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct");
-      } else {
-        assert(sig->count() == 1, "native getter has 1 argument");
-        assert(sig->type_at(0)->basic_type() == T_LONG, "getter base is long");
-      }
+      assert(sig->count() == 2, "oop getter has 2 arguments");
+      assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object");
+      assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct");
     } else {
       // void putObject(Object base, int/long offset, Object x), etc.
       assert(sig->return_type()->basic_type() == T_VOID, "putter must not return a value");
-      if (!is_native_ptr) {
-        assert(sig->count() == 3, "oop putter has 3 arguments");
-        assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object");
-        assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct");
-      } else {
-        assert(sig->count() == 2, "native putter has 2 arguments");
-        assert(sig->type_at(0)->basic_type() == T_LONG, "putter base is long");
-      }
+      assert(sig->count() == 3, "oop putter has 3 arguments");
+      assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object");
+      assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct");
       BasicType vtype = sig->type_at(sig->count()-1)->basic_type();
-      if (vtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::putAddress_name())
-        vtype = T_ADDRESS;  // it is really a C void*
       assert(vtype == type, "putter must accept the expected value");
     }
 #endif // ASSERT
@@ -2393,27 +2357,22 @@
   Node* offset = top();
   Node* val;
 
-  if (!is_native_ptr) {
-    // The base is either a Java object or a value produced by Unsafe.staticFieldBase
-    Node* base = argument(1);  // type: oop
-    // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset
-    offset = argument(2);  // type: long
-    // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
-    // to be plain byte offsets, which are also the same as those accepted
-    // by oopDesc::field_base.
-    assert(Unsafe_field_offset_to_byte_offset(11) == 11,
-           "fieldOffset must be byte-scaled");
-    // 32-bit machines ignore the high half!
-    offset = ConvL2X(offset);
-    adr = make_unsafe_address(base, offset);
+  // The base is either a Java object or a value produced by Unsafe.staticFieldBase
+  Node* base = argument(1);  // type: oop
+  // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset
+  offset = argument(2);  // type: long
+  // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
+  // to be plain byte offsets, which are also the same as those accepted
+  // by oopDesc::field_base.
+  assert(Unsafe_field_offset_to_byte_offset(11) == 11,
+         "fieldOffset must be byte-scaled");
+  // 32-bit machines ignore the high half!
+  offset = ConvL2X(offset);
+  adr = make_unsafe_address(base, offset);
+  if (_gvn.type(base)->isa_ptr() != TypePtr::NULL_PTR) {
     heap_base_oop = base;
-    val = is_store ? argument(4) : NULL;
-  } else {
-    Node* ptr = argument(1);  // type: long
-    ptr = ConvL2X(ptr);  // adjust Java long to machine word
-    adr = make_unsafe_address(NULL, ptr);
-    val = is_store ? argument(3) : NULL;
-  }
+  }
+  val = is_store ? argument(4) : NULL;
 
   const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
 
@@ -2494,11 +2453,11 @@
   // SATB log buffer using the pre-barrier mechanism.
   // Also we need to add memory barrier to prevent commoning reads
   // from this field across safepoint since GC can change its value.
-  bool need_read_barrier = !is_native_ptr && !is_store &&
+  bool need_read_barrier = !is_store &&
                            offset != top() && heap_base_oop != top();
 
   if (!is_store && type == T_OBJECT) {
-    const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type, is_native_ptr);
+    const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type);
     if (tjp != NULL) {
       value_type = tjp;
     }
--- a/src/share/vm/prims/stackwalk.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/prims/stackwalk.cpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 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
@@ -37,44 +37,44 @@
 #include "utilities/globalDefinitions.hpp"
 
 // setup and cleanup actions
-void StackWalkAnchor::setup_magic_on_entry(objArrayHandle frames_array) {
+void JavaFrameStream::setup_magic_on_entry(objArrayHandle frames_array) {
   frames_array->obj_at_put(magic_pos, _thread->threadObj());
   _anchor = address_value();
   assert(check_magic(frames_array), "invalid magic");
 }
 
-bool StackWalkAnchor::check_magic(objArrayHandle frames_array) {
+bool JavaFrameStream::check_magic(objArrayHandle frames_array) {
   oop   m1 = frames_array->obj_at(magic_pos);
   jlong m2 = _anchor;
   if (m1 == _thread->threadObj() && m2 == address_value())  return true;
   return false;
 }
 
-bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle frames_array) {
+bool JavaFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) {
   bool ok = check_magic(frames_array);
   frames_array->obj_at_put(magic_pos, NULL);
   _anchor = 0L;
   return ok;
 }
 
-// Returns StackWalkAnchor for the current stack being traversed.
+// Returns JavaFrameStream for the current stack being traversed.
 //
 // Parameters:
 //  thread         Current Java thread.
 //  magic          Magic value used for each stack walking
 //  frames_array   User-supplied buffers.  The 0th element is reserved
-//                 to this StackWalkAnchor to use
+//                 to this JavaFrameStream to use
 //
-StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
+JavaFrameStream* JavaFrameStream::from_current(JavaThread* thread, jlong magic,
                                                objArrayHandle frames_array)
 {
   assert(thread != NULL && thread->is_Java_thread(), "");
   oop m1 = frames_array->obj_at(magic_pos);
   if (m1 != thread->threadObj())      return NULL;
   if (magic == 0L)                    return NULL;
-  StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
-  if (!anchor->is_valid_in(thread, frames_array))   return NULL;
-  return anchor;
+  JavaFrameStream* stream = (JavaFrameStream*) (intptr_t) magic;
+  if (!stream->is_valid_in(thread, frames_array))   return NULL;
+  return stream;
 }
 
 // Unpacks one or more frames into user-supplied buffers.
@@ -84,19 +84,19 @@
 // In other words, do not leave any stale data in the vfst.
 //
 // Parameters:
-//   mode           Restrict which frames to be decoded.
-//   vfst           vFrameStream.
-//   max_nframes    Maximum number of frames to be filled.
-//   start_index    Start index to the user-supplied buffers.
-//   frames_array   Buffer to store Class or StackFrame in, starting at start_index.
-//                  frames array is a Class<?>[] array when only getting caller
-//                  reference, and a StackFrameInfo[] array (or derivative)
-//                  otherwise. It should never be null.
-//   end_index      End index to the user-supplied buffers with unpacked frames.
+//   mode             Restrict which frames to be decoded.
+//   JavaFrameStream  stream of javaVFrames
+//   max_nframes      Maximum number of frames to be filled.
+//   start_index      Start index to the user-supplied buffers.
+//   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
+//                    frames array is a Class<?>[] array when only getting caller
+//                    reference, and a StackFrameInfo[] array (or derivative)
+//                    otherwise. It should never be null.
+//   end_index        End index to the user-supplied buffers with unpacked frames.
 //
 // Returns the number of frames whose information was transferred into the buffers.
 //
-int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
+int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream,
                               int max_nframes, int start_index,
                               objArrayHandle  frames_array,
                               int& end_index, TRAPS) {
@@ -108,9 +108,9 @@
   assert(start_index + max_nframes <= frames_array->length(), "oob");
 
   int frames_decoded = 0;
-  for (; !vfst.at_end(); vfst.next()) {
-    Method* method = vfst.method();
-    int bci = vfst.bci();
+  for (; !stream.at_end(); stream.next()) {
+    Method* method = stream.method();
+    int bci = stream.bci();
 
     if (method == NULL) continue;
     if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) {
@@ -133,7 +133,7 @@
     if (live_frame_info(mode)) {
       assert (use_frames_array(mode), "Bad mode for get live frame");
       Handle stackFrame(frames_array->obj_at(index));
-      fill_live_stackframe(stackFrame, method, bci, vfst.java_frame(), CHECK_0);
+      fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0);
     } else if (need_method_info(mode)) {
       assert (use_frames_array(mode), "Bad mode for get stack frame");
       Handle stackFrame(frames_array->obj_at(index));
@@ -294,6 +294,7 @@
                     int skip_frames, int frame_count, int start_index,
                     objArrayHandle frames_array,
                     TRAPS) {
+  ResourceMark rm(THREAD);
   JavaThread* jt = (JavaThread*)THREAD;
   if (TraceStackWalk) {
     tty->print_cr("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
@@ -309,41 +310,39 @@
 
   methodHandle m_doStackWalk(THREAD, Universe::do_stack_walk_method());
 
-  // Open up a traversable stream onto my stack.
-  // This stream will be made available by *reference* to the inner Java call.
-  StackWalkAnchor anchor(jt);
-  vframeStream& vfst = anchor.vframe_stream();
-
+  // Setup traversal onto my stack.
+  RegisterMap regMap(jt, true);
+  JavaFrameStream stream(jt, &regMap);
   {
-    while (!vfst.at_end()) {
-      InstanceKlass* ik = vfst.method()->method_holder();
+    while (!stream.at_end()) {
+      InstanceKlass* ik = stream.method()->method_holder();
       if (ik != stackWalker_klass &&
             ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass)  {
         break;
       }
 
       if (TraceStackWalk) {
-        tty->print("  skip "); vfst.method()->print_short_name(); tty->print("\n");
+        tty->print("  skip "); stream.method()->print_short_name(); tty->print("\n");
       }
-      vfst.next();
+      stream.next();
     }
 
     // stack frame has been traversed individually and resume stack walk
     // from the stack frame at depth == skip_frames.
-    for (int n=0; n < skip_frames && !vfst.at_end(); vfst.next(), n++) {
+    for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) {
       if (TraceStackWalk) {
-        tty->print("  skip "); vfst.method()->print_short_name();
+        tty->print("  skip "); stream.method()->print_short_name();
         tty->print_cr(" frame id: " PTR_FORMAT " pc: " PTR_FORMAT,
-                      p2i(vfst.frame_id()), p2i(vfst.frame_pc()));
+                      p2i(stream.java_frame()->fr().id()),
+                      p2i(stream.java_frame()->fr().pc()));
       }
     }
   }
 
-  // The Method* pointer in the vfst has a very short shelf life.  Grab it now.
   int end_index = start_index;
   int numFrames = 0;
-  if (!vfst.at_end()) {
-    numFrames = fill_in_frames(mode, vfst, frame_count, start_index,
+  if (!stream.at_end()) {
+    numFrames = fill_in_frames(mode, stream, frame_count, start_index,
                                frames_array, end_index, CHECK_NULL);
     if (numFrames < 1) {
       THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
@@ -356,19 +355,19 @@
   // When JVM_CallStackWalk returns, it invalidates the stack stream.
   JavaValue result(T_OBJECT);
   JavaCallArguments args(stackStream);
-  args.push_long(anchor.address_value());
+  args.push_long(stream.address_value());
   args.push_int(skip_frames);
   args.push_int(frame_count);
   args.push_int(start_index);
   args.push_int(end_index);
 
   // Link the thread and vframe stream into the callee-visible object
-  anchor.setup_magic_on_entry(frames_array);
+  stream.setup_magic_on_entry(frames_array);
 
   JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
 
   // Do this before anything else happens, to disable any lingering stream objects
-  bool ok = anchor.cleanup_magic_on_exit(frames_array);
+  bool ok = stream.cleanup_magic_on_exit(frames_array);
 
   // Throw pending exception if we must
   (void) (CHECK_NULL);
@@ -379,7 +378,6 @@
 
   // Return normally
   return (oop)result.get_jobject();
-
 }
 
 // Walk the next batch of stack frames
@@ -400,8 +398,8 @@
                            TRAPS)
 {
   JavaThread* jt = (JavaThread*)THREAD;
-  StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, frames_array);
-  if (existing_anchor == NULL) {
+  JavaFrameStream* existing_stream = JavaFrameStream::from_current(jt, magic, frames_array);
+  if (existing_stream == NULL) {
     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
   }
 
@@ -410,8 +408,8 @@
   }
 
   if (TraceStackWalk) {
-    tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
-                  frame_count, p2i(existing_anchor), start_index, frames_array->length());
+    tty->print_cr("StackWalk::moreFrames frame_count %d existing_stream " PTR_FORMAT " start %d frames %d",
+                  frame_count, p2i(existing_stream), start_index, frames_array->length());
   }
   int end_index = start_index;
   if (frame_count <= 0) {
@@ -421,12 +419,11 @@
   int count = frame_count + start_index;
   assert (frames_array->length() >= count, "not enough space in buffers");
 
-  StackWalkAnchor& anchor = (*existing_anchor);
-  vframeStream& vfst = anchor.vframe_stream();
-  if (!vfst.at_end()) {
-    vfst.next();  // this was the last frame decoded in the previous batch
-    if (!vfst.at_end()) {
-      int n = fill_in_frames(mode, vfst, frame_count, start_index,
+  JavaFrameStream& stream = (*existing_stream);
+  if (!stream.at_end()) {
+    stream.next(); // advance past the last frame decoded in previous batch
+    if (!stream.at_end()) {
+      int n = fill_in_frames(mode, stream, frame_count, start_index,
                              frames_array, end_index, CHECK_0);
       if (n < 1) {
         THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
--- a/src/share/vm/prims/stackwalk.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/prims/stackwalk.hpp	Mon May 09 13:13:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 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
@@ -29,21 +29,31 @@
 #include "oops/oop.hpp"
 #include "runtime/vframe.hpp"
 
-class StackWalkAnchor : public StackObj {
+//
+// JavaFrameStream is used by StackWalker to iterate through Java stack frames
+// on the given JavaThread.
+//
+class JavaFrameStream : public StackObj {
 private:
   enum {
     magic_pos = 0
   };
 
   JavaThread*           _thread;
-  vframeStream          _vfst;
+  javaVFrame*           _jvf;
   jlong                 _anchor;
 public:
-  StackWalkAnchor(JavaThread* thread)
-    : _thread(thread), _vfst(thread), _anchor(0L) {}
+  JavaFrameStream(JavaThread* thread, RegisterMap* rm)
+    : _thread(thread), _anchor(0L) {
+    _jvf = _thread->last_java_vframe(rm);
+  }
 
-  vframeStream&   vframe_stream()         { return _vfst; }
-  JavaThread*     thread()                { return _thread; }
+  javaVFrame*     java_frame()        { return _jvf; }
+  void            next()              { _jvf = _jvf->java_sender(); }
+  bool            at_end()            { return _jvf == NULL; }
+
+  Method* method()                    { return _jvf->method(); }
+  int bci()                           { return _jvf->bci(); }
 
   void setup_magic_on_entry(objArrayHandle frames_array);
   bool check_magic(objArrayHandle frames_array);
@@ -57,12 +67,12 @@
     return (jlong) castable_address(this);
   }
 
-  static StackWalkAnchor* from_current(JavaThread* thread, jlong anchor, objArrayHandle frames_array);
+  static JavaFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array);
 };
 
 class StackWalk : public AllStatic {
 private:
-  static int fill_in_frames(jlong mode, vframeStream& vfst,
+  static int fill_in_frames(jlong mode, JavaFrameStream& stream,
                             int max_nframes, int start_index,
                             objArrayHandle frames_array,
                             int& end_index, TRAPS);
--- a/src/share/vm/prims/unsafe.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/prims/unsafe.cpp	Mon May 09 13:13:07 2016 +0300
@@ -131,38 +131,137 @@
 }
 
 
-///// Data in the Java heap.
+///// Data read/writes on the Java heap and in native (off-heap) memory
 
-#define truncate_jboolean(x) ((x) & 1)
-#define truncate_jbyte(x) (x)
-#define truncate_jshort(x) (x)
-#define truncate_jchar(x) (x)
-#define truncate_jint(x) (x)
-#define truncate_jlong(x) (x)
-#define truncate_jfloat(x) (x)
-#define truncate_jdouble(x) (x)
+/**
+ * Helper class for accessing memory.
+ *
+ * Normalizes values and wraps accesses in
+ * JavaThread::doing_unsafe_access() if needed.
+ */
+class MemoryAccess : StackObj {
+  JavaThread* _thread;
+  jobject _obj;
+  jlong _offset;
 
-#define GET_FIELD(obj, offset, type_name, v) \
-  oop p = JNIHandles::resolve(obj); \
-  type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
+  // Resolves and returns the address of the memory access
+  void* addr() {
+    return index_oop_from_field_offset_long(JNIHandles::resolve(_obj), _offset);
+  }
 
-#define SET_FIELD(obj, offset, type_name, x) \
-  oop p = JNIHandles::resolve(obj); \
-  *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x)
+  template <typename T>
+  T normalize(T x) {
+    return x;
+  }
 
-#define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
-  oop p = JNIHandles::resolve(obj); \
-  if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \
-    OrderAccess::fence(); \
-  } \
-  volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
+  jboolean normalize(jboolean x) {
+    return x & 1;
+  }
 
-#define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
-  oop p = JNIHandles::resolve(obj); \
-  OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
+  /**
+   * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
+   */
+  class GuardUnsafeAccess {
+    JavaThread* _thread;
+    bool _active;
 
+  public:
+    GuardUnsafeAccess(JavaThread* thread, jobject _obj) : _thread(thread) {
+      if (JNIHandles::resolve(_obj) == NULL) {
+        // native/off-heap access which may raise SIGBUS if accessing
+        // memory mapped file data in a region of the file which has
+        // been truncated and is now invalid
+        _thread->set_doing_unsafe_access(true);
+        _active = true;
+      } else {
+        _active = false;
+      }
+    }
 
-// Get/SetObject must be special-cased, since it works with handles.
+    ~GuardUnsafeAccess() {
+      if (_active) {
+        _thread->set_doing_unsafe_access(false);
+      }
+    }
+  };
+
+public:
+  MemoryAccess(JavaThread* thread, jobject obj, jlong offset)
+    : _thread(thread), _obj(obj), _offset(offset) {
+  }
+
+  template <typename T>
+  T get() {
+    GuardUnsafeAccess guard(_thread, _obj);
+
+    T* p = (T*)addr();
+
+    T x = *p;
+
+    return x;
+  }
+
+  template <typename T>
+  void put(T x) {
+    GuardUnsafeAccess guard(_thread, _obj);
+
+    T* p = (T*)addr();
+
+    *p = normalize(x);
+  }
+
+
+  template <typename T>
+  T get_volatile() {
+    GuardUnsafeAccess guard(_thread, _obj);
+
+    T* p = (T*)addr();
+
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      OrderAccess::fence();
+    }
+
+    T x = OrderAccess::load_acquire((volatile T*)p);
+
+    return x;
+  }
+
+  template <typename T>
+  void put_volatile(T x) {
+    GuardUnsafeAccess guard(_thread, _obj);
+
+    T* p = (T*)addr();
+
+    OrderAccess::release_store_fence((volatile T*)p, normalize(x));
+  }
+
+
+#ifndef SUPPORTS_NATIVE_CX8
+  jlong get_jlong_locked() {
+    GuardUnsafeAccess guard(_thread, _obj);
+
+    MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+
+    jlong* p = (jlong*)addr();
+
+    jlong x = Atomic::load(p);
+
+    return x;
+  }
+
+  void put_jlong_locked(jlong x) {
+    GuardUnsafeAccess guard(_thread, _obj);
+
+    MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+
+    jlong* p = (jlong*)addr();
+
+    Atomic::store(normalize(x),  p);
+  }
+#endif
+};
+
+// Get/PutObject must be special-cased, since it works with handles.
 
 // These functions allow a null base pointer with an arbitrary address.
 // But if the base pointer is non-null, the offset should make some sense.
@@ -208,7 +307,7 @@
   return ret;
 } UNSAFE_END
 
-UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
+UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
 
@@ -236,7 +335,7 @@
   return JNIHandles::make_local(env, v);
 } UNSAFE_END
 
-UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
+UNSAFE_ENTRY(void, Unsafe_PutObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
   void* addr = index_oop_from_field_offset_long(p, offset);
@@ -301,25 +400,17 @@
 
 UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
   if (VM_Version::supports_cx8()) {
-    GET_FIELD_VOLATILE(obj, offset, jlong, v);
-    return v;
+    return MemoryAccess(thread, obj, offset).get_volatile<jlong>();
   } else {
-    Handle p (THREAD, JNIHandles::resolve(obj));
-    jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
-    MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
-    jlong value = Atomic::load(addr);
-    return value;
+    return MemoryAccess(thread, obj, offset).get_jlong_locked();
   }
 } UNSAFE_END
 
-UNSAFE_ENTRY(void, Unsafe_SetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) {
+UNSAFE_ENTRY(void, Unsafe_PutLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) {
   if (VM_Version::supports_cx8()) {
-    SET_FIELD_VOLATILE(obj, offset, jlong, x);
+    MemoryAccess(thread, obj, offset).put_volatile<jlong>(x);
   } else {
-    Handle p (THREAD, JNIHandles::resolve(obj));
-    jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
-    MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
-    Atomic::store(x, addr);
+    MemoryAccess(thread, obj, offset).put_jlong_locked(x);
   }
 } UNSAFE_END
 
@@ -337,15 +428,14 @@
   return UseUnalignedAccesses;
 } UNSAFE_END
 
-#define DEFINE_GETSETOOP(java_type, Type)        \
+#define DEFINE_GETSETOOP(java_type, Type) \
  \
 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
-  GET_FIELD(obj, offset, java_type, v); \
-  return v; \
+  return MemoryAccess(thread, obj, offset).get<java_type>(); \
 } UNSAFE_END \
  \
-UNSAFE_ENTRY(void, Unsafe_Set##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
-  SET_FIELD(obj, offset, java_type, x); \
+UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
+  MemoryAccess(thread, obj, offset).put<java_type>(x); \
 } UNSAFE_END \
  \
 // END DEFINE_GETSETOOP.
@@ -364,12 +454,11 @@
 #define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \
  \
 UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
-  GET_FIELD_VOLATILE(obj, offset, java_type, v); \
-  return v; \
+  return MemoryAccess(thread, obj, offset).get_volatile<java_type>(); \
 } UNSAFE_END \
  \
-UNSAFE_ENTRY(void, Unsafe_Set##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
-  SET_FIELD_VOLATILE(obj, offset, java_type, x); \
+UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
+  MemoryAccess(thread, obj, offset).put_volatile<java_type>(x); \
 } UNSAFE_END \
  \
 // END DEFINE_GETSETOOP_VOLATILE.
@@ -400,98 +489,6 @@
   OrderAccess::fence();
 } UNSAFE_END
 
-////// Data in the C heap.
-
-// Note:  These do not throw NullPointerException for bad pointers.
-// They just crash.  Only a oop base pointer can generate a NullPointerException.
-//
-#define DEFINE_GETSETNATIVE(java_type, Type, native_type) \
- \
-UNSAFE_ENTRY(java_type, Unsafe_GetNative##Type(JNIEnv *env, jobject unsafe, jlong addr)) { \
-  void* p = addr_from_java(addr); \
-  JavaThread* t = JavaThread::current(); \
-  t->set_doing_unsafe_access(true); \
-  java_type x = *(volatile native_type*)p; \
-  t->set_doing_unsafe_access(false); \
-  return x; \
-} UNSAFE_END \
- \
-UNSAFE_ENTRY(void, Unsafe_SetNative##Type(JNIEnv *env, jobject unsafe, jlong addr, java_type x)) { \
-  JavaThread* t = JavaThread::current(); \
-  t->set_doing_unsafe_access(true); \
-  void* p = addr_from_java(addr); \
-  *(volatile native_type*)p = x; \
-  t->set_doing_unsafe_access(false); \
-} UNSAFE_END \
- \
-// END DEFINE_GETSETNATIVE.
-
-DEFINE_GETSETNATIVE(jbyte, Byte, signed char)
-DEFINE_GETSETNATIVE(jshort, Short, signed short);
-DEFINE_GETSETNATIVE(jchar, Char, unsigned short);
-DEFINE_GETSETNATIVE(jint, Int, jint);
-// no long -- handled specially
-DEFINE_GETSETNATIVE(jfloat, Float, float);
-DEFINE_GETSETNATIVE(jdouble, Double, double);
-
-#undef DEFINE_GETSETNATIVE
-
-UNSAFE_ENTRY(jlong, Unsafe_GetNativeLong(JNIEnv *env, jobject unsafe, jlong addr)) {
-  JavaThread* t = JavaThread::current();
-  // We do it this way to avoid problems with access to heap using 64
-  // bit loads, as jlong in heap could be not 64-bit aligned, and on
-  // some CPUs (SPARC) it leads to SIGBUS.
-  t->set_doing_unsafe_access(true);
-  void* p = addr_from_java(addr);
-  jlong x;
-
-  if (is_ptr_aligned(p, sizeof(jlong)) == 0) {
-    // jlong is aligned, do a volatile access
-    x = *(volatile jlong*)p;
-  } else {
-    jlong_accessor acc;
-    acc.words[0] = ((volatile jint*)p)[0];
-    acc.words[1] = ((volatile jint*)p)[1];
-    x = acc.long_value;
-  }
-
-  t->set_doing_unsafe_access(false);
-
-  return x;
-} UNSAFE_END
-
-UNSAFE_ENTRY(void, Unsafe_SetNativeLong(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) {
-  JavaThread* t = JavaThread::current();
-  // see comment for Unsafe_GetNativeLong
-  t->set_doing_unsafe_access(true);
-  void* p = addr_from_java(addr);
-
-  if (is_ptr_aligned(p, sizeof(jlong))) {
-    // jlong is aligned, do a volatile access
-    *(volatile jlong*)p = x;
-  } else {
-    jlong_accessor acc;
-    acc.long_value = x;
-    ((volatile jint*)p)[0] = acc.words[0];
-    ((volatile jint*)p)[1] = acc.words[1];
-  }
-
-  t->set_doing_unsafe_access(false);
-} UNSAFE_END
-
-
-UNSAFE_LEAF(jlong, Unsafe_GetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr)) {
-  void* p = addr_from_java(addr);
-
-  return addr_to_java(*(void**)p);
-} UNSAFE_END
-
-UNSAFE_LEAF(void, Unsafe_SetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) {
-  void* p = addr_from_java(addr);
-  *(void**)p = addr_from_java(x);
-} UNSAFE_END
-
-
 ////// Allocation requests
 
 UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) {
@@ -980,8 +977,8 @@
 } UNSAFE_END
 
 UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
-  Handle p (THREAD, JNIHandles::resolve(obj));
-  jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
+  Handle p(THREAD, JNIHandles::resolve(obj));
+  jlong* addr = (jlong*)index_oop_from_field_offset_long(p(), offset);
 
 #ifdef SUPPORTS_NATIVE_CX8
   return (jlong)(Atomic::cmpxchg(x, addr, e));
@@ -1017,7 +1014,7 @@
 
 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
   oop p = JNIHandles::resolve(obj);
-  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
+  jint* addr = (jint *)index_oop_from_field_offset_long(p, offset);
 
   return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
 } UNSAFE_END
@@ -1143,20 +1140,16 @@
 
 #define DECLARE_GETPUTOOP(Type, Desc) \
     {CC "get" #Type,      CC "(" OBJ "J)" #Desc,       FN_PTR(Unsafe_Get##Type)}, \
-    {CC "put" #Type,      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Set##Type)}, \
+    {CC "put" #Type,      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Put##Type)}, \
     {CC "get" #Type "Volatile",      CC "(" OBJ "J)" #Desc,       FN_PTR(Unsafe_Get##Type##Volatile)}, \
-    {CC "put" #Type "Volatile",      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Set##Type##Volatile)}
+    {CC "put" #Type "Volatile",      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Put##Type##Volatile)}
 
 
-#define DECLARE_GETPUTNATIVE(Byte, B) \
-    {CC "get" #Byte,         CC "(" ADR ")" #B,       FN_PTR(Unsafe_GetNative##Byte)}, \
-    {CC "put" #Byte,         CC "(" ADR#B ")V",       FN_PTR(Unsafe_SetNative##Byte)}
-
 static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
     {CC "getObject",        CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObject)},
-    {CC "putObject",        CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_SetObject)},
+    {CC "putObject",        CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_PutObject)},
     {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObjectVolatile)},
-    {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
+    {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_PutObjectVolatile)},
 
     {CC "getUncompressedObject", CC "(" ADR ")" OBJ,  FN_PTR(Unsafe_GetUncompressedObject)},
     {CC "getJavaMirror",         CC "(" ADR ")" CLS,  FN_PTR(Unsafe_GetJavaMirror)},
@@ -1171,17 +1164,6 @@
     DECLARE_GETPUTOOP(Float, F),
     DECLARE_GETPUTOOP(Double, D),
 
-    DECLARE_GETPUTNATIVE(Byte, B),
-    DECLARE_GETPUTNATIVE(Short, S),
-    DECLARE_GETPUTNATIVE(Char, C),
-    DECLARE_GETPUTNATIVE(Int, I),
-    DECLARE_GETPUTNATIVE(Long, J),
-    DECLARE_GETPUTNATIVE(Float, F),
-    DECLARE_GETPUTNATIVE(Double, D),
-
-    {CC "getAddress",         CC "(" ADR ")" ADR,        FN_PTR(Unsafe_GetNativeAddress)},
-    {CC "putAddress",         CC "(" ADR "" ADR ")V",    FN_PTR(Unsafe_SetNativeAddress)},
-
     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
@@ -1239,7 +1221,6 @@
 #undef DAC_Args
 
 #undef DECLARE_GETPUTOOP
-#undef DECLARE_GETPUTNATIVE
 
 
 // This function is exported, used by NativeLookup.
--- a/src/share/vm/runtime/sharedRuntime.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Mon May 09 13:13:07 2016 +0300
@@ -1762,6 +1762,21 @@
   return callee_method;
 }
 
+address SharedRuntime::handle_unsafe_access(JavaThread* thread, address next_pc) {
+  // The faulting unsafe accesses should be changed to throw the error
+  // synchronously instead. Meanwhile the faulting instruction will be
+  // skipped over (effectively turning it into a no-op) and an
+  // asynchronous exception will be raised which the thread will
+  // handle at a later point. If the instruction is a load it will
+  // return garbage.
+
+  // Request an async exception.
+  thread->set_pending_unsafe_access_error();
+
+  // Return address of next instruction to execute.
+  return next_pc;
+}
+
 #ifdef ASSERT
 void SharedRuntime::check_member_name_argument_is_last_argument(const methodHandle& method,
                                                                 const BasicType* sig_bt,
--- a/src/share/vm/runtime/sharedRuntime.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Mon May 09 13:13:07 2016 +0300
@@ -522,6 +522,8 @@
   static address handle_wrong_method_abstract(JavaThread* thread);
   static address handle_wrong_method_ic_miss(JavaThread* thread);
 
+  static address handle_unsafe_access(JavaThread* thread, address next_pc);
+
 #ifndef PRODUCT
 
   // Collect and print inline cache miss statistics
--- a/src/share/vm/runtime/stubRoutines.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/runtime/stubRoutines.cpp	Mon May 09 13:13:07 2016 +0300
@@ -55,7 +55,6 @@
 address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
 address StubRoutines::_throw_StackOverflowError_entry           = NULL;
 address StubRoutines::_throw_delayed_StackOverflowError_entry   = NULL;
-address StubRoutines::_handler_for_unsafe_access_entry          = NULL;
 jint    StubRoutines::_verify_oop_count                         = 0;
 address StubRoutines::_verify_oop_subroutine_entry              = NULL;
 address StubRoutines::_atomic_xchg_entry                        = NULL;
--- a/src/share/vm/runtime/stubRoutines.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/runtime/stubRoutines.hpp	Mon May 09 13:13:07 2016 +0300
@@ -111,7 +111,6 @@
   static address _throw_NullPointerException_at_call_entry;
   static address _throw_StackOverflowError_entry;
   static address _throw_delayed_StackOverflowError_entry;
-  static address _handler_for_unsafe_access_entry;
 
   static address _atomic_xchg_entry;
   static address _atomic_xchg_ptr_entry;
@@ -288,10 +287,6 @@
   static address throw_StackOverflowError_entry()          { return _throw_StackOverflowError_entry; }
   static address throw_delayed_StackOverflowError_entry()  { return _throw_delayed_StackOverflowError_entry; }
 
-  // Exceptions during unsafe access - should throw Java exception rather
-  // than crash.
-  static address handler_for_unsafe_access()               { return _handler_for_unsafe_access_entry; }
-
   static address atomic_xchg_entry()                       { return _atomic_xchg_entry; }
   static address atomic_xchg_ptr_entry()                   { return _atomic_xchg_ptr_entry; }
   static address atomic_store_entry()                      { return _atomic_store_entry; }
--- a/src/share/vm/runtime/vframe.hpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/runtime/vframe.hpp	Mon May 09 13:13:07 2016 +0300
@@ -317,14 +317,6 @@
   intptr_t* frame_id() const { return _frame.id(); }
   address frame_pc() const { return _frame.pc(); }
 
-  javaVFrame* java_frame() {
-    vframe* vf = vframe::new_vframe(&_frame, &_reg_map, _thread);
-    if (vf->is_java_frame()) {
-      return (javaVFrame*)vf;
-    }
-    return NULL;
-  }
-
   CodeBlob*          cb()         const { return _frame.cb();  }
   CompiledMethod*   nm()         const {
       assert( cb() != NULL && cb()->is_compiled(), "usage");
--- a/src/share/vm/utilities/vmError.cpp	Fri May 06 19:45:22 2016 +0300
+++ b/src/share/vm/utilities/vmError.cpp	Mon May 09 13:13:07 2016 +0300
@@ -290,8 +290,8 @@
 
 void VMError::report(outputStream* st, bool _verbose) {
 
-# define BEGIN if (_current_step == 0) { _current_step = 1;
-# define STEP(n, s) } if (_current_step < n) { _current_step = n; _current_step_info = s;
+# define BEGIN if (_current_step == 0) { _current_step = __LINE__;
+# define STEP(s) } if (_current_step < __LINE__) { _current_step = __LINE__; _current_step_info = s;
 # define END }
 
   // don't allocate large buffer on stack
@@ -299,7 +299,7 @@
 
   BEGIN
 
-  STEP(10, "(printing fatal error message)")
+  STEP("printing fatal error message")
 
     st->print_cr("#");
     if (should_report_bug(_id)) {
@@ -314,21 +314,21 @@
 
   // test secondary error handling. Test it twice, to test that resetting
   // error handler after a secondary crash works.
-  STEP(20, "(test secondary crash 1)")
+  STEP("test secondary crash 1")
     if (_verbose && TestCrashInErrorHandler != 0) {
       st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
         TestCrashInErrorHandler);
       controlled_crash(TestCrashInErrorHandler);
     }
 
-  STEP(30, "(test secondary crash 2)")
+  STEP("test secondary crash 2")
     if (_verbose && TestCrashInErrorHandler != 0) {
       st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
         TestCrashInErrorHandler);
       controlled_crash(TestCrashInErrorHandler);
     }
 
-  STEP(40, "(test safefetch in error handler)")
+  STEP("test safefetch in error handler")
     // test whether it is safe to use SafeFetch32 in Crash Handler. Test twice
     // to test that resetting the signal handler works correctly.
     if (_verbose && TestSafeFetchInErrorHandler) {
@@ -349,7 +349,7 @@
     }
 #endif // PRODUCT
 
-  STEP(50, "(printing type of error)")
+  STEP("printing type of error")
 
      switch(_id) {
        case OOM_MALLOC_ERROR:
@@ -384,7 +384,7 @@
          break;
      }
 
-  STEP(60, "(printing exception/signal name)")
+  STEP("printing exception/signal name")
 
      st->print_cr("#");
      st->print("#  ");
@@ -414,14 +414,14 @@
        }
      }
 
-  STEP(70, "(printing current thread and pid)")
+  STEP("printing current thread and pid")
 
      // process id, thread id
      st->print(", pid=%d", os::current_process_id());
      st->print(", tid=" UINTX_FORMAT, os::current_thread_id());
      st->cr();
 
-  STEP(80, "(printing error message)")
+  STEP("printing error message")
 
      if (should_report_bug(_id)) {  // already printed the message.
        // error message
@@ -432,11 +432,11 @@
        }
      }
 
-  STEP(90, "(printing Java version string)")
+  STEP("printing Java version string")
 
      report_vm_version(st, buf, sizeof(buf));
 
-  STEP(100, "(printing problematic frame)")
+  STEP("printing problematic frame")
 
      // Print current frame if we have a context (i.e. it's a crash)
      if (_context) {
@@ -448,7 +448,7 @@
        st->print_cr("#");
      }
 
-  STEP(110, "(printing core file information)")
+  STEP("printing core file information")
     st->print("# ");
     if (CreateCoredumpOnCrash) {
       if (coredump_status) {
@@ -462,13 +462,13 @@
     st->cr();
     st->print_cr("#");
 
-  STEP(120, "(printing bug submit message)")
+  STEP("printing bug submit message")
 
      if (should_report_bug(_id) && _verbose) {
        print_bug_submit_message(st, _thread);
      }
 
-  STEP(130, "(printing summary)" )
+  STEP("printing summary")
 
      if (_verbose) {
        st->cr();
@@ -476,7 +476,7 @@
        st->cr();
      }
 
-  STEP(140, "(printing VM option summary)" )
+  STEP("printing VM option summary")
 
      if (_verbose) {
        // VM options
@@ -484,20 +484,20 @@
        st->cr();
      }
 
-  STEP(150, "(printing summary machine and OS info)")
+  STEP("printing summary machine and OS info")
 
      if (_verbose) {
        os::print_summary_info(st, buf, sizeof(buf));
      }
 
 
-  STEP(160, "(printing date and time)" )
+  STEP("printing date and time")
 
      if (_verbose) {
        os::print_date_and_time(st, buf, sizeof(buf));
      }
 
-  STEP(170, "(printing thread)" )
+  STEP("printing thread")
 
      if (_verbose) {
        st->cr();
@@ -505,7 +505,7 @@
        st->cr();
      }
 
-  STEP(180, "(printing current thread)" )
+  STEP("printing current thread")
 
      // current thread
      if (_verbose) {
@@ -519,7 +519,7 @@
        st->cr();
      }
 
-  STEP(190, "(printing current compile task)" )
+  STEP("printing current compile task")
 
      if (_verbose && _thread && _thread->is_Compiler_thread()) {
         CompilerThread* t = (CompilerThread*)_thread;
@@ -532,7 +532,7 @@
      }
 
 
-  STEP(200, "(printing stack bounds)" )
+  STEP("printing stack bounds")
 
      if (_verbose) {
        st->print("Stack: ");
@@ -563,7 +563,7 @@
        st->cr();
      }
 
-  STEP(210, "(printing native stack)" )
+  STEP("printing native stack")
 
    if (_verbose) {
      if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) {
@@ -577,13 +577,13 @@
      }
    }
 
-  STEP(220, "(printing Java stack)" )
+  STEP("printing Java stack")
 
      if (_verbose && _thread && _thread->is_Java_thread()) {
        print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf));
      }
 
-  STEP(230, "(printing target Java thread stack)" )
+  STEP("printing target Java thread stack")
 
      // printing Java thread stack trace if it is involved in GC crash
      if (_verbose && _thread && (_thread->is_Named_thread())) {
@@ -594,7 +594,7 @@
        }
      }
 
-  STEP(240, "(printing siginfo)" )
+  STEP("printing siginfo")
 
      // signal no, signal code, address that caused the fault
      if (_verbose && _siginfo) {
@@ -603,7 +603,7 @@
        st->cr();
      }
 
-  STEP(245, "(CDS archive access warning)" )
+  STEP("CDS archive access warning")
 
      // Print an explicit hint if we crashed on access to the CDS archive.
      if (_verbose && _siginfo) {
@@ -611,7 +611,7 @@
        st->cr();
      }
 
-  STEP(250, "(printing register info)")
+  STEP("printing register info")
 
      // decode register contents if possible
      if (_verbose && _context && Universe::is_fully_initialized()) {
@@ -619,7 +619,7 @@
        st->cr();
      }
 
-  STEP(260, "(printing registers, top of stack, instructions near pc)")
+  STEP("printing registers, top of stack, instructions near pc")
 
      // registers, top of stack, instructions near pc
      if (_verbose && _context) {
@@ -627,7 +627,7 @@
        st->cr();
      }
 
-  STEP(265, "(printing code blob if possible)")
+  STEP("printing code blob if possible")
 
      if (_verbose && _context) {
        CodeBlob* cb = CodeCache::find_blob(_pc);
@@ -652,7 +652,7 @@
        }
      }
 
-  STEP(270, "(printing VM operation)" )
+  STEP("printing VM operation")
 
      if (_verbose && _thread && _thread->is_VM_thread()) {
         VMThread* t = (VMThread*)_thread;
@@ -664,7 +664,7 @@
         }
      }
 
-  STEP(280, "(printing process)" )
+  STEP("printing process")
 
      if (_verbose) {
        st->cr();
@@ -672,7 +672,7 @@
        st->cr();
      }
 
-  STEP(290, "(printing all threads)" )
+  STEP("printing all threads")
 
      // all threads
      if (_verbose && _thread) {
@@ -680,7 +680,7 @@
        st->cr();
      }
 
-  STEP(300, "(printing VM state)" )
+  STEP("printing VM state")
 
      if (_verbose) {
        // Safepoint state
@@ -702,7 +702,7 @@
        st->cr();
      }
 
-  STEP(310, "(printing owned locks on error)" )
+  STEP("printing owned locks on error")
 
      // mutexes/monitors that currently have an owner
      if (_verbose) {
@@ -710,7 +710,7 @@
        st->cr();
      }
 
-  STEP(320, "(printing number of OutOfMemoryError and StackOverflow exceptions)")
+  STEP("printing number of OutOfMemoryError and StackOverflow exceptions")
 
      if (_verbose && Exceptions::has_exception_counts()) {
        st->print_cr("OutOfMemory and StackOverflow Exception counts:");
@@ -718,7 +718,7 @@
        st->cr();
      }
 
-  STEP(330, "(printing compressed oops mode")
+  STEP("printing compressed oops mode")
 
      if (_verbose && UseCompressedOops) {
        Universe::print_compressed_oops_mode(st);
@@ -728,7 +728,7 @@
        st->cr();
      }
 
-  STEP(340, "(printing heap information)" )
+  STEP("printing heap information")
 
      if (_verbose && Universe::is_fully_initialized()) {
        Universe::heap()->print_on_error(st);
@@ -737,7 +737,7 @@
        st->cr();
      }
 
-  STEP(350, "(printing code cache information)" )
+  STEP("printing code cache information")
 
      if (_verbose && Universe::is_fully_initialized()) {
        // print code cache information before vm abort
@@ -745,14 +745,14 @@
        st->cr();
      }
 
-  STEP(360, "(printing ring buffers)" )
+  STEP("printing ring buffers")
 
      if (_verbose) {
        Events::print_all(st);
        st->cr();
      }
 
-  STEP(370, "(printing dynamic libraries)" )
+  STEP("printing dynamic libraries")
 
      if (_verbose) {
        // dynamic libraries, or memory map
@@ -760,7 +760,7 @@
        st->cr();
      }
 
-  STEP(380, "(printing VM options)" )
+  STEP("printing VM options")
 
      if (_verbose) {
        // VM options
@@ -768,40 +768,40 @@
        st->cr();
      }
 
-  STEP(390, "(printing warning if internal testing API used)" )
+  STEP("printing warning if internal testing API used")
 
      if (WhiteBox::used()) {
        st->print_cr("Unsupported internal testing APIs have been used.");
        st->cr();
      }
 
-  STEP(395, "(printing log configuration)")
+  STEP("printing log configuration")
     if (_verbose){
       st->print_cr("Logging:");
       LogConfiguration::describe_current_configuration(st);
       st->cr();
     }
 
-  STEP(400, "(printing all environment variables)" )
+  STEP("printing all environment variables")
 
      if (_verbose) {
        os::print_environment_variables(st, env_list);
        st->cr();
      }
 
-  STEP(410, "(printing signal handlers)" )
+  STEP("printing signal handlers")
 
      if (_verbose) {
        os::print_signal_handlers(st, buf, sizeof(buf));
        st->cr();
      }
 
-  STEP(420, "(Native Memory Tracking)" )
+  STEP("Native Memory Tracking")
      if (_verbose) {
        MemTracker::error_report(st);
      }
 
-  STEP(430, "(printing system)" )
+  STEP("printing system")
 
      if (_verbose) {
        st->cr();
@@ -809,27 +809,27 @@
        st->cr();
      }
 
-  STEP(440, "(printing OS information)" )
+  STEP("printing OS information")
 
      if (_verbose) {
        os::print_os_info(st);
        st->cr();
      }
 
-  STEP(450, "(printing CPU info)" )
+  STEP("printing CPU info")
      if (_verbose) {
        os::print_cpu_info(st, buf, sizeof(buf));
        st->cr();
      }
 
-  STEP(460, "(printing memory info)" )
+  STEP("printing memory info")
 
      if (_verbose) {
        os::print_memory_info(st);
        st->cr();
      }
 
-  STEP(470, "(printing internal vm info)" )
+  STEP("printing internal vm info")
 
      if (_verbose) {
        st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string());
@@ -837,7 +837,7 @@
      }
 
   // print a defined marker to show that error handling finished correctly.
-  STEP(480, "(printing end marker)" )
+  STEP("printing end marker")
 
      if (_verbose) {
        st->print_cr("END.");
@@ -858,35 +858,35 @@
   char buf[O_BUFLEN];
   report_vm_version(st, buf, sizeof(buf));
 
-  // STEP("(printing summary)")
+  // STEP("printing summary")
 
   st->cr();
   st->print_cr("---------------  S U M M A R Y ------------");
   st->cr();
 
-  // STEP("(printing VM option summary)")
+  // STEP("printing VM option summary")
 
   // VM options
   Arguments::print_summary_on(st);
   st->cr();
 
-  // STEP("(printing summary machine and OS info)")
+  // STEP("printing summary machine and OS info")
 
   os::print_summary_info(st, buf, sizeof(buf));
 
-  // STEP("(printing date and time)")
+  // STEP("printing date and time")
 
   os::print_date_and_time(st, buf, sizeof(buf));
 
-  // Skip: STEP("(printing thread)")
+  // Skip: STEP("printing thread")
 
-  // STEP("(printing process)")
+  // STEP("printing process")
 
   st->cr();
   st->print_cr("---------------  P R O C E S S  ---------------");
   st->cr();
 
-  // STEP("(printing number of OutOfMemoryError and StackOverflow exceptions)")
+  // STEP("printing number of OutOfMemoryError and StackOverflow exceptions")
 
   if (Exceptions::has_exception_counts()) {
     st->print_cr("OutOfMemory and StackOverflow Exception counts:");
@@ -894,7 +894,7 @@
     st->cr();
   }
 
-  // STEP("(printing compressed oops mode")
+  // STEP("printing compressed oops mode")
 
   if (UseCompressedOops) {
     Universe::print_compressed_oops_mode(st);
@@ -904,7 +904,7 @@
     st->cr();
   }
 
-  // STEP("(printing heap information)")
+  // STEP("printing heap information")
 
   if (Universe::is_fully_initialized()) {
     Universe::heap()->print_on_error(st);
@@ -913,7 +913,7 @@
     st->cr();
   }
 
-  // STEP("(printing code cache information)")
+  // STEP("printing code cache information")
 
   if (Universe::is_fully_initialized()) {
     // print code cache information before vm abort
@@ -921,77 +921,77 @@
     st->cr();
   }
 
-  // STEP("(printing ring buffers)")
+  // STEP("printing ring buffers")
 
   Events::print_all(st);
   st->cr();
 
-  // STEP("(printing dynamic libraries)")
+  // STEP("printing dynamic libraries")
 
   // dynamic libraries, or memory map
   os::print_dll_info(st);
   st->cr();
 
-  // STEP("(printing VM options)")
+  // STEP("printing VM options")
 
   // VM options
   Arguments::print_on(st);
   st->cr();
 
-  // STEP("(printing warning if internal testing API used)")
+  // STEP("printing warning if internal testing API used")
 
   if (WhiteBox::used()) {
     st->print_cr("Unsupported internal testing APIs have been used.");
     st->cr();
   }
 
-  // STEP("(printing log configuration)")
+  // STEP("printing log configuration")
   st->print_cr("Logging:");
   LogConfiguration::describe(st);
   st->cr();
 
-  // STEP("(printing all environment variables)")
+  // STEP("printing all environment variables")
 
   os::print_environment_variables(st, env_list);
   st->cr();
 
-  // STEP("(printing signal handlers)")
+  // STEP("printing signal handlers")
 
   os::print_signal_handlers(st, buf, sizeof(buf));
   st->cr();
 
-  // STEP("(Native Memory Tracking)")
+  // STEP("Native Memory Tracking")
 
   MemTracker::error_report(st);
 
-  // STEP("(printing system)")
+  // STEP("printing system")
 
   st->cr();
   st->print_cr("---------------  S Y S T E M  ---------------");
   st->cr();
 
-  // STEP("(printing OS information)")
+  // STEP("printing OS information")
 
   os::print_os_info(st);
   st->cr();
 
-  // STEP("(printing CPU info)")
+  // STEP("printing CPU info")
 
   os::print_cpu_info(st, buf, sizeof(buf));
   st->cr();
 
-  // STEP("(printing memory info)")
+  // STEP("printing memory info")
 
   os::print_memory_info(st);
   st->cr();
 
-  // STEP("(printing internal vm info)")
+  // STEP("printing internal vm info")
 
   st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string());
   st->cr();
 
   // print a defined marker to show that error handling finished correctly.
-  // STEP("(printing end marker)")
+  // STEP("printing end marker")
 
   st->print_cr("END.");
 }
@@ -1190,7 +1190,7 @@
       }
 
       jio_snprintf(buffer, sizeof(buffer),
-                   "[error occurred during error reporting %s, id 0x%x]",
+                   "[error occurred during error reporting (%s), id 0x%x]",
                    _current_step_info, _id);
       if (log.is_open()) {
         log.cr();
--- a/test/compiler/jvmci/compilerToVM/ReadUncompressedOopTest.java	Fri May 06 19:45:22 2016 +0300
+++ b/test/compiler/jvmci/compilerToVM/ReadUncompressedOopTest.java	Mon May 09 13:13:07 2016 +0300
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 8136421
+ * @ignore 8155216
  * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
  * @library / /testlibrary /test/lib/
  * @library ../common/patches