changeset 4902:97c998b91726

Merge
author asaha
date Tue, 23 Jul 2013 20:39:54 -0700
parents 63085fd28f10 0af6bc95c1cb
children cf4d5e8cadf6
files .hgtags make/hotspot_version src/os/posix/vm/os_posix.cpp src/os/windows/vm/os_windows.cpp src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp src/os_cpu/linux_x86/vm/os_linux_x86.cpp src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp src/share/vm/runtime/os.cpp src/share/vm/runtime/os.hpp src/share/vm/runtime/thread.hpp
diffstat 50 files changed, 939 insertions(+), 137 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Jul 19 17:18:49 2013 -0700
+++ b/.hgtags	Tue Jul 23 20:39:54 2013 -0700
@@ -519,6 +519,7 @@
 0b9149d22ee08fe13b4f198ff258a1348e27b8b2 jdk7u40-b33
 1118c5d38ac0693d98f913485ceb3c57366cfbab hs24-b53
 1274c4750118bbdb3f3aa6dbf79af4568a2cca93 jdk7u40-b34
+f969880098fda55589cae8efaea5eff2c044e81e hs24-b54
 bf2d84c5103d98db1697b50071a649ea23c4e33d jdk7u25-b01
 07119340f80f77dfcb03fa568641e80b43d4be74 jdk7u25-b02
 655bea6843fb7beabd8d9eeda59572c0c7055b85 jdk7u25-b03
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java	Fri Jul 19 17:18:49 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java	Tue Jul 23 20:39:54 2013 -0700
@@ -40,8 +40,8 @@
    }
 
    private static synchronized void initialize(TypeDataBase db) {
-      Type type = db.lookupType("BinaryTreeDictionary");
-      totalSizeField = type.getCIntegerField("_totalSize");
+      Type type = db.lookupType("BinaryTreeDictionary<FreeChunk>");
+      totalSizeField = type.getCIntegerField("_total_size");
    }
 
    // Fields
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java	Fri Jul 19 17:18:49 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java	Tue Jul 23 20:39:54 2013 -0700
@@ -41,7 +41,7 @@
    }
 
    private static synchronized void initialize(TypeDataBase db) {
-      Type type = db.lookupType("FreeList");
+      Type type = db.lookupType("FreeList<FreeChunk>");
       sizeField = type.getCIntegerField("_size");
       countField = type.getCIntegerField("_count");
       headerSize = type.getSize();
--- a/make/hotspot_version	Fri Jul 19 17:18:49 2013 -0700
+++ b/make/hotspot_version	Tue Jul 23 20:39:54 2013 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=24
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=53
+HS_BUILD_NUMBER=54
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/linux/makefiles/vm.make	Fri Jul 19 17:18:49 2013 -0700
+++ b/make/linux/makefiles/vm.make	Tue Jul 23 20:39:54 2013 -0700
@@ -46,6 +46,7 @@
   include $(MAKEFILES_DIR)/zeroshark.make
 else
   include $(MAKEFILES_DIR)/$(BUILDARCH).make
+  -include $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/$(BUILDARCH).make
 endif
 
 # set VPATH so make knows where to look for source files
@@ -388,4 +389,5 @@
 
 install: install_jvm install_jsig install_saproc
 
-.PHONY: default build install install_jvm
+.PHONY: default build install install_jvm $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/$(BUILDARCH).make
+
--- a/src/cpu/sparc/vm/frame_sparc.inline.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/cpu/sparc/vm/frame_sparc.inline.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -231,10 +231,10 @@
 #endif // CC_INTERP
 
 
-inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
+inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
   // note: adjust this code if the link argument in StubGenerator::call_stub() changes!
   const Argument link = Argument(0, false);
-  return (JavaCallWrapper*)sp()[link.as_in().as_register()->sp_offset_in_saved_window()];
+  return (JavaCallWrapper**)&sp()[link.as_in().as_register()->sp_offset_in_saved_window()];
 }
 
 
--- a/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/cpu/x86/vm/frame_x86.inline.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -270,11 +270,10 @@
 
 // Entry frames
 
-inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
- return (JavaCallWrapper*)at(entry_frame_call_wrapper_offset);
+inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
+ return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
 }
 
-
 // Compiled frames
 
 inline int frame::local_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors) {
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -290,7 +290,7 @@
       __ stmxcsr(mxcsr_save);
       __ movl(rax, mxcsr_save);
       __ andl(rax, MXCSR_MASK);    // Only check control and mask bits
-      ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std());
+      ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
       __ cmp32(rax, mxcsr_std);
       __ jcc(Assembler::equal, skip_ldmx);
       __ ldmxcsr(mxcsr_std);
@@ -740,17 +740,18 @@
 
     if (CheckJNICalls) {
       Label ok_ret;
+      ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
       __ push(rax);
       __ subptr(rsp, wordSize);      // allocate a temp location
       __ stmxcsr(mxcsr_save);
       __ movl(rax, mxcsr_save);
       __ andl(rax, MXCSR_MASK);    // Only check control and mask bits
-      __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std()));
+      __ cmp32(rax, mxcsr_std);
       __ jcc(Assembler::equal, ok_ret);
 
       __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
 
-      __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std()));
+      __ ldmxcsr(mxcsr_std);
 
       __ bind(ok_ret);
       __ addptr(rsp, wordSize);
@@ -3719,12 +3720,35 @@
     return stub->entry_point();
   }
 
+  void create_control_words() {
+    // Round to nearest, 53-bit mode, exceptions masked
+    StubRoutines::_fpu_cntrl_wrd_std   = 0x027F;
+    // Round to zero, 53-bit mode, exception mased
+    StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F;
+    // Round to nearest, 24-bit mode, exceptions masked
+    StubRoutines::_fpu_cntrl_wrd_24    = 0x007F;
+    // Round to nearest, 64-bit mode, exceptions masked
+    StubRoutines::_fpu_cntrl_wrd_64    = 0x037F;
+    // Round to nearest, 64-bit mode, exceptions masked
+    StubRoutines::_mxcsr_std           = 0x1F80;
+    // Note: the following two constants are 80-bit values
+    //       layout is critical for correct loading by FPU.
+    // Bias for strict fp multiply/divide
+    StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
+    StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
+    StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
+    // Un-Bias for strict fp multiply/divide
+    StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
+    StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
+    StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
+  }
+
   // Initialization
   void generate_initial() {
     // Generates all stubs and initializes the entry points
 
-    // This platform-specific stub is needed by generate_call_stub()
-    StubRoutines::x86::_mxcsr_std        = generate_fp_mask("mxcsr_std",        0x0000000000001F80);
+    // This platform-specific settings are needed by generate_call_stub()
+    create_control_words();
 
     // entry points that exist in all platforms Note: This is code
     // that could be shared among different platforms - however the
--- a/src/cpu/x86/vm/stubRoutines_x86_64.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/cpu/x86/vm/stubRoutines_x86_64.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -55,5 +55,4 @@
 address StubRoutines::x86::_float_sign_flip = NULL;
 address StubRoutines::x86::_double_sign_mask = NULL;
 address StubRoutines::x86::_double_sign_flip = NULL;
-address StubRoutines::x86::_mxcsr_std = NULL;
 address StubRoutines::x86::_key_shuffle_mask_addr = NULL;
--- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -53,7 +53,6 @@
   static address _float_sign_flip;
   static address _double_sign_mask;
   static address _double_sign_flip;
-  static address _mxcsr_std;
   // shuffle mask for fixing up 128-bit words consisting of big-endian 32-bit integers
   static address _key_shuffle_mask_addr;
 
@@ -114,11 +113,6 @@
     return _double_sign_flip;
   }
 
-  static address mxcsr_std()
-  {
-    return _mxcsr_std;
-  }
-
   static address key_shuffle_mask_addr()                     { return _key_shuffle_mask_addr; }
 
 };
--- a/src/os/bsd/vm/attachListener_bsd.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/bsd/vm/attachListener_bsd.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -452,6 +452,30 @@
   return op;
 }
 
+
+// Performs initialization at vm startup
+// For BSD we remove any stale .java_pid file which could cause
+// an attaching process to think we are ready to receive on the
+// domain socket before we are properly initialized
+
+void AttachListener::vm_start() {
+  char fn[UNIX_PATH_MAX];
+  struct stat64 st;
+  int ret;
+
+  int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d",
+           os::get_temp_directory(), os::current_process_id());
+  assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow");
+
+  RESTARTABLE(::stat64(fn, &st), ret);
+  if (ret == 0) {
+    ret = ::unlink(fn);
+    if (ret == -1) {
+      debug_only(warning("failed to remove stale attach pid file at %s", fn));
+    }
+  }
+}
+
 int AttachListener::pd_init() {
   JavaThread* thread = JavaThread::current();
   ThreadBlockInVM tbivm(thread);
--- a/src/os/linux/vm/attachListener_linux.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/linux/vm/attachListener_linux.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -435,6 +435,30 @@
   return op;
 }
 
+
+// Performs initialization at vm startup
+// For Linux we remove any stale .java_pid file which could cause
+// an attaching process to think we are ready to receive on the
+// domain socket before we are properly initialized
+
+void AttachListener::vm_start() {
+  char fn[UNIX_PATH_MAX];
+  struct stat64 st;
+  int ret;
+
+  int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d",
+           os::get_temp_directory(), os::current_process_id());
+  assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow");
+
+  RESTARTABLE(::stat64(fn, &st), ret);
+  if (ret == 0) {
+    ret = ::unlink(fn);
+    if (ret == -1) {
+      debug_only(warning("failed to remove stale attach pid file at %s", fn));
+    }
+  }
+}
+
 int AttachListener::pd_init() {
   JavaThread* thread = JavaThread::current();
   ThreadBlockInVM tbivm(thread);
--- a/src/os/posix/vm/os_posix.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/posix/vm/os_posix.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -192,4 +192,53 @@
   st->cr();
 }
 
+os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
+  assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
+}
 
+/*
+ * See the caveats for this class in os_posix.hpp
+ * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
+ * method and returns false. If none of the signals are raised, returns true.
+ * The callback is supposed to provide the method that should be protected.
+ */
+bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
+  assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
+  assert(!WatcherThread::watcher_thread()->has_crash_protection(),
+      "crash_protection already set?");
+
+  if (sigsetjmp(_jmpbuf, 1) == 0) {
+    // make sure we can see in the signal handler that we have crash protection
+    // installed
+    WatcherThread::watcher_thread()->set_crash_protection(this);
+    cb.call();
+    // and clear the crash protection
+    WatcherThread::watcher_thread()->set_crash_protection(NULL);
+    return true;
+  }
+  // this happens when we siglongjmp() back
+  WatcherThread::watcher_thread()->set_crash_protection(NULL);
+  return false;
+}
+
+void os::WatcherThreadCrashProtection::restore() {
+  assert(WatcherThread::watcher_thread()->has_crash_protection(),
+      "must have crash protection");
+
+  siglongjmp(_jmpbuf, 1);
+}
+
+void os::WatcherThreadCrashProtection::check_crash_protection(int sig,
+    Thread* thread) {
+
+  if (thread != NULL &&
+      thread->is_Watcher_thread() &&
+      WatcherThread::watcher_thread()->has_crash_protection()) {
+
+    if (sig == SIGSEGV || sig == SIGBUS) {
+      WatcherThread::watcher_thread()->crash_protection()->restore();
+    }
+  }
+}
+
+
--- a/src/os/posix/vm/os_posix.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/posix/vm/os_posix.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -37,5 +37,24 @@
 
 };
 
+/*
+ * Crash protection for the watcher thread. Wrap the callback
+ * with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp
+ * back.
+ * To be able to use this - don't take locks, don't rely on destructors,
+ * don't make OS library calls, don't allocate memory, don't print,
+ * don't call code that could leave the heap / memory in an inconsistent state,
+ * or anything else where we are not in control if we suddenly jump out.
+ */
+class WatcherThreadCrashProtection : public StackObj {
+public:
+  WatcherThreadCrashProtection();
+  bool call(os::CrashProtectionCallback& cb);
+
+  static void check_crash_protection(int signal, Thread* thread);
+private:
+  void restore();
+  sigjmp_buf _jmpbuf;
+};
 
 #endif
--- a/src/os/solaris/vm/attachListener_solaris.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/solaris/vm/attachListener_solaris.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -576,6 +576,30 @@
   return op;
 }
 
+
+// Performs initialization at vm startup
+// For Solaris we remove any stale .java_pid file which could cause
+// an attaching process to think we are ready to receive a door_call
+// before we are properly initialized
+
+void AttachListener::vm_start() {
+  char fn[PATH_MAX+1];
+  struct stat64 st;
+  int ret;
+
+  int n = snprintf(fn, sizeof(fn), "%s/.java_pid%d",
+           os::get_temp_directory(), os::current_process_id());
+  assert(n < sizeof(fn), "java_pid file name buffer overflow");
+
+  RESTARTABLE(::stat64(fn, &st), ret);
+  if (ret == 0) {
+    ret = ::unlink(fn);
+    if (ret == -1) {
+      debug_only(warning("failed to remove stale attach pid file at %s", fn));
+    }
+  }
+}
+
 int AttachListener::pd_init() {
   JavaThread* thread = JavaThread::current();
   ThreadBlockInVM tbivm(thread);
--- a/src/os/windows/vm/attachListener_windows.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/windows/vm/attachListener_windows.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -358,6 +358,10 @@
   return op;
 }
 
+void AttachListener::vm_start() {
+  // nothing to do
+}
+
 int AttachListener::pd_init() {
   return Win32AttachListener::init();
 }
--- a/src/os/windows/vm/os_windows.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -4627,6 +4627,34 @@
   }
 }
 
+os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
+  assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
+}
+
+/*
+ * See the caveats for this class in os_windows.hpp
+ * Protects the callback call so that raised OS EXCEPTIONS causes a jump back
+ * into this method and returns false. If no OS EXCEPTION was raised, returns
+ * true.
+ * The callback is supposed to provide the method that should be protected.
+ */
+bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
+  assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
+  assert(!WatcherThread::watcher_thread()->has_crash_protection(),
+      "crash_protection already set?");
+
+  bool success = true;
+  __try {
+    WatcherThread::watcher_thread()->set_crash_protection(this);
+    cb.call();
+  } __except(EXCEPTION_EXECUTE_HANDLER) {
+    // only for protection, nothing to do
+    success = false;
+  }
+  WatcherThread::watcher_thread()->set_crash_protection(NULL);
+  return success;
+}
+
 // An Event wraps a win32 "CreateEvent" kernel handle.
 //
 // We have a number of choices regarding "CreateEvent" win32 handle leakage:
--- a/src/os/windows/vm/os_windows.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os/windows/vm/os_windows.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -102,6 +102,20 @@
   static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
 };
 
+/*
+ * Crash protection for the watcher thread. Wrap the callback
+ * with a __try { call() }
+ * To be able to use this - don't take locks, don't rely on destructors,
+ * don't make OS library calls, don't allocate memory, don't print,
+ * don't call code that could leave the heap / memory in an inconsistent state,
+ * or anything else where we are not in control if we suddenly jump out.
+ */
+class WatcherThreadCrashProtection : public StackObj {
+public:
+  WatcherThreadCrashProtection();
+  bool call(os::CrashProtectionCallback& cb);
+};
+
 class PlatformEvent : public CHeapObj<mtInternal> {
   private:
     double CachePad [4] ;   // increase odds that _Event is sole occupant of cache line
--- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -402,6 +402,10 @@
 
   Thread* t = ThreadLocalStorage::get_thread_slow();
 
+  // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+  // (no destructors can be run)
+  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
   SignalHandlerMark shm(t);
 
   // Note: it's not uncommon that JNI code uses signal/sigset to install
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -553,6 +553,10 @@
 
   Thread* t = ThreadLocalStorage::get_thread_slow();
 
+  // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+  // (no destructors can be run)
+  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
   SignalHandlerMark shm(t);
 
   // Note: it's not uncommon that JNI code uses signal/sigset to install
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -219,6 +219,10 @@
 
   Thread* t = ThreadLocalStorage::get_thread_slow();
 
+  // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+  // (no destructors can be run)
+  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
   SignalHandlerMark shm(t);
 
   // Note: it's not uncommon that JNI code uses signal/sigset to install
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -315,6 +315,10 @@
 
   Thread* t = ThreadLocalStorage::get_thread_slow();
 
+  // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+  // (no destructors can be run)
+  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
   SignalHandlerMark shm(t);
 
   if(sig == SIGPIPE || sig == SIGXFSZ) {
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -375,6 +375,10 @@
 
   Thread* t = ThreadLocalStorage::get_thread_slow();  // slow & steady
 
+  // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+  // (no destructors can be run)
+  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
   SignalHandlerMark shm(t);
 
   if(sig == SIGPIPE || sig == SIGXFSZ) {
--- a/src/share/vm/ci/bcEscapeAnalyzer.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -138,6 +138,16 @@
   return false;
 }
 
+// return true if all argument elements of vars are returned
+bool BCEscapeAnalyzer::returns_all(ArgumentMap vars) {
+  for (int i = 0; i < _arg_size; i++) {
+    if (vars.contains(i) && !_arg_returned.test(i)) {
+      return false;
+    }
+  }
+  return true;
+}
+
 void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) {
   for (int i = 0; i < _arg_size; i++) {
     if (vars.contains(i)) {
@@ -166,6 +176,11 @@
     if (vars.contains_unknown() || vars.contains_vars()) {
       _return_allocated = false;
     }
+    if (_return_local && vars.contains_vars() && !returns_all(vars)) {
+      // Return result should be invalidated if args in new
+      // state are not recorded in return state.
+      _return_local = false;
+    }
   }
 }
 
--- a/src/share/vm/ci/bcEscapeAnalyzer.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -79,6 +79,7 @@
   void set_returned(ArgumentMap vars);
   bool is_argument(ArgumentMap vars);
   bool is_arg_stack(ArgumentMap vars);
+  bool returns_all(ArgumentMap vars);
   void clear_bits(ArgumentMap vars, VectorSet &bs);
   void set_method_escape(ArgumentMap vars);
   void set_global_escape(ArgumentMap vars, bool merge = false);
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -870,7 +870,7 @@
   size_t alloc_byte_size = alloc_word_size * HeapWordSize;
 
   if ((cur_used_bytes + alloc_byte_size) > marking_initiating_used_threshold) {
-    if (gcs_are_young()) {
+    if (gcs_are_young() && !_last_young_gc) {
       ergo_verbose5(ErgoConcCycles,
         "request concurrent cycle initiation",
         ergo_format_reason("occupancy higher than threshold")
@@ -928,7 +928,7 @@
   last_pause_included_initial_mark = during_initial_mark_pause();
   if (last_pause_included_initial_mark) {
     record_concurrent_mark_init_end(0.0);
-  } else if (!_last_young_gc && need_to_start_conc_mark("end of GC")) {
+  } else if (need_to_start_conc_mark("end of GC")) {
     // Note: this might have already been set, if during the last
     // pause we decided to start a cycle but at the beginning of
     // this pause we decided to postpone it. That's OK.
--- a/src/share/vm/opto/matcher.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/opto/matcher.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -2303,26 +2303,26 @@
 // atomic instruction acting as a store_load barrier without any
 // intervening volatile load, and thus we don't need a barrier here.
 // We retain the Node to act as a compiler ordering barrier.
-bool Matcher::post_store_load_barrier(const Node *vmb) {
-  Compile *C = Compile::current();
-  assert( vmb->is_MemBar(), "" );
-  assert( vmb->Opcode() != Op_MemBarAcquire, "" );
-  const MemBarNode *mem = (const MemBarNode*)vmb;
+bool Matcher::post_store_load_barrier(const Node* vmb) {
+  Compile* C = Compile::current();
+  assert(vmb->is_MemBar(), "");
+  assert(vmb->Opcode() != Op_MemBarAcquire, "");
+  const MemBarNode* membar = vmb->as_MemBar();
 
-  // Get the Proj node, ctrl, that can be used to iterate forward
-  Node *ctrl = NULL;
-  DUIterator_Fast imax, i = mem->fast_outs(imax);
-  while( true ) {
-    ctrl = mem->fast_out(i);            // Throw out-of-bounds if proj not found
-    assert( ctrl->is_Proj(), "only projections here" );
-    ProjNode *proj = (ProjNode*)ctrl;
-    if( proj->_con == TypeFunc::Control &&
-        !C->node_arena()->contains(ctrl) ) // Unmatched old-space only
+  // Get the Ideal Proj node, ctrl, that can be used to iterate forward
+  Node* ctrl = NULL;
+  for (DUIterator_Fast imax, i = membar->fast_outs(imax); i < imax; i++) {
+    Node* p = membar->fast_out(i);
+    assert(p->is_Proj(), "only projections here");
+    if ((p->as_Proj()->_con == TypeFunc::Control) &&
+        !C->node_arena()->contains(p)) { // Unmatched old-space only
+      ctrl = p;
       break;
-    i++;
+    }
   }
+  assert((ctrl != NULL), "missing control projection");
 
-  for( DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++ ) {
+  for (DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++) {
     Node *x = ctrl->fast_out(j);
     int xop = x->Opcode();
 
@@ -2334,37 +2334,36 @@
     // that a monitor exit operation contains a serializing instruction.
 
     if (xop == Op_MemBarVolatile ||
-        xop == Op_FastLock ||
         xop == Op_CompareAndSwapL ||
         xop == Op_CompareAndSwapP ||
         xop == Op_CompareAndSwapN ||
-        xop == Op_CompareAndSwapI)
+        xop == Op_CompareAndSwapI) {
       return true;
+    }
+
+    // Op_FastLock previously appeared in the Op_* list above.
+    // With biased locking we're no longer guaranteed that a monitor
+    // enter operation contains a serializing instruction.
+    if ((xop == Op_FastLock) && !UseBiasedLocking) {
+      return true;
+    }
 
     if (x->is_MemBar()) {
       // We must retain this membar if there is an upcoming volatile
-      // load, which will be preceded by acquire membar.
-      if (xop == Op_MemBarAcquire)
+      // load, which will be followed by acquire membar.
+      if (xop == Op_MemBarAcquire) {
         return false;
-      // For other kinds of barriers, check by pretending we
-      // are them, and seeing if we can be removed.
-      else
-        return post_store_load_barrier((const MemBarNode*)x);
+      } else {
+        // For other kinds of barriers, check by pretending we
+        // are them, and seeing if we can be removed.
+        return post_store_load_barrier(x->as_MemBar());
+      }
     }
 
-    // Delicate code to detect case of an upcoming fastlock block
-    if( x->is_If() && x->req() > 1 &&
-        !C->node_arena()->contains(x) ) { // Unmatched old-space only
-      Node *iff = x;
-      Node *bol = iff->in(1);
-      // The iff might be some random subclass of If or bol might be Con-Top
-      if (!bol->is_Bool())  return false;
-      assert( bol->req() > 1, "" );
-      return (bol->in(1)->Opcode() == Op_FastUnlock);
+    // probably not necessary to check for these
+    if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) {
+      return false;
     }
-    // probably not necessary to check for these
-    if (x->is_Call() || x->is_SafePoint() || x->is_block_proj())
-      return false;
   }
   return false;
 }
--- a/src/share/vm/opto/parse3.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/opto/parse3.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -277,25 +277,7 @@
   // If reference is volatile, prevent following volatiles ops from
   // floating up before the volatile write.
   if (is_vol) {
-    // First place the specific membar for THIS volatile index. This first
-    // membar is dependent on the store, keeping any other membars generated
-    // below from floating up past the store.
-    int adr_idx = C->get_alias_index(adr_type);
-    insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store);
-
-    // Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed
-    // volatile alias indices. Skip this if the membar is redundant.
-    if (adr_idx != Compile::AliasIdxBot) {
-      insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store);
-    }
-
-    // Finally, place alias-index-specific membars for each volatile index
-    // that isn't the adr_idx membar. Typically there's only 1 or 2.
-    for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) {
-      if (i != adr_idx && C->alias_type(i)->is_volatile()) {
-        insert_mem_bar_volatile(Op_MemBarVolatile, i, store);
-      }
-    }
+    insert_mem_bar(Op_MemBarVolatile); // Use fat membar
   }
 
   // If the field is final, the rules of Java say we are in <init> or <clinit>.
--- a/src/share/vm/prims/forte.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/prims/forte.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -31,6 +31,7 @@
 #include "oops/oop.inline.hpp"
 #include "oops/oop.inline2.hpp"
 #include "prims/forte.hpp"
+#include "runtime/javaCalls.hpp"
 #include "runtime/thread.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframeArray.hpp"
@@ -296,10 +297,14 @@
 
   for (loop_count = 0; loop_count < loop_max; loop_count++) {
 
-    if (candidate.is_first_frame()) {
+    if (candidate.is_entry_frame()) {
+      // jcw is NULL if the java call wrapper couldn't be found
+      JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(thread);
       // If initial frame is frame from StubGenerator and there is no
       // previous anchor, there are no java frames associated with a method
-      return false;
+      if (jcw == NULL || jcw->is_first_frame()) {
+        return false;
+      }
     }
 
     if (candidate.is_interpreted_frame()) {
--- a/src/share/vm/runtime/arguments.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -245,6 +245,27 @@
                            JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) },
   { "AllowTransitionalJSR292",       JDK_Version::jdk(7), JDK_Version::jdk(8) },
   { "UseCompressedStrings",          JDK_Version::jdk(7), JDK_Version::jdk(8) },
+  { "AlwaysInflate",       JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "AnonymousClasses",    JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "CMSOldPLABReactivityCeiling",
+                           JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "EventLogLength",      JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "GCOverheadReporting", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "GCOverheadReportingPeriodMS",
+                           JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "HPILibPath",          JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "PreSpinYield",        JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "PreBlockSpin",        JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "PostSpinYield",       JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "PreserveMarkStackSize",
+                           JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "ReadSpinIterations",  JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "StressTieredRuntime", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "Tier1Inline",         JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "Tier1FreqInlineSize", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "Tier1MaxInlineSize",  JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "Tier1LoopOptsCount",  JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "UseSpinning",         JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
 #ifdef PRODUCT
   { "DesiredMethodLimit",
                            JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
--- a/src/share/vm/runtime/frame.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/frame.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -220,9 +220,20 @@
 
 
 bool frame::entry_frame_is_first() const {
-  return entry_frame_call_wrapper()->anchor()->last_Java_sp() == NULL;
+  return entry_frame_call_wrapper()->is_first_frame();
 }
 
+JavaCallWrapper* frame::entry_frame_call_wrapper_if_safe(JavaThread* thread) const {
+  JavaCallWrapper** jcw = entry_frame_call_wrapper_addr();
+  address addr = (address) jcw;
+
+  // addr must be within the usable part of the stack
+  if (thread->is_in_usable_stack(addr)) {
+    return *jcw;
+  }
+
+  return NULL;
+}
 
 bool frame::should_be_deoptimized() const {
   if (_deopt_state == is_deoptimized ||
--- a/src/share/vm/runtime/frame.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/frame.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -354,7 +354,9 @@
 
  public:
   // Entry frames
-  JavaCallWrapper* entry_frame_call_wrapper() const;
+  JavaCallWrapper* entry_frame_call_wrapper() const { return *entry_frame_call_wrapper_addr(); }
+  JavaCallWrapper* entry_frame_call_wrapper_if_safe(JavaThread* thread) const;
+  JavaCallWrapper** entry_frame_call_wrapper_addr() const;
   intptr_t* entry_frame_argument_at(int offset) const;
 
   // tells whether there is another chunk of Delta stack above
--- a/src/share/vm/runtime/javaCalls.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/javaCalls.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -91,6 +91,8 @@
   oop              receiver()               { return _receiver; }
   void             oops_do(OopClosure* f);
 
+  bool             is_first_frame() const   { return _anchor.last_Java_sp() == NULL; }
+
 };
 
 
--- a/src/share/vm/runtime/mutex.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/mutex.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -1373,6 +1373,10 @@
     debug_only(if (rank() != Mutex::special) \
       thread->check_for_valid_safepoint_state(false);)
   }
+  if (thread->is_Watcher_thread()) {
+    assert(!WatcherThread::watcher_thread()->has_crash_protection(),
+        "locking not allowed when crash protection is set");
+  }
 }
 
 void Monitor::check_block_state(Thread *thread) {
--- a/src/share/vm/runtime/os.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/os.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -564,6 +564,22 @@
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
 
+#ifdef ASSERT
+  // checking for the WatcherThread and crash_protection first
+  // since os::malloc can be called when the libjvm.{dll,so} is
+  // first loaded and we don't have a thread yet.
+  // try to find the thread after we see that the watcher thread
+  // exists and has crash protection.
+  WatcherThread *wt = WatcherThread::watcher_thread();
+  if (wt != NULL && wt->has_crash_protection()) {
+    Thread* thread = ThreadLocalStorage::get_thread_slow();
+    if (thread == wt) {
+      assert(!wt->has_crash_protection(),
+          "Can't malloc with crash protection from WatcherThread");
+    }
+  }
+#endif
+
   if (size == 0) {
     // return a valid pointer if size is zero
     // if NULL is returned the calling functions assume out of memory.
--- a/src/share/vm/runtime/os.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/os.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -32,15 +32,18 @@
 #include "utilities/top.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "jvm_linux.h"
+# include <setjmp.h>
 #endif
 #ifdef TARGET_OS_FAMILY_solaris
 # include "jvm_solaris.h"
+# include <setjmp.h>
 #endif
 #ifdef TARGET_OS_FAMILY_windows
 # include "jvm_windows.h"
 #endif
 #ifdef TARGET_OS_FAMILY_bsd
 # include "jvm_bsd.h"
+# include <setjmp.h>
 #endif
 
 // os defines the interface to operating system; this includes traditional
@@ -734,6 +737,10 @@
 #include "runtime/os_ext.hpp"
 
  public:
+  class CrashProtectionCallback : public StackObj {
+  public:
+    virtual void call() = 0;
+  };
 
   // Platform dependent stuff
 #ifdef TARGET_OS_FAMILY_linux
@@ -919,6 +926,7 @@
                                 char pathSep);
   static bool set_boot_path(char fileSep, char pathSep);
   static char** split_path(const char* path, int* n);
+
 };
 
 // Note that "PAUSE" is almost always used with synchronization
--- a/src/share/vm/runtime/thread.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/thread.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -936,6 +936,14 @@
 }
 
 
+bool Thread::is_in_usable_stack(address adr) const {
+  size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
+  size_t usable_stack_size = _stack_size - stack_guard_size;
+
+  return ((adr < stack_base()) && (adr >= stack_base() - usable_stack_size));
+}
+
+
 // We had to move these methods here, because vm threads get into ObjectSynchronizer::enter
 // However, there is a note in JavaThread::is_lock_owned() about the VM threads not being
 // used for compilation in the future. If that change is made, the need for these methods
@@ -1200,7 +1208,7 @@
 bool WatcherThread::_startable = false;
 volatile bool  WatcherThread::_should_terminate = false;
 
-WatcherThread::WatcherThread() : Thread() {
+WatcherThread::WatcherThread() : Thread(), _crash_protection(NULL) {
   assert(watcher_thread() == NULL, "we can only allocate one WatcherThread");
   if (os::create_thread(this, os::watcher_thread)) {
     _watcher_thread = this;
@@ -3608,6 +3616,7 @@
 
   // Start Attach Listener if +StartAttachListener or it can't be started lazily
   if (!DisableAttachMechanism) {
+    AttachListener::vm_start();
     if (StartAttachListener || AttachListener::init_at_startup()) {
       AttachListener::init();
     }
--- a/src/share/vm/runtime/thread.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/runtime/thread.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -506,6 +506,9 @@
   // Check if address is in the stack of the thread (not just for locks).
   // Warning: the method can only be used on the running thread
   bool is_in_stack(address adr) const;
+  // Check if address is in the usable part of the stack (excludes protected
+  // guard pages)
+  bool is_in_usable_stack(address adr) const;
 
   // Sets this thread as starting thread. Returns failure if thread
   // creation fails due to lack of memory, too many threads etc.
@@ -713,6 +716,8 @@
 
   static bool _startable;
   volatile static bool _should_terminate; // updated without holding lock
+
+  os::WatcherThreadCrashProtection* _crash_protection;
  public:
   enum SomeConstants {
     delay_interval = 10                          // interrupt delay in milliseconds
@@ -740,6 +745,14 @@
   // Otherwise the first task to enroll will trigger the start
   static void make_startable();
 
+  void set_crash_protection(os::WatcherThreadCrashProtection* crash_protection) {
+    assert(Thread::current()->is_Watcher_thread(), "Can only be set by WatcherThread");
+    _crash_protection = crash_protection;
+  }
+
+  bool has_crash_protection() const { return _crash_protection != NULL; }
+  os::WatcherThreadCrashProtection* crash_protection() const { return _crash_protection; }
+
  private:
   int sleep() const;
 };
--- a/src/share/vm/services/attachListener.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/services/attachListener.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -49,6 +49,7 @@
 
 class AttachListener: AllStatic {
  public:
+  static void vm_start();
   static void init();
   static void abort();
 
--- a/src/share/vm/services/memTracker.cpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/services/memTracker.cpp	Tue Jul 23 20:39:54 2013 -0700
@@ -83,13 +83,13 @@
   } else if (strcmp(option_line, "=detail") == 0) {
     // detail relies on a stack-walking ability that may not
     // be available depending on platform and/or compiler flags
-    if (PLATFORM_NMT_DETAIL_SUPPORTED) {
+#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
       _tracking_level = NMT_detail;
-    } else {
+#else
       jio_fprintf(defaultStream::error_stream(),
         "NMT detail is not supported on this platform.  Using NMT summary instead.\n");
        _tracking_level = NMT_summary;
-    }
+#endif
   } else if (strcmp(option_line, "=off") != 0) {
     vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
   }
@@ -387,6 +387,7 @@
 #define SAFE_SEQUENCE_THRESHOLD    30
 #define HIGH_GENERATION_THRESHOLD  60
 #define MAX_RECORDER_THREAD_RATIO  30
+#define MAX_RECORDER_PER_THREAD    100
 
 void MemTracker::sync() {
   assert(_tracking_level > NMT_off, "NMT is not enabled");
@@ -439,8 +440,14 @@
       // means that worker thread is lagging behind in processing them.
       if (!AutoShutdownNMT) {
         _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count);
+      } else {
+        // If auto shutdown is on, enforce MAX_RECORDER_PER_THREAD threshold to prevent OOM
+        if (MemRecorder::_instance_count >= _thread_count * MAX_RECORDER_PER_THREAD) {
+          shutdown(NMT_out_of_memory);
+        }
       }
 
+
       // check _worker_thread with lock to avoid racing condition
       if (_worker_thread != NULL) {
         _worker_thread->at_sync_point(pending_recorders, instanceKlass::number_of_instance_classes());
--- a/src/share/vm/trace/traceDataTypes.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/trace/traceDataTypes.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 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,5 +63,7 @@
 typedef u8 methodid;
 typedef u8 fieldid;
 
+class TraceUnicodeString;
+
 #endif // SHARE_VM_TRACE_TRACEDATATYPES_HPP
 
--- a/src/share/vm/trace/tracetypes.xml	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/trace/tracetypes.xml	Tue Jul 23 20:39:54 2013 -0700
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2013 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
@@ -55,18 +55,6 @@
               type="u8" sizeop="sizeof(u1)"/>
 
 Now we can use the content + data type in declaring event fields.
-Remember however, that for us to be able to resolve the value later we must also add
-creating the constant pool data in  VM_JFRCheckpoint::write_checkpoint
-
-   ...
-   //CGMODE
-   w->be_uint(CONTENT_TYPE_GCMODE);
-   w->be_uint(MM_GC_MODE_UNINITIALIZED);
-   for (i = 0; i < MM_GC_MODE_UNINITIALIZED; i++) {
-      w->uchar(i);
-      w->write_utf8(gcModeGetName(i));
-   }
-
  -->
 
  <types>
@@ -81,10 +69,6 @@
       <value type="OSTHREAD" field="thread" label="VM Thread"/>
     </content_type>
 
-    <!-- The first argument ("JavaThread") is misleading, it's really a
-         java.lang.Thread id (long), but Mission Control depends on the name
-         being "JavaThread" so it shouldn't be changed.
-    -->
     <content_type id="JavaThread" hr_name="Java thread"
                   type="U8" builtin_type="JAVALANGTHREAD">
       <value type="OSTHREAD" field="thread" label="OS Thread ID"/>
@@ -285,6 +269,10 @@
     <primary_type symbol="UTF8" datatype="UTF8" contenttype="NONE"
                   type="const char *" sizeop="sizeof_utf(%)"/>
 
+    <!-- UTF-16 encoded (Unicode) string, max length maxjuint -->
+    <primary_type symbol="STRING" datatype="STRING" contenttype="NONE"
+                  type="TraceUnicodeString*" sizeop="sizeof_unicode(%)"/>
+
     <!-- Symbol* constant. Note that this may currently ONLY be used by
           classes, methods fields.  This restriction might be lifted. -->
     <primary_type symbol="SYMBOL" datatype="U8" contenttype="SYMBOL"
--- a/src/share/vm/trace/xinclude.mod	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/trace/xinclude.mod	Tue Jul 23 20:39:54 2013 -0700
@@ -22,30 +22,6 @@
  questions.
   
 -->
-
-<!--
- Copyright (c) 2012, 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.
-  
--->
 <!ELEMENT xi:include (xi:fallback?) >
 <!ATTLIST xi:include
     xmlns:xi   CDATA       #FIXED    "http://www.w3.org/2001/XInclude"
--- a/src/share/vm/utilities/globalDefinitions.hpp	Fri Jul 19 17:18:49 2013 -0700
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Tue Jul 23 20:39:54 2013 -0700
@@ -354,12 +354,12 @@
 #endif
 
 /*
- * If a platform does not support NMT_detail
+ * If a platform does not support native stack walking
  * the platform specific globalDefinitions (above)
- * can set PLATFORM_NMT_DETAIL_SUPPORTED to false
+ * can set PLATFORM_NATIVE_STACK_WALKING_SUPPORTED to 0
  */
-#ifndef PLATFORM_NMT_DETAIL_SUPPORTED
-#define PLATFORM_NMT_DETAIL_SUPPORTED true
+#ifndef PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
+#define PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 1
 #endif
 
 // The byte alignment to be used by Arena::Amalloc.  See bugid 4169348.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/EscapeAnalysis/Test8020215.java	Tue Jul 23 20:39:54 2013 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8020215
+ * @summary Different execution plan when using JIT vs interpreter
+ * @run main Test8020215
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Test8020215 {
+    public static class NamedObject {
+        public int id;
+        public String name;
+        public NamedObject(int id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+    }
+
+    public static class NamedObjectList {
+        public List<NamedObject> namedObjectList = new ArrayList<NamedObject>();
+
+        public NamedObject getBest(int id) {
+            NamedObject bestObject = null;
+            for (NamedObject o : namedObjectList) {
+                bestObject = id==o.id ? getBetter(bestObject, o) : bestObject;
+            }
+            return (bestObject != null) ? bestObject : null;
+        }
+
+        private static NamedObject getBetter(NamedObject p1, NamedObject p2) {
+            return (p1 == null) ? p2 : (p2 == null) ? p1 : (p2.name.compareTo(p1.name) >= 0) ? p2 : p1;
+        }
+    }
+
+    static void test(NamedObjectList b, int i) {
+        NamedObject x = b.getBest(2);
+        // test
+        if (x == null) {
+            throw new RuntimeException("x should never be null here! (i=" + i + ")");
+        }
+    }
+
+    public static void main(String[] args) {
+        // setup
+        NamedObjectList b = new NamedObjectList();
+        for (int i = 0; i < 10000; i++) {
+            b.namedObjectList.add(new NamedObject(1, "2012-12-31"));
+        }
+        b.namedObjectList.add(new NamedObject(2, "2013-12-31"));
+
+        // execution
+        for (int i = 0; i < 12000; i++) {
+            test(b, i);
+        }
+        System.out.println("PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/cpuflags/RestoreMXCSR.java	Tue Jul 23 20:39:54 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8020433
+ * @summary Crash when using -XX:+RestoreMXCSROnJNICalls
+ * @library /testlibrary
+ *
+ */
+import com.oracle.java.testlibrary.*;
+
+public class RestoreMXCSR {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb;
+    OutputAnalyzer out;
+
+    pb = ProcessTools.createJavaProcessBuilder("-XX:+RestoreMXCSROnJNICalls", "-version");
+    out = new OutputAnalyzer(pb.start());
+    out.shouldHaveExitValue(0);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/membars/DekkerTest.java	Tue Jul 23 20:39:54 2013 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2013 SAP AG.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8007898
+ * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @author Martin Doerr martin DOT doerr AT sap DOT com
+ *
+ * Run 3 times since the failure is intermittent.
+ */
+
+public class DekkerTest {
+
+    /*
+      Read After Write Test (basically a simple Dekker test with volatile variables)
+      Derived from the original jcstress test, available at:
+        http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/
+        tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java
+     */
+
+    static final int ITERATIONS = 1000000;
+
+    static class TestData {
+        public volatile int a;
+        public volatile int b;
+    }
+
+    static class ResultData {
+        public int a;
+        public int b;
+    }
+
+    TestData[]   testDataArray;
+    ResultData[] results;
+
+    volatile boolean start;
+
+    public DekkerTest() {
+        testDataArray = new TestData[ITERATIONS];
+        results = new ResultData[ITERATIONS];
+        for (int i = 0; i < ITERATIONS; ++i) {
+            testDataArray[i] = new TestData();
+            results[i] = new ResultData();
+        }
+        start = false;
+    }
+
+    public void reset() {
+        for (int i = 0; i < ITERATIONS; ++i) {
+            testDataArray[i].a = 0;
+            testDataArray[i].b = 0;
+            results[i].a = 0;
+            results[i].b = 0;
+        }
+        start = false;
+    }
+
+    int actor1(TestData t) {
+        t.a = 1;
+        return t.b;
+    }
+
+    int actor2(TestData t) {
+        t.b = 1;
+        return t.a;
+    }
+
+    class Runner1 extends Thread {
+        public void run() {
+            do {} while (!start);
+            for (int i = 0; i < ITERATIONS; ++i) {
+                results[i].a = actor1(testDataArray[i]);
+            }
+        }
+    }
+
+    class Runner2 extends Thread {
+        public void run() {
+            do {} while (!start);
+            for (int i = 0; i < ITERATIONS; ++i) {
+                results[i].b = actor2(testDataArray[i]);
+            }
+        }
+    }
+
+    void testRunner() {
+        Thread thread1 = new Runner1();
+        Thread thread2 = new Runner2();
+        thread1.start();
+        thread2.start();
+        do {} while (!thread1.isAlive());
+        do {} while (!thread2.isAlive());
+        start = true;
+        Thread.yield();
+        try {
+            thread1.join();
+            thread2.join();
+        } catch (InterruptedException e) {
+            System.out.println("interrupted!");
+            System.exit(1);
+        }
+    }
+
+    boolean printResult() {
+        int[] count = new int[4];
+        for (int i = 0; i < ITERATIONS; ++i) {
+            int event_kind = (results[i].a << 1) + results[i].b;
+            ++count[event_kind];
+        }
+        if (count[0] == 0 && count[3] == 0) {
+            System.out.println("[not interesting]");
+            return false; // not interesting
+        }
+        String error = (count[0] == 0) ? " ok" : " disallowed!";
+        System.out.println("[0,0] " + count[0] + error);
+        System.out.println("[0,1] " + count[1]);
+        System.out.println("[1,0] " + count[2]);
+        System.out.println("[1,1] " + count[3]);
+        return (count[0] != 0);
+    }
+
+    public static void main(String args[]) {
+        DekkerTest test = new DekkerTest();
+        final int runs = 30;
+        int failed = 0;
+        for (int c = 0; c < runs; ++c) {
+            test.testRunner();
+            if (test.printResult()) {
+                failed++;
+            }
+            test.reset();
+        }
+        if (failed > 0) {
+            throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS");
+        }
+        System.out.println("PASSED.");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/attach/AttachWithStalePidFile.java	Tue Jul 23 20:39:54 2013 -0700
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7162400
+ * @key regression
+ * @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues
+ * @library /testlibrary
+ * @compile AttachWithStalePidFileTarget.java
+ * @run main AttachWithStalePidFile
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.sun.tools.attach.VirtualMachine;
+import sun.tools.attach.HotSpotVirtualMachine;
+import java.lang.reflect.Field;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+
+public class AttachWithStalePidFile {
+  public static void main(String... args) throws Exception {
+
+    // this test is only valid on non-Windows platforms
+    if(Platform.isWindows()) {
+      System.out.println("This test is only valid on non-Windows platforms.");
+      return;
+    }
+
+    // Since there might be stale pid-files owned by different
+    // users on the system we may need to retry the test in case we
+    // are unable to remove the existing file.
+    int retries = 5;
+    while(!runTest() && --retries > 0);
+
+    if(retries == 0) {
+      throw new RuntimeException("Test failed after 5 retries. " +
+        "Remove any /tmp/.java_pid* files and retry.");
+    }
+  }
+
+  public static boolean runTest() throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      "-XX:+UnlockDiagnosticVMOptions", "-XX:+PauseAtStartup", "AttachWithStalePidFileTarget");
+    Process target = pb.start();
+    Path pidFile = null;
+
+    try {
+      int pid = getUnixProcessId(target);
+
+      // create the stale .java_pid file. use hard-coded /tmp path as in th VM
+      pidFile = createJavaPidFile(pid);
+      if(pidFile == null) {
+        return false;
+      }
+
+      // wait for vm.paused file to be created and delete it once we find it.
+      waitForAndResumeVM(pid);
+
+      // unfortunately there's no reliable way to know the VM is ready to receive the
+      // attach request so we have to do an arbitrary sleep.
+      Thread.sleep(5000);
+
+      HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString());
+      BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(vm.remoteDataDump()));
+      String line = null;
+      while((line = remoteDataReader.readLine()) != null);
+
+      vm.detach();
+      return true;
+    }
+    finally {
+      target.destroy();
+      target.waitFor();
+
+      if(pidFile != null && Files.exists(pidFile)) {
+        Files.delete(pidFile);
+      }
+    }
+  }
+
+  private static Path createJavaPidFile(int pid) throws Exception {
+    Path pidFile = Paths.get("/tmp/.java_pid" + pid);
+    if(Files.exists(pidFile)) {
+      try {
+        Files.delete(pidFile);
+      }
+      catch(FileSystemException e) {
+        if(e.getReason().equals("Operation not permitted")) {
+          System.out.println("Unable to remove exisiting stale PID file" + pidFile);
+          return null;
+        }
+        throw e;
+      }
+    }
+    return Files.createFile(pidFile,
+      PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------")));
+  }
+
+  private static void waitForAndResumeVM(int pid) throws Exception {
+    Path pauseFile = Paths.get("vm.paused." + pid);
+    int retries = 60;
+    while(!Files.exists(pauseFile) && --retries > 0) {
+      Thread.sleep(1000);
+    }
+    if(retries == 0) {
+      throw new RuntimeException("Timeout waiting for VM to start. " +
+        "vm.paused file not created within 60 seconds.");
+    }
+    Files.delete(pauseFile);
+  }
+
+  private static int getUnixProcessId(Process unixProcess) throws Exception {
+    Field pidField = unixProcess.getClass().getDeclaredField("pid");
+    pidField.setAccessible(true);
+    return (Integer)pidField.get(unixProcess);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/attach/AttachWithStalePidFileTarget.java	Tue Jul 23 20:39:54 2013 -0700
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+public class AttachWithStalePidFileTarget {
+  public static void main(String... args) throws Exception {
+    Thread.sleep(2*60*1000);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Tue Jul 23 20:39:54 2013 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+public class Platform {
+  private static final String osName = System.getProperty("os.name");
+  private static final String dataModel = System.getProperty("sun.arch.data.model");
+  private static final String vmVersion = System.getProperty("java.vm.version");
+
+  public static boolean is64bit() {
+    return dataModel.equals("64");
+  }
+
+  public static boolean isSolaris() {
+    return osName.toLowerCase().startsWith("sunos");
+  }
+
+  public static boolean isWindows() {
+    return osName.toLowerCase().startsWith("win");
+  }
+
+  public static boolean isOSX() {
+    return osName.toLowerCase().startsWith("mac");
+  }
+
+  public static boolean isLinux() {
+    return osName.toLowerCase().startsWith("linux");
+  }
+
+  public static String getOsName() {
+    return osName;
+  }
+
+  public static boolean isDebugBuild() {
+    return vmVersion.toLowerCase().contains("debug");
+  }
+
+  public static String getVMVersion() {
+    return vmVersion;
+  }
+}