changeset 76:d6fe2e4959d6

Merge
author rasbold
date Fri, 21 Mar 2008 08:32:17 -0700
parents cd0742ba123c (diff) f68325221ce1 (current diff)
children 36cd3cc4d27b d05ebaf00ed0 deb97b8ef02b
files src/cpu/x86/vm/assembler_x86_64.cpp src/share/vm/runtime/arguments.cpp src/share/vm/runtime/globals.hpp
diffstat 46 files changed, 549 insertions(+), 309 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/os/linux/ps_core.c	Fri Mar 21 00:49:06 2008 -0700
+++ b/agent/src/os/linux/ps_core.c	Fri Mar 21 08:32:17 2008 -0700
@@ -518,10 +518,10 @@
 }
 
 static ps_prochandle_ops core_ops = {
-   release:  core_release,
-   p_pread:  core_read_data,
-   p_pwrite: core_write_data,
-   get_lwp_regs: core_get_lwp_regs
+   .release=  core_release,
+   .p_pread=  core_read_data,
+   .p_pwrite= core_write_data,
+   .get_lwp_regs= core_get_lwp_regs
 };
 
 // read regs and create thread from NT_PRSTATUS entries from core file
--- a/agent/src/os/linux/ps_proc.c	Fri Mar 21 00:49:06 2008 -0700
+++ b/agent/src/os/linux/ps_proc.c	Fri Mar 21 08:32:17 2008 -0700
@@ -291,10 +291,10 @@
 }
 
 static ps_prochandle_ops process_ops = {
-  release:  process_cleanup,
-  p_pread:  process_read_data,
-  p_pwrite: process_write_data,
-  get_lwp_regs: process_get_lwp_regs
+  .release=  process_cleanup,
+  .p_pread=  process_read_data,
+  .p_pwrite= process_write_data,
+  .get_lwp_regs= process_get_lwp_regs
 };
 
 // attach to the process. One and only one exposed stuff
--- a/build/linux/Makefile	Fri Mar 21 00:49:06 2008 -0700
+++ b/build/linux/Makefile	Fri Mar 21 08:32:17 2008 -0700
@@ -80,6 +80,11 @@
   MFLAGS += " LP64=1 "
 endif
 
+# pass USE_SUNCC further, through MFLAGS
+ifdef USE_SUNCC
+  MFLAGS += " USE_SUNCC=1 "
+endif
+
 # The following renders pathnames in generated Makefiles valid on
 # machines other than the machine containing the build tree.
 #
--- a/build/linux/makefiles/amd64.make	Fri Mar 21 00:49:06 2008 -0700
+++ b/build/linux/makefiles/amd64.make	Fri Mar 21 08:32:17 2008 -0700
@@ -35,6 +35,8 @@
 CFLAGS += -D_LP64=1
 
 # The serviceability agent relies on frame pointer (%rbp) to walk thread stack
-CFLAGS += -fno-omit-frame-pointer
+ifndef USE_SUNCC
+  CFLAGS += -fno-omit-frame-pointer
+endif
 
 OPT_CFLAGS/compactingPermGenGen.o = -O1
--- a/build/linux/makefiles/buildtree.make	Fri Mar 21 00:49:06 2008 -0700
+++ b/build/linux/makefiles/buildtree.make	Fri Mar 21 08:32:17 2008 -0700
@@ -63,7 +63,11 @@
 # For now, until the compiler is less wobbly:
 TESTFLAGS	= -Xbatch -showversion
 
-PLATFORM_FILE	= $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH)
+ifdef USE_SUNCC
+PLATFORM_FILE	= $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
+else
+PLATFORM_FILE   = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH)
+endif
 
 ifdef FORCE_TIERED
 ifeq		($(VARIANT),tiered)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build/linux/makefiles/sparcWorks.make	Fri Mar 21 08:32:17 2008 -0700
@@ -0,0 +1,93 @@
+#
+# Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#  
+#
+
+#------------------------------------------------------------------------
+# CC, CPP & AS
+
+CPP = CC
+CC  = cc
+AS  = $(CC) -c
+
+ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
+ARCHFLAG/i486    = -m32
+ARCHFLAG/amd64   = -m64
+
+CFLAGS     += $(ARCHFLAG)
+AOUT_FLAGS += $(ARCHFLAG)
+LFLAGS     += $(ARCHFLAG)
+ASFLAGS    += $(ARCHFLAG)
+
+#------------------------------------------------------------------------
+# Compiler flags
+
+# position-independent code
+PICFLAG = -KPIC
+
+CFLAGS += $(PICFLAG)
+# no more exceptions
+CFLAGS += -features=no%except
+# Reduce code bloat by reverting back to 5.0 behavior for static initializers
+CFLAGS += -features=no%split_init
+# allow zero sized arrays
+CFLAGS += -features=zla
+
+# Use C++ Interpreter
+ifdef CC_INTERP
+  CFLAGS += -DCC_INTERP
+endif
+
+# We don't need libCstd.so and librwtools7.so, only libCrun.so
+CFLAGS += -library=Crun
+LIBS += -lCrun
+
+CFLAGS += -mt
+LFLAGS += -mt
+
+# Compiler warnings are treated as errors
+#WARNINGS_ARE_ERRORS = -errwarn=%all
+CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) 
+# Special cases
+CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) 
+
+# The flags to use for an Optimized build
+OPT_CFLAGS+=-xO4
+OPT_CFLAGS/NOOPT=-xO0
+
+#------------------------------------------------------------------------
+# Linker flags
+
+# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
+MAPFLAG = -Wl,--version-script=FILENAME
+
+# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
+SONAMEFLAG = -h SONAME
+
+# Build shared library
+SHARED_FLAG = -G
+
+#------------------------------------------------------------------------
+# Debug flags
+DEBUG_CFLAGS += -g
+FASTDEBUG_CFLAGS = -g0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build/linux/platform_amd64.suncc	Fri Mar 21 08:32:17 2008 -0700
@@ -0,0 +1,17 @@
+os_family = linux
+
+arch = x86
+
+arch_model = x86_64
+
+os_arch = linux_x86
+
+os_arch_model = linux_x86_64
+
+lib_arch = amd64
+
+compiler = sparcWorks
+
+gnu_dis_arch = amd64
+
+sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DAMD64
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build/linux/platform_i486.suncc	Fri Mar 21 08:32:17 2008 -0700
@@ -0,0 +1,17 @@
+os_family = linux
+
+arch = x86
+
+arch_model = x86_32
+
+os_arch = linux_x86
+
+os_arch_model = linux_x86_32
+
+lib_arch = i386
+
+compiler = sparcWorks
+
+gnu_dis_arch = i386
+
+sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DIA32
--- a/build/windows/makefiles/compile.make	Fri Mar 21 00:49:06 2008 -0700
+++ b/build/windows/makefiles/compile.make	Fri Mar 21 08:32:17 2008 -0700
@@ -44,6 +44,10 @@
 #   /Od       Disable all optimizations
 #
 # NOTE: Normally following any of the above with a '-' will turn off that flag
+#
+# 6655385: For VS2003/2005 we now specify /Oy- (disable frame pointer
+# omission.)  This has little to no effect on performance while vastly
+# improving the quality of crash log stack traces involving jvm.dll.
 
 # These are always used in all compiles
 CPP_FLAGS=/nologo /W3 /WX
@@ -141,14 +145,14 @@
 !endif
 
 !if "$(COMPILER_NAME)" == "VS2003"
-PRODUCT_OPT_OPTION   = /O2
-FASTDEBUG_OPT_OPTION = /O2
+PRODUCT_OPT_OPTION   = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
 DEBUG_OPT_OPTION     = /Od
 !endif
 
 !if "$(COMPILER_NAME)" == "VS2005"
-PRODUCT_OPT_OPTION   = /O2
-FASTDEBUG_OPT_OPTION = /O2
+PRODUCT_OPT_OPTION   = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
 DEBUG_OPT_OPTION     = /Od
 GX_OPTION = /EHsc
 # This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib 
@@ -165,8 +169,8 @@
 
 # Compile for space above time.
 !if "$(Variant)" == "kernel"
-PRODUCT_OPT_OPTION   = /O1
-FASTDEBUG_OPT_OPTION = /O1
+PRODUCT_OPT_OPTION   = /O1 /Oy-
+FASTDEBUG_OPT_OPTION = /O1 /Oy-
 DEBUG_OPT_OPTION     = /Od
 !endif
 
--- a/src/cpu/x86/vm/assembler_x86_64.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/cpu/x86/vm/assembler_x86_64.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1304,7 +1304,7 @@
   emit_operand(src, dst);
 }
 
-void Assembler::mov64(Register dst, int64_t imm64) {
+void Assembler::mov64(Register dst, intptr_t imm64) {
   InstructionMark im(this);
   int encode = prefixq_and_encode(dst->encoding());
   emit_byte(0xB8 | encode);
@@ -1331,7 +1331,7 @@
   emit_operand(dst, src);
 }
 
-void Assembler::mov64(Address dst, int64_t imm32) {
+void Assembler::mov64(Address dst, intptr_t imm32) {
   assert(is_simm32(imm32), "lost bits");
   InstructionMark im(this);
   prefixq(dst);
--- a/src/os/linux/vm/attachListener_linux.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/os/linux/vm/attachListener_linux.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -232,7 +232,7 @@
   // where <ver> is the protocol version (1), <cmd> is the command
   // name ("load", "datadump", ...), and <arg> is an argument
   int expected_str_count = 2 + AttachOperation::arg_count_max;
-  int max_len = (strlen(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
+  const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
     AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
 
   char buf[max_len];
--- a/src/os/linux/vm/os_linux.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1261,19 +1261,13 @@
   return (1000 * 1000);
 }
 
-jlong os::timeofday() {
+jlong os::javaTimeMillis() {
   timeval time;
   int status = gettimeofday(&time, NULL);
   assert(status != -1, "linux error");
   return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
 }
 
-// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
-// _use_global_time is only set if CacheTimeMillis is true
-jlong os::javaTimeMillis() {
-  return (_use_global_time ? read_global_time() : timeofday());
-}
-
 #ifndef CLOCK_MONOTONIC
 #define CLOCK_MONOTONIC (1)
 #endif
--- a/src/os/solaris/vm/os_solaris.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1691,19 +1691,14 @@
   return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
 }
 
-jlong os::timeofday() {
+// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
+jlong os::javaTimeMillis() {
   timeval t;
   if (gettimeofday( &t, NULL) == -1)
-    fatal1("timeofday: gettimeofday (%s)", strerror(errno));
+    fatal1("os::javaTimeMillis: gettimeofday (%s)", strerror(errno));
   return jlong(t.tv_sec) * 1000  +  jlong(t.tv_usec) / 1000;
 }
 
-// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
-// _use_global_time is only set if CacheTimeMillis is true
-jlong os::javaTimeMillis() {
-  return (_use_global_time ? read_global_time() : timeofday());
-}
-
 jlong os::javaTimeNanos() {
   return (jlong)getTimeNanos();
 }
@@ -2785,16 +2780,15 @@
   return b;
 }
 
-char*
-os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
-  char* addr = NULL;
-  int   flags;
-
-  flags = MAP_PRIVATE | MAP_NORESERVE;
-  if (requested_addr != NULL) {
-      flags |= MAP_FIXED;
-      addr = requested_addr;
-  } else if (has_map_align && alignment_hint > (size_t) vm_page_size()) {
+char* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) {
+  char* addr = requested_addr;
+  int flags = MAP_PRIVATE | MAP_NORESERVE;
+
+  assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap");
+
+  if (fixed) {
+    flags |= MAP_FIXED;
+  } else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) {
     flags |= MAP_ALIGN;
     addr = (char*) alignment_hint;
   }
@@ -2802,11 +2796,14 @@
   // Map uncommitted pages PROT_NONE so we fail early if we touch an
   // uncommitted page. Otherwise, the read/write might succeed if we
   // have enough swap space to back the physical page.
-  addr = Solaris::mmap_chunk(addr, bytes, flags, PROT_NONE);
+  return mmap_chunk(addr, bytes, flags, PROT_NONE);
+}
+
+char* os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
+  char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL));
 
   guarantee(requested_addr == NULL || requested_addr == addr,
             "OS failed to return requested mmap address.");
-
   return addr;
 }
 
@@ -2832,6 +2829,31 @@
   // in one of the methods further up the call chain.  See bug 5044738.
   assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
 
+  // Since snv_84, Solaris attempts to honor the address hint - see 5003415.
+  // Give it a try, if the kernel honors the hint we can return immediately.
+  char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false);
+  volatile int err = errno;
+  if (addr == requested_addr) {
+    return addr;
+  } else if (addr != NULL) {
+    unmap_memory(addr, bytes);
+  }
+
+  if (PrintMiscellaneous && Verbose) {
+    char buf[256];
+    buf[0] = '\0';
+    if (addr == NULL) {
+      jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
+    }
+    warning("attempt_reserve_memory_at: couldn't reserve %d bytes at "
+            PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
+            "%s", bytes, requested_addr, addr, buf);
+  }
+
+  // Address hint method didn't work.  Fall back to the old method.
+  // In theory, once SNV becomes our oldest supported platform, this
+  // code will no longer be needed.
+  //
   // Repeatedly allocate blocks until the block is allocated at the
   // right spot. Give up after max_tries.
   int i;
--- a/src/os/solaris/vm/os_solaris.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/os/solaris/vm/os_solaris.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -156,6 +156,7 @@
   static int get_dev_zero_fd() { return _dev_zero_fd; }
   static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; }
   static char* mmap_chunk(char *addr, size_t size, int flags, int prot);
+  static char* anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed);
   static bool mpss_sanity_check(bool warn, size_t * page_size);
   static bool ism_sanity_check (bool warn, size_t * page_size);
 
--- a/src/os/windows/vm/os_windows.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -737,20 +737,13 @@
   return result;
 }
 
-jlong os::timeofday() {
-  FILETIME wt;
-  GetSystemTimeAsFileTime(&wt);
-  return windows_to_java_time(wt);
-}
-
-
-// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
-// _use_global_time is only set if CacheTimeMillis is true
 jlong os::javaTimeMillis() {
   if (UseFakeTimers) {
     return fake_time++;
   } else {
-    return (_use_global_time ? read_global_time() : timeofday());
+    FILETIME wt;
+    GetSystemTimeAsFileTime(&wt);
+    return windows_to_java_time(wt);
   }
 }
 
--- a/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -60,7 +60,18 @@
 
 #ifdef AMD64
 inline u8 Bytes::swap_u8(u8 x) {
+#ifdef SPARC_WORKS
+  // workaround for SunStudio12 CR6615391
+  __asm__ __volatile__ (
+    "bswapq %0"
+    :"=r" (x)        // output : register 0 => x
+    :"0"  (x)        // input  : x => register 0
+    :"0"             // clobbered register
+  );
+  return x;
+#else
   return bswap_64(x);
+#endif
 }
 #else
 // Helper function for swap_u8
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -62,8 +62,14 @@
 #endif // AMD64
 
 address os::current_stack_pointer() {
+#ifdef SPARC_WORKS
+  register void *esp;
+  __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
+  return (address) ((char*)esp + sizeof(long)*2);
+#else
   register void *esp __asm__ (SPELL_REG_SP);
   return (address) esp;
+#endif
 }
 
 char* os::non_memory_address_word() {
@@ -139,7 +145,12 @@
 }
 
 intptr_t* _get_previous_fp() {
+#ifdef SPARC_WORKS
+  register intptr_t **ebp;
+  __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
+#else
   register intptr_t **ebp __asm__ (SPELL_REG_FP);
+#endif
   return (intptr_t*) *ebp;   // we want what it points to.
 }
 
@@ -560,7 +571,9 @@
 #else
 size_t os::Linux::min_stack_allowed  =  (48 DEBUG_ONLY(+4))*K;
 
+#ifdef __GNUC__
 #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
+#endif
 
 // Test if pthread library can support variable thread stack size. LinuxThreads
 // in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads
@@ -591,7 +604,11 @@
     // return true and skip _thread_safety_check(), so we may not be able to
     // detect stack-heap collisions. But otherwise it's harmless.
     //
+#ifdef __GNUC__
     return (GET_GS() != 0);
+#else
+    return false;
+#endif
   }
 }
 #endif // AMD64
--- a/src/share/vm/classfile/dictionary.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/classfile/dictionary.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -155,8 +155,8 @@
         for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
           // check the previous versions array for GC'ed weak refs
           PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
-          jweak cp_ref = pv_node->prev_constant_pool();
-          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+          jobject cp_ref = pv_node->prev_constant_pool();
+          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
           if (cp_ref == NULL) {
             delete pv_node;
             ik->previous_versions()->remove_at(i);
--- a/src/share/vm/code/dependencies.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/code/dependencies.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1499,9 +1499,12 @@
     // fall through:
     _change_type = Change_new_sub;
   case Change_new_sub:
-    _klass = instanceKlass::cast(_klass)->super();
-    if (_klass != NULL) {
-      return true;
+    // 6598190: brackets workaround Sun Studio C++ compiler bug 6629277
+    {
+      _klass = instanceKlass::cast(_klass)->super();
+      if (_klass != NULL) {
+        return true;
+      }
     }
     // else set up _ti_limit and fall through:
     _ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length();
--- a/src/share/vm/includeDB_core	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/includeDB_core	Fri Mar 21 08:32:17 2008 -0700
@@ -3067,6 +3067,7 @@
 
 oopMapCache.cpp                         allocation.inline.hpp
 oopMapCache.cpp                         handles.inline.hpp
+oopMapCache.cpp                         jvmtiRedefineClassesTrace.hpp
 oopMapCache.cpp                         oop.inline.hpp
 oopMapCache.cpp                         oopMapCache.hpp
 oopMapCache.cpp                         resourceArea.hpp
--- a/src/share/vm/interpreter/oopMapCache.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/interpreter/oopMapCache.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -532,6 +532,10 @@
     if (!_array[i].is_empty() && _array[i].method()->is_old()) {
       // Cache entry is occupied by an old redefined method and we don't want
       // to pin it down so flush the entry.
+      RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
+        _array[i].method()->name()->as_C_string(),
+        _array[i].method()->signature()->as_C_string(), i));
+
       _array[i].flush();
     }
 }
@@ -577,6 +581,15 @@
   // Entry is not in hashtable.
   // Compute entry and return it
 
+  if (method->should_not_be_cached()) {
+    // It is either not safe or not a good idea to cache this methodOop
+    // at this time. We give the caller of lookup() a copy of the
+    // interesting info via parameter entry_for, but we don't add it to
+    // the cache. See the gory details in methodOop.cpp.
+    compute_one_oop_map(method, bci, entry_for);
+    return;
+  }
+
   // First search for an empty slot
   for(i = 0; i < _probe_depth; i++) {
     entry  = entry_at(probe + i);
@@ -584,12 +597,6 @@
       entry->fill(method, bci);
       entry_for->resource_copy(entry);
       assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
-      if (method->is_old()) {
-        // The caller of lookup() will receive a copy of the interesting
-        // info via entry_for, but we don't keep an old redefined method in
-        // the cache to avoid pinning down the method.
-        entry->flush();
-      }
       return;
     }
   }
@@ -623,13 +630,6 @@
   }
   assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
 
-  if (method->is_old()) {
-    // The caller of lookup() will receive a copy of the interesting
-    // info via entry_for, but we don't keep an old redefined method in
-    // the cache to avoid pinning down the method.
-    entry->flush();
-  }
-
   return;
 }
 
--- a/src/share/vm/memory/compactingPermGenGen.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/memory/compactingPermGenGen.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -26,9 +26,27 @@
 #include "incls/_compactingPermGenGen.cpp.incl"
 
 
-// Recursively adjust all pointers in an object and all objects by
-// referenced it.  Clear marks on objects in order to prevent visiting
-// any object twice.
+// An ObjectClosure helper: Recursively adjust all pointers in an object
+// and all objects by referenced it. Clear marks on objects in order to
+// prevent visiting any object twice. This helper is used when the
+// RedefineClasses() API has been called.
+
+class AdjustSharedObjectClosure : public ObjectClosure {
+public:
+  void do_object(oop obj) {
+    if (obj->is_shared_readwrite()) {
+      if (obj->mark()->is_marked()) {
+        obj->init_mark();         // Don't revisit this object.
+        obj->adjust_pointers();   // Adjust this object's references.
+      }
+    }
+  }
+};
+
+
+// An OopClosure helper: Recursively adjust all pointers in an object
+// and all objects by referenced it. Clear marks on objects in order
+// to prevent visiting any object twice.
 
 class RecursiveAdjustSharedObjectClosure : public OopClosure {
 public:
@@ -274,15 +292,34 @@
 // objects in the space will page in more objects than we need.
 // Instead, use the system dictionary as strong roots into the read
 // write space.
+//
+// If a RedefineClasses() call has been made, then we have to iterate
+// over the entire shared read-write space in order to find all the
+// objects that need to be forwarded. For example, it is possible for
+// an nmethod to be found and marked in GC phase-1 only for the nmethod
+// to be freed by the time we reach GC phase-3. The underlying method
+// is still marked, but we can't (easily) find it in GC phase-3 so we
+// blow up in GC phase-4. With RedefineClasses() we want replaced code
+// (EMCP or obsolete) to go away (i.e., be collectible) once it is no
+// longer being executed by any thread so we keep minimal attachments
+// to the replaced code. However, we can't guarantee when those EMCP
+// or obsolete methods will be collected so they may still be out there
+// even after we've severed our minimal attachments.
 
 void CompactingPermGenGen::pre_adjust_pointers() {
   if (spec()->enable_shared_spaces()) {
-    RecursiveAdjustSharedObjectClosure blk;
-    Universe::oops_do(&blk);
-    StringTable::oops_do(&blk);
-    SystemDictionary::always_strong_classes_do(&blk);
-    TraversePlaceholdersClosure tpc;
-    SystemDictionary::placeholders_do(&tpc);
+    if (JvmtiExport::has_redefined_a_class()) {
+      // RedefineClasses() requires a brute force approach
+      AdjustSharedObjectClosure blk;
+      rw_space()->object_iterate(&blk);
+    } else {
+      RecursiveAdjustSharedObjectClosure blk;
+      Universe::oops_do(&blk);
+      StringTable::oops_do(&blk);
+      SystemDictionary::always_strong_classes_do(&blk);
+      TraversePlaceholdersClosure tpc;
+      SystemDictionary::placeholders_do(&tpc);
+    }
   }
 }
 
--- a/src/share/vm/oops/instanceKlass.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -972,7 +972,6 @@
     // These allocations will have to be freed if they are unused.
 
     // Allocate a new array of methods.
-    jmethodID* to_dealloc_jmeths = NULL;
     jmethodID* new_jmeths = NULL;
     if (length <= idnum) {
       // A new array will be needed (unless some other thread beats us to it)
@@ -983,7 +982,6 @@
     }
 
     // Allocate a new method ID.
-    jmethodID to_dealloc_id = NULL;
     jmethodID new_id = NULL;
     if (method_h->is_old() && !method_h->is_obsolete()) {
       // The method passed in is old (but not obsolete), we need to use the current version
@@ -997,40 +995,51 @@
       new_id = JNIHandles::make_jmethod_id(method_h);
     }
 
-    {
+    if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
+      // No need and unsafe to lock the JmethodIdCreation_lock at safepoint.
+      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
+    } else {
       MutexLocker ml(JmethodIdCreation_lock);
+      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
+    }
+  }
+  return id;
+}
 
-      // We must not go to a safepoint while holding this lock.
-      debug_only(No_Safepoint_Verifier nosafepoints;)
+
+jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
+                                        jmethodID new_id, jmethodID* new_jmeths) {
+  // Retry lookup after we got the lock or ensured we are at safepoint
+  jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
+  jmethodID  id                = NULL;
+  jmethodID  to_dealloc_id     = NULL;
+  jmethodID* to_dealloc_jmeths = NULL;
+  size_t     length;
 
-      // Retry lookup after we got the lock
-      jmeths = ik_h->methods_jmethod_ids_acquire();
-      if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
-        if (jmeths != NULL) {
-          // We have grown the array: copy the existing entries, and delete the old array
-          for (size_t index = 0; index < length; index++) {
-            new_jmeths[index+1] = jmeths[index+1];
-          }
-          to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
-        }
-        ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
-      } else {
-        id = jmeths[idnum+1];
-        to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
+  if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
+    if (jmeths != NULL) {
+      // We have grown the array: copy the existing entries, and delete the old array
+      for (size_t index = 0; index < length; index++) {
+        new_jmeths[index+1] = jmeths[index+1];
       }
-      if (id == NULL) {
-        id = new_id;
-        jmeths[idnum+1] = id;  // install the new method ID
-      } else {
-        to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
-      }
+      to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
     }
+    ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
+  } else {
+    id = jmeths[idnum+1];
+    to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
+  }
+  if (id == NULL) {
+    id = new_id;
+    jmeths[idnum+1] = id;  // install the new method ID
+  } else {
+    to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
+  }
 
-    // Free up unneeded or no longer needed resources
-    FreeHeap(to_dealloc_jmeths);
-    if (to_dealloc_id != NULL) {
-      JNIHandles::destroy_jmethod_id(to_dealloc_id);
-    }
+  // Free up unneeded or no longer needed resources
+  FreeHeap(to_dealloc_jmeths);
+  if (to_dealloc_id != NULL) {
+    JNIHandles::destroy_jmethod_id(to_dealloc_id);
   }
   return id;
 }
@@ -2187,12 +2196,20 @@
   RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
     ikh->external_name(), _previous_versions->length(), emcp_method_count));
   constantPoolHandle cp_h(ikh->constants());
-  jweak cp_ref = JNIHandles::make_weak_global(cp_h);
+  jobject cp_ref;
+  if (cp_h->is_shared()) {
+    // a shared ConstantPool requires a regular reference; a weak
+    // reference would be collectible
+    cp_ref = JNIHandles::make_global(cp_h);
+  } else {
+    cp_ref = JNIHandles::make_weak_global(cp_h);
+  }
   PreviousVersionNode * pv_node = NULL;
   objArrayOop old_methods = ikh->methods();
 
   if (emcp_method_count == 0) {
-    pv_node = new PreviousVersionNode(cp_ref, NULL);
+    // non-shared ConstantPool gets a weak reference
+    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
     RC_TRACE(0x00000400,
       ("add: all methods are obsolete; flushing any EMCP weak refs"));
   } else {
@@ -2212,7 +2229,8 @@
         }
       }
     }
-    pv_node = new PreviousVersionNode(cp_ref, method_refs);
+    // non-shared ConstantPool gets a weak reference
+    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs);
   }
 
   _previous_versions->append(pv_node);
@@ -2230,7 +2248,7 @@
     // check the previous versions array for a GC'ed weak refs
     pv_node = _previous_versions->at(i);
     cp_ref = pv_node->prev_constant_pool();
-    assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+    assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
     if (cp_ref == NULL) {
       delete pv_node;
       _previous_versions->remove_at(i);
@@ -2303,7 +2321,7 @@
           // check the previous versions array for a GC'ed weak refs
           pv_node = _previous_versions->at(j);
           cp_ref = pv_node->prev_constant_pool();
-          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
           if (cp_ref == NULL) {
             delete pv_node;
             _previous_versions->remove_at(j);
@@ -2401,8 +2419,8 @@
     // been GC'ed
     PreviousVersionNode * pv_node = _previous_versions->at(i);
 
-    jweak cp_ref = pv_node->prev_constant_pool();
-    assert(cp_ref != NULL, "weak reference was unexpectedly cleared");
+    jobject cp_ref = pv_node->prev_constant_pool();
+    assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
     if (cp_ref == NULL) {
       continue;  // robustness
     }
@@ -2462,10 +2480,11 @@
 
 // Construct a PreviousVersionNode entry for the array hung off
 // the instanceKlass.
-PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
-  GrowableArray<jweak>* prev_EMCP_methods) {
+PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
+  bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
 
   _prev_constant_pool = prev_constant_pool;
+  _prev_cp_is_weak = prev_cp_is_weak;
   _prev_EMCP_methods = prev_EMCP_methods;
 }
 
@@ -2473,7 +2492,11 @@
 // Destroy a PreviousVersionNode
 PreviousVersionNode::~PreviousVersionNode() {
   if (_prev_constant_pool != NULL) {
-    JNIHandles::destroy_weak_global(_prev_constant_pool);
+    if (_prev_cp_is_weak) {
+      JNIHandles::destroy_weak_global(_prev_constant_pool);
+    } else {
+      JNIHandles::destroy_global(_prev_constant_pool);
+    }
   }
 
   if (_prev_EMCP_methods != NULL) {
@@ -2493,8 +2516,8 @@
   _prev_constant_pool_handle = constantPoolHandle();  // NULL handle
   _prev_EMCP_method_handles = NULL;
 
-  jweak cp_ref = pv_node->prev_constant_pool();
-  assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared");
+  jobject cp_ref = pv_node->prev_constant_pool();
+  assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
   if (cp_ref == NULL) {
     return;  // robustness
   }
--- a/src/share/vm/oops/instanceKlass.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/oops/instanceKlass.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -432,6 +432,8 @@
                                                         _enclosing_method_method_index = method_index; }
 
   // jmethodID support
+  static jmethodID get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
+                                  jmethodID new_id, jmethodID* new_jmeths);
   static jmethodID jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h);
   jmethodID jmethod_id_or_null(methodOop method);
 
@@ -838,11 +840,20 @@
 // A collection point for interesting information about the previous
 // version(s) of an instanceKlass. This class uses weak references to
 // the information so that the information may be collected as needed
-// by the system. A GrowableArray of PreviousVersionNodes is attached
+// by the system. If the information is shared, then a regular
+// reference must be used because a weak reference would be seen as
+// collectible. A GrowableArray of PreviousVersionNodes is attached
 // to the instanceKlass as needed. See PreviousVersionWalker below.
 class PreviousVersionNode : public CHeapObj {
  private:
-  jweak _prev_constant_pool;
+  // A shared ConstantPool is never collected so we'll always have
+  // a reference to it so we can update items in the cache. We'll
+  // have a weak reference to a non-shared ConstantPool until all
+  // of the methods (EMCP or obsolete) have been collected; the
+  // non-shared ConstantPool becomes collectible at that point.
+  jobject _prev_constant_pool;  // regular or weak reference
+  bool    _prev_cp_is_weak;     // true if not a shared ConstantPool
+
   // If the previous version of the instanceKlass doesn't have any
   // EMCP methods, then _prev_EMCP_methods will be NULL. If all the
   // EMCP methods have been collected, then _prev_EMCP_methods can
@@ -850,10 +861,10 @@
   GrowableArray<jweak>* _prev_EMCP_methods;
 
 public:
-  PreviousVersionNode(jweak prev_constant_pool,
+  PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak,
     GrowableArray<jweak>* prev_EMCP_methods);
   ~PreviousVersionNode();
-  jweak prev_constant_pool() const {
+  jobject prev_constant_pool() const {
     return _prev_constant_pool;
   }
   GrowableArray<jweak>* prev_EMCP_methods() const {
--- a/src/share/vm/oops/markOop.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/oops/markOop.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -37,3 +37,32 @@
     st->print("age %d)", age());
   }
 }
+
+
+// Give advice about whether the oop that contains this markOop
+// should be cached or not.
+bool markOopDesc::should_not_be_cached() const {
+  // the cast is because decode_pointer() isn't marked const
+  if (is_marked() && ((markOopDesc *)this)->decode_pointer() != NULL) {
+    // If the oop containing this markOop is being forwarded, then
+    // we are in the middle of GC and we do not want the containing
+    // oop to be added to a cache. We have no way of knowing whether
+    // the cache has already been visited by the current GC phase so
+    // we don't know whether the forwarded oop will be properly
+    // processed in this phase. If the forwarded oop is not properly
+    // processed, then we'll see strange crashes or asserts during
+    // the next GC run because the markOop will contain an unexpected
+    // value.
+    //
+    // This situation has been seen when we are GC'ing a methodOop
+    // because we use the methodOop while we're GC'ing it. Scary
+    // stuff. Some of the uses the methodOop cause the methodOop to
+    // be added to the OopMapCache in the instanceKlass as a side
+    // effect. This check lets the cache maintainer know when a
+    // cache addition would not be safe.
+    return true;
+  }
+
+  // caching the containing oop should be just fine
+  return false;
+}
--- a/src/share/vm/oops/markOop.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/oops/markOop.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -357,4 +357,7 @@
 
   // Recover address of oop from encoded form used in mark
   inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); }
+
+  // see the definition in markOop.cpp for the gory details
+  bool should_not_be_cached() const;
 };
--- a/src/share/vm/oops/methodOop.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/oops/methodOop.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -765,6 +765,28 @@
 }
 
 
+// give advice about whether this methodOop should be cached or not
+bool methodOopDesc::should_not_be_cached() const {
+  if (is_old()) {
+    // This method has been redefined. It is either EMCP or obsolete
+    // and we don't want to cache it because that would pin the method
+    // down and prevent it from being collectible if and when it
+    // finishes executing.
+    return true;
+  }
+
+  if (mark()->should_not_be_cached()) {
+    // It is either not safe or not a good idea to cache this
+    // method at this time because of the state of the embedded
+    // markOop. See markOop.cpp for the gory details.
+    return true;
+  }
+
+  // caching this method should be just fine
+  return false;
+}
+
+
 methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
   // Code below does not work for native methods - they should never get rewritten anyway
--- a/src/share/vm/oops/methodOop.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/oops/methodOop.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -524,6 +524,8 @@
   void set_is_old()                                 { _access_flags.set_is_old(); }
   bool is_obsolete() const                          { return access_flags().is_obsolete(); }
   void set_is_obsolete()                            { _access_flags.set_is_obsolete(); }
+  // see the definition in methodOop.cpp for the gory details
+  bool should_not_be_cached() const;
 
   // JVMTI Native method prefixing support:
   bool is_prefixed_native() const                   { return access_flags().is_prefixed_native(); }
--- a/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -64,7 +64,7 @@
 //    0x01000000 |   16777216 - impl details: nmethod evolution info
 //    0x02000000 |   33554432 - impl details: annotation updates
 //    0x04000000 |   67108864 - impl details: StackMapTable updates
-//    0x08000000 |  134217728 - unused
+//    0x08000000 |  134217728 - impl details: OopMapCache updates
 //    0x10000000 |  268435456 - unused
 //    0x20000000 |  536870912 - unused
 //    0x40000000 | 1073741824 - unused
--- a/src/share/vm/runtime/arguments.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1282,12 +1282,10 @@
 #endif
 
   if (AggressiveOpts) {
-NOT_WINDOWS(
-    // No measured benefit on Windows
-    if (FLAG_IS_DEFAULT(CacheTimeMillis)) {
-      FLAG_SET_DEFAULT(CacheTimeMillis, true);
-    }
-)
+// Sample flag setting code
+//    if (FLAG_IS_DEFAULT(EliminateZeroing)) {
+//      FLAG_SET_DEFAULT(EliminateZeroing, true);
+//    }
   }
 }
 
--- a/src/share/vm/runtime/biasedLocking.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/biasedLocking.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -38,8 +38,11 @@
 
 class VM_EnableBiasedLocking: public VM_Operation {
  public:
-  VM_EnableBiasedLocking() {}
-  VMOp_Type type() const   { return VMOp_EnableBiasedLocking; }
+  VM_EnableBiasedLocking()        {}
+  VMOp_Type type() const          { return VMOp_EnableBiasedLocking; }
+  Mode evaluation_mode() const    { return _async_safepoint; }
+  bool is_cheap_allocated() const { return true; }
+
   void doit() {
     // Iterate the system dictionary enabling biased locking for all
     // currently loaded classes
@@ -62,8 +65,10 @@
   EnableBiasedLockingTask(size_t interval_time) : PeriodicTask(interval_time) {}
 
   virtual void task() {
-    VM_EnableBiasedLocking op;
-    VMThread::execute(&op);
+    // Use async VM operation to avoid blocking the Watcher thread.
+    // VM Thread will free C heap storage.
+    VM_EnableBiasedLocking *op = new VM_EnableBiasedLocking();
+    VMThread::execute(op);
 
     // Reclaim our storage and disenroll ourself
     delete this;
--- a/src/share/vm/runtime/globals.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/globals.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -344,12 +344,6 @@
   product(bool, ForceTimeHighResolution, false,                             \
           "Using high time resolution(For Win32 only)")                     \
                                                                             \
-  product(bool, CacheTimeMillis, false,                                     \
-          "Cache os::javaTimeMillis with CacheTimeMillisGranularity")       \
-                                                                            \
-  diagnostic(uintx, CacheTimeMillisGranularity, 50,                         \
-          "Granularity for CacheTimeMillis")                                \
-                                                                            \
   develop(bool, TraceItables, false,                                        \
           "Trace initialization and use of itables")                        \
                                                                             \
--- a/src/share/vm/runtime/java.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/java.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -390,11 +390,6 @@
   StatSampler::disengage();
   StatSampler::destroy();
 
-  // shut down the TimeMillisUpdateTask
-  if (CacheTimeMillis) {
-    TimeMillisUpdateTask::disengage();
-  }
-
 #ifndef SERIALGC
   // stop CMS threads
   if (UseConcMarkSweepGC) {
--- a/src/share/vm/runtime/mutex.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/mutex.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1119,10 +1119,15 @@
   assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ;
 }
 
-void Monitor::ClearMonitor (Monitor * m) {
+void Monitor::ClearMonitor (Monitor * m, const char *name) {
   m->_owner             = NULL ;
   m->_snuck             = false ;
-  m->_name              = "UNKNOWN" ;
+  if (name == NULL) {
+    strcpy(m->_name, "UNKNOWN") ;
+  } else {
+    strncpy(m->_name, name, MONITOR_NAME_LEN - 1);
+    m->_name[MONITOR_NAME_LEN - 1] = '\0';
+  }
   m->_LockWord.FullWord = 0 ;
   m->_EntryList         = NULL ;
   m->_OnDeck            = NULL ;
@@ -1133,7 +1138,7 @@
 Monitor::Monitor() { ClearMonitor(this); }
 
 Monitor::Monitor (int Rank, const char * name, bool allow_vm_block) {
-  ClearMonitor (this) ;
+  ClearMonitor (this, name) ;
 #ifdef ASSERT
   _allow_vm_block  = allow_vm_block;
   _rank            = Rank ;
@@ -1145,7 +1150,7 @@
 }
 
 Mutex::Mutex (int Rank, const char * name, bool allow_vm_block) {
-  ClearMonitor ((Monitor *) this) ;
+  ClearMonitor ((Monitor *) this, name) ;
 #ifdef ASSERT
  _allow_vm_block   = allow_vm_block;
  _rank             = Rank ;
--- a/src/share/vm/runtime/mutex.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/mutex.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -82,6 +82,9 @@
 // *in that order*.  If their implementations change such that these
 // assumptions are violated, a whole lot of code will break.
 
+// The default length of monitor name is choosen to be 64 to avoid false sharing.
+static const int MONITOR_NAME_LEN = 64;
+
 class Monitor : public CHeapObj {
 
  public:
@@ -126,9 +129,8 @@
   volatile intptr_t _WaitLock [1] ;      // Protects _WaitSet
   ParkEvent * volatile  _WaitSet ;       // LL of ParkEvents
   volatile bool     _snuck;              // Used for sneaky locking (evil).
-  const char * _name;                    // Name of mutex
   int NotifyCount ;                      // diagnostic assist
-  double pad [8] ;                       // avoid false sharing
+  char _name[MONITOR_NAME_LEN];          // Name of mutex
 
   // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
 #ifndef PRODUCT
@@ -170,7 +172,7 @@
    int  ILocked () ;
 
  protected:
-   static void ClearMonitor (Monitor * m) ;
+   static void ClearMonitor (Monitor * m, const char* name = NULL) ;
    Monitor() ;
 
  public:
--- a/src/share/vm/runtime/mutexLocker.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/mutexLocker.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -188,10 +188,6 @@
 
   def(Safepoint_lock               , Monitor, safepoint,   true ); // locks SnippetCache_lock/Threads_lock
 
-  if (!UseMembar) {
-    def(SerializePage_lock         , Monitor, leaf,        true );
-  }
-
   def(Threads_lock                 , Monitor, barrier,     true );
 
   def(VMOperationQueue_lock        , Monitor, nonleaf,     true ); // VM_thread allowed to block on these
--- a/src/share/vm/runtime/mutexLocker.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/mutexLocker.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -52,7 +52,6 @@
 extern Monitor* VMOperationQueue_lock;           // a lock on queue of vm_operations waiting to execute
 extern Monitor* VMOperationRequest_lock;         // a lock on Threads waiting for a vm_operation to terminate
 extern Monitor* Safepoint_lock;                  // a lock used by the safepoint abstraction
-extern Monitor* SerializePage_lock;              // a lock used when VMThread changing serialize memory page permission during safepoint
 extern Monitor* Threads_lock;                    // a lock on the Threads table of active Java threads
                                                  // (also used by Safepoints too to block threads creation/destruction)
 extern Monitor* CGC_lock;                        // used for coordination between
--- a/src/share/vm/runtime/os.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/os.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -33,9 +33,6 @@
 uintptr_t         os::_serialize_page_mask = 0;
 long              os::_rand_seed          = 1;
 int               os::_processor_count    = 0;
-volatile jlong    os::_global_time        = 0;
-volatile int      os::_global_time_lock   = 0;
-bool              os::_use_global_time    = false;
 size_t            os::_page_sizes[os::page_sizes_max];
 
 #ifndef PRODUCT
@@ -44,74 +41,6 @@
 int os::num_frees = 0;              // # of calls to free
 #endif
 
-// Atomic read of a jlong is assured by a seqlock; see update_global_time()
-jlong os::read_global_time() {
-#ifdef _LP64
-  return _global_time;
-#else
-  volatile int lock;
-  volatile jlong current_time;
-  int ctr = 0;
-
-  for (;;) {
-    lock = _global_time_lock;
-
-    // spin while locked
-    while ((lock & 0x1) != 0) {
-      ++ctr;
-      if ((ctr & 0xFFF) == 0) {
-        // Guarantee writer progress.  Can't use yield; yield is advisory
-        // and has almost no effect on some platforms.  Don't need a state
-        // transition - the park call will return promptly.
-        assert(Thread::current() != NULL, "TLS not initialized");
-        assert(Thread::current()->_ParkEvent != NULL, "sync not initialized");
-        Thread::current()->_ParkEvent->park(1);
-      }
-      lock = _global_time_lock;
-    }
-
-    OrderAccess::loadload();
-    current_time = _global_time;
-    OrderAccess::loadload();
-
-    // ratify seqlock value
-    if (lock == _global_time_lock) {
-      return current_time;
-    }
-  }
-#endif
-}
-
-//
-// NOTE - Assumes only one writer thread!
-//
-// We use a seqlock to guarantee that jlong _global_time is updated
-// atomically on 32-bit platforms.  A locked value is indicated by
-// the lock variable LSB == 1.  Readers will initially read the lock
-// value, spinning until the LSB == 0.  They then speculatively read
-// the global time value, then re-read the lock value to ensure that
-// it hasn't changed.  If the lock value has changed, the entire read
-// sequence is retried.
-//
-// Writers simply set the LSB = 1 (i.e. increment the variable),
-// update the global time, then release the lock and bump the version
-// number (i.e. increment the variable again.)  In this case we don't
-// even need a CAS since we ensure there's only one writer.
-//
-void os::update_global_time() {
-#ifdef _LP64
-  _global_time = timeofday();
-#else
-  assert((_global_time_lock & 0x1) == 0, "multiple writers?");
-  jlong current_time = timeofday();
-  _global_time_lock++; // lock
-  OrderAccess::storestore();
-  _global_time = current_time;
-  OrderAccess::storestore();
-  _global_time_lock++; // unlock
-#endif
-}
-
 // Fill in buffer with current local time as an ISO-8601 string.
 // E.g., yyyy-mm-ddThh:mm:ss-zzzz.
 // Returns buffer, or NULL if it failed.
@@ -138,7 +67,7 @@
     return NULL;
   }
   // Get the current time
-  jlong milliseconds_since_19700101 = timeofday();
+  jlong milliseconds_since_19700101 = javaTimeMillis();
   const int milliseconds_per_microsecond = 1000;
   const time_t seconds_since_19700101 =
     milliseconds_since_19700101 / milliseconds_per_microsecond;
@@ -956,7 +885,6 @@
     return true;
 }
 
-
 void os::set_memory_serialize_page(address page) {
   int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64);
   _mem_serialize_page = (volatile int32_t *)page;
@@ -967,6 +895,8 @@
   set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t)));
 }
 
+static volatile intptr_t SerializePageLock = 0;
+
 // This method is called from signal handler when SIGSEGV occurs while the current
 // thread tries to store to the "read-only" memory serialize page during state
 // transition.
@@ -974,15 +904,14 @@
   if (TraceSafepoint) {
     tty->print_cr("Block until the serialize page permission restored");
   }
-  // When VMThread is holding the SerializePage_lock during modifying the
+  // When VMThread is holding the SerializePageLock during modifying the
   // access permission of the memory serialize page, the following call
   // will block until the permission of that page is restored to rw.
   // Generally, it is unsafe to manipulate locks in signal handlers, but in
   // this case, it's OK as the signal is synchronous and we know precisely when
-  // it can occur. SerializePage_lock is a transiently-held leaf lock, so
-  // lock_without_safepoint_check should be safe.
-  SerializePage_lock->lock_without_safepoint_check();
-  SerializePage_lock->unlock();
+  // it can occur.
+  Thread::muxAcquire(&SerializePageLock, "set_memory_serialize_page");
+  Thread::muxRelease(&SerializePageLock);
 }
 
 // Serialize all thread state variables
@@ -990,14 +919,12 @@
   // On some platforms such as Solaris & Linux, the time duration of the page
   // permission restoration is observed to be much longer than expected  due to
   // scheduler starvation problem etc. To avoid the long synchronization
-  // time and expensive page trap spinning, 'SerializePage_lock' is used to block
-  // the mutator thread if such case is encountered. Since this method is always
-  // called by VMThread during safepoint, lock_without_safepoint_check is used
-  // instead. See bug 6546278.
-  SerializePage_lock->lock_without_safepoint_check();
+  // time and expensive page trap spinning, 'SerializePageLock' is used to block
+  // the mutator thread if such case is encountered. See bug 6546278 for details.
+  Thread::muxAcquire(&SerializePageLock, "serialize_thread_states");
   os::protect_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
   os::unguard_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
-  SerializePage_lock->unlock();
+  Thread::muxRelease(&SerializePageLock);
 }
 
 // Returns true if the current stack pointer is above the stack shadow
--- a/src/share/vm/runtime/os.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/os.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -66,9 +66,6 @@
   static address            _polling_page;
   static volatile int32_t * _mem_serialize_page;
   static uintptr_t          _serialize_page_mask;
-  static volatile jlong     _global_time;
-  static volatile int       _global_time_lock;
-  static bool               _use_global_time;
   static size_t             _page_sizes[page_sizes_max];
 
   static void init_page_sizes(size_t default_page_size) {
@@ -88,11 +85,6 @@
   static bool getenv(const char* name, char* buffer, int len);
   static bool have_special_privileges();
 
-  static jlong  timeofday();
-  static void   enable_global_time()   { _use_global_time = true; }
-  static void   disable_global_time()  { _use_global_time = false; }
-  static jlong  read_global_time();
-  static void   update_global_time();
   static jlong  javaTimeMillis();
   static jlong  javaTimeNanos();
   static void   javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
--- a/src/share/vm/runtime/reflection.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/reflection.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1548,10 +1548,11 @@
   }
 
   instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
-  if (!klass->methods()->is_within_bounds(slot)) {
+  methodOop m = klass->method_with_idnum(slot);
+  if (m == NULL) {
     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
   }
-  methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot)));
+  methodHandle method(THREAD, m);
 
   return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
 }
@@ -1564,10 +1565,11 @@
   objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
 
   instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
-  if (!klass->methods()->is_within_bounds(slot)) {
+  methodOop m = klass->method_with_idnum(slot);
+  if (m == NULL) {
     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
   }
-  methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot)));
+  methodHandle method(THREAD, m);
   assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
 
   // Make sure klass gets initialize
--- a/src/share/vm/runtime/sharedRuntime.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1486,11 +1486,9 @@
   const char* desc = " cannot be cast to ";
   size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1;
 
-  char* message = NEW_C_HEAP_ARRAY(char, msglen);
+  char* message = NEW_RESOURCE_ARRAY(char, msglen);
   if (NULL == message) {
-    // out of memory - can't use a detailed message.  Since caller is
-    // using a resource mark to free memory, returning this should be
-    // safe (caller won't explicitly delete it).
+    // Shouldn't happen, but don't cause even more problems if it does
     message = const_cast<char*>(objName);
   } else {
     jio_snprintf(message, msglen, "%s%s%s", objName, desc, targetKlassName);
--- a/src/share/vm/runtime/task.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/task.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -107,25 +107,3 @@
     _tasks[index] = _tasks[index+1];
   }
 }
-
-TimeMillisUpdateTask* TimeMillisUpdateTask::_task = NULL;
-
-void TimeMillisUpdateTask::task() {
-  os::update_global_time();
-}
-
-void TimeMillisUpdateTask::engage() {
-  assert(_task == NULL, "init twice?");
-  os::update_global_time(); // initial update
-  os::enable_global_time();
-  _task = new TimeMillisUpdateTask(CacheTimeMillisGranularity);
-  _task->enroll();
-}
-
-void TimeMillisUpdateTask::disengage() {
-  assert(_task != NULL, "uninit twice?");
-  os::disable_global_time();
-  _task->disenroll();
-  delete _task;
-  _task = NULL;
-}
--- a/src/share/vm/runtime/task.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/task.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -113,13 +113,3 @@
   // The task to perform at each period
   virtual void task() = 0;
 };
-
-class TimeMillisUpdateTask : public PeriodicTask {
- private:
-  static TimeMillisUpdateTask* _task;
- public:
-  TimeMillisUpdateTask(int interval) : PeriodicTask(interval) {}
-  void task();
-  static void engage();
-  static void disengage();
-};
--- a/src/share/vm/runtime/thread.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/runtime/thread.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -1317,10 +1317,6 @@
   ThreadSafepointState::destroy(this);
   if (_thread_profiler != NULL) delete _thread_profiler;
   if (_thread_stat != NULL) delete _thread_stat;
-
-  if (jvmti_thread_state() != NULL) {
-    JvmtiExport::cleanup_thread(this);
-  }
 }
 
 
@@ -1571,6 +1567,10 @@
     tlab().make_parsable(true);  // retire TLAB
   }
 
+  if (jvmti_thread_state() != NULL) {
+    JvmtiExport::cleanup_thread(this);
+  }
+
   // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
   Threads::remove(this);
 }
@@ -3085,7 +3085,6 @@
   if (MemProfiling)                   MemProfiler::engage();
   StatSampler::engage();
   if (CheckJNICalls)                  JniPeriodicChecker::engage();
-  if (CacheTimeMillis)                TimeMillisUpdateTask::engage();
 
   BiasedLocking::init();
 
--- a/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	Fri Mar 21 08:32:17 2008 -0700
@@ -37,23 +37,45 @@
 # include <stdlib.h>
 # include <wchar.h>
 # include <stdarg.h>
+#ifdef SOLARIS
 # include <ieeefp.h>
+#endif
 # include <math.h>
+#ifdef LINUX
+#ifndef FP_PZERO
+  // Linux doesn't have positive/negative zero
+  #define FP_PZERO FP_ZERO
+#endif
+#ifndef fpclass
+  #define fpclass fpclassify
+#endif
+#endif
 # include <time.h>
 # include <fcntl.h>
 # include <dlfcn.h>
 # include <pthread.h>
+#ifdef SOLARIS
 # include <thread.h>
+#endif
 # include <limits.h>
 # include <errno.h>
+#ifdef SOLARIS
 # include <sys/trap.h>
 # include <sys/regset.h>
 # include <sys/procset.h>
 # include <ucontext.h>
 # include <setjmp.h>
+#endif
 # ifdef SOLARIS_MUTATOR_LIBTHREAD
 # include <sys/procfs.h>
 # endif
+#ifdef LINUX
+# include <inttypes.h>
+# include <signal.h>
+# include <ucontext.h>
+# include <sys/time.h>
+#endif
+
 
 // 4810578: varargs unsafe on 32-bit integer/64-bit pointer architectures
 // When __cplusplus is defined, NULL is defined as 0 (32-bit constant) in
@@ -68,6 +90,11 @@
 // pointer when it extracts the argument, then we have a problem.
 //
 // Solution: For 64-bit architectures, redefine NULL as 64-bit constant 0.
+//
+// Note: this fix doesn't work well on Linux because NULL will be overwritten
+// whenever a system header file is included. Linux handles NULL correctly
+// through a special type '__null'.
+#ifdef SOLARIS
 #ifdef _LP64
 #undef NULL
 #define NULL 0L
@@ -76,13 +103,25 @@
 #define NULL 0
 #endif
 #endif
+#endif
 
 // NULL vs NULL_WORD:
 // On Linux NULL is defined as a special type '__null'. Assigning __null to
 // integer variable will cause gcc warning. Use NULL_WORD in places where a
-// pointer is stored as integer value.
-#define NULL_WORD NULL
+// pointer is stored as integer value. On some platforms, sizeof(intptr_t) >
+// sizeof(void*), so here we want something which is integer type, but has the
+// same size as a pointer.
+#ifdef LINUX
+  #ifdef _LP64
+    #define NULL_WORD  0L
+  #else
+    #define NULL_WORD  0
+  #endif
+#else
+  #define NULL_WORD  NULL
+#endif
 
+#ifndef LINUX
 // Compiler-specific primitive types
 typedef unsigned short     uint16_t;
 #ifndef _UINT32_T
@@ -100,6 +139,7 @@
 // If this gets an error, figure out a symbol XXX that implies the
 // prior definition of intptr_t, and add "&& !defined(XXX)" above.
 #endif
+#endif
 
 // Additional Java basic types
 
@@ -128,7 +168,7 @@
 const jlong min_jlong = CONST64(0x8000000000000000);
 const jlong max_jlong = CONST64(0x7fffffffffffffff);
 
-
+#ifdef SOLARIS
 //----------------------------------------------------------------------------------------------------
 // ANSI C++ fixes
 // NOTE:In the ANSI committee's continuing attempt to make each version
@@ -162,7 +202,7 @@
    typedef int (*int_fnP_cond_tP_i_vP)(cond_t *cv, int scope, void *arg);
    typedef int (*int_fnP_cond_tP)(cond_t *cv);
 };
-
+#endif
 
 //----------------------------------------------------------------------------------------------------
 // Debugging
@@ -173,7 +213,7 @@
 #define BREAKPOINT ::breakpoint()
 
 // checking for nanness
-
+#ifdef SOLARIS
 #ifdef SPARC
 inline int g_isnan(float  f) { return isnanf(f); }
 #else
@@ -182,6 +222,12 @@
 #endif
 
 inline int g_isnan(double f) { return isnand(f); }
+#elif LINUX
+inline int g_isnan(float  f) { return isnanf(f); }
+inline int g_isnan(double f) { return isnan(f); }
+#else
+#error "missing platform-specific definition here"
+#endif
 
 // Checking for finiteness
 
@@ -195,9 +241,11 @@
 
 
 // Misc
+// NOTE: This one leads to an infinite recursion on Linux
+#ifndef LINUX
 int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr);
 #define vsnprintf local_vsnprintf
-
+#endif
 
 // Portability macros
 #define PRAGMA_INTERFACE
--- a/src/share/vm/utilities/vmError.cpp	Fri Mar 21 00:49:06 2008 -0700
+++ b/src/share/vm/utilities/vmError.cpp	Fri Mar 21 08:32:17 2008 -0700
@@ -170,7 +170,8 @@
   out->print_raw_cr(Arguments::java_vendor_url_bug());
   // If the crash is in native code, encourage user to submit a bug to the
   // provider of that code.
-  if (thread && thread->is_Java_thread()) {
+  if (thread && thread->is_Java_thread() &&
+      !thread->is_hidden_from_external_view()) {
     JavaThread* jt = (JavaThread*)thread;
     if (jt->thread_state() == _thread_in_native) {
       out->print_cr("# The crash happened outside the Java Virtual Machine in native code.\n# See problematic frame for where to report the bug.");
@@ -249,10 +250,10 @@
 
   BEGIN
 
-  STEP(10, "(printing unexpected error message)")
+  STEP(10, "(printing fatal error message)")
 
      st->print_cr("#");
-     st->print_cr("# An unexpected error has been detected by Java Runtime Environment:");
+     st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
 
   STEP(15, "(printing type of error)")