changeset 1331:7c358fbb6a84

Merge
author acorn
date Thu, 01 Apr 2010 11:23:01 -0400
parents 4a9cc99938e3 (diff) d4197f8d516a (current diff)
children 4b60f23c4223
files
diffstat 25 files changed, 463 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/make/windows/build.bat	Thu Mar 18 12:14:59 2010 -0400
+++ b/make/windows/build.bat	Thu Apr 01 11:23:01 2010 -0400
@@ -28,6 +28,9 @@
 REM Since we don't have uname and we could be cross-compiling,
 REM Use the compiler to determine which ARCH we are building
 REM 
+REM Note: Running this batch file from the Windows command shell requires
+REM that "grep" be accessible on the PATH. An MKS install does this.
+REM 
 cl 2>&1 | grep "IA-64" >NUL
 if %errorlevel% == 0 goto isia64
 cl 2>&1 | grep "AMD64" >NUL
@@ -57,11 +60,12 @@
 if "%1" == "product"   goto test1
 if "%1" == "debug"     goto test1
 if "%1" == "fastdebug" goto test1
+if "%1" == "tree"      goto test1
 goto usage
 
 :test1
 if "%2" == "core"      goto test2
-if "%2" == "kernel"   goto test2
+if "%2" == "kernel"    goto test2
 if "%2" == "compiler1" goto test2
 if "%2" == "compiler2" goto test2
 if "%2" == "tiered"    goto test2
@@ -70,6 +74,7 @@
 goto usage
 
 :test2
+if "%1" == "tree"      goto build_tree
 REM check_j2se_version
 REM jvmti.make requires J2SE 1.4.x or newer.
 REM If not found then fail fast.
@@ -93,6 +98,10 @@
 nmake -f %3/make/windows/build.make Variant=compiler2 WorkSpace=%3 BootStrapDir=%4 BuildUser="%USERNAME%" HOTSPOT_BUILD_VERSION=%5 ADLC_ONLY=1 %1
 goto end
 
+:build_tree
+nmake -f %3/make/windows/build.make Variant=%2 WorkSpace=%3 BootStrapDir=%4 BuildUser="%USERNAME%" HOTSPOT_BUILD_VERSION="%5" %1
+goto end
+
 :usage
 echo Usage: build flavor version workspace bootstrap_dir [build_id] [windbg_home]
 echo.
@@ -100,8 +109,10 @@
 echo flavor is "product", "debug" or "fastdebug",
 echo version is "core", "kernel", "compiler1", "compiler2", or "tiered",
 echo workspace is source directory without trailing slash, 
-echo bootstrap_dir is a full path to echo a JDK in which bin/java 
-echo   and bin/javac are present and working, and echo build_id is an 
+echo bootstrap_dir is a full path to a JDK in which bin/java 
+echo   and bin/javac are present and working, and build_id is an 
 echo   optional build identifier displayed by java -version
+exit /b 1
 
 :end
+exit /b %errorlevel%
--- a/make/windows/build.make	Thu Mar 18 12:14:59 2010 -0400
+++ b/make/windows/build.make	Thu Apr 01 11:23:01 2010 -0400
@@ -27,6 +27,9 @@
 # environment variables (Variant, WorkSpace, BootStrapDir, BuildUser, HOTSPOT_BUILD_VERSION)
 # are passed in as command line arguments.
 
+# Note: Running nmake or build.bat from the Windows command shell requires
+# that "sh" be accessible on the PATH. An MKS install does this.
+
 # SA components are built if BUILD_WIN_SA=1 is specified.
 # See notes in README. This produces files:
 #  1. sa-jdi.jar       - This is built before building jvm.dll
@@ -233,6 +236,12 @@
 	cd $(variantDir)
 	nmake -nologo -f $(WorkSpace)\make\windows\makefiles\top.make BUILD_FLAVOR=product DEVELOP=1 ARCH=$(ARCH)
 
+# target to create just the directory structure
+tree: checks $(variantDir) $(variantDir)\local.make sanity
+	mkdir $(variantDir)\product
+	mkdir $(variantDir)\debug
+	mkdir $(variantDir)\fastdebug
+
 sanity:
 	@ echo;
 	@ cd $(variantDir)
--- a/make/windows/create.bat	Thu Mar 18 12:14:59 2010 -0400
+++ b/make/windows/create.bat	Thu Apr 01 11:23:01 2010 -0400
@@ -36,6 +36,9 @@
 REM Since we don't have uname and we could be cross-compiling,
 REM Use the compiler to determine which ARCH we are building
 REM 
+REM Note: Running this batch file from the Windows command shell requires
+REM that "grep" be accessible on the PATH. An MKS install does this.
+REM 
 cl 2>&1 | grep "IA-64" >NUL
 if %errorlevel% == 0 goto isia64
 cl 2>&1 | grep "AMD64" >NUL
--- a/make/windows/get_msc_ver.sh	Thu Mar 18 12:14:59 2010 -0400
+++ b/make/windows/get_msc_ver.sh	Thu Apr 01 11:23:01 2010 -0400
@@ -22,6 +22,8 @@
 #  
 #
 
+set -e
+
 # This shell script echoes "MSC_VER=<munged version of cl>"
 # It ignores the micro version component.
 # Examples:
@@ -38,17 +40,20 @@
 # sh, and it has been found that sometimes `which sh` fails.
 
 if [ "x$HotSpotMksHome" != "x" ]; then
- MKS_HOME="$HotSpotMksHome"
+  TOOL_DIR="$HotSpotMksHome"
 else
- SH=`which sh`
- MKS_HOME=`dirname "$SH"`
+  # HotSpotMksHome is not set so use the directory that contains "sh".
+  # This works with both MKS and Cygwin.
+  SH=`which sh`
+  TOOL_DIR=`dirname "$SH"`
 fi
 
-HEAD="$MKS_HOME/head"
-ECHO="$MKS_HOME/echo"
-EXPR="$MKS_HOME/expr"
-CUT="$MKS_HOME/cut"
-SED="$MKS_HOME/sed"
+DIRNAME="$TOOL_DIR/dirname"
+HEAD="$TOOL_DIR/head"
+ECHO="$TOOL_DIR/echo"
+EXPR="$TOOL_DIR/expr"
+CUT="$TOOL_DIR/cut"
+SED="$TOOL_DIR/sed"
 
 if [ "x$FORCE_MSC_VER" != "x" ]; then
   echo "MSC_VER=$FORCE_MSC_VER"
@@ -70,7 +75,15 @@
 if [ "x$FORCE_LINK_VER" != "x" ]; then
   echo "LINK_VER=$FORCE_LINK_VER"
 else
-  LINK_VER_RAW=`link 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'`
+  # use the "link" command that is co-located with the "cl" command
+  cl_cmd=`which cl`
+  if [ "x$cl_cmd" != "x" ]; then
+    link_cmd=`$DIRNAME "$cl_cmd"`/link
+  else
+    # which can't find "cl" so just use which ever "link" we find
+    link_cmd="link"
+  fi
+  LINK_VER_RAW=`"$link_cmd" 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'`
   LINK_VER_MAJOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f1`
   LINK_VER_MINOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f2`
   LINK_VER_MICRO=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f3`
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -1065,7 +1065,7 @@
           __ movptr(rbx_temp, Address(rsi_array, elem_offset));
           __ movptr(Address(rax_argslot, slot_offset), rbx_temp);
           elem_offset += type2aelembytes(elem_type);
-          slot_offset += Interpreter::stackElementSize();
+           slot_offset += Interpreter::stackElementSize();
         }
       }
 
--- a/src/os/linux/vm/os_linux.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/os/linux/vm/os_linux.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -22,6 +22,8 @@
  *
  */
 
+# define __STDC_FORMAT_MACROS
+
 // do not include  precompiled  header file
 # include "incls/_os_linux.cpp.incl"
 
@@ -53,6 +55,8 @@
 # include <sys/ipc.h>
 # include <sys/shm.h>
 # include <link.h>
+# include <stdint.h>
+# include <inttypes.h>
 
 #define MAX_PATH    (2 * K)
 
@@ -2492,6 +2496,91 @@
     != MAP_FAILED;
 }
 
+// Linux uses a growable mapping for the stack, and if the mapping for
+// the stack guard pages is not removed when we detach a thread the
+// stack cannot grow beyond the pages where the stack guard was
+// mapped.  If at some point later in the process the stack expands to
+// that point, the Linux kernel cannot expand the stack any further
+// because the guard pages are in the way, and a segfault occurs.
+//
+// However, it's essential not to split the stack region by unmapping
+// a region (leaving a hole) that's already part of the stack mapping,
+// so if the stack mapping has already grown beyond the guard pages at
+// the time we create them, we have to truncate the stack mapping.
+// So, we need to know the extent of the stack mapping when
+// create_stack_guard_pages() is called.
+
+// Find the bounds of the stack mapping.  Return true for success.
+//
+// We only need this for stacks that are growable: at the time of
+// writing thread stacks don't use growable mappings (i.e. those
+// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
+// only applies to the main thread.
+static bool
+get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
+{
+  FILE *f = fopen("/proc/self/maps", "r");
+  if (f == NULL)
+    return false;
+
+  while (!feof(f)) {
+    size_t dummy;
+    char *str = NULL;
+    ssize_t len = getline(&str, &dummy, f);
+    if (len == -1) {
+      fclose(f);
+      return false;
+    }
+
+    if (len > 0 && str[len-1] == '\n') {
+      str[len-1] = 0;
+      len--;
+    }
+
+    static const char *stack_str = "[stack]";
+    if (len > (ssize_t)strlen(stack_str)
+       && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
+      if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
+        uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
+        if (sp >= *bottom && sp <= *top) {
+          free(str);
+          fclose(f);
+          return true;
+        }
+      }
+    }
+    free(str);
+  }
+  fclose(f);
+  return false;
+}
+
+// If the (growable) stack mapping already extends beyond the point
+// where we're going to put our guard pages, truncate the mapping at
+// that point by munmap()ping it.  This ensures that when we later
+// munmap() the guard pages we don't leave a hole in the stack
+// mapping.
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+  uintptr_t stack_extent, stack_base;
+  if (get_stack_bounds(&stack_extent, &stack_base)) {
+    if (stack_extent < (uintptr_t)addr)
+      ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
+  }
+
+  return os::commit_memory(addr, size);
+}
+
+// If this is a growable mapping, remove the guard pages entirely by
+// munmap()ping them.  If not, just call uncommit_memory().
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+  uintptr_t stack_extent, stack_base;
+  if (get_stack_bounds(&stack_extent, &stack_base)) {
+    return ::munmap(addr, size) == 0;
+  }
+
+  return os::uncommit_memory(addr, size);
+}
+
 static address _highest_vm_reserved_address = NULL;
 
 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
--- a/src/os/solaris/dtrace/hotspot.d	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/os/solaris/dtrace/hotspot.d	Thu Apr 01 11:23:01 2010 -0400
@@ -25,9 +25,20 @@
 provider hotspot {
   probe class__loaded(char*, uintptr_t, void*, uintptr_t);
   probe class__unloaded(char*, uintptr_t, void*, uintptr_t);
+  probe class__initialization__required(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__recursive(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__concurrent(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__erroneous(char*, uintptr_t, void*, intptr_t, int);
+  probe class__initialization__super__failed(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__clinit(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__error(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__end(char*, uintptr_t, void*, intptr_t,int);
   probe vm__init__begin();
   probe vm__init__end();
   probe vm__shutdown();
+  probe vmops__request(char*, uintptr_t, int);
+  probe vmops__begin(char*, uintptr_t, int);
+  probe vmops__end(char*, uintptr_t, int);
   probe gc__begin(uintptr_t);
   probe gc__end();
   probe mem__pool__gc__begin(
@@ -38,6 +49,12 @@
     uintptr_t, uintptr_t, uintptr_t, uintptr_t);
   probe thread__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
   probe thread__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+  probe thread__sleep__begin(long long);
+  probe thread__sleep__end(int);
+  probe thread__yield();
+  probe thread__park__begin(uintptr_t, int, long long);
+  probe thread__park__end(uintptr_t);
+  probe thread__unpark(uintptr_t);
   probe method__compile__begin(
     char*, uintptr_t, char*, uintptr_t, char*, uintptr_t, char*, uintptr_t); 
   probe method__compile__end(
--- a/src/os/solaris/vm/attachListener_solaris.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/os/solaris/vm/attachListener_solaris.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -668,13 +668,18 @@
     }
   }
 
-  if (strcmp(name, "ExtendedDTraceProbes") != 0) {
-    out->print_cr("flag '%s' cannot be changed", name);
-    return JNI_ERR;
+  if (strcmp(name, "ExtendedDTraceProbes") == 0) {
+    DTrace::set_extended_dprobes(flag);
+    return JNI_OK;
   }
 
-  DTrace::set_extended_dprobes(flag);
-  return JNI_OK;
+  if (strcmp(name, "DTraceMonitorProbes") == 0) {
+    DTrace::set_monitor_dprobes(flag);
+    return JNI_OK;
+  }
+
+  out->print_cr("flag '%s' cannot be changed", name);
+  return JNI_ERR;
 }
 
 void AttachListener::pd_detachall() {
--- a/src/os/solaris/vm/os_solaris.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/os/solaris/vm/os_solaris.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -2698,6 +2698,14 @@
   }
 }
 
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+  return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+  return os::uncommit_memory(addr, size);
+}
+
 // Change the page size in a given range.
 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
   assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
--- a/src/os/windows/vm/os_windows.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/os/windows/vm/os_windows.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -2803,6 +2803,14 @@
   return VirtualFree(addr, 0, MEM_RELEASE) != 0;
 }
 
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+  return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+  return os::uncommit_memory(addr, size);
+}
+
 // Set protections specified
 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
                         bool is_committed) {
--- a/src/share/vm/includeDB_core	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/includeDB_core	Thu Apr 01 11:23:01 2010 -0400
@@ -2026,6 +2026,7 @@
 
 instanceKlass.cpp                       collectedHeap.inline.hpp
 instanceKlass.cpp                       compileBroker.hpp
+instanceKlass.cpp                       dtrace.hpp
 instanceKlass.cpp                       fieldDescriptor.hpp
 instanceKlass.cpp                       genOopClosures.inline.hpp
 instanceKlass.cpp                       handles.inline.hpp
@@ -2485,6 +2486,7 @@
 jvm.cpp                                 collectedHeap.inline.hpp
 jvm.cpp                                 copy.hpp
 jvm.cpp                                 defaultStream.hpp
+jvm.cpp                                 dtrace.hpp
 jvm.cpp                                 dtraceJSDT.hpp
 jvm.cpp                                 events.hpp
 jvm.cpp                                 handles.inline.hpp
@@ -4458,6 +4460,7 @@
 
 unsafe.cpp                              allocation.inline.hpp
 unsafe.cpp                              copy.hpp
+unsafe.cpp                              dtrace.hpp
 unsafe.cpp                              globals.hpp
 unsafe.cpp                              interfaceSupport.hpp
 unsafe.cpp                              jni.h
@@ -4629,6 +4632,7 @@
 
 vmThread.cpp                            collectedHeap.hpp
 vmThread.cpp                            compileBroker.hpp
+vmThread.cpp                            dtrace.hpp
 vmThread.cpp                            events.hpp
 vmThread.cpp                            interfaceSupport.hpp
 vmThread.cpp                            methodOop.hpp
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/oops/instanceKlass.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -25,6 +25,58 @@
 # include "incls/_precompiled.incl"
 # include "incls/_instanceKlass.cpp.incl"
 
+#ifdef DTRACE_ENABLED
+
+HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required,
+  char*, intptr_t, oop, intptr_t);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__concurrent,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__erroneous,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__super__failed,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__clinit,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__error,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
+  char*, intptr_t, oop, intptr_t, int);
+
+#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)          \
+  {                                                              \
+    char* data = NULL;                                           \
+    int len = 0;                                                 \
+    symbolOop name = (clss)->name();                             \
+    if (name != NULL) {                                          \
+      data = (char*)name->bytes();                               \
+      len = name->utf8_length();                                 \
+    }                                                            \
+    HS_DTRACE_PROBE4(hotspot, class__initialization__##type,     \
+      data, len, (clss)->class_loader(), thread_type);           \
+  }
+
+#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
+  {                                                              \
+    char* data = NULL;                                           \
+    int len = 0;                                                 \
+    symbolOop name = (clss)->name();                             \
+    if (name != NULL) {                                          \
+      data = (char*)name->bytes();                               \
+      len = name->utf8_length();                                 \
+    }                                                            \
+    HS_DTRACE_PROBE5(hotspot, class__initialization__##type,     \
+      data, len, (clss)->class_loader(), thread_type, wait);     \
+  }
+
+#else //  ndef DTRACE_ENABLED
+
+#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)
+#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait)
+
+#endif //  ndef DTRACE_ENABLED
+
 bool instanceKlass::should_be_initialized() const {
   return !is_initialized();
 }
@@ -292,6 +344,10 @@
   // A class could already be verified, since it has been reflected upon.
   this_oop->link_class(CHECK);
 
+  DTRACE_CLASSINIT_PROBE(required, instanceKlass::cast(this_oop()), -1);
+
+  bool wait = false;
+
   // refer to the JVM book page 47 for description of steps
   // Step 1
   { ObjectLocker ol(this_oop, THREAD);
@@ -303,19 +359,25 @@
     // we might end up throwing IE from link/symbol resolution sites
     // that aren't expected to throw.  This would wreak havoc.  See 6320309.
     while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) {
+        wait = true;
       ol.waitUninterruptibly(CHECK);
     }
 
     // Step 3
-    if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self))
+    if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) {
+      DTRACE_CLASSINIT_PROBE_WAIT(recursive, instanceKlass::cast(this_oop()), -1,wait);
       return;
+    }
 
     // Step 4
-    if (this_oop->is_initialized())
+    if (this_oop->is_initialized()) {
+      DTRACE_CLASSINIT_PROBE_WAIT(concurrent, instanceKlass::cast(this_oop()), -1,wait);
       return;
+    }
 
     // Step 5
     if (this_oop->is_in_error_state()) {
+      DTRACE_CLASSINIT_PROBE_WAIT(erroneous, instanceKlass::cast(this_oop()), -1,wait);
       ResourceMark rm(THREAD);
       const char* desc = "Could not initialize class ";
       const char* className = this_oop->external_name();
@@ -348,6 +410,7 @@
         this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads
         CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, superclass initialization error is thrown below
       }
+      DTRACE_CLASSINIT_PROBE_WAIT(super__failed, instanceKlass::cast(this_oop()), -1,wait);
       THROW_OOP(e());
     }
   }
@@ -356,6 +419,7 @@
   {
     assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
     JavaThread* jt = (JavaThread*)THREAD;
+    DTRACE_CLASSINIT_PROBE_WAIT(clinit, instanceKlass::cast(this_oop()), -1,wait);
     // Timer includes any side effects of class initialization (resolution,
     // etc), but not recursive entry into call_class_initializer().
     PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
@@ -383,6 +447,7 @@
       this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
       CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, class initialization error is thrown below
     }
+    DTRACE_CLASSINIT_PROBE_WAIT(error, instanceKlass::cast(this_oop()), -1,wait);
     if (e->is_a(SystemDictionary::Error_klass())) {
       THROW_OOP(e());
     } else {
@@ -392,6 +457,7 @@
                 &args);
     }
   }
+  DTRACE_CLASSINIT_PROBE_WAIT(end, instanceKlass::cast(this_oop()), -1,wait);
 }
 
 
--- a/src/share/vm/prims/jvm.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/prims/jvm.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -26,6 +26,10 @@
 #include "incls/_jvm.cpp.incl"
 #include <errno.h>
 
+HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__end, int);
+HS_DTRACE_PROBE_DECL0(hotspot, thread__yield);
+
 /*
   NOTE about use of any ctor or function call that can trigger a safepoint/GC:
   such ctors and calls MUST NOT come between an oop declaration/init and its
@@ -2762,6 +2766,7 @@
 JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))
   JVMWrapper("JVM_Yield");
   if (os::dont_yield()) return;
+  HS_DTRACE_PROBE0(hotspot, thread__yield);
   // When ConvertYieldToSleep is off (default), this matches the classic VM use of yield.
   // Critical for similar threading behaviour
   if (ConvertYieldToSleep) {
@@ -2787,6 +2792,8 @@
   // And set new thread state to SLEEPING.
   JavaThreadSleepState jtss(thread);
 
+  HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis);
+
   if (millis == 0) {
     // When ConvertSleepToYield is on, this matches the classic VM implementation of
     // JVM_Sleep. Critical for similar threading behaviour (Win32)
@@ -2807,6 +2814,7 @@
       // An asynchronous exception (e.g., ThreadDeathException) could have been thrown on
       // us while we were sleeping. We do not overwrite those.
       if (!HAS_PENDING_EXCEPTION) {
+        HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);
         // TODO-FIXME: THROW_MSG returns which means we will not call set_state()
         // to properly restore the thread state.  That's likely wrong.
         THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
@@ -2814,6 +2822,7 @@
     }
     thread->osthread()->set_state(old_state);
   }
+  HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);
 JVM_END
 
 JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
--- a/src/share/vm/prims/unsafe.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/prims/unsafe.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -29,6 +29,10 @@
 #include "incls/_precompiled.incl"
 #include "incls/_unsafe.cpp.incl"
 
+HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t);
+
 #define MAX_OBJECT_SIZE \
   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
     + ((julong)max_jint * sizeof(double)) )
@@ -1083,8 +1087,10 @@
 
 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
   UnsafeWrapper("Unsafe_Park");
+  HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
   JavaThreadParkedState jtps(thread, time != 0);
   thread->parker()->park(isAbsolute != 0, time);
+  HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
 UNSAFE_END
 
 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
@@ -1116,6 +1122,7 @@
     }
   }
   if (p != NULL) {
+    HS_DTRACE_PROBE1(hotspot, thread__unpark, p);
     p->unpark();
   }
 UNSAFE_END
--- a/src/share/vm/runtime/globals.hpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/runtime/globals.hpp	Thu Apr 01 11:23:01 2010 -0400
@@ -2293,6 +2293,10 @@
           "print safepoint statistics only when safepoint takes"            \
           " more than PrintSafepointSatisticsTimeout in millis")            \
                                                                             \
+  product(bool, TraceSafepointCleanupTime, false,                           \
+          "print the break down of clean up tasks performed during"         \
+          " safepoint")                                                     \
+                                                                            \
   develop(bool, InlineAccessors, true,                                      \
           "inline accessor methods (get/set)")                              \
                                                                             \
--- a/src/share/vm/runtime/os.hpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/runtime/os.hpp	Thu Apr 01 11:23:01 2010 -0400
@@ -218,6 +218,9 @@
 
   static bool   guard_memory(char* addr, size_t bytes);
   static bool   unguard_memory(char* addr, size_t bytes);
+  static bool   create_stack_guard_pages(char* addr, size_t bytes);
+  static bool   remove_stack_guard_pages(char* addr, size_t bytes);
+
   static char*  map_memory(int fd, const char* file_name, size_t file_offset,
                            char *addr, size_t bytes, bool read_only = false,
                            bool allow_exec = false);
--- a/src/share/vm/runtime/safepoint.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/runtime/safepoint.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -457,21 +457,21 @@
 // Various cleaning tasks that should be done periodically at safepoints
 void SafepointSynchronize::do_cleanup_tasks() {
   {
-    TraceTime t1("deflating idle monitors", TraceSafepoint);
+    TraceTime t1("deflating idle monitors", TraceSafepointCleanupTime);
     ObjectSynchronizer::deflate_idle_monitors();
   }
 
   {
-    TraceTime t2("updating inline caches", TraceSafepoint);
+    TraceTime t2("updating inline caches", TraceSafepointCleanupTime);
     InlineCacheBuffer::update_inline_caches();
   }
 
   if(UseCounterDecay && CounterDecay::is_decay_needed()) {
-    TraceTime t3("decaying counter", TraceSafepoint);
+    TraceTime t3("decaying counter", TraceSafepointCleanupTime);
     CounterDecay::decay();
   }
 
-  TraceTime t4("sweeping nmethods", TraceSafepoint);
+  TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime);
   NMethodSweeper::sweep();
 }
 
--- a/src/share/vm/runtime/thread.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/runtime/thread.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -2137,7 +2137,7 @@
   int allocate = os::allocate_stack_guard_pages();
   // warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
 
-  if (allocate && !os::commit_memory((char *) low_addr, len)) {
+  if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {
     warning("Attempt to allocate stack guard pages failed.");
     return;
   }
@@ -2158,7 +2158,7 @@
   size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
 
   if (os::allocate_stack_guard_pages()) {
-    if (os::uncommit_memory((char *) low_addr, len)) {
+    if (os::remove_stack_guard_pages((char *) low_addr, len)) {
       _stack_guard_state = stack_guard_unused;
     } else {
       warning("Attempt to deallocate stack guard pages failed.");
--- a/src/share/vm/runtime/vmThread.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/runtime/vmThread.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -25,6 +25,10 @@
 # include "incls/_precompiled.incl"
 # include "incls/_vmThread.cpp.incl"
 
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int);
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int);
+
 // Dummy VM operation to act as first element in our circular double-linked list
 class VM_Dummy: public VM_Operation {
   VMOp_Type type() const { return VMOp_Dummy; }
@@ -132,6 +136,10 @@
 //-----------------------------------------------------------------
 // High-level interface
 bool VMOperationQueue::add(VM_Operation *op) {
+
+  HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()),
+                   op->evaluation_mode());
+
   // Encapsulates VM queue policy. Currently, that
   // only involves putting them on the right list
   if (op->evaluate_at_safepoint()) {
@@ -325,7 +333,11 @@
 
   {
     PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
+    HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()),
+                     op->evaluation_mode());
     op->evaluate();
+    HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
+                     op->evaluation_mode());
   }
 
   // Last access of info in _cur_vm_operation!
--- a/src/share/vm/services/dtraceAttacher.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/services/dtraceAttacher.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -135,4 +135,9 @@
   }
 }
 
+void DTrace::set_monitor_dprobes(bool flag) {
+  // explicit setting of DTraceMonitorProbes flag
+  set_bool_flag("DTraceMonitorProbes", flag);
+}
+
 #endif /* SOLARIS */
--- a/src/share/vm/services/dtraceAttacher.hpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/services/dtraceAttacher.hpp	Thu Apr 01 11:23:01 2010 -0400
@@ -41,4 +41,6 @@
   static void detach_all_clients();
   // set ExtendedDTraceProbes flag
   static void set_extended_dprobes(bool value);
+  // set DTraceMonitorProbes flag
+  static void set_monitor_dprobes(bool value);
 };
--- a/src/share/vm/services/management.cpp	Thu Mar 18 12:14:59 2010 -0400
+++ b/src/share/vm/services/management.cpp	Thu Apr 01 11:23:01 2010 -0400
@@ -1537,7 +1537,6 @@
     global->type = JMM_VMGLOBAL_TYPE_JSTRING;
   } else {
     global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;
-    assert(false, "Unsupported VMGlobal Type");
     return false;
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6929067/T.java	Thu Apr 01 11:23:01 2010 -0400
@@ -0,0 +1,12 @@
+public class T
+{
+  public static boolean foo(boolean bar)
+  {
+    return bar;
+  }
+
+  public static void printIt()
+  {
+    System.out.println("Hello");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6929067/Test6929067.sh	Thu Apr 01 11:23:01 2010 -0400
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+##
+## @test Test6929067.sh
+## @bug 6929067
+## @summary Stack guard pages should be removed when thread is detached
+## @run shell Test6929067.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+then
+  PARENT=`dirname \`which java\``
+  TESTJAVA=`dirname ${PARENT}`
+  echo "TESTJAVA not set, selecting " ${TESTJAVA}
+  echo "If this is incorrect, try setting the variable manually."
+fi
+
+BIT_FLAG=""
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  Linux)
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    ;;
+  SunOS | Windows_* )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    echo "Test passed; only valid for Linux"
+    exit 0;
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/i386/client:/usr/openwin/lib:/usr/dt/lib:/usr/lib:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+THIS_DIR=`pwd`
+
+cp ${TESTSRC}${FS}invoke.c ${THIS_DIR}
+cp ${TESTSRC}${FS}T.java ${THIS_DIR}
+
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
+
+${TESTJAVA}${FS}bin${FS}javac T.java
+
+gcc -o invoke -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c ${TESTJAVA}/jre/lib/i386/client/libjvm.so
+./invoke
+exit $?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6929067/invoke.c	Thu Apr 01 11:23:01 2010 -0400
@@ -0,0 +1,90 @@
+#include <assert.h>
+#include <jni.h>
+#include <alloca.h>
+
+#include <pthread.h>
+
+union env_union
+{
+  void *void_env;
+  JNIEnv *jni_env;
+};
+
+union env_union tmp;
+JNIEnv* env;
+JavaVM* jvm;
+JavaVMInitArgs vm_args;
+JavaVMOption options[1];
+jclass class_id;
+jmethodID method_id;
+jint result;
+
+long product(unsigned long n, unsigned long m) {
+    if (m == 1) {
+      return n;
+    } else {
+      int *p = alloca(sizeof (int));
+      *p = n;
+      return product (n, m-1) + *p;
+    }
+}
+
+void *
+floobydust (void *p)
+{
+  (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL);
+  env = tmp.jni_env;
+
+  class_id = (*env)->FindClass (env, "T");
+  assert (class_id);
+
+  method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V");
+  assert (method_id);
+
+  (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL);
+
+  (*jvm)->DetachCurrentThread(jvm);
+
+  printf("%ld\n", product(5000,5000));
+
+  (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL);
+  env = tmp.jni_env;
+
+  class_id = (*env)->FindClass (env, "T");
+  assert (class_id);
+
+  method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V");
+  assert (method_id);
+
+  (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL);
+
+  (*jvm)->DetachCurrentThread(jvm);
+
+  printf("%ld\n", product(5000,5000));
+
+  return NULL;
+}
+
+int
+main (int argc, const char** argv)
+{
+  options[0].optionString = "-Xss320k";
+
+  vm_args.version = JNI_VERSION_1_2;
+  vm_args.ignoreUnrecognized = JNI_TRUE;
+  vm_args.options = options;
+  vm_args.nOptions = 1;
+
+  result = JNI_CreateJavaVM (&jvm, &tmp.void_env, &vm_args);
+  assert (result >= 0);
+
+  env = tmp.jni_env;
+
+  floobydust (NULL);
+
+  pthread_t thr;
+  pthread_create (&thr, NULL, floobydust, NULL);
+  pthread_join (thr, NULL);
+
+  return 0;
+}