changeset 11587:16b0200f252d

Merge
author brutisso
date Fri, 27 Jan 2012 09:04:57 +0100
parents ccc217c177ee e1deb7ec91fa
children 384c4e224855 ae5115bdd736
files hotspot/src/os/bsd/vm/decoder_bsd.cpp hotspot/src/share/vm/runtime/arguments.cpp hotspot/src/share/vm/runtime/mutexLocker.cpp hotspot/src/share/vm/runtime/mutexLocker.hpp jdk/test/java/io/File/BlockIsDirectory.java jdk/test/tools/launcher/DefaultLocaleTest.sh
diffstat 424 files changed, 21399 insertions(+), 2332 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Jan 26 14:14:55 2012 -0800
+++ b/.hgtags	Fri Jan 27 09:04:57 2012 +0100
@@ -140,3 +140,7 @@
 736a63b854f321c7824b7e47890135f80aee05e3 jdk8-b16
 f0eccb2946986fb9626efde7d8ed9c8192623f5c jdk8-b17
 885050364691ac1ac978305c63f3368a197fb04d jdk8-b18
+0ff7113a0882ec82d642cb9f0297b4e497807ced jdk8-b19
+6561530ea757c3f3a6fb171c9cc7b3885cdeca85 jdk8-b20
+b3a426170188f52981cf4573a2f14d487fddab0d jdk8-b21
+e8f03541af27e38aafb619b96863e17f65ffe53b jdk8-b22
--- a/.hgtags-top-repo	Thu Jan 26 14:14:55 2012 -0800
+++ b/.hgtags-top-repo	Fri Jan 27 09:04:57 2012 +0100
@@ -140,3 +140,7 @@
 4e06ae613e99549835896720c7a68c29ad5543f5 jdk8-b17
 4e06ae613e99549835896720c7a68c29ad5543f5 jdk8-b16
 7010bd24cdd07bc7daef80702f39124854dec36c jdk8-b18
+237bc29afbfc6f56a4fe4a6008e2befb59c44bac jdk8-b19
+5a5eaf6374bcbe23530899579fed17a05b7705f3 jdk8-b20
+cc771d92284f71765eca14d6d08703c4af254c04 jdk8-b21
+7ad075c809952e355d25030605da6af30456ed74 jdk8-b22
--- a/corba/.hgtags	Thu Jan 26 14:14:55 2012 -0800
+++ b/corba/.hgtags	Fri Jan 27 09:04:57 2012 +0100
@@ -140,3 +140,7 @@
 82dc033975bb9b553b4ef97b6d483eda8de32e0f jdk8-b17
 82dc033975bb9b553b4ef97b6d483eda8de32e0f jdk8-b16
 312cf15d16577ef198b033d2a4cc0a52369b7343 jdk8-b18
+e1366c5d84ef984095a332bcee70b3938232d07d jdk8-b19
+51d8b6cb18c0978ecfa4f33e1537d35ee01b69fa jdk8-b20
+f157fc2a71a38ce44007a6f18d5b011824dce705 jdk8-b21
+a11d0062c445d5f36651c78650ab88aa594bcbff jdk8-b22
--- a/hotspot/.hgtags	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/.hgtags	Fri Jan 27 09:04:57 2012 +0100
@@ -207,3 +207,9 @@
 a2fef924d8e6f37dac2a887315e3502876cc8e24 hs23-b08
 61165f53f1656b9f99e4fb806429bf98b99d59c3 jdk8-b18
 4bcf61041217f8677dcec18e90e9196acc945bba hs23-b09
+9232e0ecbc2cec54dcc8f93004fb00c214446460 jdk8-b19
+fe2c8764998112b7fefcd7d41599714813ae4327 jdk8-b20
+9952d1c439d64c5fd4ad1236a63a62bd5a49d4c3 jdk8-b21
+513351373923f74a7c91755748b95c9771e59f96 hs23-b10
+24727fb37561779077fdfa5a33342246f20e5c0f jdk8-b22
+dcc292399a39113957eebbd3e487b7e05e2c79fc hs23-b11
--- a/hotspot/make/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -367,7 +367,7 @@
 $(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
 	$(install-file)
 
-# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
+# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
 $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
 	$(install-file)
 
@@ -384,6 +384,16 @@
 $(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/services/%
 	$(install-file)
 
+JFR_EXISTS=$(shell if [ -d $(HS_ALT_SRC) ]; then echo 1; else echo 0; fi)
+# export jfr.h
+ifeq ($JFR_EXISTS,1)
+$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/agent/%
+	$(install-file)
+else
+$(EXPORT_INCLUDE_DIR)/jfr.h:
+	
+endif
+
 # Doc files (jvmti.html)
 $(EXPORT_DOCS_DIR)/platform/jvmti/%: $(DOCS_DIR)/%
 	$(install-file)
--- a/hotspot/make/bsd/makefiles/vm.make	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/bsd/makefiles/vm.make	Fri Jan 27 09:04:57 2012 +0100
@@ -96,6 +96,10 @@
 CPPFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\""
 endif
 
+ifndef JAVASE_EMBEDDED
+CFLAGS += -DINCLUDE_TRACE
+endif
+
 # CFLAGS_WARN holds compiler options to suppress/enable warnings.
 CFLAGS += $(CFLAGS_WARN/BYFILE)
 
@@ -147,6 +151,12 @@
 SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
 
+ifndef JAVASE_EMBEDDED
+SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+  find $(HS_ALT_SRC)/share/vm/jfr -type d; \
+  fi)
+endif
+
 CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
 CORE_PATHS+=$(GENERATED)/jvmtifiles
 
--- a/hotspot/make/defs.make	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/defs.make	Fri Jan 27 09:04:57 2012 +0100
@@ -294,3 +294,7 @@
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
+
+ifndef JAVASE_EMBEDDED
+EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h
+endif
--- a/hotspot/make/hotspot_version	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/hotspot_version	Fri Jan 27 09:04:57 2012 +0100
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=23
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=10
+HS_BUILD_NUMBER=12
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/vm.make	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/linux/makefiles/vm.make	Fri Jan 27 09:04:57 2012 +0100
@@ -98,6 +98,10 @@
   ${JRE_VERSION}     \
   ${VM_DISTRO}
 
+ifndef JAVASE_EMBEDDED
+CFLAGS += -DINCLUDE_TRACE
+endif
+
 # CFLAGS_WARN holds compiler options to suppress/enable warnings.
 CFLAGS += $(CFLAGS_WARN/BYFILE)
 
@@ -143,6 +147,12 @@
 SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
 
+ifndef JAVASE_EMBEDDED
+SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+  find $(HS_ALT_SRC)/share/vm/jfr -type d; \
+  fi)
+endif
+
 CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
 CORE_PATHS+=$(GENERATED)/jvmtifiles
 
--- a/hotspot/make/solaris/makefiles/vm.make	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/solaris/makefiles/vm.make	Fri Jan 27 09:04:57 2012 +0100
@@ -93,7 +93,7 @@
 CFLAGS += $(CFLAGS/NOEX)
 
 # Extra flags from gnumake's invocation or environment
-CFLAGS += $(EXTRA_CFLAGS)
+CFLAGS += $(EXTRA_CFLAGS) -DINCLUDE_TRACE
 
 # Math Library (libm.so), do not use -lm.
 #    There might be two versions of libm.so on the build system:
@@ -160,6 +160,10 @@
 SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
 
+SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+  find $(HS_ALT_SRC)/share/vm/jfr -type d; \
+  fi)
+
 CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
 CORE_PATHS+=$(GENERATED)/jvmtifiles
 
--- a/hotspot/make/windows/build.bat	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/windows/build.bat	Fri Jan 27 09:04:57 2012 +0100
@@ -35,6 +35,8 @@
 if %errorlevel% == 0 goto isia64
 cl 2>&1 | grep "AMD64" >NUL
 if %errorlevel% == 0 goto amd64
+cl 2>&1 | grep "x64" >NUL
+if %errorlevel% == 0 goto amd64
 set ARCH=x86
 set BUILDARCH=i486
 set Platform_arch=x86
--- a/hotspot/make/windows/create_obj_files.sh	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/windows/create_obj_files.sh	Fri Jan 27 09:04:57 2012 +0100
@@ -73,6 +73,13 @@
 
 BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles"
 
+if [ -d "${ALTSRC}/share/vm/jfr" ]; then
+  BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent"
+  BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent/isolated_deps/util"
+  BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/jvm"
+  BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
+fi
+
 CORE_PATHS="${BASE_PATHS}"
 # shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS.
 if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then
--- a/hotspot/make/windows/makefiles/projectcreator.make	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/windows/makefiles/projectcreator.make	Fri Jan 27 09:04:57 2012 +0100
@@ -58,7 +58,8 @@
         -absoluteInclude $(HOTSPOTBUILDSPACE)/%f/generated \
         -ignorePath $(HOTSPOTBUILDSPACE)/%f/generated \
         -ignorePath src\share\vm\adlc \
-        -ignorePath src\share\vm\shark
+        -ignorePath src\share\vm\shark \
+        -ignorePath posix
 
 # This is referenced externally by both the IDE and batch builds
 ProjectCreatorOptions=
@@ -88,7 +89,7 @@
         -jdkTargetRoot $(HOTSPOTJDKDIST) \
         -define ALIGN_STACK_FRAMES \
         -define VM_LITTLE_ENDIAN \
-        -prelink  "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b	set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME)	$(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
+        -prelink  "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b	set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME)	set JAVA_HOME=$(HOTSPOTJDKDIST)	$(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
         -postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b	set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME)	nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \
         -ignoreFile jsig.c \
         -ignoreFile jvmtiEnvRecommended.cpp \
--- a/hotspot/make/windows/makefiles/vm.make	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/make/windows/makefiles/vm.make	Fri Jan 27 09:04:57 2012 +0100
@@ -19,7 +19,7 @@
 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 # or visit www.oracle.com if you need additional information or have any
 # questions.
-#  
+#
 #
 
 # Resource file containing VERSIONINFO
@@ -30,7 +30,7 @@
 COMMONSRC=$(WorkSpace)\src
 ALTSRC=$(WorkSpace)\src\closed
 
-!ifdef RELEASE 
+!ifdef RELEASE
 !ifdef DEVELOP
 CPP_FLAGS=$(CPP_FLAGS) /D "DEBUG"
 !else
@@ -74,6 +74,10 @@
 CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\""
 CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\""
 
+!ifndef JAVASE_EMBEDDED
+CPP_FLAGS=$(CPP_FLAGS) /D "INCLUDE_TRACE"
+!endif
+
 CPP_FLAGS=$(CPP_FLAGS) $(CPP_INCLUDE_DIRS)
 
 # Define that so jni.h is on correct side
@@ -97,7 +101,7 @@
 !endif
 
 # If you modify exports below please do the corresponding changes in
-# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java 
+# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
 LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
   /export:JNI_GetDefaultJavaVMInitArgs       \
   /export:JNI_CreateJavaVM                   \
@@ -170,6 +174,7 @@
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/prims
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/runtime
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/services
+VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/trace
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/utilities
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/libadt
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/os/windows/vm
@@ -177,6 +182,13 @@
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto
 
+!if exists($(ALTSRC)\share\vm\jfr)
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent/isolated_deps/util
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/jvm
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr
+!endif
+
 VM_PATH={$(VM_PATH)}
 
 # Special case files not using precompiled header files.
@@ -263,6 +275,9 @@
 {$(COMMONSRC)\share\vm\services}.cpp.obj::
         $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
 
+{$(COMMONSRC)\share\vm\trace}.cpp.obj::
+        $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
 {$(COMMONSRC)\share\vm\utilities}.cpp.obj::
         $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
 
@@ -340,6 +355,9 @@
 {$(ALTSRC)\share\vm\services}.cpp.obj::
         $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
 
+{$(ALTSRC)\share\vm\trace}.cpp.obj::
+        $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
 {$(ALTSRC)\share\vm\utilities}.cpp.obj::
         $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
 
@@ -371,6 +389,18 @@
 {..\generated\jvmtifiles}.cpp.obj::
         $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
 
+{$(ALTSRC)\share\vm\jfr}.cpp.obj::
+        $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
+{$(ALTSRC)\share\vm\jfr\agent}.cpp.obj::
+        $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
+{$(ALTSRC)\share\vm\jfr\agent\isolated_deps\util}.cpp.obj::
+        $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
+{$(ALTSRC)\share\vm\jfr\jvm}.cpp.obj::
+        $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
 default::
 
 _build_pch_file.obj:
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -391,7 +391,7 @@
   __ call(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id), relocInfo::runtime_call_type);
   __ delayed()->nop();
   __ should_not_reach_here();
-  assert(code_offset() - offset <= exception_handler_size, "overflow");
+  guarantee(code_offset() - offset <= exception_handler_size, "overflow");
   __ end_a_stub();
 
   return offset;
@@ -474,8 +474,7 @@
   AddressLiteral deopt_blob(SharedRuntime::deopt_blob()->unpack());
   __ JUMP(deopt_blob, G3_scratch, 0); // sethi;jmp
   __ delayed()->nop();
-  assert(code_offset() - offset <= deopt_handler_size, "overflow");
-  debug_only(__ stop("should have gone to the caller");)
+  guarantee(code_offset() - offset <= deopt_handler_size, "overflow");
   __ end_a_stub();
 
   return offset;
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -69,7 +69,7 @@
 #else
          call_stub_size = 20,
 #endif // _LP64
-         exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(10*4),
-         deopt_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(10*4) };
+         exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(128),
+         deopt_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(64)  };
 
 #endif // CPU_SPARC_VM_C1_LIRASSEMBLER_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -810,7 +810,7 @@
 }
 
 
-#ifdef ASSERT
+#ifndef PRODUCT
 
 #define DESCRIBE_FP_OFFSET(name) \
   values.describe(frame_no, fp() + frame::name##_offset, #name)
@@ -820,11 +820,19 @@
     values.describe(frame_no, sp() + w, err_msg("register save area word %d", w), 1);
   }
 
-  if (is_interpreted_frame()) {
+  if (is_ricochet_frame()) {
+    MethodHandles::RicochetFrame::describe(this, values, frame_no);
+  } else if (is_interpreted_frame()) {
     DESCRIBE_FP_OFFSET(interpreter_frame_d_scratch_fp);
     DESCRIBE_FP_OFFSET(interpreter_frame_l_scratch_fp);
     DESCRIBE_FP_OFFSET(interpreter_frame_padding);
     DESCRIBE_FP_OFFSET(interpreter_frame_oop_temp);
+
+    // esp, according to Lesp (e.g. not depending on bci), if seems valid
+    intptr_t* esp = *interpreter_frame_esp_addr();
+    if ((esp >= sp()) && (esp < fp())) {
+      values.describe(-1, esp, "*Lesp");
+    }
   }
 
   if (!is_compiled_frame()) {
@@ -844,4 +852,3 @@
   // unused... but returns fp() to minimize changes introduced by 7087445
   return fp();
 }
-
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,6 +82,8 @@
 
 inline intptr_t*    frame::sender_sp() const  { return fp(); }
 
+inline intptr_t* frame::real_fp() const { return fp(); }
+
 // Used only in frame::oopmapreg_to_location
 // This return a value in VMRegImpl::slot_size
 inline int frame::pd_oop_map_offset_adjustment() const {
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -177,7 +177,7 @@
   BLOCK_COMMENT("ricochet_blob.bounce");
 
   if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
-  trace_method_handle(_masm, "ricochet_blob.bounce");
+  trace_method_handle(_masm, "return/ricochet_blob.bounce");
 
   __ JMP(L1_continuation, 0);
   __ delayed()->nop();
@@ -268,14 +268,16 @@
 }
 
 // Emit code to verify that FP is pointing at a valid ricochet frame.
-#ifdef ASSERT
+#ifndef PRODUCT
 enum {
   ARG_LIMIT = 255, SLOP = 45,
   // use this parameter for checking for garbage stack movements:
   UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
   // the slop defends against false alarms due to fencepost errors
 };
+#endif
 
+#ifdef ASSERT
 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
   // The stack should look like this:
   //    ... keep1 | dest=42 | keep2 | magic | handler | magic | recursive args | [RF]
@@ -1001,31 +1003,142 @@
 }
 
 #ifndef PRODUCT
+void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no)  {
+    RicochetFrame* rf = new RicochetFrame(*fr);
+
+    // ricochet slots (kept in registers for sparc)
+    values.describe(frame_no, rf->register_addr(I5_savedSP), err_msg("exact_sender_sp reg for #%d", frame_no));
+    values.describe(frame_no, rf->register_addr(L5_conversion), err_msg("conversion reg for #%d", frame_no));
+    values.describe(frame_no, rf->register_addr(L4_saved_args_base), err_msg("saved_args_base reg for #%d", frame_no));
+    values.describe(frame_no, rf->register_addr(L3_saved_args_layout), err_msg("saved_args_layout reg for #%d", frame_no));
+    values.describe(frame_no, rf->register_addr(L2_saved_target), err_msg("saved_target reg for #%d", frame_no));
+    values.describe(frame_no, rf->register_addr(L1_continuation), err_msg("continuation reg for #%d", frame_no));
+
+    // relevant ricochet targets (in caller frame)
+    values.describe(-1, rf->saved_args_base(),  err_msg("*saved_args_base for #%d", frame_no));
+    values.describe(-1, (intptr_t *)(STACK_BIAS+(uintptr_t)rf->exact_sender_sp()),  err_msg("*exact_sender_sp+STACK_BIAS for #%d", frame_no));
+}
+#endif // ASSERT
+
+#ifndef PRODUCT
 extern "C" void print_method_handle(oop mh);
 void trace_method_handle_stub(const char* adaptername,
                               oopDesc* mh,
-                              intptr_t* saved_sp) {
+                              intptr_t* saved_sp,
+                              intptr_t* args,
+                              intptr_t* tracing_fp) {
   bool has_mh = (strstr(adaptername, "return/") == NULL);  // return adapters don't have mh
-  tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp);
-  if (has_mh)
+
+  tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp, args);
+
+  if (Verbose) {
+    // dumping last frame with frame::describe
+
+    JavaThread* p = JavaThread::active();
+
+    ResourceMark rm;
+    PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here
+    FrameValues values;
+
+    // Note: We want to allow trace_method_handle from any call site.
+    // While trace_method_handle creates a frame, it may be entered
+    // without a valid return PC in O7 (e.g. not just after a call).
+    // Walking that frame could lead to failures due to that invalid PC.
+    // => carefully detect that frame when doing the stack walking
+
+    // walk up to the right frame using the "tracing_fp" argument
+    intptr_t* cur_sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
+    frame cur_frame(cur_sp, frame::unpatchable, NULL);
+
+    while (cur_frame.fp() != (intptr_t *)(STACK_BIAS+(uintptr_t)tracing_fp)) {
+      cur_frame = os::get_sender_for_C_frame(&cur_frame);
+    }
+
+    // safely create a frame and call frame::describe
+    intptr_t *dump_sp = cur_frame.sender_sp();
+    intptr_t *dump_fp = cur_frame.link();
+
+    bool walkable = has_mh; // whether the traced frame shoud be walkable
+
+    // the sender for cur_frame is the caller of trace_method_handle
+    if (walkable) {
+      // The previous definition of walkable may have to be refined
+      // if new call sites cause the next frame constructor to start
+      // failing. Alternatively, frame constructors could be
+      // modified to support the current or future non walkable
+      // frames (but this is more intrusive and is not considered as
+      // part of this RFE, which will instead use a simpler output).
+      frame dump_frame = frame(dump_sp,
+                               cur_frame.sp(), // younger_sp
+                               false); // no adaptation
+      dump_frame.describe(values, 1);
+    } else {
+      // Robust dump for frames which cannot be constructed from sp/younger_sp
+      // Add descriptions without building a Java frame to avoid issues
+      values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
+      values.describe(-1, dump_sp, "sp");
+    }
+
+    bool has_args = has_mh; // whether Gargs is meaningful
+
+    // mark args, if seems valid (may not be valid for some adapters)
+    if (has_args) {
+      if ((args >= dump_sp) && (args < dump_fp)) {
+        values.describe(-1, args, "*G4_args");
+      }
+    }
+
+    // mark saved_sp, if seems valid (may not be valid for some adapters)
+    intptr_t *unbiased_sp = (intptr_t *)(STACK_BIAS+(uintptr_t)saved_sp);
+    if ((unbiased_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (unbiased_sp < dump_fp)) {
+      values.describe(-1, unbiased_sp, "*saved_sp+STACK_BIAS");
+    }
+
+    // Note: the unextended_sp may not be correct
+    tty->print_cr("  stack layout:");
+    values.print(p);
+  }
+
+  if (has_mh) {
     print_method_handle(mh);
+  }
 }
+
 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
   if (!TraceMethodHandles)  return;
   BLOCK_COMMENT("trace_method_handle {");
   // save: Gargs, O5_savedSP
-  __ save_frame(16);
+  __ save_frame(16); // need space for saving required FPU state
+
   __ set((intptr_t) adaptername, O0);
   __ mov(G3_method_handle, O1);
   __ mov(I5_savedSP, O2);
+  __ mov(Gargs, O3);
+  __ mov(I6, O4); // frame identifier for safe stack walking
+
+  // Save scratched registers that might be needed. Robustness is more
+  // important than optimizing the saves for this debug only code.
+
+  // save FP result, valid at some call sites (adapter_opt_return_float, ...)
+  Address d_save(FP, -sizeof(jdouble) + STACK_BIAS);
+  __ stf(FloatRegisterImpl::D, Ftos_d, d_save);
+  // Safely save all globals but G2 (handled by call_VM_leaf) and G7
+  // (OS reserved).
   __ mov(G3_method_handle, L3);
   __ mov(Gargs, L4);
   __ mov(G5_method_type, L5);
-  __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
+  __ mov(G6, L6);
+  __ mov(G1, L1);
+
+  __ call_VM_leaf(L2 /* for G2 */, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
 
   __ mov(L3, G3_method_handle);
   __ mov(L4, Gargs);
   __ mov(L5, G5_method_type);
+  __ mov(L6, G6);
+  __ mov(L1, G1);
+  __ ldf(FloatRegisterImpl::D, d_save, Ftos_d);
+
   __ restore();
   BLOCK_COMMENT("} trace_method_handle");
 }
@@ -1045,7 +1158,7 @@
          |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
           // OP_COLLECT_ARGS is below...
          |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
-         |(!UseRicochetFrames ? 0 :
+         |(
            java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 :
            ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF)
            |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS)
@@ -1250,7 +1363,7 @@
         move_typed_arg(_masm, arg_type, false,
                        prim_value_addr,
                        Address(O0_argslot, 0),
-                       O2_scratch);  // must be an even register for !_LP64 long moves (uses O2/O3)
+                      O2_scratch);  // must be an even register for !_LP64 long moves (uses O2/O3)
       }
 
       if (direct_to_method) {
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -145,6 +145,8 @@
   }
 
   static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
+
+  static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
 };
 
 // Additional helper methods for MethodHandles code generation:
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Fri Jan 27 09:04:57 2012 +0100
@@ -9283,6 +9283,7 @@
 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
 instruct jumpXtnd(iRegX switch_val, o7RegI table) %{
   match(Jump switch_val);
+  effect(TEMP table);
 
   ins_cost(350);
 
@@ -10273,24 +10274,24 @@
 // ============================================================================
 // inlined locking and unlocking
 
-instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{
+instruct cmpFastLock(flagsRegP pcc, iRegP object, o1RegP box, iRegP scratch2, o7RegP scratch ) %{
   match(Set pcc (FastLock object box));
 
-  effect(KILL scratch, TEMP scratch2);
+  effect(TEMP scratch2, USE_KILL box, KILL scratch);
   ins_cost(100);
 
-  format %{ "FASTLOCK  $object, $box; KILL $scratch, $scratch2, $box" %}
+  format %{ "FASTLOCK  $object,$box\t! kills $box,$scratch,$scratch2" %}
   ins_encode( Fast_Lock(object, box, scratch, scratch2) );
   ins_pipe(long_memory_op);
 %}
 
 
-instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{
+instruct cmpFastUnlock(flagsRegP pcc, iRegP object, o1RegP box, iRegP scratch2, o7RegP scratch ) %{
   match(Set pcc (FastUnlock object box));
-  effect(KILL scratch, TEMP scratch2);
+  effect(TEMP scratch2, USE_KILL box, KILL scratch);
   ins_cost(100);
 
-  format %{ "FASTUNLOCK  $object, $box; KILL $scratch, $scratch2, $box" %}
+  format %{ "FASTUNLOCK  $object,$box\t! kills $box,$scratch,$scratch2" %}
   ins_encode( Fast_Unlock(object, box, scratch, scratch2) );
   ins_pipe(long_memory_op);
 %}
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -406,7 +406,7 @@
   // search an exception handler (rax: exception oop, rdx: throwing pc)
   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id)));
   __ should_not_reach_here();
-  assert(code_offset() - offset <= exception_handler_size, "overflow");
+  guarantee(code_offset() - offset <= exception_handler_size, "overflow");
   __ end_a_stub();
 
   return offset;
@@ -490,8 +490,7 @@
 
   __ pushptr(here.addr());
   __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
-
-  assert(code_offset() - offset <= deopt_handler_size, "overflow");
+  guarantee(code_offset() - offset <= deopt_handler_size, "overflow");
   __ end_a_stub();
 
   return offset;
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -651,13 +651,15 @@
   return &interpreter_frame_tos_address()[index];
 }
 
-#ifdef ASSERT
+#ifndef PRODUCT
 
 #define DESCRIBE_FP_OFFSET(name) \
   values.describe(frame_no, fp() + frame::name##_offset, #name)
 
 void frame::describe_pd(FrameValues& values, int frame_no) {
-  if (is_interpreted_frame()) {
+  if (is_ricochet_frame()) {
+    MethodHandles::RicochetFrame::describe(this, values, frame_no);
+  } else if (is_interpreted_frame()) {
     DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_method);
@@ -667,7 +669,6 @@
     DESCRIBE_FP_OFFSET(interpreter_frame_bcx);
     DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
   }
-
 }
 #endif
 
@@ -675,3 +676,21 @@
   // used to reset the saved FP
   return fp();
 }
+
+intptr_t* frame::real_fp() const {
+  if (_cb != NULL) {
+    // use the frame size if valid
+    int size = _cb->frame_size();
+    if ((size > 0) &&
+        (! is_ricochet_frame())) {
+      // Work-around: ricochet explicitly excluded because frame size is not
+      // constant for the ricochet blob but its frame_size could not, for
+      // some reasons, be declared as <= 0. This potentially confusing
+      // size declaration should be fixed as another CR.
+      return unextended_sp() + size;
+    }
+  }
+  // else rely on fp()
+  assert(! is_compiled_frame(), "unknown compiled frame size");
+  return fp();
+}
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -188,6 +188,7 @@
   frame(intptr_t* sp, intptr_t* fp);
 
   // accessors for the instance variables
+  // Note: not necessarily the real 'frame pointer' (see real_fp)
   intptr_t*   fp() const { return _fp; }
 
   inline address* sender_pc_addr() const;
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -279,14 +279,16 @@
 }
 
 // Emit code to verify that RBP is pointing at a valid ricochet frame.
-#ifdef ASSERT
+#ifndef PRODUCT
 enum {
   ARG_LIMIT = 255, SLOP = 4,
   // use this parameter for checking for garbage stack movements:
   UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
   // the slop defends against false alarms due to fencepost errors
 };
+#endif
 
+#ifdef ASSERT
 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
   // The stack should look like this:
   //    ... keep1 | dest=42 | keep2 | RF | magic | handler | magic | recursive args |
@@ -990,6 +992,26 @@
   BLOCK_COMMENT("} move_return_value");
 }
 
+#ifndef PRODUCT
+#define DESCRIBE_RICOCHET_OFFSET(rf, name) \
+  values.describe(frame_no, (intptr_t *) (((uintptr_t)rf) + MethodHandles::RicochetFrame::name##_offset_in_bytes()), #name)
+
+void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no)  {
+    address bp = (address) fr->fp();
+    RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes());
+
+    // ricochet slots
+    DESCRIBE_RICOCHET_OFFSET(rf, exact_sender_sp);
+    DESCRIBE_RICOCHET_OFFSET(rf, conversion);
+    DESCRIBE_RICOCHET_OFFSET(rf, saved_args_base);
+    DESCRIBE_RICOCHET_OFFSET(rf, saved_args_layout);
+    DESCRIBE_RICOCHET_OFFSET(rf, saved_target);
+    DESCRIBE_RICOCHET_OFFSET(rf, continuation);
+
+    // relevant ricochet targets (in caller frame)
+    values.describe(-1, rf->saved_args_base(),  err_msg("*saved_args_base for #%d", frame_no));
+}
+#endif // ASSERT
 
 #ifndef PRODUCT
 extern "C" void print_method_handle(oop mh);
@@ -1001,11 +1023,12 @@
                               intptr_t* saved_bp) {
   // called as a leaf from native code: do not block the JVM!
   bool has_mh = (strstr(adaptername, "return/") == NULL);  // return adapters don't have rcx_mh
+
   intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
   intptr_t* base_sp = last_sp;
   typedef MethodHandles::RicochetFrame RicochetFrame;
   RicochetFrame* rfp = (RicochetFrame*)((address)saved_bp - RicochetFrame::sender_link_offset_in_bytes());
-  if (!UseRicochetFrames || Universe::heap()->is_in((address) rfp->saved_args_base())) {
+  if (Universe::heap()->is_in((address) rfp->saved_args_base())) {
     // Probably an interpreter frame.
     base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
   }
@@ -1030,13 +1053,64 @@
     tty->cr();
     if (last_sp != saved_sp && last_sp != NULL)
       tty->print_cr("*** last_sp="PTR_FORMAT, (intptr_t)last_sp);
-    int stack_dump_count = 16;
-    if (stack_dump_count < (int)(saved_bp + 2 - saved_sp))
-      stack_dump_count = (int)(saved_bp + 2 - saved_sp);
-    if (stack_dump_count > 64)  stack_dump_count = 48;
-    for (i = 0; i < stack_dump_count; i += 4) {
-      tty->print_cr(" dump at SP[%d] "PTR_FORMAT": "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT,
-                    i, (intptr_t) &entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]);
+
+    {
+     // dumping last frame with frame::describe
+
+      JavaThread* p = JavaThread::active();
+
+      ResourceMark rm;
+      PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here
+      FrameValues values;
+
+      // Note: We want to allow trace_method_handle from any call site.
+      // While trace_method_handle creates a frame, it may be entered
+      // without a PC on the stack top (e.g. not just after a call).
+      // Walking that frame could lead to failures due to that invalid PC.
+      // => carefully detect that frame when doing the stack walking
+
+      // Current C frame
+      frame cur_frame = os::current_frame();
+
+      // Robust search of trace_calling_frame (independant of inlining).
+      // Assumes saved_regs comes from a pusha in the trace_calling_frame.
+      assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?");
+      frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame);
+      while (trace_calling_frame.fp() < saved_regs) {
+        trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame);
+      }
+
+      // safely create a frame and call frame::describe
+      intptr_t *dump_sp = trace_calling_frame.sender_sp();
+      intptr_t *dump_fp = trace_calling_frame.link();
+
+      bool walkable = has_mh; // whether the traced frame shoud be walkable
+
+      if (walkable) {
+        // The previous definition of walkable may have to be refined
+        // if new call sites cause the next frame constructor to start
+        // failing. Alternatively, frame constructors could be
+        // modified to support the current or future non walkable
+        // frames (but this is more intrusive and is not considered as
+        // part of this RFE, which will instead use a simpler output).
+        frame dump_frame = frame(dump_sp, dump_fp);
+        dump_frame.describe(values, 1);
+      } else {
+        // Stack may not be walkable (invalid PC above FP):
+        // Add descriptions without building a Java frame to avoid issues
+        values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
+        values.describe(-1, dump_sp, "sp for #1");
+      }
+
+      // mark saved_sp if seems valid
+      if (has_mh) {
+        if ((saved_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (saved_sp < dump_fp)) {
+          values.describe(-1, saved_sp, "*saved_sp");
+        }
+      }
+
+      tty->print_cr("  stack layout:");
+      values.print(p);
     }
     if (has_mh)
       print_method_handle(mh);
@@ -1066,26 +1140,49 @@
 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
   if (!TraceMethodHandles)  return;
   BLOCK_COMMENT("trace_method_handle {");
-  __ push(rax);
-  __ lea(rax, Address(rsp, wordSize * NOT_LP64(6) LP64_ONLY(14))); // entry_sp  __ pusha();
+  __ enter();
+  __ andptr(rsp, -16); // align stack if needed for FPU state
   __ pusha();
-  __ mov(rbx, rsp);
-  __ enter();
+  __ mov(rbx, rsp); // for retreiving saved_regs
+  // Note: saved_regs must be in the entered frame for the
+  // robust stack walking implemented in trace_method_handle_stub.
+
+  // save FP result, valid at some call sites (adapter_opt_return_float, ...)
+  __ increment(rsp, -2 * wordSize);
+  if  (UseSSE >= 2) {
+    __ movdbl(Address(rsp, 0), xmm0);
+  } else if (UseSSE == 1) {
+    __ movflt(Address(rsp, 0), xmm0);
+  } else {
+    __ fst_d(Address(rsp, 0));
+  }
+
   // incoming state:
   // rcx: method handle
   // r13 or rsi: saved sp
   // To avoid calling convention issues, build a record on the stack and pass the pointer to that instead.
+  // Note: fix the increment below if pushing more arguments
   __ push(rbp);               // saved_bp
-  __ push(rsi);               // saved_sp
-  __ push(rax);               // entry_sp
+  __ push(saved_last_sp_register()); // saved_sp
+  __ push(rbp);               // entry_sp (with extra align space)
   __ push(rbx);               // pusha saved_regs
   __ push(rcx);               // mh
-  __ push(rcx);               // adaptername
+  __ push(rcx);               // slot for adaptername
   __ movptr(Address(rsp, 0), (intptr_t) adaptername);
   __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp);
+  __ increment(rsp, 6 * wordSize); // MethodHandleStubArguments
+
+  if  (UseSSE >= 2) {
+    __ movdbl(xmm0, Address(rsp, 0));
+  } else if (UseSSE == 1) {
+    __ movflt(xmm0, Address(rsp, 0));
+  } else {
+    __ fld_d(Address(rsp, 0));
+  }
+  __ increment(rsp, 2 * wordSize);
+
+  __ popa();
   __ leave();
-  __ popa();
-  __ pop(rax);
   BLOCK_COMMENT("} trace_method_handle");
 }
 #endif //PRODUCT
@@ -1104,7 +1201,7 @@
          |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
           //OP_COLLECT_ARGS is below...
          |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
-         |(!UseRicochetFrames ? 0 :
+         |(
            java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 :
            ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF)
            |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS)
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -224,6 +224,8 @@
   }
 
   static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
+
+  static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
 };
 
 // Additional helper methods for MethodHandles code generation:
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Fri Jan 27 09:04:57 2012 +0100
@@ -13435,20 +13435,20 @@
 // inlined locking and unlocking
 
 
-instruct cmpFastLock( eFlagsReg cr, eRegP object, eRegP box, eAXRegI tmp, eRegP scr) %{
+instruct cmpFastLock( eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eRegP scr) %{
   match( Set cr (FastLock object box) );
-  effect( TEMP tmp, TEMP scr );
+  effect( TEMP tmp, TEMP scr, USE_KILL box );
   ins_cost(300);
-  format %{ "FASTLOCK $object, $box KILLS $tmp,$scr" %}
+  format %{ "FASTLOCK $object,$box\t! kills $box,$tmp,$scr" %}
   ins_encode( Fast_Lock(object,box,tmp,scr) );
   ins_pipe( pipe_slow );
 %}
 
 instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
   match( Set cr (FastUnlock object box) );
-  effect( TEMP tmp );
+  effect( TEMP tmp, USE_KILL box );
   ins_cost(300);
-  format %{ "FASTUNLOCK $object, $box, $tmp" %}
+  format %{ "FASTUNLOCK $object,$box\t! kills $box,$tmp" %}
   ins_encode( Fast_Unlock(object,box,tmp) );
   ins_pipe( pipe_slow );
 %}
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Fri Jan 27 09:04:57 2012 +0100
@@ -11511,13 +11511,13 @@
 // inlined locking and unlocking
 
 instruct cmpFastLock(rFlagsReg cr,
-                     rRegP object, rRegP box, rax_RegI tmp, rRegP scr)
+                     rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr)
 %{
   match(Set cr (FastLock object box));
-  effect(TEMP tmp, TEMP scr);
+  effect(TEMP tmp, TEMP scr, USE_KILL box);
 
   ins_cost(300);
-  format %{ "fastlock $object,$box,$tmp,$scr" %}
+  format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
   ins_encode(Fast_Lock(object, box, tmp, scr));
   ins_pipe(pipe_slow);
 %}
@@ -11526,10 +11526,10 @@
                        rRegP object, rax_RegP box, rRegP tmp)
 %{
   match(Set cr (FastUnlock object box));
-  effect(TEMP tmp);
+  effect(TEMP tmp, USE_KILL box);
 
   ins_cost(300);
-  format %{ "fastunlock $object, $box, $tmp" %}
+  format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
   ins_encode(Fast_Unlock(object, box, tmp));
   ins_pipe(pipe_slow);
 %}
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -418,7 +418,7 @@
   }
 }
 
-#ifdef ASSERT
+#ifndef PRODUCT
 
 void frame::describe_pd(FrameValues& values, int frame_no) {
 
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -72,6 +72,10 @@
   return fp() + 1;
 }
 
+inline intptr_t* frame::real_fp() const {
+  return fp();
+}
+
 inline intptr_t* frame::link() const {
   ShouldNotCallThis();
 }
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -29,43 +29,3 @@
   adapter_code_size = 0
 };
 
-#define TARGET_ARCH_NYI_6939861 1
-// ..#ifdef TARGET_ARCH_NYI_6939861
-// ..  // Here are some backward compatible declarations until the 6939861 ports are updated.
-// ..  #define _adapter_flyby    (_EK_LIMIT + 10)
-// ..  #define _adapter_ricochet (_EK_LIMIT + 11)
-// ..  #define _adapter_opt_spread_1    _adapter_opt_spread_1_ref
-// ..  #define _adapter_opt_spread_more _adapter_opt_spread_ref
-// ..  enum {
-// ..    _INSERT_NO_MASK   = -1,
-// ..    _INSERT_REF_MASK  = 0,
-// ..    _INSERT_INT_MASK  = 1,
-// ..    _INSERT_LONG_MASK = 3
-// ..  };
-// ..  static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) {
-// ..    arg_type = ek_bound_mh_arg_type(ek);
-// ..    arg_mask = 0;
-// ..    arg_slots = type2size[arg_type];;
-// ..  }
-// ..  static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) {
-// ..    int swap_slots = ek_adapter_opt_swap_slots(ek);
-// ..    rotate = ek_adapter_opt_swap_mode(ek);
-// ..    swap_bytes = swap_slots * Interpreter::stackElementSize;
-// ..  }
-// ..  static int get_ek_adapter_opt_spread_info(EntryKind ek) {
-// ..    return ek_adapter_opt_spread_count(ek);
-// ..  }
-// ..
-// ..  static void insert_arg_slots(MacroAssembler* _masm,
-// ..                               RegisterOrConstant arg_slots,
-// ..                               int arg_mask,
-// ..                               Register argslot_reg,
-// ..                               Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-// ..
-// ..  static void remove_arg_slots(MacroAssembler* _masm,
-// ..                               RegisterOrConstant arg_slots,
-// ..                               Register argslot_reg,
-// ..                               Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-// ..
-// ..  static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
-// ..#endif //TARGET_ARCH_NYI_6939861
--- a/hotspot/src/os/bsd/vm/decoder_bsd.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "prims/jvm.h"
-#include "utilities/decoder.hpp"
-
-#include <cxxabi.h>
-
-#ifdef __APPLE__
-
-void Decoder::initialize() {
-  _initialized = true;
-}
-
-void Decoder::uninitialize() {
-  _initialized = false;
-}
-
-bool Decoder::can_decode_C_frame_in_vm() {
-  return false;
-}
-
-Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
-  return symbol_not_found;
-}
-
-
-#endif
-
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
-  int   status;
-  char* result;
-  size_t size = (size_t)buflen;
-
-  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
-  // __cxa_demangle will call system "realloc" for additional memory, which
-  // may use different malloc/realloc mechanism that allocates 'buf'.
-  if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
-    jio_snprintf(buf, buflen, "%s", result);
-      // call c library's free
-      ::free(result);
-      return true;
-  }
-  return false;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/bsd/vm/decoder_machO.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#ifdef __APPLE__
+#include "decoder_machO.hpp"
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/bsd/vm/decoder_machO.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_BSD_VM_DECODER_MACHO_HPP
+#define OS_BSD_VM_DECODER_MACHO_HPP
+
+#ifdef __APPLE__
+
+#include "utilities/decoder.hpp"
+
+// Just a placehold for now
+class MachODecoder: public NullDecoder {
+public:
+  MachODecoder() { }
+  ~MachODecoder() { }
+};
+
+#endif
+
+#endif // OS_BSD_VM_DECODER_MACHO_HPP
+
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1920,7 +1920,7 @@
     return true;
   } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
     if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
-       dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+       buf, buflen, offset, dlinfo.dli_fname)) {
        return true;
     }
   }
--- a/hotspot/src/os/linux/vm/decoder_linux.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/os/linux/vm/decoder_linux.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -23,11 +23,11 @@
  */
 
 #include "prims/jvm.h"
-#include "utilities/decoder.hpp"
+#include "utilities/decoder_elf.hpp"
 
 #include <cxxabi.h>
 
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
+bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
   int   status;
   char* result;
   size_t size = (size_t)buflen;
@@ -43,3 +43,4 @@
   }
   return false;
 }
+
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1732,7 +1732,7 @@
     return true;
   } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
     if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
-       dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+        buf, buflen, offset, dlinfo.dli_fname)) {
        return true;
     }
   }
--- a/hotspot/src/os/solaris/vm/decoder_solaris.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/os/solaris/vm/decoder_solaris.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -22,10 +22,11 @@
  *
  */
 
-#include "utilities/decoder.hpp"
+#include "utilities/decoder_elf.hpp"
 
 #include <demangle.h>
 
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
+bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
   return !cplus_demangle(symbol, buf, (size_t)buflen);
 }
+
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1997,7 +1997,7 @@
       }
       if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
         if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
-          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+           buf, buflen, offset, dlinfo.dli_fname)) {
           return true;
         }
       }
@@ -2015,7 +2015,7 @@
         return true;
       } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
         if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
-          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+          buf, buflen, offset, dlinfo.dli_fname)) {
           return true;
         }
       }
--- a/hotspot/src/os/windows/vm/decoder_windows.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/os/windows/vm/decoder_windows.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,22 +24,24 @@
 
 #include "precompiled.hpp"
 #include "prims/jvm.h"
-#include "runtime/os.hpp"
-#include "utilities/decoder.hpp"
+#include "decoder_windows.hpp"
 
-HMODULE                   Decoder::_dbghelp_handle = NULL;
-bool                      Decoder::_can_decode_in_vm = false;
-pfn_SymGetSymFromAddr64   Decoder::_pfnSymGetSymFromAddr64 = NULL;
-pfn_UndecorateSymbolName  Decoder::_pfnUndecorateSymbolName = NULL;
+WindowsDecoder::WindowsDecoder() {
+  _dbghelp_handle = NULL;
+  _can_decode_in_vm = false;
+  _pfnSymGetSymFromAddr64 = NULL;
+  _pfnUndecorateSymbolName = NULL;
 
-void Decoder::initialize() {
-  if (!_initialized) {
-    _initialized = true;
+  _decoder_status = no_error;
+  initialize();
+}
 
-    HINSTANCE handle = os::win32::load_Windows_dll("dbghelp.dll", NULL, 0);
+void WindowsDecoder::initialize() {
+  if (!has_error() && _dbghelp_handle == NULL) {
+    HMODULE handle = ::LoadLibrary("dbghelp.dll");
     if (!handle) {
       _decoder_status = helper_not_found;
-        return;
+      return;
     }
 
     _dbghelp_handle = handle;
@@ -70,32 +72,29 @@
 
      // find out if jvm.dll contains private symbols, by decoding
      // current function and comparing the result
-     address addr = (address)Decoder::initialize;
+     address addr = (address)Decoder::decode;
      char buf[MAX_PATH];
-     if (decode(addr, buf, sizeof(buf), NULL) == no_error) {
-       _can_decode_in_vm = !strcmp(buf, "Decoder::initialize");
+     if (decode(addr, buf, sizeof(buf), NULL)) {
+       _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
      }
   }
 }
 
-void Decoder::uninitialize() {
-  assert(_initialized, "Decoder not yet initialized");
+void WindowsDecoder::uninitialize() {
   _pfnSymGetSymFromAddr64 = NULL;
   _pfnUndecorateSymbolName = NULL;
   if (_dbghelp_handle != NULL) {
     ::FreeLibrary(_dbghelp_handle);
   }
-  _initialized = false;
+  _dbghelp_handle = NULL;
 }
 
-bool Decoder::can_decode_C_frame_in_vm() {
-  initialize();
-  return  _can_decode_in_vm;
+bool WindowsDecoder::can_decode_C_frame_in_vm() const {
+  return  (!has_error() && _can_decode_in_vm);
 }
 
 
-Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) {
-  assert(_initialized, "Decoder not yet initialized");
+bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath)  {
   if (_pfnSymGetSymFromAddr64 != NULL) {
     PIMAGEHLP_SYMBOL64 pSymbol;
     char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
@@ -105,19 +104,20 @@
     DWORD64 displacement;
     if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
       if (buf != NULL) {
-        if (!demangle(pSymbol->Name, buf, buflen)) {
+        if (demangle(pSymbol->Name, buf, buflen)) {
           jio_snprintf(buf, buflen, "%s", pSymbol->Name);
         }
       }
-      if (offset != NULL) *offset = (int)displacement;
-      return no_error;
+      if(offset != NULL) *offset = (int)displacement;
+      return true;
     }
   }
-  return helper_not_found;
+  if (buf != NULL && buflen > 0) buf[0] = '\0';
+  if (offset != NULL) *offset = -1;
+  return false;
 }
 
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
-  assert(_initialized, "Decoder not yet initialized");
+bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
   return _pfnUndecorateSymbolName != NULL &&
          _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_WINDOWS_VM_DECODER_WINDOWS_HPP
+#define OS_WINDOWS_VM_DECIDER_WINDOWS_HPP
+
+#include <windows.h>
+#include <imagehlp.h>
+
+#include "utilities/decoder.hpp"
+
+// functions needed for decoding symbols
+typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
+typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
+typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
+typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
+
+class WindowsDecoder: public NullDecoder {
+
+public:
+  WindowsDecoder();
+  ~WindowsDecoder() { uninitialize(); };
+
+  bool can_decode_C_frame_in_vm() const;
+  bool demangle(const char* symbol, char *buf, int buflen);
+  bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath = NULL);
+
+private:
+  void initialize();
+  void uninitialize();
+
+private:
+  HMODULE                   _dbghelp_handle;
+  bool                      _can_decode_in_vm;
+  pfn_SymGetSymFromAddr64   _pfnSymGetSymFromAddr64;
+  pfn_UndecorateSymbolName  _pfnUndecorateSymbolName;
+};
+
+#endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP
+
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1391,7 +1391,7 @@
 
 bool os::dll_address_to_function_name(address addr, char *buf,
                                       int buflen, int *offset) {
-  if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
+  if (Decoder::decode(addr, buf, buflen, offset)) {
     return true;
   }
   if (offset != NULL)  *offset  = -1;
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1354,9 +1354,10 @@
   CodeStub*     _stub;   // if this is a branch to a stub, this is the stub
 
  public:
-  LIR_OpBranch(LIR_Condition cond, Label* lbl)
+  LIR_OpBranch(LIR_Condition cond, BasicType type, Label* lbl)
     : LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL)
     , _cond(cond)
+    , _type(type)
     , _label(lbl)
     , _block(NULL)
     , _ublock(NULL)
@@ -2053,7 +2054,7 @@
   void jump(CodeStub* stub) {
     append(new LIR_OpBranch(lir_cond_always, T_ILLEGAL, stub));
   }
-  void branch(LIR_Condition cond, Label* lbl)        { append(new LIR_OpBranch(cond, lbl)); }
+  void branch(LIR_Condition cond, BasicType type, Label* lbl)        { append(new LIR_OpBranch(cond, type, lbl)); }
   void branch(LIR_Condition cond, BasicType type, BlockBegin* block) {
     assert(type != T_FLOAT && type != T_DOUBLE, "no fp comparisons");
     append(new LIR_OpBranch(cond, type, block));
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -2350,7 +2350,7 @@
     } else {
       LabelObj* L = new LabelObj();
       __ cmp(lir_cond_less, value, low_key);
-      __ branch(lir_cond_less, L->label());
+      __ branch(lir_cond_less, T_INT, L->label());
       __ cmp(lir_cond_lessEqual, value, high_key);
       __ branch(lir_cond_lessEqual, T_INT, dest);
       __ branch_destination(L->label());
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -413,8 +413,9 @@
     }
     bci = branch_bci + offset;
   }
-
+  assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
   osr_nm = CompilationPolicy::policy()->event(enclosing_method, method, branch_bci, bci, level, nm, THREAD);
+  assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions");
   return osr_nm;
 }
 
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1589,7 +1589,7 @@
   _next = NULL;
   _on_work_list = false;
   _backedge_copy = false;
-  _exception_entry = false;
+  _has_monitorenter = false;
   _trap_bci = -1;
   _trap_index = 0;
   df_init();
@@ -2182,6 +2182,10 @@
         !head->is_clonable_exit(lp))
       continue;
 
+    // Avoid BoxLock merge.
+    if (EliminateNestedLocks && head->has_monitorenter())
+      continue;
+
     // check not already cloned
     if (head->backedge_copy_count() != 0)
       continue;
@@ -2322,6 +2326,10 @@
     // Watch for bailouts.
     if (failing())  return;
 
+    if (str.cur_bc() == Bytecodes::_monitorenter) {
+      block->set_has_monitorenter();
+    }
+
     if (res) {
 
       // We have encountered a trap.  Record it in this block.
--- a/hotspot/src/share/vm/ci/ciTypeFlow.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -544,15 +544,19 @@
     // Has this block been cloned for a loop backedge?
     bool                             _backedge_copy;
 
+    // This block is entry to irreducible loop.
+    bool                             _irreducible_entry;
+
+    // This block has monitor entry point.
+    bool                             _has_monitorenter;
+
     // A pointer used for our internal work list
+    bool                             _on_work_list;      // on the work list
     Block*                           _next;
-    bool                             _on_work_list;      // on the work list
     Block*                           _rpo_next;          // Reverse post order list
 
     // Loop info
     Loop*                            _loop;              // nearest loop
-    bool                             _irreducible_entry; // entry to irreducible loop
-    bool                             _exception_entry;   // entry to exception handler
 
     ciBlock*     ciblock() const     { return _ciblock; }
     StateVector* state() const     { return _state; }
@@ -689,6 +693,8 @@
     bool   is_loop_head() const          { return _loop && _loop->head() == this; }
     void   set_irreducible_entry(bool c) { _irreducible_entry = c; }
     bool   is_irreducible_entry() const  { return _irreducible_entry; }
+    void   set_has_monitorenter()        { _has_monitorenter = true; }
+    bool   has_monitorenter() const      { return _has_monitorenter; }
     bool   is_visited() const            { return has_pre_order(); }
     bool   is_post_visited() const       { return has_post_order(); }
     bool   is_clonable_exit(Loop* lp);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1347,7 +1347,13 @@
     return _backtrace();
   }
 
-  inline void push(methodOop method, short bci, TRAPS) {
+  inline void push(methodOop method, int bci, TRAPS) {
+    // Smear the -1 bci to 0 since the array only holds unsigned
+    // shorts.  The later line number lookup would just smear the -1
+    // to a 0 even if it could be recorded.
+    if (bci == SynchronizationEntryBCI) bci = 0;
+    assert(bci == (jushort)bci, "doesn't fit");
+
     if (_index >= trace_chunk_size) {
       methodHandle mhandle(THREAD, method);
       expand(CHECK);
@@ -1574,8 +1580,13 @@
   int chunk_count = 0;
 
   for (;!st.at_end(); st.next()) {
-    // add element
-    bcis->ushort_at_put(chunk_count, st.bci());
+    // Add entry and smear the -1 bci to 0 since the array only holds
+    // unsigned shorts.  The later line number lookup would just smear
+    // the -1 to a 0 even if it could be recorded.
+    int bci = st.bci();
+    if (bci == SynchronizationEntryBCI) bci = 0;
+    assert(bci == (jushort)bci, "doesn't fit");
+    bcis->ushort_at_put(chunk_count, bci);
     methods->obj_at_put(chunk_count, st.method());
 
     chunk_count++;
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -204,6 +204,24 @@
   return s;
 }
 
+// Look up the address of the literal in the SymbolTable for this Symbol*
+// Do not create any new symbols
+// Do not increment the reference count to keep this alive
+Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){
+  unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length());
+  int index = the_table()->hash_to_index(hash);
+
+  for (HashtableEntry<Symbol*>* e = the_table()->bucket(index); e != NULL; e = e->next()) {
+    if (e->hash() == hash) {
+      Symbol* literal_sym = e->literal();
+      if (sym == literal_sym) {
+        return e->literal_addr();
+      }
+    }
+  }
+  return NULL;
+}
+
 // Suggestion: Push unicode-based lookup all the way into the hashing
 // and probing logic, so there is no need for convert_to_utf8 until
 // an actual new Symbol* is created.
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -144,6 +144,9 @@
 
   static void release(Symbol* sym);
 
+  // Look up the address of the literal in the SymbolTable for this Symbol*
+  static Symbol** lookup_symbol_addr(Symbol* sym);
+
   // jchar (utf16) version of lookups
   static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
   static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -2131,6 +2131,12 @@
     }
   }
 
+  // Assign a classid if one has not already been assigned.  The
+  // counter does not need to be atomically incremented since this
+  // is only done while holding the SystemDictionary_lock.
+  // All loaded classes get a unique ID.
+  TRACE_INIT_ID(k);
+
   // Check for a placeholder. If there, remove it and make a
   // new system dictionary entry.
   placeholders()->find_and_remove(p_index, p_hash, name, class_loader, THREAD);
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -961,7 +961,7 @@
                                         methodHandle hot_method,
                                         int hot_count,
                                         const char* comment,
-                                        TRAPS) {
+                                        Thread* thread) {
   // do nothing if compiler thread(s) is not available
   if (!_initialized ) {
     return;
@@ -1037,7 +1037,7 @@
 
   // Acquire our lock.
   {
-    MutexLocker locker(queue->lock(), THREAD);
+    MutexLocker locker(queue->lock(), thread);
 
     // Make sure the method has not slipped into the queues since
     // last we checked; note that those checks were "fast bail-outs".
@@ -1119,7 +1119,7 @@
 nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
                                        int comp_level,
                                        methodHandle hot_method, int hot_count,
-                                       const char* comment, TRAPS) {
+                                       const char* comment, Thread* THREAD) {
   // make sure arguments make sense
   assert(method->method_holder()->klass_part()->oop_is_instance(), "not an instance method");
   assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
@@ -1173,10 +1173,10 @@
   assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
   // some prerequisites that are compiler specific
   if (compiler(comp_level)->is_c2() || compiler(comp_level)->is_shark()) {
-    method->constants()->resolve_string_constants(CHECK_0);
+    method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL);
     // Resolve all classes seen in the signature of the method
     // we are compiling.
-    methodOopDesc::load_signature_classes(method, CHECK_0);
+    methodOopDesc::load_signature_classes(method, CHECK_AND_CLEAR_NULL);
   }
 
   // If the method is native, do the lookup in the thread requesting
@@ -1230,7 +1230,7 @@
       return NULL;
     }
   } else {
-    compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, CHECK_0);
+    compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, THREAD);
   }
 
   // return requested nmethod
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -333,7 +333,7 @@
                                   methodHandle hot_method,
                                   int hot_count,
                                   const char* comment,
-                                  TRAPS);
+                                  Thread* thread);
   static CompileQueue* compile_queue(int comp_level) {
     if (is_c2_compile(comp_level)) return _c2_method_queue;
     if (is_c1_compile(comp_level)) return _c1_method_queue;
@@ -363,7 +363,7 @@
                                  int comp_level,
                                  methodHandle hot_method,
                                  int hot_count,
-                                 const char* comment, TRAPS);
+                                 const char* comment, Thread* thread);
 
   static void compiler_thread_loop();
 
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -859,7 +859,9 @@
   const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci;
   const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci;
 
+  assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
   nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
+  assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions");
 
   if (osr_nm != NULL) {
     // We may need to do on-stack replacement which requires that no
--- a/hotspot/src/share/vm/oops/klass.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/oops/klass.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -158,6 +158,9 @@
   kl->set_next_sibling(NULL);
   kl->set_alloc_count(0);
   kl->set_alloc_size(0);
+#ifdef TRACE_SET_KLASS_TRACE_ID
+  TRACE_SET_KLASS_TRACE_ID(kl, 0);
+#endif
 
   kl->set_prototype_header(markOopDesc::prototype());
   kl->set_biased_lock_revocation_count(0);
--- a/hotspot/src/share/vm/oops/klass.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/oops/klass.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -33,6 +33,7 @@
 #include "oops/klassPS.hpp"
 #include "oops/oop.hpp"
 #include "runtime/orderAccess.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/accessFlags.hpp"
 #ifndef SERIALGC
 #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
@@ -80,6 +81,7 @@
 //    [last_biased_lock_bulk_revocation_time] (64 bits)
 //    [prototype_header]
 //    [biased_lock_revocation_count]
+//    [trace_id]
 
 
 // Forward declarations.
@@ -263,6 +265,9 @@
   markOop  _prototype_header;   // Used when biased locking is both enabled and disabled for this type
   jint     _biased_lock_revocation_count;
 
+#ifdef TRACE_DEFINE_KLASS_TRACE_ID
+  TRACE_DEFINE_KLASS_TRACE_ID;
+#endif
  public:
 
   // returns the enclosing klassOop
@@ -683,6 +688,9 @@
   jlong last_biased_lock_bulk_revocation_time() { return _last_biased_lock_bulk_revocation_time; }
   void  set_last_biased_lock_bulk_revocation_time(jlong cur_time) { _last_biased_lock_bulk_revocation_time = cur_time; }
 
+#ifdef TRACE_DEFINE_KLASS_METHODS
+  TRACE_DEFINE_KLASS_METHODS;
+#endif
 
   // garbage collection support
   virtual void follow_weak_klass_links(
--- a/hotspot/src/share/vm/oops/methodKlass.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/oops/methodKlass.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -83,6 +83,7 @@
   m->set_max_stack(0);
   m->set_max_locals(0);
   m->set_intrinsic_id(vmIntrinsics::_none);
+  m->set_jfr_towrite(false);
   m->set_method_data(NULL);
   m->set_interpreter_throwout_count(0);
   m->set_vtable_index(methodOopDesc::garbage_vtable_index);
--- a/hotspot/src/share/vm/oops/methodOop.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/oops/methodOop.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -77,7 +77,7 @@
 // | method_size             | max_stack                  |
 // | max_locals              | size_of_parameters         |
 // |------------------------------------------------------|
-// | intrinsic_id, (unused)  |  throwout_count            |
+// |intrinsic_id|   flags    |  throwout_count            |
 // |------------------------------------------------------|
 // | num_breakpoints         |  (unused)                  |
 // |------------------------------------------------------|
@@ -124,6 +124,8 @@
   u2                _max_locals;                 // Number of local variables used by this method
   u2                _size_of_parameters;         // size of the parameter block (receiver + arguments) in words
   u1                _intrinsic_id;               // vmSymbols::intrinsic_id (0 == _none)
+  u1                _jfr_towrite : 1,            // Flags
+                                 : 7;
   u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
   u2                _number_of_breakpoints;      // fullspeed debugging support
   InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
@@ -225,6 +227,7 @@
   void clear_number_of_breakpoints()             { _number_of_breakpoints = 0; }
 
   // index into instanceKlass methods() array
+  // note: also used by jfr
   u2 method_idnum() const           { return constMethod()->method_idnum(); }
   void set_method_idnum(u2 idnum)   { constMethod()->set_method_idnum(idnum); }
 
@@ -650,6 +653,9 @@
   void init_intrinsic_id();     // updates from _none if a match
   static vmSymbols::SID klass_id_for_intrinsics(klassOop holder);
 
+  bool jfr_towrite()                 { return _jfr_towrite; }
+  void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; }
+
   // On-stack replacement support
   bool has_osr_nmethod(int level, bool match_level) {
    return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
--- a/hotspot/src/share/vm/opto/block.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/block.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -284,13 +284,13 @@
   // helper function that adds caller save registers to MachProjNode
   void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe);
   // Schedule a call next in the block
-  uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call);
+  uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call);
 
   // Perform basic-block local scheduling
-  Node *select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot);
+  Node *select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot);
   void set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs );
   void needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs);
-  bool schedule_local(PhaseCFG *cfg, Matcher &m, int *ready_cnt, VectorSet &next_call);
+  bool schedule_local(PhaseCFG *cfg, Matcher &m, GrowableArray<int> &ready_cnt, VectorSet &next_call);
   // Cleanup if any code lands between a Call and his Catch
   void call_catch_cleanup(Block_Array &bbs);
   // Detect implicit-null-check opportunities.  Basically, find NULL checks
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -426,6 +426,9 @@
   product(bool, EliminateLocks, true,                                       \
           "Coarsen locks when possible")                                    \
                                                                             \
+  product(bool, EliminateNestedLocks, true,                                 \
+          "Eliminate nested locks of the same object when possible")        \
+                                                                            \
   notproduct(bool, PrintLockStatistics, false,                              \
           "Print precise statistics on the dynamic lock usage")             \
                                                                             \
--- a/hotspot/src/share/vm/opto/callnode.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -400,10 +400,10 @@
       Node *box = mcall->monitor_box(this, i);
       Node *obj = mcall->monitor_obj(this, i);
       if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
-        while( !box->is_BoxLock() )  box = box->in(1);
+        box = BoxLockNode::box_node(box);
         format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
       } else {
-        OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
+        OptoReg::Name box_reg = BoxLockNode::reg(box);
         st->print(" MON-BOX%d=%s+%d",
                    i,
                    OptoReg::regname(OptoReg::c_frame_pointer),
@@ -411,8 +411,7 @@
       }
       const char* obj_msg = "MON-OBJ[";
       if (EliminateLocks) {
-        while( !box->is_BoxLock() )  box = box->in(1);
-        if (box->as_BoxLock()->is_eliminated())
+        if (BoxLockNode::box_node(box)->is_eliminated())
           obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
       }
       format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
@@ -1387,8 +1386,9 @@
     Node *n = ctrl_proj->in(0);
     if (n != NULL && n->is_Unlock()) {
       UnlockNode *unlock = n->as_Unlock();
-      if ((lock->obj_node() == unlock->obj_node()) &&
-          (lock->box_node() == unlock->box_node()) && !unlock->is_eliminated()) {
+      if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
+          BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) &&
+          !unlock->is_eliminated()) {
         lock_ops.append(unlock);
         return true;
       }
@@ -1431,8 +1431,8 @@
   }
   if (ctrl->is_Lock()) {
     LockNode *lock = ctrl->as_Lock();
-    if ((lock->obj_node() == unlock->obj_node()) &&
-            (lock->box_node() == unlock->box_node())) {
+    if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
+        BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) {
       lock_result = lock;
     }
   }
@@ -1462,8 +1462,9 @@
       }
       if (lock1_node != NULL && lock1_node->is_Lock()) {
         LockNode *lock1 = lock1_node->as_Lock();
-        if ((lock->obj_node() == lock1->obj_node()) &&
-            (lock->box_node() == lock1->box_node()) && !lock1->is_eliminated()) {
+        if (lock->obj_node()->eqv_uncast(lock1->obj_node()) &&
+            BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) &&
+            !lock1->is_eliminated()) {
           lock_ops.append(lock1);
           return true;
         }
@@ -1507,19 +1508,16 @@
 void AbstractLockNode::create_lock_counter(JVMState* state) {
   _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
 }
-#endif
 
-void AbstractLockNode::set_eliminated() {
-  _eliminate = true;
-#ifndef PRODUCT
+void AbstractLockNode::set_eliminated_lock_counter() {
   if (_counter) {
     // Update the counter to indicate that this lock was eliminated.
     // The counter update code will stay around even though the
     // optimizer will eliminate the lock operation itself.
     _counter->set_tag(NamedCounter::EliminatedLockCounter);
   }
+}
 #endif
-}
 
 //=============================================================================
 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
@@ -1535,7 +1533,7 @@
   // prevents macro expansion from expanding the lock.  Since we don't
   // modify the graph, the value returned from this function is the
   // one computed above.
-  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
+  if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
     //
     // If we are locking an unescaped object, the lock/unlock is unnecessary
     //
@@ -1544,16 +1542,11 @@
     if (cgr != NULL)
       es = cgr->escape_state(obj_node());
     if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
-      if (!is_eliminated()) {
-        // Mark it eliminated to update any counters
-        this->set_eliminated();
-      } else {
-        assert(is_coarsened(), "sanity");
-        // The lock could be marked eliminated by lock coarsening
-        // code during first IGVN before EA. Clear coarsened flag
-        // to eliminate all associated locks/unlocks.
-        this->clear_coarsened();
-      }
+      assert(!is_eliminated() || is_coarsened(), "sanity");
+      // The lock could be marked eliminated by lock coarsening
+      // code during first IGVN before EA. Replace coarsened flag
+      // to eliminate all associated locks/unlocks.
+      this->set_non_esc_obj();
       return result;
     }
 
@@ -1613,8 +1606,7 @@
         for (int i = 0; i < lock_ops.length(); i++) {
           AbstractLockNode* lock = lock_ops.at(i);
 
-          // Mark it eliminated to update any counters
-          lock->set_eliminated();
+          // Mark it eliminated by coarsening and update any counters
           lock->set_coarsened();
         }
       } else if (ctrl->is_Region() &&
@@ -1632,6 +1624,40 @@
 }
 
 //=============================================================================
+bool LockNode::is_nested_lock_region() {
+  BoxLockNode* box = box_node()->as_BoxLock();
+  int stk_slot = box->stack_slot();
+  if (stk_slot <= 0)
+    return false; // External lock or it is not Box (Phi node).
+
+  // Ignore complex cases: merged locks or multiple locks.
+  Node* obj = obj_node();
+  LockNode* unique_lock = NULL;
+  if (!box->is_simple_lock_region(&unique_lock, obj) ||
+      (unique_lock != this)) {
+    return false;
+  }
+
+  // Look for external lock for the same object.
+  SafePointNode* sfn = this->as_SafePoint();
+  JVMState* youngest_jvms = sfn->jvms();
+  int max_depth = youngest_jvms->depth();
+  for (int depth = 1; depth <= max_depth; depth++) {
+    JVMState* jvms = youngest_jvms->of_depth(depth);
+    int num_mon  = jvms->nof_monitors();
+    // Loop over monitors
+    for (int idx = 0; idx < num_mon; idx++) {
+      Node* obj_node = sfn->monitor_obj(jvms, idx);
+      BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock();
+      if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+//=============================================================================
 uint UnlockNode::size_of() const { return sizeof(*this); }
 
 //=============================================================================
@@ -1649,7 +1675,7 @@
   // modify the graph, the value returned from this function is the
   // one computed above.
   // Escape state is defined after Parse phase.
-  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
+  if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
     //
     // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
     //
@@ -1658,16 +1684,11 @@
     if (cgr != NULL)
       es = cgr->escape_state(obj_node());
     if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
-      if (!is_eliminated()) {
-        // Mark it eliminated to update any counters
-        this->set_eliminated();
-      } else {
-        assert(is_coarsened(), "sanity");
-        // The lock could be marked eliminated by lock coarsening
-        // code during first IGVN before EA. Clear coarsened flag
-        // to eliminate all associated locks/unlocks.
-        this->clear_coarsened();
-      }
+      assert(!is_eliminated() || is_coarsened(), "sanity");
+      // The lock could be marked eliminated by lock coarsening
+      // code during first IGVN before EA. Replace coarsened flag
+      // to eliminate all associated locks/unlocks.
+      this->set_non_esc_obj();
     }
   }
   return result;
--- a/hotspot/src/share/vm/opto/callnode.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -840,8 +840,12 @@
 //------------------------------AbstractLockNode-----------------------------------
 class AbstractLockNode: public CallNode {
 private:
-  bool _eliminate;    // indicates this lock can be safely eliminated
-  bool _coarsened;    // indicates this lock was coarsened
+  enum {
+    Regular = 0,  // Normal lock
+    NonEscObj,    // Lock is used for non escaping object
+    Coarsened,    // Lock was coarsened
+    Nested        // Nested lock
+  } _kind;
 #ifndef PRODUCT
   NamedCounter* _counter;
 #endif
@@ -858,12 +862,13 @@
                                GrowableArray<AbstractLockNode*> &lock_ops);
   LockNode *find_matching_lock(UnlockNode* unlock);
 
+  // Update the counter to indicate that this lock was eliminated.
+  void set_eliminated_lock_counter() PRODUCT_RETURN;
 
 public:
   AbstractLockNode(const TypeFunc *tf)
     : CallNode(tf, NULL, TypeRawPtr::BOTTOM),
-      _coarsened(false),
-      _eliminate(false)
+      _kind(Regular)
   {
 #ifndef PRODUCT
     _counter = NULL;
@@ -873,20 +878,23 @@
   Node *   obj_node() const       {return in(TypeFunc::Parms + 0); }
   Node *   box_node() const       {return in(TypeFunc::Parms + 1); }
   Node *   fastlock_node() const  {return in(TypeFunc::Parms + 2); }
+  void     set_box_node(Node* box) { set_req(TypeFunc::Parms + 1, box); }
+
   const Type *sub(const Type *t1, const Type *t2) const { return TypeInt::CC;}
 
   virtual uint size_of() const { return sizeof(*this); }
 
-  bool is_eliminated()         {return _eliminate; }
-  // mark node as eliminated and update the counter if there is one
-  void set_eliminated();
+  bool is_eliminated()  const { return (_kind != Regular); }
+  bool is_non_esc_obj() const { return (_kind == NonEscObj); }
+  bool is_coarsened()   const { return (_kind == Coarsened); }
+  bool is_nested()      const { return (_kind == Nested); }
 
-  bool is_coarsened()  { return _coarsened; }
-  void set_coarsened() { _coarsened = true; }
-  void clear_coarsened() { _coarsened = false; }
+  void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
+  void set_coarsened()   { _kind = Coarsened; set_eliminated_lock_counter(); }
+  void set_nested()      { _kind = Nested; set_eliminated_lock_counter(); }
 
   // locking does not modify its arguments
-  virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
+  virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
 
 #ifndef PRODUCT
   void create_lock_counter(JVMState* s);
@@ -936,6 +944,8 @@
   virtual void  clone_jvms() {
     set_jvms(jvms()->clone_deep(Compile::current()));
   }
+
+  bool is_nested_lock_region(); // Is this Lock nested?
 };
 
 //------------------------------Unlock---------------------------------------
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1597,7 +1597,7 @@
       bool is_loop = (r->is_Loop() && r->req() == 3);
       // Then, check if there is a data loop when phi references itself directly
       // or through other data nodes.
-      if (is_loop && !phase->eqv_uncast(uin, in(LoopNode::EntryControl)) ||
+      if (is_loop && !uin->eqv_uncast(in(LoopNode::EntryControl)) ||
          !is_loop && is_unsafe_data_reference(uin)) {
         // Break this data loop to avoid creation of a dead loop.
         if (can_reshape) {
--- a/hotspot/src/share/vm/opto/chaitin.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/chaitin.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -485,7 +485,11 @@
     return yank_if_dead(old, current_block, &value, &regnd);
   }
 
-  int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
+  int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
+    return yank_if_dead_recurse(old, old, current_block, value, regnd);
+  }
+  int yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block,
+                           Node_List *value, Node_List *regnd);
   int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
   int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs );
   int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd );
--- a/hotspot/src/share/vm/opto/escape.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1842,20 +1842,15 @@
       Node *n = C->macro_node(i);
       if (n->is_AbstractLock()) { // Lock and Unlock nodes
         AbstractLockNode* alock = n->as_AbstractLock();
-        if (!alock->is_eliminated() || alock->is_coarsened()) {
+        if (!alock->is_non_esc_obj()) {
           PointsToNode::EscapeState es = escape_state(alock->obj_node());
           assert(es != PointsToNode::UnknownEscape, "should know");
           if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
-            if (!alock->is_eliminated()) {
-              // Mark it eliminated to update any counters
-              alock->set_eliminated();
-            } else {
-              // The lock could be marked eliminated by lock coarsening
-              // code during first IGVN before EA. Clear coarsened flag
-              // to eliminate all associated locks/unlocks and relock
-              // during deoptimization.
-              alock->clear_coarsened();
-            }
+            assert(!alock->is_eliminated() || alock->is_coarsened(), "sanity");
+            // The lock could be marked eliminated by lock coarsening
+            // code during first IGVN before EA. Replace coarsened flag
+            // to eliminate all associated locks/unlocks.
+            alock->set_non_esc_obj();
           }
         }
       }
--- a/hotspot/src/share/vm/opto/gcm.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1344,8 +1344,8 @@
 
   // Schedule locally.  Right now a simple topological sort.
   // Later, do a real latency aware scheduler.
-  int *ready_cnt = NEW_RESOURCE_ARRAY(int,C->unique());
-  memset( ready_cnt, -1, C->unique() * sizeof(int) );
+  uint max_idx = C->unique();
+  GrowableArray<int> ready_cnt(max_idx, max_idx, -1);
   visited.Clear();
   for (i = 0; i < _num_blocks; i++) {
     if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) {
--- a/hotspot/src/share/vm/opto/lcm.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -404,7 +404,7 @@
 // remaining cases (most), choose the instruction with the greatest latency
 // (that is, the most number of pseudo-cycles required to the end of the
 // routine). If there is a tie, choose the instruction with the most inputs.
-Node *Block::select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot) {
+Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot) {
 
   // If only a single entry on the stack, use it
   uint cnt = worklist.size();
@@ -465,7 +465,7 @@
 
         // More than this instruction pending for successor to be ready,
         // don't choose this if other opportunities are ready
-        if (ready_cnt[use->_idx] > 1)
+        if (ready_cnt.at(use->_idx) > 1)
           n_choice = 1;
       }
 
@@ -565,7 +565,7 @@
 
 
 //------------------------------sched_call-------------------------------------
-uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
+uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
   RegMask regs;
 
   // Schedule all the users of the call right now.  All the users are
@@ -574,8 +574,9 @@
   for (DUIterator_Fast imax, i = mcall->fast_outs(imax); i < imax; i++) {
     Node* n = mcall->fast_out(i);
     assert( n->is_MachProj(), "" );
-    --ready_cnt[n->_idx];
-    assert( !ready_cnt[n->_idx], "" );
+    int n_cnt = ready_cnt.at(n->_idx)-1;
+    ready_cnt.at_put(n->_idx, n_cnt);
+    assert( n_cnt == 0, "" );
     // Schedule next to call
     _nodes.map(node_cnt++, n);
     // Collect defined registers
@@ -590,7 +591,9 @@
       Node* m = n->fast_out(j); // Get user
       if( bbs[m->_idx] != this ) continue;
       if( m->is_Phi() ) continue;
-      if( !--ready_cnt[m->_idx] )
+      int m_cnt = ready_cnt.at(m->_idx)-1;
+      ready_cnt.at_put(m->_idx, m_cnt);
+      if( m_cnt == 0 )
         worklist.push(m);
     }
 
@@ -655,7 +658,7 @@
 
 //------------------------------schedule_local---------------------------------
 // Topological sort within a block.  Someday become a real scheduler.
-bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, int *ready_cnt, VectorSet &next_call) {
+bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray<int> &ready_cnt, VectorSet &next_call) {
   // Already "sorted" are the block start Node (as the first entry), and
   // the block-ending Node and any trailing control projections.  We leave
   // these alone.  PhiNodes and ParmNodes are made to follow the block start
@@ -695,7 +698,7 @@
         if( m && cfg->_bbs[m->_idx] == this && !m->is_top() )
           local++;              // One more block-local input
       }
-      ready_cnt[n->_idx] = local; // Count em up
+      ready_cnt.at_put(n->_idx, local); // Count em up
 
 #ifdef ASSERT
       if( UseConcMarkSweepGC || UseG1GC ) {
@@ -729,7 +732,7 @@
     }
   }
   for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count
-    ready_cnt[_nodes[i2]->_idx] = 0;
+    ready_cnt.at_put(_nodes[i2]->_idx, 0);
 
   // All the prescheduled guys do not hold back internal nodes
   uint i3;
@@ -737,8 +740,10 @@
     Node *n = _nodes[i3];       // Get pre-scheduled
     for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
       Node* m = n->fast_out(j);
-      if( cfg->_bbs[m->_idx] ==this ) // Local-block user
-        ready_cnt[m->_idx]--;   // Fix ready count
+      if( cfg->_bbs[m->_idx] ==this ) { // Local-block user
+        int m_cnt = ready_cnt.at(m->_idx)-1;
+        ready_cnt.at_put(m->_idx, m_cnt);   // Fix ready count
+      }
     }
   }
 
@@ -747,7 +752,7 @@
   Node_List worklist;
   for(uint i4=i3; i4<node_cnt; i4++ ) {    // Put ready guys on worklist
     Node *m = _nodes[i4];
-    if( !ready_cnt[m->_idx] ) {   // Zero ready count?
+    if( !ready_cnt.at(m->_idx) ) {   // Zero ready count?
       if (m->is_iteratively_computed()) {
         // Push induction variable increments last to allow other uses
         // of the phi to be scheduled first. The select() method breaks
@@ -775,14 +780,14 @@
       for (uint j=0; j<_nodes.size(); j++) {
         Node     *n = _nodes[j];
         int     idx = n->_idx;
-        tty->print("#   ready cnt:%3d  ", ready_cnt[idx]);
+        tty->print("#   ready cnt:%3d  ", ready_cnt.at(idx));
         tty->print("latency:%3d  ", cfg->_node_latency->at_grow(idx));
         tty->print("%4d: %s\n", idx, n->Name());
       }
     }
 #endif
 
-  uint max_idx = matcher.C->unique();
+  uint max_idx = (uint)ready_cnt.length();
   // Pull from worklist and schedule
   while( worklist.size() ) {    // Worklist is not ready
 
@@ -840,11 +845,13 @@
       Node* m = n->fast_out(i5); // Get user
       if( cfg->_bbs[m->_idx] != this ) continue;
       if( m->is_Phi() ) continue;
-      if (m->_idx > max_idx) { // new node, skip it
+      if (m->_idx >= max_idx) { // new node, skip it
         assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types");
         continue;
       }
-      if( !--ready_cnt[m->_idx] )
+      int m_cnt = ready_cnt.at(m->_idx)-1;
+      ready_cnt.at_put(m->_idx, m_cnt);
+      if( m_cnt == 0 )
         worklist.push(m);
     }
   }
--- a/hotspot/src/share/vm/opto/library_call.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -819,7 +819,7 @@
   if (stopped())
     return NULL;                // already stopped
   bool zero_offset = _gvn.type(offset) == TypeInt::ZERO;
-  if (zero_offset && _gvn.eqv_uncast(subseq_length, array_length))
+  if (zero_offset && subseq_length->eqv_uncast(array_length))
     return NULL;                // common case of whole-array copy
   Node* last = subseq_length;
   if (!zero_offset)             // last += offset
@@ -4667,7 +4667,7 @@
   if (ReduceBulkZeroing
       && !ZeroTLAB              // pointless if already zeroed
       && basic_elem_type != T_CONFLICT // avoid corner case
-      && !_gvn.eqv_uncast(src, dest)
+      && !src->eqv_uncast(dest)
       && ((alloc = tightly_coupled_allocation(dest, slow_region))
           != NULL)
       && _gvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0
@@ -4745,7 +4745,7 @@
     // copy_length is 0.
     if (!stopped() && dest_uninitialized) {
       Node* dest_length = alloc->in(AllocateNode::ALength);
-      if (_gvn.eqv_uncast(copy_length, dest_length)
+      if (copy_length->eqv_uncast(dest_length)
           || _gvn.find_int_con(dest_length, 1) <= 0) {
         // There is no zeroing to do. No need for a secondary raw memory barrier.
       } else {
@@ -4791,7 +4791,7 @@
     // with its attendant messy index arithmetic, and upgrade
     // the copy to a more hardware-friendly word size of 64 bits.
     Node* tail_ctl = NULL;
-    if (!stopped() && !_gvn.eqv_uncast(dest_tail, dest_length)) {
+    if (!stopped() && !dest_tail->eqv_uncast(dest_length)) {
       Node* cmp_lt   = _gvn.transform( new(C,3) CmpINode(dest_tail, dest_length) );
       Node* bol_lt   = _gvn.transform( new(C,2) BoolNode(cmp_lt, BoolTest::lt) );
       tail_ctl = generate_slow_guard(bol_lt, NULL);
--- a/hotspot/src/share/vm/opto/locknode.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/locknode.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -49,18 +49,22 @@
 
 //-----------------------------hash--------------------------------------------
 uint BoxLockNode::hash() const {
+  if (EliminateNestedLocks)
+    return NO_HASH; // Each locked region has own BoxLock node
   return Node::hash() + _slot + (_is_eliminated ? Compile::current()->fixed_slots() : 0);
 }
 
 //------------------------------cmp--------------------------------------------
 uint BoxLockNode::cmp( const Node &n ) const {
+  if (EliminateNestedLocks)
+    return (&n == this); // Always fail except on self
   const BoxLockNode &bn = (const BoxLockNode &)n;
   return bn._slot == _slot && bn._is_eliminated == _is_eliminated;
 }
 
-OptoReg::Name BoxLockNode::stack_slot(Node* box_node) {
-  // Chase down the BoxNode
-  while (!box_node->is_BoxLock()) {
+BoxLockNode* BoxLockNode::box_node(Node* box) {
+  // Chase down the BoxNode after RA which may spill box nodes.
+  while (!box->is_BoxLock()) {
     //    if (box_node->is_SpillCopy()) {
     //      Node *m = box_node->in(1);
     //      if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_StoreP) {
@@ -68,10 +72,64 @@
     //        continue;
     //      }
     //    }
-    assert(box_node->is_SpillCopy() || box_node->is_Phi(), "Bad spill of Lock.");
-    box_node = box_node->in(1);
+    assert(box->is_SpillCopy() || box->is_Phi(), "Bad spill of Lock.");
+    // Only BoxLock nodes with the same stack slot are merged.
+    // So it is enough to trace one path to find the slot value.
+    box = box->in(1);
   }
-  return box_node->in_RegMask(0).find_first_elem();
+  return box->as_BoxLock();
+}
+
+OptoReg::Name BoxLockNode::reg(Node* box) {
+  return box_node(box)->in_RegMask(0).find_first_elem();
+}
+
+// Is BoxLock node used for one simple lock region (same box and obj)?
+bool BoxLockNode::is_simple_lock_region(LockNode** unique_lock, Node* obj) {
+  LockNode* lock = NULL;
+  bool has_one_lock = false;
+  for (uint i = 0; i < this->outcnt(); i++) {
+    Node* n = this->raw_out(i);
+    assert(!n->is_Phi(), "should not merge BoxLock nodes");
+    if (n->is_AbstractLock()) {
+      AbstractLockNode* alock = n->as_AbstractLock();
+      // Check lock's box since box could be referenced by Lock's debug info.
+      if (alock->box_node() == this) {
+        if (alock->obj_node()->eqv_uncast(obj)) {
+          if ((unique_lock != NULL) && alock->is_Lock()) {
+            if (lock == NULL) {
+              lock = alock->as_Lock();
+              has_one_lock = true;
+            } else if (lock != alock->as_Lock()) {
+              has_one_lock = false;
+            }
+          }
+        } else {
+          return false; // Different objects
+        }
+      }
+    }
+  }
+#ifdef ASSERT
+  // Verify that FastLock and Safepoint reference only this lock region.
+  for (uint i = 0; i < this->outcnt(); i++) {
+    Node* n = this->raw_out(i);
+    if (n->is_FastLock()) {
+      FastLockNode* flock = n->as_FastLock();
+      assert((flock->box_node() == this) && flock->obj_node()->eqv_uncast(obj),"");
+    }
+    // Don't check monitor info in safepoints since the referenced object could
+    // be different from the locked object. It could be Phi node of different
+    // cast nodes which point to this locked object.
+    // We assume that no other objects could be referenced in monitor info
+    // associated with this BoxLock node because all associated locks and
+    // unlocks are reference only this one object.
+  }
+#endif
+  if (unique_lock != NULL && has_one_lock) {
+    *unique_lock = lock;
+  }
+  return true;
 }
 
 //=============================================================================
--- a/hotspot/src/share/vm/opto/locknode.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/locknode.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -49,11 +49,11 @@
 
 //------------------------------BoxLockNode------------------------------------
 class BoxLockNode : public Node {
+  const int     _slot; // stack slot
+  RegMask     _inmask; // OptoReg corresponding to stack slot
+  bool _is_eliminated; // Associated locks were safely eliminated
+
 public:
-  const int _slot;
-  RegMask   _inmask;
-  bool _is_eliminated;    // indicates this lock was safely eliminated
-
   BoxLockNode( int lock );
   virtual int Opcode() const;
   virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
@@ -66,11 +66,19 @@
   virtual const class Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
   virtual uint ideal_reg() const { return Op_RegP; }
 
-  static OptoReg::Name stack_slot(Node* box_node);
+  static OptoReg::Name reg(Node* box_node);
+  static BoxLockNode* box_node(Node* box_node);
+  static bool same_slot(Node* box1, Node* box2) {
+    return box1->as_BoxLock()->_slot == box2->as_BoxLock()->_slot;
+  }
+  int stack_slot() const { return _slot; }
 
-  bool is_eliminated()  { return _is_eliminated; }
+  bool is_eliminated() const { return _is_eliminated; }
   // mark lock as eliminated.
-  void set_eliminated() { _is_eliminated = true; }
+  void set_eliminated()      { _is_eliminated = true; }
+
+  // Is BoxLock node used for one simple lock region?
+  bool is_simple_lock_region(LockNode** unique_lock, Node* obj);
 
 #ifndef PRODUCT
   virtual void format( PhaseRegAlloc *, outputStream *st ) const;
@@ -91,6 +99,7 @@
   }
   Node* obj_node() const { return in(1); }
   Node* box_node() const { return in(2); }
+  void  set_box_node(Node* box) { set_req(2, box); }
 
   // FastLock and FastUnlockNode do not hash, we need one for each correspoding
   // LockNode/UnLockNode to avoid creating Phi's.
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -3278,16 +3278,7 @@
 #ifdef ASSERT
     if (legal->is_Start() && !early->is_Root()) {
       // Bad graph. Print idom path and fail.
-      tty->print_cr( "Bad graph detected in build_loop_late");
-      tty->print("n: ");n->dump(); tty->cr();
-      tty->print("early: ");early->dump(); tty->cr();
-      int ct = 0;
-      Node *dbg_legal = LCA;
-      while(!dbg_legal->is_Start() && ct < 100) {
-        tty->print("idom[%d] ",ct); dbg_legal->dump(); tty->cr();
-        ct++;
-        dbg_legal = idom(dbg_legal);
-      }
+      dump_bad_graph(n, early, LCA);
       assert(false, "Bad graph detected in build_loop_late");
     }
 #endif
@@ -3337,6 +3328,88 @@
     chosen_loop->_body.push(n);// Collect inner loops
 }
 
+#ifdef ASSERT
+void PhaseIdealLoop::dump_bad_graph(Node* n, Node* early, Node* LCA) {
+  tty->print_cr( "Bad graph detected in build_loop_late");
+  tty->print("n: "); n->dump();
+  tty->print("early(n): "); early->dump();
+  if (n->in(0) != NULL  && !n->in(0)->is_top() &&
+      n->in(0) != early && !n->in(0)->is_Root()) {
+    tty->print("n->in(0): "); n->in(0)->dump();
+  }
+  for (uint i = 1; i < n->req(); i++) {
+    Node* in1 = n->in(i);
+    if (in1 != NULL && in1 != n && !in1->is_top()) {
+      tty->print("n->in(%d): ", i); in1->dump();
+      Node* in1_early = get_ctrl(in1);
+      tty->print("early(n->in(%d)): ", i); in1_early->dump();
+      if (in1->in(0) != NULL     && !in1->in(0)->is_top() &&
+          in1->in(0) != in1_early && !in1->in(0)->is_Root()) {
+        tty->print("n->in(%d)->in(0): ", i); in1->in(0)->dump();
+      }
+      for (uint j = 1; j < in1->req(); j++) {
+        Node* in2 = in1->in(j);
+        if (in2 != NULL && in2 != n && in2 != in1 && !in2->is_top()) {
+          tty->print("n->in(%d)->in(%d): ", i, j); in2->dump();
+          Node* in2_early = get_ctrl(in2);
+          tty->print("early(n->in(%d)->in(%d)): ", i, j); in2_early->dump();
+          if (in2->in(0) != NULL     && !in2->in(0)->is_top() &&
+              in2->in(0) != in2_early && !in2->in(0)->is_Root()) {
+            tty->print("n->in(%d)->in(%d)->in(0): ", i, j); in2->in(0)->dump();
+          }
+        }
+      }
+    }
+  }
+  tty->cr();
+  tty->print("LCA(n): "); LCA->dump();
+  for (uint i = 0; i < n->outcnt(); i++) {
+    Node* u1 = n->raw_out(i);
+    if (u1 == n)
+      continue;
+    tty->print("n->out(%d): ", i); u1->dump();
+    if (u1->is_CFG()) {
+      for (uint j = 0; j < u1->outcnt(); j++) {
+        Node* u2 = u1->raw_out(j);
+        if (u2 != u1 && u2 != n && u2->is_CFG()) {
+          tty->print("n->out(%d)->out(%d): ", i, j); u2->dump();
+        }
+      }
+    } else {
+      Node* u1_later = get_ctrl(u1);
+      tty->print("later(n->out(%d)): ", i); u1_later->dump();
+      if (u1->in(0) != NULL     && !u1->in(0)->is_top() &&
+          u1->in(0) != u1_later && !u1->in(0)->is_Root()) {
+        tty->print("n->out(%d)->in(0): ", i); u1->in(0)->dump();
+      }
+      for (uint j = 0; j < u1->outcnt(); j++) {
+        Node* u2 = u1->raw_out(j);
+        if (u2 == n || u2 == u1)
+          continue;
+        tty->print("n->out(%d)->out(%d): ", i, j); u2->dump();
+        if (!u2->is_CFG()) {
+          Node* u2_later = get_ctrl(u2);
+          tty->print("later(n->out(%d)->out(%d)): ", i, j); u2_later->dump();
+          if (u2->in(0) != NULL     && !u2->in(0)->is_top() &&
+              u2->in(0) != u2_later && !u2->in(0)->is_Root()) {
+            tty->print("n->out(%d)->in(0): ", i); u2->in(0)->dump();
+          }
+        }
+      }
+    }
+  }
+  tty->cr();
+  int ct = 0;
+  Node *dbg_legal = LCA;
+  while(!dbg_legal->is_Start() && ct < 100) {
+    tty->print("idom[%d] ",ct); dbg_legal->dump();
+    ct++;
+    dbg_legal = idom(dbg_legal);
+  }
+  tty->cr();
+}
+#endif
+
 #ifndef PRODUCT
 //------------------------------dump-------------------------------------------
 void PhaseIdealLoop::dump( ) const {
--- a/hotspot/src/share/vm/opto/loopnode.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/loopnode.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1040,6 +1040,10 @@
   bool created_loop_node()     { return _created_loop_node; }
   void register_new_node( Node *n, Node *blk );
 
+#ifdef ASSERT
+void dump_bad_graph(Node* n, Node* early, Node* LCA);
+#endif
+
 #ifndef PRODUCT
   void dump( ) const;
   void dump( IdealLoopTree *loop, uint rpo_idx, Node_List &rpo_list ) const;
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -819,6 +819,8 @@
     if( iff->is_If() ) {        // Classic split-if?
       if( iff->in(0) != n_ctrl ) return; // Compare must be in same blk as if
     } else if (iff->is_CMove()) { // Trying to split-up a CMOVE
+      // Can't split CMove with different control edge.
+      if (iff->in(0) != NULL && iff->in(0) != n_ctrl ) return;
       if( get_ctrl(iff->in(2)) == n_ctrl ||
           get_ctrl(iff->in(3)) == n_ctrl )
         return;                 // Inputs not yet split-up
@@ -937,7 +939,7 @@
       }
       bool did_break = (i < imax);  // Did we break out of the previous loop?
       if (!did_break && n->outcnt() > 1) { // All uses in outer loops!
-        Node *late_load_ctrl;
+        Node *late_load_ctrl = NULL;
         if (n->is_Load()) {
           // If n is a load, get and save the result from get_late_ctrl(),
           // to be later used in calculating the control for n's clones.
--- a/hotspot/src/share/vm/opto/macro.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1789,7 +1789,8 @@
                          slow_call_address);
 }
 
-//-----------------------mark_eliminated_locking_nodes-----------------------
+//-------------------mark_eliminated_box----------------------------------
+//
 // During EA obj may point to several objects but after few ideal graph
 // transformations (CCP) it may point to only one non escaping object
 // (but still using phi), corresponding locks and unlocks will be marked
@@ -1800,62 +1801,148 @@
 // marked for elimination since new obj has no escape information.
 // Mark all associated (same box and obj) lock and unlock nodes for
 // elimination if some of them marked already.
-void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) {
-  if (!alock->is_eliminated()) {
+void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) {
+  if (oldbox->as_BoxLock()->is_eliminated())
+    return; // This BoxLock node was processed already.
+
+  // New implementation (EliminateNestedLocks) has separate BoxLock
+  // node for each locked region so mark all associated locks/unlocks as
+  // eliminated even if different objects are referenced in one locked region
+  // (for example, OSR compilation of nested loop inside locked scope).
+  if (EliminateNestedLocks ||
+      oldbox->as_BoxLock()->is_simple_lock_region(NULL, obj)) {
+    // Box is used only in one lock region. Mark this box as eliminated.
+    _igvn.hash_delete(oldbox);
+    oldbox->as_BoxLock()->set_eliminated(); // This changes box's hash value
+    _igvn.hash_insert(oldbox);
+
+    for (uint i = 0; i < oldbox->outcnt(); i++) {
+      Node* u = oldbox->raw_out(i);
+      if (u->is_AbstractLock() && !u->as_AbstractLock()->is_non_esc_obj()) {
+        AbstractLockNode* alock = u->as_AbstractLock();
+        // Check lock's box since box could be referenced by Lock's debug info.
+        if (alock->box_node() == oldbox) {
+          // Mark eliminated all related locks and unlocks.
+          alock->set_non_esc_obj();
+        }
+      }
+    }
     return;
   }
-  if (!alock->is_coarsened()) { // Eliminated by EA
-      // Create new "eliminated" BoxLock node and use it
-      // in monitor debug info for the same object.
-      BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
-      Node* obj = alock->obj_node();
-      if (!oldbox->is_eliminated()) {
-        BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
+
+  // Create new "eliminated" BoxLock node and use it in monitor debug info
+  // instead of oldbox for the same object.
+  BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
+
+  // Note: BoxLock node is marked eliminated only here and it is used
+  // to indicate that all associated lock and unlock nodes are marked
+  // for elimination.
+  newbox->set_eliminated();
+  transform_later(newbox);
+
+  // Replace old box node with new box for all users of the same object.
+  for (uint i = 0; i < oldbox->outcnt();) {
+    bool next_edge = true;
+
+    Node* u = oldbox->raw_out(i);
+    if (u->is_AbstractLock()) {
+      AbstractLockNode* alock = u->as_AbstractLock();
+      if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) {
+        // Replace Box and mark eliminated all related locks and unlocks.
+        alock->set_non_esc_obj();
+        _igvn.hash_delete(alock);
+        alock->set_box_node(newbox);
+        _igvn._worklist.push(alock);
+        next_edge = false;
+      }
+    }
+    if (u->is_FastLock() && u->as_FastLock()->obj_node()->eqv_uncast(obj)) {
+      FastLockNode* flock = u->as_FastLock();
+      assert(flock->box_node() == oldbox, "sanity");
+      _igvn.hash_delete(flock);
+      flock->set_box_node(newbox);
+      _igvn._worklist.push(flock);
+      next_edge = false;
+    }
+
+    // Replace old box in monitor debug info.
+    if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
+      SafePointNode* sfn = u->as_SafePoint();
+      JVMState* youngest_jvms = sfn->jvms();
+      int max_depth = youngest_jvms->depth();
+      for (int depth = 1; depth <= max_depth; depth++) {
+        JVMState* jvms = youngest_jvms->of_depth(depth);
+        int num_mon  = jvms->nof_monitors();
+        // Loop over monitors
+        for (int idx = 0; idx < num_mon; idx++) {
+          Node* obj_node = sfn->monitor_obj(jvms, idx);
+          Node* box_node = sfn->monitor_box(jvms, idx);
+          if (box_node == oldbox && obj_node->eqv_uncast(obj)) {
+            int j = jvms->monitor_box_offset(idx);
+            _igvn.hash_delete(u);
+            u->set_req(j, newbox);
+            _igvn._worklist.push(u);
+            next_edge = false;
+          }
+        }
+      }
+    }
+    if (next_edge) i++;
+  }
+}
+
+//-----------------------mark_eliminated_locking_nodes-----------------------
+void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) {
+  if (EliminateNestedLocks) {
+    if (alock->is_nested()) {
+       assert(alock->box_node()->as_BoxLock()->is_eliminated(), "sanity");
+       return;
+    } else if (!alock->is_non_esc_obj()) { // Not eliminated or coarsened
+      // Only Lock node has JVMState needed here.
+      if (alock->jvms() != NULL && alock->as_Lock()->is_nested_lock_region()) {
+        // Mark eliminated related nested locks and unlocks.
+        Node* obj = alock->obj_node();
+        BoxLockNode* box_node = alock->box_node()->as_BoxLock();
+        assert(!box_node->is_eliminated(), "should not be marked yet");
         // Note: BoxLock node is marked eliminated only here
         // and it is used to indicate that all associated lock
         // and unlock nodes are marked for elimination.
-        newbox->set_eliminated();
-        transform_later(newbox);
-        // Replace old box node with new box for all users
-        // of the same object.
-        for (uint i = 0; i < oldbox->outcnt();) {
+        box_node->set_eliminated(); // Box's hash is always NO_HASH here
+        for (uint i = 0; i < box_node->outcnt(); i++) {
+          Node* u = box_node->raw_out(i);
+          if (u->is_AbstractLock()) {
+            alock = u->as_AbstractLock();
+            if (alock->box_node() == box_node) {
+              // Verify that this Box is referenced only by related locks.
+              assert(alock->obj_node()->eqv_uncast(obj), "");
+              // Mark all related locks and unlocks.
+              alock->set_nested();
+            }
+          }
+        }
+      }
+      return;
+    }
+    // Process locks for non escaping object
+    assert(alock->is_non_esc_obj(), "");
+  } // EliminateNestedLocks
 
-          bool next_edge = true;
-          Node* u = oldbox->raw_out(i);
-          if (u->is_AbstractLock() &&
-              u->as_AbstractLock()->obj_node() == obj &&
-              u->as_AbstractLock()->box_node() == oldbox) {
-            // Mark all associated locks and unlocks.
-            u->as_AbstractLock()->set_eliminated();
-            _igvn.hash_delete(u);
-            u->set_req(TypeFunc::Parms + 1, newbox);
-            next_edge = false;
-          }
-          // Replace old box in monitor debug info.
-          if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
-            SafePointNode* sfn = u->as_SafePoint();
-            JVMState* youngest_jvms = sfn->jvms();
-            int max_depth = youngest_jvms->depth();
-            for (int depth = 1; depth <= max_depth; depth++) {
-              JVMState* jvms = youngest_jvms->of_depth(depth);
-              int num_mon  = jvms->nof_monitors();
-              // Loop over monitors
-              for (int idx = 0; idx < num_mon; idx++) {
-                Node* obj_node = sfn->monitor_obj(jvms, idx);
-                Node* box_node = sfn->monitor_box(jvms, idx);
-                if (box_node == oldbox && obj_node == obj) {
-                  int j = jvms->monitor_box_offset(idx);
-                  _igvn.hash_delete(u);
-                  u->set_req(j, newbox);
-                  next_edge = false;
-                }
-              } // for (int idx = 0;
-            } // for (int depth = 1;
-          } // if (u->is_SafePoint()
-          if (next_edge) i++;
-        } // for (uint i = 0; i < oldbox->outcnt();)
-      } // if (!oldbox->is_eliminated())
-  } // if (!alock->is_coarsened())
+  if (alock->is_non_esc_obj()) { // Lock is used for non escaping object
+    // Look for all locks of this object and mark them and
+    // corresponding BoxLock nodes as eliminated.
+    Node* obj = alock->obj_node();
+    for (uint j = 0; j < obj->outcnt(); j++) {
+      Node* o = obj->raw_out(j);
+      if (o->is_AbstractLock() &&
+          o->as_AbstractLock()->obj_node()->eqv_uncast(obj)) {
+        alock = o->as_AbstractLock();
+        Node* box = alock->box_node();
+        // Replace old box node with new eliminated box for all users
+        // of the same object and mark related locks as eliminated.
+        mark_eliminated_box(box, obj);
+      }
+    }
+  }
 }
 
 // we have determined that this lock/unlock can be eliminated, we simply
@@ -1870,7 +1957,7 @@
     return false;
   }
 #ifdef ASSERT
-  if (alock->is_Lock() && !alock->is_coarsened()) {
+  if (!alock->is_coarsened()) {
     // Check that new "eliminated" BoxLock node is created.
     BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
     assert(oldbox->is_eliminated(), "should be done already");
@@ -1962,6 +2049,8 @@
   Node* box = lock->box_node();
   Node* flock = lock->fastlock_node();
 
+  assert(!box->as_BoxLock()->is_eliminated(), "sanity");
+
   // Make the merge point
   Node *region;
   Node *mem_phi;
@@ -2196,6 +2285,8 @@
   Node* obj = unlock->obj_node();
   Node* box = unlock->box_node();
 
+  assert(!box->as_BoxLock()->is_eliminated(), "sanity");
+
   // No need for a null check on unlock
 
   // Make the merge point
--- a/hotspot/src/share/vm/opto/macro.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/macro.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -92,6 +92,7 @@
   void process_users_of_allocation(AllocateNode *alloc);
 
   void eliminate_card_mark(Node *cm);
+  void mark_eliminated_box(Node* box, Node* obj);
   void mark_eliminated_locking_nodes(AbstractLockNode *alock);
   bool eliminate_locking_node(AbstractLockNode *alock);
   void expand_lock_node(LockNode *lock);
--- a/hotspot/src/share/vm/opto/memnode.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1718,8 +1718,10 @@
   bool is_instance = (tinst != NULL) && tinst->is_known_instance_field();
   if (ReduceFieldZeroing || is_instance) {
     Node* value = can_see_stored_value(mem,phase);
-    if (value != NULL && value->is_Con())
+    if (value != NULL && value->is_Con()) {
+      assert(value->bottom_type()->higher_equal(_type),"sanity");
       return value->bottom_type();
+    }
   }
 
   if (is_instance) {
@@ -1759,6 +1761,20 @@
   return LoadNode::Ideal(phase, can_reshape);
 }
 
+const Type* LoadBNode::Value(PhaseTransform *phase) const {
+  Node* mem = in(MemNode::Memory);
+  Node* value = can_see_stored_value(mem,phase);
+  if (value != NULL && value->is_Con() &&
+      !value->bottom_type()->higher_equal(_type)) {
+    // If the input to the store does not fit with the load's result type,
+    // it must be truncated. We can't delay until Ideal call since
+    // a singleton Value is needed for split_thru_phi optimization.
+    int con = value->get_int();
+    return TypeInt::make((con << 24) >> 24);
+  }
+  return LoadNode::Value(phase);
+}
+
 //--------------------------LoadUBNode::Ideal-------------------------------------
 //
 //  If the previous store is to the same address as this load,
@@ -1775,6 +1791,20 @@
   return LoadNode::Ideal(phase, can_reshape);
 }
 
+const Type* LoadUBNode::Value(PhaseTransform *phase) const {
+  Node* mem = in(MemNode::Memory);
+  Node* value = can_see_stored_value(mem,phase);
+  if (value != NULL && value->is_Con() &&
+      !value->bottom_type()->higher_equal(_type)) {
+    // If the input to the store does not fit with the load's result type,
+    // it must be truncated. We can't delay until Ideal call since
+    // a singleton Value is needed for split_thru_phi optimization.
+    int con = value->get_int();
+    return TypeInt::make(con & 0xFF);
+  }
+  return LoadNode::Value(phase);
+}
+
 //--------------------------LoadUSNode::Ideal-------------------------------------
 //
 //  If the previous store is to the same address as this load,
@@ -1791,6 +1821,20 @@
   return LoadNode::Ideal(phase, can_reshape);
 }
 
+const Type* LoadUSNode::Value(PhaseTransform *phase) const {
+  Node* mem = in(MemNode::Memory);
+  Node* value = can_see_stored_value(mem,phase);
+  if (value != NULL && value->is_Con() &&
+      !value->bottom_type()->higher_equal(_type)) {
+    // If the input to the store does not fit with the load's result type,
+    // it must be truncated. We can't delay until Ideal call since
+    // a singleton Value is needed for split_thru_phi optimization.
+    int con = value->get_int();
+    return TypeInt::make(con & 0xFFFF);
+  }
+  return LoadNode::Value(phase);
+}
+
 //--------------------------LoadSNode::Ideal--------------------------------------
 //
 //  If the previous store is to the same address as this load,
@@ -1809,6 +1853,20 @@
   return LoadNode::Ideal(phase, can_reshape);
 }
 
+const Type* LoadSNode::Value(PhaseTransform *phase) const {
+  Node* mem = in(MemNode::Memory);
+  Node* value = can_see_stored_value(mem,phase);
+  if (value != NULL && value->is_Con() &&
+      !value->bottom_type()->higher_equal(_type)) {
+    // If the input to the store does not fit with the load's result type,
+    // it must be truncated. We can't delay until Ideal call since
+    // a singleton Value is needed for split_thru_phi optimization.
+    int con = value->get_int();
+    return TypeInt::make((con << 16) >> 16);
+  }
+  return LoadNode::Value(phase);
+}
+
 //=============================================================================
 //----------------------------LoadKlassNode::make------------------------------
 // Polymorphic factory method:
@@ -2201,7 +2259,7 @@
   // unsafe if I have intervening uses...  Also disallowed for StoreCM
   // since they must follow each StoreP operation.  Redundant StoreCMs
   // are eliminated just before matching in final_graph_reshape.
-  if (mem->is_Store() && phase->eqv_uncast(mem->in(MemNode::Address), address) &&
+  if (mem->is_Store() && mem->in(MemNode::Address)->eqv_uncast(address) &&
       mem->Opcode() != Op_StoreCM) {
     // Looking at a dead closed cycle of memory?
     assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal");
@@ -2274,16 +2332,16 @@
 
   // Load then Store?  Then the Store is useless
   if (val->is_Load() &&
-      phase->eqv_uncast( val->in(MemNode::Address), adr ) &&
-      phase->eqv_uncast( val->in(MemNode::Memory ), mem ) &&
+      val->in(MemNode::Address)->eqv_uncast(adr) &&
+      val->in(MemNode::Memory )->eqv_uncast(mem) &&
       val->as_Load()->store_Opcode() == Opcode()) {
     return mem;
   }
 
   // Two stores in a row of the same value?
   if (mem->is_Store() &&
-      phase->eqv_uncast( mem->in(MemNode::Address), adr ) &&
-      phase->eqv_uncast( mem->in(MemNode::ValueIn), val ) &&
+      mem->in(MemNode::Address)->eqv_uncast(adr) &&
+      mem->in(MemNode::ValueIn)->eqv_uncast(val) &&
       mem->Opcode() == Opcode()) {
     return mem;
   }
--- a/hotspot/src/share/vm/opto/memnode.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/memnode.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -215,6 +215,7 @@
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegI; }
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+  virtual const Type *Value(PhaseTransform *phase) const;
   virtual int store_Opcode() const { return Op_StoreB; }
   virtual BasicType memory_type() const { return T_BYTE; }
 };
@@ -228,6 +229,7 @@
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegI; }
   virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
+  virtual const Type *Value(PhaseTransform *phase) const;
   virtual int store_Opcode() const { return Op_StoreB; }
   virtual BasicType memory_type() const { return T_BYTE; }
 };
@@ -241,10 +243,25 @@
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegI; }
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+  virtual const Type *Value(PhaseTransform *phase) const;
   virtual int store_Opcode() const { return Op_StoreC; }
   virtual BasicType memory_type() const { return T_CHAR; }
 };
 
+//------------------------------LoadSNode--------------------------------------
+// Load a short (16bits signed) from memory
+class LoadSNode : public LoadNode {
+public:
+  LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT )
+    : LoadNode(c,mem,adr,at,ti) {}
+  virtual int Opcode() const;
+  virtual uint ideal_reg() const { return Op_RegI; }
+  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+  virtual const Type *Value(PhaseTransform *phase) const;
+  virtual int store_Opcode() const { return Op_StoreC; }
+  virtual BasicType memory_type() const { return T_SHORT; }
+};
+
 //------------------------------LoadINode--------------------------------------
 // Load an integer from memory
 class LoadINode : public LoadNode {
@@ -433,19 +450,6 @@
 };
 
 
-//------------------------------LoadSNode--------------------------------------
-// Load a short (16bits signed) from memory
-class LoadSNode : public LoadNode {
-public:
-  LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT )
-    : LoadNode(c,mem,adr,at,ti) {}
-  virtual int Opcode() const;
-  virtual uint ideal_reg() const { return Op_RegI; }
-  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
-  virtual int store_Opcode() const { return Op_StoreC; }
-  virtual BasicType memory_type() const { return T_SHORT; }
-};
-
 //------------------------------StoreNode--------------------------------------
 // Store value; requires Store, Address and Value
 class StoreNode : public MemNode {
--- a/hotspot/src/share/vm/opto/node.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/node.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -833,8 +833,20 @@
 
 //---------------------------uncast_helper-------------------------------------
 Node* Node::uncast_helper(const Node* p) {
-  uint max_depth = 3;
-  for (uint i = 0; i < max_depth; i++) {
+#ifdef ASSERT
+  uint depth_count = 0;
+  const Node* orig_p = p;
+#endif
+
+  while (true) {
+#ifdef ASSERT
+    if (depth_count >= K) {
+      orig_p->dump(4);
+      if (p != orig_p)
+        p->dump(1);
+    }
+    assert(depth_count++ < K, "infinite loop in Node::uncast_helper");
+#endif
     if (p == NULL || p->req() != 2) {
       break;
     } else if (p->is_ConstraintCast()) {
--- a/hotspot/src/share/vm/opto/node.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/node.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -429,6 +429,10 @@
 
   // Strip away casting.  (It is depth-limited.)
   Node* uncast() const;
+  // Return whether two Nodes are equivalent, after stripping casting.
+  bool eqv_uncast(const Node* n) const {
+    return (this->uncast() == n->uncast());
+  }
 
 private:
   static Node* uncast_helper(const Node* n);
--- a/hotspot/src/share/vm/opto/output.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/output.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -924,10 +924,10 @@
         scval = new ConstantOopWriteValue(tp->is_oopptr()->const_oop()->constant_encoding());
       }
 
-      OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
+      OptoReg::Name box_reg = BoxLockNode::reg(box_node);
       Location basic_lock = Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg));
-      while( !box_node->is_BoxLock() )  box_node = box_node->in(1);
-      monarray->append(new MonitorValue(scval, basic_lock, box_node->as_BoxLock()->is_eliminated()));
+      bool eliminated = (box_node->is_BoxLock() && box_node->as_BoxLock()->is_eliminated());
+      monarray->append(new MonitorValue(scval, basic_lock, eliminated));
     }
 
     // We dump the object pool first, since deoptimization reads it in first.
--- a/hotspot/src/share/vm/opto/parse1.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1604,7 +1604,16 @@
           continue;
         default:                // All normal stuff
           if (phi == NULL) {
-            if (!check_elide_phi || !target->can_elide_SEL_phi(j)) {
+            const JVMState* jvms = map()->jvms();
+            if (EliminateNestedLocks &&
+                jvms->is_mon(j) && jvms->is_monitor_box(j)) {
+              // BoxLock nodes are not commoning.
+              // Use old BoxLock node as merged box.
+              assert(newin->jvms()->is_monitor_box(j), "sanity");
+              // This assert also tests that nodes are BoxLock.
+              assert(BoxLockNode::same_slot(n, m), "sanity");
+              C->gvn_replace_by(n, m);
+            } else if (!check_elide_phi || !target->can_elide_SEL_phi(j)) {
               phi = ensure_phi(j, nophi);
             }
           }
--- a/hotspot/src/share/vm/opto/parseHelper.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -71,14 +71,14 @@
   // Throw uncommon trap if class is not loaded or the value we are casting
   // _from_ is not loaded, and value is not null.  If the value _is_ NULL,
   // then the checkcast does nothing.
-  const TypeInstPtr *tp = _gvn.type(obj)->isa_instptr();
-  if (!will_link || (tp && !tp->is_loaded())) {
+  const TypeOopPtr *tp = _gvn.type(obj)->isa_oopptr();
+  if (!will_link || (tp && tp->klass() && !tp->klass()->is_loaded())) {
     if (C->log() != NULL) {
       if (!will_link) {
         C->log()->elem("assert_null reason='checkcast' klass='%d'",
                        C->log()->identify(klass));
       }
-      if (tp && !tp->is_loaded()) {
+      if (tp && tp->klass() && !tp->klass()->is_loaded()) {
         // %%% Cannot happen?
         C->log()->elem("assert_null reason='checkcast source' klass='%d'",
                        C->log()->identify(tp->klass()));
--- a/hotspot/src/share/vm/opto/phaseX.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/phaseX.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -256,11 +256,6 @@
   // For pessimistic optimizations this is simply pointer equivalence.
   bool eqv(const Node* n1, const Node* n2) const { return n1 == n2; }
 
-  // Return whether two Nodes are equivalent, after stripping casting.
-  bool eqv_uncast(const Node* n1, const Node* n2) const {
-    return eqv(n1->uncast(), n2->uncast());
-  }
-
   // For pessimistic passes, the return type must monotonically narrow.
   // For optimistic  passes, the return type must monotonically widen.
   // It is possible to get into a "death march" in either type of pass,
--- a/hotspot/src/share/vm/opto/postaloc.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/postaloc.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -89,32 +89,62 @@
   return blk_adjust;
 }
 
+#ifdef ASSERT
+static bool expected_yanked_node(Node *old, Node *orig_old) {
+  // This code is expected only next original nodes:
+  // - load from constant table node which may have next data input nodes:
+  //     MachConstantBase, Phi, MachTemp, MachSpillCopy
+  // - load constant node which may have next data input nodes:
+  //     MachTemp, MachSpillCopy
+  // - MachSpillCopy
+  // - MachProj and Copy dead nodes
+  if (old->is_MachSpillCopy()) {
+    return true;
+  } else if (old->is_Con()) {
+    return true;
+  } else if (old->is_MachProj()) { // Dead kills projection of Con node
+    return (old == orig_old);
+  } else if (old->is_Copy()) {     // Dead copy of a callee-save value
+    return (old == orig_old);
+  } else if (old->is_MachTemp()) {
+    return orig_old->is_Con();
+  } else if (old->is_Phi() || old->is_MachConstantBase()) {
+    return (orig_old->is_Con() && orig_old->is_MachConstant());
+  }
+  return false;
+}
+#endif
+
 //------------------------------yank_if_dead-----------------------------------
-// Removed an edge from 'old'.  Yank if dead.  Return adjustment counts to
+// Removed edges from 'old'.  Yank if dead.  Return adjustment counts to
 // iterators in the current block.
-int PhaseChaitin::yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
+int PhaseChaitin::yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block,
+                                       Node_List *value, Node_List *regnd) {
   int blk_adjust=0;
-  while (old->outcnt() == 0 && old != C->top()) {
+  if (old->outcnt() == 0 && old != C->top()) {
+#ifdef ASSERT
+    if (!expected_yanked_node(old, orig_old)) {
+      tty->print_cr("==============================================");
+      tty->print_cr("orig_old:");
+      orig_old->dump();
+      tty->print_cr("old:");
+      old->dump();
+      assert(false, "unexpected yanked node");
+    }
+    if (old->is_Con())
+      orig_old = old; // Reset to satisfy expected nodes checks.
+#endif
     blk_adjust += yank(old, current_block, value, regnd);
 
-    Node *tmp = NULL;
     for (uint i = 1; i < old->req(); i++) {
-      if (old->in(i)->is_MachTemp()) {
-        // handle TEMP inputs
-        Node* machtmp = old->in(i);
-        if (machtmp->outcnt() == 1) {
-          assert(machtmp->unique_out() == old, "sanity");
-          blk_adjust += yank(machtmp, current_block, value, regnd);
-          machtmp->disconnect_inputs(NULL);
-        }
-      } else {
-        assert(tmp == NULL, "can't handle more non MachTemp inputs");
-        tmp = old->in(i);
+      Node* n = old->in(i);
+      if (n != NULL) {
+        old->set_req(i, NULL);
+        blk_adjust += yank_if_dead_recurse(n, orig_old, current_block, value, regnd);
       }
     }
+    // Disconnect control and remove precedence edges if any exist
     old->disconnect_inputs(NULL);
-    if( !tmp ) break;
-    old = tmp;
   }
   return blk_adjust;
 }
--- a/hotspot/src/share/vm/opto/subnode.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/opto/subnode.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -91,7 +91,7 @@
 
   // Not correct for SubFnode and AddFNode (must check for infinity)
   // Equal?  Subtract is zero
-  if (phase->eqv_uncast(in1, in2))  return add_id();
+  if (in1->eqv_uncast(in2))  return add_id();
 
   // Either input is BOTTOM ==> the result is the local BOTTOM
   if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
--- a/hotspot/src/share/vm/prims/jni.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/prims/jni.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -48,6 +48,7 @@
 #include "oops/typeArrayOop.hpp"
 #include "prims/jni.h"
 #include "prims/jniCheck.hpp"
+#include "prims/jniExport.hpp"
 #include "prims/jniFastGetField.hpp"
 #include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
@@ -66,6 +67,8 @@
 #include "runtime/signature.hpp"
 #include "runtime/vm_operations.hpp"
 #include "services/runtimeService.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceEventTypes.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
@@ -5139,6 +5142,11 @@
     if (JvmtiExport::should_post_thread_life()) {
        JvmtiExport::post_thread_start(thread);
     }
+
+    EVENT_BEGIN(TraceEventThreadStart, event);
+    EVENT_COMMIT(event,
+        EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
     // Check if we should compile all classes on bootclasspath
     NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
     // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
@@ -5337,6 +5345,10 @@
     JvmtiExport::post_thread_start(thread);
   }
 
+  EVENT_BEGIN(TraceEventThreadStart, event);
+  EVENT_COMMIT(event,
+      EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
   *(JNIEnv**)penv = thread->jni_environment();
 
   // Now leaving the VM, so change thread_state. This is normally automatically taken care
@@ -5464,8 +5476,7 @@
     return ret;
   }
 
-  if (JvmtiExport::is_jvmti_version(version)) {
-    ret = JvmtiExport::get_jvmti_interface(vm, penv, version);
+  if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
     return ret;
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/prims/jniExport.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_PRIMS_JNI_EXPORT_HPP
+#define SHARE_VM_PRIMS_JNI_EXPORT_HPP
+
+#include "prims/jni.h"
+#include "prims/jvmtiExport.hpp"
+
+class JniExportedInterface {
+ public:
+  static bool GetExportedInterface(JavaVM* vm, void** penv, jint version, jint* iface) {
+    if (JvmtiExport::is_jvmti_version(version)) {
+      *iface = JvmtiExport::get_jvmti_interface(vm, penv, version);
+      return true;
+    }
+    return false;
+  }
+};
+
+#endif // SHARE_VM_PRIMS_JNI_EXPORT_HPP
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -194,9 +194,6 @@
 // MethodHandles::generate_adapters
 //
 void MethodHandles::generate_adapters() {
-#ifdef TARGET_ARCH_NYI_6939861
-  if (FLAG_IS_DEFAULT(UseRicochetFrames))  UseRicochetFrames = false;
-#endif
   if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL)  return;
 
   assert(_adapter_code == NULL, "generate only once");
@@ -230,18 +227,6 @@
 }
 
 
-#ifdef TARGET_ARCH_NYI_6939861
-// these defs belong in methodHandles_<arch>.cpp
-frame MethodHandles::ricochet_frame_sender(const frame& fr, RegisterMap *map) {
-  ShouldNotCallThis();
-  return fr;
-}
-void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* f, const RegisterMap* reg_map) {
-  ShouldNotCallThis();
-}
-#endif //TARGET_ARCH_NYI_6939861
-
-
 //------------------------------------------------------------------------------
 // MethodHandles::ek_supported
 //
@@ -251,28 +236,11 @@
   case _adapter_unused_13:
     return false;  // not defined yet
   case _adapter_prim_to_ref:
-    return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF);
+    return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF);
   case _adapter_collect_args:
-    return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS);
+    return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS);
   case _adapter_fold_args:
-    return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS);
-  case _adapter_opt_return_any:
-    return UseRicochetFrames;
-#ifdef TARGET_ARCH_NYI_6939861
-  // ports before 6939861 supported only three kinds of spread ops
-  case _adapter_spread_args:
-    // restrict spreads to three kinds:
-    switch (ek) {
-    case _adapter_opt_spread_0:
-    case _adapter_opt_spread_1:
-    case _adapter_opt_spread_more:
-      break;
-    default:
-      return false;
-      break;
-    }
-    break;
-#endif //TARGET_ARCH_NYI_6939861
+    return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS);
   }
   return true;
 }
@@ -1988,9 +1956,6 @@
     case _adapter_prim_to_ref:    // boxer MH to use
     case _adapter_collect_args:   // method handle which collects the args
     case _adapter_fold_args:      // method handle which collects the args
-      if (!UseRicochetFrames) {
-        { err = "box/collect/fold operators are not supported"; break; }
-      }
       if (!java_lang_invoke_MethodHandle::is_instance(argument()))
         { err = "MethodHandle adapter argument required"; break; }
       arg_mtype = Handle(THREAD, java_lang_invoke_MethodHandle::type(argument()));
@@ -2370,7 +2335,6 @@
 
   case _adapter_prim_to_ref:
     {
-      assert(UseRicochetFrames, "else don't come here");
       // vminfo will be the location to insert the return value
       vminfo = argslot;
       ek_opt = _adapter_opt_collect_ref;
@@ -2436,20 +2400,6 @@
 
   case _adapter_spread_args:
     {
-#ifdef TARGET_ARCH_NYI_6939861
-      // ports before 6939861 supported only three kinds of spread ops
-      if (!UseRicochetFrames) {
-        int array_size   = slots_pushed + 1;
-        assert(array_size >= 0, "");
-        vminfo = array_size;
-        switch (array_size) {
-        case 0:   ek_opt = _adapter_opt_spread_0;       break;
-        case 1:   ek_opt = _adapter_opt_spread_1;       break;
-        default:  ek_opt = _adapter_opt_spread_more;    break;
-        }
-        break;
-      }
-#endif //TARGET_ARCH_NYI_6939861
       // vminfo will be the required length of the array
       int array_size = (slots_pushed + 1) / (type2size[dest] == 2 ? 2 : 1);
       vminfo = array_size;
@@ -2494,7 +2444,6 @@
 
   case _adapter_collect_args:
     {
-      assert(UseRicochetFrames, "else don't come here");
       int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
       // vminfo will be the location to insert the return value
       vminfo = argslot;
@@ -2563,7 +2512,6 @@
 
   case _adapter_fold_args:
     {
-      assert(UseRicochetFrames, "else don't come here");
       int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
       // vminfo will be the location to insert the return value
       vminfo = argslot + elem_slots;
--- a/hotspot/src/share/vm/prims/methodHandles.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -738,46 +738,6 @@
 #ifdef TARGET_ARCH_ppc
 # include "methodHandles_ppc.hpp"
 #endif
-
-#ifdef TARGET_ARCH_NYI_6939861
-  // Here are some backward compatible declarations until the 6939861 ports are updated.
-  #define _adapter_flyby    (_EK_LIMIT + 10)
-  #define _adapter_ricochet (_EK_LIMIT + 11)
-  #define _adapter_opt_spread_1    _adapter_opt_spread_1_ref
-  #define _adapter_opt_spread_more _adapter_opt_spread_ref
-  enum {
-    _INSERT_NO_MASK   = -1,
-    _INSERT_REF_MASK  = 0,
-    _INSERT_INT_MASK  = 1,
-    _INSERT_LONG_MASK = 3
-  };
-  static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) {
-    arg_type = ek_bound_mh_arg_type(ek);
-    arg_mask = 0;
-    arg_slots = type2size[arg_type];;
-  }
-  static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) {
-    int swap_slots = ek_adapter_opt_swap_slots(ek);
-    rotate = ek_adapter_opt_swap_mode(ek);
-    swap_bytes = swap_slots * Interpreter::stackElementSize;
-  }
-  static int get_ek_adapter_opt_spread_info(EntryKind ek) {
-    return ek_adapter_opt_spread_count(ek);
-  }
-
-  static void insert_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               int arg_mask,
-                               Register argslot_reg,
-                               Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-
-  static void remove_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               Register argslot_reg,
-                               Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-
-  static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
-#endif //TARGET_ARCH_NYI_6939861
 };
 
 
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -271,13 +271,10 @@
 }
 
 // Create MDO if necessary.
-void AdvancedThresholdPolicy::create_mdo(methodHandle mh, TRAPS) {
+void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) {
   if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return;
   if (mh->method_data() == NULL) {
-    methodOopDesc::build_interpreter_method_data(mh, THREAD);
-    if (HAS_PENDING_EXCEPTION) {
-      CLEAR_PENDING_EXCEPTION;
-    }
+    methodOopDesc::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
   }
 }
 
@@ -426,22 +423,22 @@
 }
 
 // Update the rate and submit compile
-void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS) {
+void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
   int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
   update_rate(os::javaTimeMillis(), mh());
-  CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD);
+  CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
 }
 
 // Handle the invocation event.
 void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
-                                                      CompLevel level, nmethod* nm, TRAPS) {
+                                                      CompLevel level, nmethod* nm, JavaThread* thread) {
   if (should_create_mdo(mh(), level)) {
-    create_mdo(mh, THREAD);
+    create_mdo(mh, thread);
   }
   if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
     CompLevel next_level = call_event(mh(), level);
     if (next_level != level) {
-      compile(mh, InvocationEntryBci, next_level, THREAD);
+      compile(mh, InvocationEntryBci, next_level, thread);
     }
   }
 }
@@ -449,13 +446,13 @@
 // Handle the back branch event. Notice that we can compile the method
 // with a regular entry from here.
 void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
-                                                       int bci, CompLevel level, nmethod* nm, TRAPS) {
+                                                       int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
   if (should_create_mdo(mh(), level)) {
-    create_mdo(mh, THREAD);
+    create_mdo(mh, thread);
   }
   // Check if MDO should be created for the inlined method
   if (should_create_mdo(imh(), level)) {
-    create_mdo(imh, THREAD);
+    create_mdo(imh, thread);
   }
 
   if (is_compilation_enabled()) {
@@ -463,7 +460,7 @@
     CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
     // At the very least compile the OSR version
     if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_osr_level != level) {
-      compile(imh, bci, next_osr_level, THREAD);
+      compile(imh, bci, next_osr_level, thread);
     }
 
     // Use loop event as an opportunity to also check if there's been
@@ -502,14 +499,14 @@
           next_level = CompLevel_full_profile;
         }
         if (cur_level != next_level) {
-          compile(mh, InvocationEntryBci, next_level, THREAD);
+          compile(mh, InvocationEntryBci, next_level, thread);
         }
       }
     } else {
       cur_level = comp_level(imh());
       next_level = call_event(imh(), cur_level);
       if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_level != cur_level) {
-        compile(imh, InvocationEntryBci, next_level, THREAD);
+        compile(imh, InvocationEntryBci, next_level, thread);
       }
     }
   }
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -197,7 +197,7 @@
   // determines whether we should do that.
   inline bool should_create_mdo(methodOop method, CompLevel cur_level);
   // Create MDO if necessary.
-  void create_mdo(methodHandle mh, TRAPS);
+  void create_mdo(methodHandle mh, JavaThread* thread);
   // Is method profiled enough?
   bool is_method_profiled(methodOop method);
 
@@ -208,12 +208,12 @@
   jlong start_time() const     { return _start_time; }
 
   // Submit a given method for compilation (and update the rate).
-  virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS);
+  virtual void submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
   // event() from SimpleThresholdPolicy would call these.
   virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
-                                       CompLevel level, nmethod* nm, TRAPS);
+                                       CompLevel level, nmethod* nm, JavaThread* thread);
   virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
-                                        int bci, CompLevel level, nmethod* nm, TRAPS);
+                                        int bci, CompLevel level, nmethod* nm, JavaThread* thread);
 public:
   AdvancedThresholdPolicy() : _start_time(0) { }
   // Select task is called by CompileBroker. We should return a task or NULL.
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -3164,6 +3164,9 @@
   if (!UseBiasedLocking || EmitSync != 0) {
     UseOptoBiasInlining = false;
   }
+  if (!EliminateLocks) {
+    EliminateNestedLocks = false;
+  }
 #endif
 
   if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -306,29 +306,27 @@
   return (current >= initial + target);
 }
 
-nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) {
+nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci,
+                                    int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
   assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
   NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
-  if (JvmtiExport::can_post_interpreter_events()) {
-    assert(THREAD->is_Java_thread(), "Wrong type of thread");
-    if (((JavaThread*)THREAD)->is_interp_only_mode()) {
-      // If certain JVMTI events (e.g. frame pop event) are requested then the
-      // thread is forced to remain in interpreted code. This is
-      // implemented partly by a check in the run_compiled_code
-      // section of the interpreter whether we should skip running
-      // compiled code, and partly by skipping OSR compiles for
-      // interpreted-only threads.
-      if (bci != InvocationEntryBci) {
-        reset_counter_for_back_branch_event(method);
-        return NULL;
-      }
+  if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
+    // If certain JVMTI events (e.g. frame pop event) are requested then the
+    // thread is forced to remain in interpreted code. This is
+    // implemented partly by a check in the run_compiled_code
+    // section of the interpreter whether we should skip running
+    // compiled code, and partly by skipping OSR compiles for
+    // interpreted-only threads.
+    if (bci != InvocationEntryBci) {
+      reset_counter_for_back_branch_event(method);
+      return NULL;
     }
   }
   if (bci == InvocationEntryBci) {
     // when code cache is full, compilation gets switched off, UseCompiler
     // is set to false
     if (!method->has_compiled_code() && UseCompiler) {
-      method_invocation_event(method, CHECK_NULL);
+      method_invocation_event(method, thread);
     } else {
       // Force counter overflow on method entry, even if no compilation
       // happened.  (The method_invocation_event call does this also.)
@@ -344,7 +342,7 @@
     NOT_PRODUCT(trace_osr_request(method, osr_nm, bci));
     // when code cache is full, we should not compile any more...
     if (osr_nm == NULL && UseCompiler) {
-      method_back_branch_event(method, bci, CHECK_NULL);
+      method_back_branch_event(method, bci, thread);
       osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
     }
     if (osr_nm == NULL) {
@@ -395,7 +393,7 @@
 
 // SimpleCompPolicy - compile current method
 
-void SimpleCompPolicy::method_invocation_event( methodHandle m, TRAPS) {
+void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
   int hot_count = m->invocation_count();
   reset_counter_for_invocation_event(m);
   const char* comment = "count";
@@ -405,18 +403,18 @@
     if (nm == NULL ) {
       const char* comment = "count";
       CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier,
-                                    m, hot_count, comment, CHECK);
+                                    m, hot_count, comment, thread);
     }
   }
 }
 
-void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, TRAPS) {
+void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
   int hot_count = m->backedge_count();
   const char* comment = "backedge_count";
 
   if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) {
     CompileBroker::compile_method(m, bci, CompLevel_highest_tier,
-                                  m, hot_count, comment, CHECK);
+                                  m, hot_count, comment, thread);
     NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));)
   }
 }
@@ -427,14 +425,13 @@
 
 
 // Consider m for compilation
-void StackWalkCompPolicy::method_invocation_event(methodHandle m, TRAPS) {
+void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
   int hot_count = m->invocation_count();
   reset_counter_for_invocation_event(m);
   const char* comment = "count";
 
   if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m)) {
-    ResourceMark rm(THREAD);
-    JavaThread *thread = (JavaThread*)THREAD;
+    ResourceMark rm(thread);
     frame       fr     = thread->last_frame();
     assert(fr.is_interpreted_frame(), "must be interpreted");
     assert(fr.interpreter_frame_method() == m(), "bad method");
@@ -461,17 +458,17 @@
       assert(top != NULL, "findTopInlinableFrame returned null");
       if (TraceCompilationPolicy) top->print();
       CompileBroker::compile_method(top->top_method(), InvocationEntryBci, CompLevel_highest_tier,
-                                    m, hot_count, comment, CHECK);
+                                    m, hot_count, comment, thread);
     }
   }
 }
 
-void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, TRAPS) {
+void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
   int hot_count = m->backedge_count();
   const char* comment = "backedge_count";
 
   if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) {
-    CompileBroker::compile_method(m, bci, CompLevel_highest_tier, m, hot_count, comment, CHECK);
+    CompileBroker::compile_method(m, bci, CompLevel_highest_tier, m, hot_count, comment, thread);
 
     NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));)
   }
--- a/hotspot/src/share/vm/runtime/compilationPolicy.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -64,7 +64,7 @@
   virtual int compiler_count(CompLevel comp_level) = 0;
   // main notification entry, return a pointer to an nmethod if the OSR is required,
   // returns NULL otherwise.
-  virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) = 0;
+  virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) = 0;
   // safepoint() is called at the end of the safepoint
   virtual void do_safepoint_work() = 0;
   // reprofile request
@@ -105,15 +105,15 @@
   virtual bool is_mature(methodOop method);
   virtual void initialize();
   virtual CompileTask* select_task(CompileQueue* compile_queue);
-  virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS);
-  virtual void method_invocation_event(methodHandle m, TRAPS) = 0;
-  virtual void method_back_branch_event(methodHandle m, int bci, TRAPS) = 0;
+  virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
+  virtual void method_invocation_event(methodHandle m, JavaThread* thread) = 0;
+  virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread) = 0;
 };
 
 class SimpleCompPolicy : public NonTieredCompPolicy {
  public:
-  virtual void method_invocation_event(methodHandle m, TRAPS);
-  virtual void method_back_branch_event(methodHandle m, int bci, TRAPS);
+  virtual void method_invocation_event(methodHandle m, JavaThread* thread);
+  virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
 };
 
 // StackWalkCompPolicy - existing C2 policy
@@ -121,8 +121,8 @@
 #ifdef COMPILER2
 class StackWalkCompPolicy : public NonTieredCompPolicy {
  public:
-  virtual void method_invocation_event(methodHandle m, TRAPS);
-  virtual void method_back_branch_event(methodHandle m, int bci, TRAPS);
+  virtual void method_invocation_event(methodHandle m, JavaThread* thread);
+  virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
 
  private:
   RFrame* findTopInlinableFrame(GrowableArray<RFrame*>* stack);
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -211,7 +211,7 @@
 #ifdef COMPILER2
   // Reallocate the non-escaping objects and restore their fields. Then
   // relock objects if synchronization on them was eliminated.
-  if (DoEscapeAnalysis) {
+  if (DoEscapeAnalysis || EliminateNestedLocks) {
     if (EliminateAllocations) {
       assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
       GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
--- a/hotspot/src/share/vm/runtime/frame.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1315,7 +1315,6 @@
 }
 #endif
 
-
 #ifdef ASSERT
 void frame::interpreter_frame_verify_monitor(BasicObjectLock* value) const {
   assert(is_interpreted_frame(), "Not an interpreted frame");
@@ -1331,27 +1330,35 @@
   guarantee((current - low_mark) % monitor_size  ==  0         , "Misaligned bottom of BasicObjectLock*");
   guarantee( current >= low_mark                               , "Current BasicObjectLock* below than low_mark");
 }
+#endif
 
+#ifndef PRODUCT
+void frame::describe(FrameValues& values, int frame_no) {
+  // boundaries: sp and the 'real' frame pointer
+  values.describe(-1, sp(), err_msg("sp for #%d", frame_no), 1);
+  intptr_t* frame_pointer = real_fp(); // Note: may differ from fp()
 
-void frame::describe(FrameValues& values, int frame_no) {
+  // print frame info at the highest boundary
+  intptr_t* info_address = MAX2(sp(), frame_pointer);
+
+  if (info_address != frame_pointer) {
+    // print frame_pointer explicitly if not marked by the frame info
+    values.describe(-1, frame_pointer, err_msg("frame pointer for #%d", frame_no), 1);
+  }
+
   if (is_entry_frame() || is_compiled_frame() || is_interpreted_frame() || is_native_frame()) {
     // Label values common to most frames
     values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no));
-    values.describe(-1, sp(), err_msg("sp for #%d", frame_no));
-    if (is_compiled_frame()) {
-      values.describe(-1, sp() + _cb->frame_size(), err_msg("computed fp for #%d", frame_no));
-    } else {
-      values.describe(-1, fp(), err_msg("fp for #%d", frame_no));
-    }
   }
+
   if (is_interpreted_frame()) {
     methodOop m = interpreter_frame_method();
     int bci = interpreter_frame_bci();
 
     // Label the method and current bci
-    values.describe(-1, MAX2(sp(), fp()),
+    values.describe(-1, info_address,
                     FormatBuffer<1024>("#%d method %s @ %d", frame_no, m->name_and_sig_as_C_string(), bci), 2);
-    values.describe(-1, MAX2(sp(), fp()),
+    values.describe(-1, info_address,
                     err_msg("- %d locals %d max stack", m->max_locals(), m->max_stack()), 1);
     if (m->max_locals() > 0) {
       intptr_t* l0 = interpreter_frame_local_at(0);
@@ -1383,21 +1390,36 @@
     }
   } else if (is_entry_frame()) {
     // For now just label the frame
-    values.describe(-1, MAX2(sp(), fp()), err_msg("#%d entry frame", frame_no), 2);
+    values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2);
   } else if (is_compiled_frame()) {
     // For now just label the frame
     nmethod* nm = cb()->as_nmethod_or_null();
-    values.describe(-1, MAX2(sp(), fp()),
+    values.describe(-1, info_address,
                     FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method %s%s", frame_no,
                                        nm, nm->method()->name_and_sig_as_C_string(),
-                                       is_deoptimized_frame() ? " (deoptimized" : ""), 2);
+                                       (_deopt_state == is_deoptimized) ?
+                                       " (deoptimized)" :
+                                       ((_deopt_state == unknown) ? " (state unknown)" : "")),
+                    2);
   } else if (is_native_frame()) {
     // For now just label the frame
     nmethod* nm = cb()->as_nmethod_or_null();
-    values.describe(-1, MAX2(sp(), fp()),
+    values.describe(-1, info_address,
                     FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for native method %s", frame_no,
                                        nm, nm->method()->name_and_sig_as_C_string()), 2);
+  } else if (is_ricochet_frame()) {
+      values.describe(-1, info_address, err_msg("#%d ricochet frame", frame_no), 2);
+  } else {
+    // provide default info if not handled before
+    char *info = (char *) "special frame";
+    if ((_cb != NULL) &&
+        (_cb->name() != NULL)) {
+      info = (char *)_cb->name();
+    }
+    values.describe(-1, info_address, err_msg("#%d <%s>", frame_no, info), 2);
   }
+
+  // platform dependent additional data
   describe_pd(values, frame_no);
 }
 
@@ -1414,7 +1436,7 @@
 }
 
 
-#ifdef ASSERT
+#ifndef PRODUCT
 
 void FrameValues::describe(int owner, intptr_t* location, const char* description, int priority) {
   FrameValue fv;
@@ -1427,6 +1449,7 @@
 }
 
 
+#ifdef ASSERT
 void FrameValues::validate() {
   _values.sort(compare);
   bool error = false;
@@ -1452,7 +1475,7 @@
   }
   assert(!error, "invalid layout");
 }
-
+#endif // ASSERT
 
 void FrameValues::print(JavaThread* thread) {
   _values.sort(compare);
@@ -1501,4 +1524,4 @@
   }
 }
 
-#endif
+#endif // ndef PRODUCT
--- a/hotspot/src/share/vm/runtime/frame.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -221,6 +221,15 @@
   // returns the stack pointer of the calling frame
   intptr_t* sender_sp() const;
 
+  // Returns the real 'frame pointer' for the current frame.
+  // This is the value expected by the platform ABI when it defines a
+  // frame pointer register. It may differ from the effective value of
+  // the FP register when that register is used in the JVM for other
+  // purposes (like compiled frames on some platforms).
+  // On other platforms, it is defined so that the stack area used by
+  // this frame goes from real_fp() to sp().
+  intptr_t* real_fp() const;
+
   // Deoptimization info, if needed (platform dependent).
   // Stored in the initial_info field of the unroll info, to be used by
   // the platform dependent deoptimization blobs.
@@ -485,7 +494,7 @@
 
 };
 
-#ifdef ASSERT
+#ifndef PRODUCT
 // A simple class to describe a location on the stack
 class FrameValue VALUE_OBJ_CLASS_SPEC {
  public:
@@ -515,7 +524,9 @@
   // Used by frame functions to describe locations.
   void describe(int owner, intptr_t* location, const char* description, int priority = 0);
 
+#ifdef ASSERT
   void validate();
+#endif
   void print(JavaThread* thread);
 };
 
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -3574,7 +3574,7 @@
           "Threshold at which tier 3 compilation is invoked (invocation "   \
           "minimum must be satisfied.")                                     \
                                                                             \
-  product(intx, Tier3BackEdgeThreshold,  7000,                              \
+  product(intx, Tier3BackEdgeThreshold,  60000,                             \
           "Back edge threshold at which tier 3 OSR compilation is invoked") \
                                                                             \
   product(intx, Tier4InvocationThreshold, 5000,                             \
@@ -3826,10 +3826,6 @@
   develop(bool, StressMethodHandleWalk, false,                              \
           "Process all method handles with MethodHandleWalk")               \
                                                                             \
-  diagnostic(bool, UseRicochetFrames, true,                                 \
-          "use ricochet stack frames for method handle combination, "       \
-          "if the platform supports them")                                  \
-                                                                            \
   experimental(bool, TrustFinalNonStaticFields, false,                      \
           "trust final non-static declarations for constant folding")       \
                                                                             \
--- a/hotspot/src/share/vm/runtime/java.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/java.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -57,6 +57,8 @@
 #include "runtime/task.hpp"
 #include "runtime/timer.hpp"
 #include "runtime/vm_operations.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceEventTypes.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/histogram.hpp"
@@ -502,6 +504,11 @@
   if (JvmtiExport::should_post_thread_life()) {
     JvmtiExport::post_thread_end(thread);
   }
+
+  EVENT_BEGIN(TraceEventThreadEnd, event);
+  EVENT_COMMIT(event,
+      EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
   // Always call even when there are not JVMTI environments yet, since environments
   // may be attached late and JVMTI must track phases of VM execution
   JvmtiExport::post_vm_death();
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -134,6 +134,12 @@
 
 Mutex*   Management_lock              = NULL;
 Monitor* Service_lock                 = NULL;
+Mutex*   Stacktrace_lock              = NULL;
+
+Monitor* JfrQuery_lock                = NULL;
+Monitor* JfrMsg_lock                  = NULL;
+Mutex*   JfrBuffer_lock               = NULL;
+Mutex*   JfrStream_lock               = NULL;
 
 #define MAX_NUM_MUTEX 128
 static Monitor * _mutex_array[MAX_NUM_MUTEX];
@@ -209,6 +215,7 @@
   def(Patching_lock                , Mutex  , special,     true ); // used for safepointing and code patching.
   def(ObjAllocPost_lock            , Monitor, special,     false);
   def(Service_lock                 , Monitor, special,     true ); // used for service thread operations
+  def(Stacktrace_lock              , Mutex,   special,     true ); // used for JFR stacktrace database
   def(JmethodIdCreation_lock       , Mutex  , leaf,        true ); // used for creating jmethodIDs.
 
   def(SystemDictionary_lock        , Monitor, leaf,        true ); // lookups done by VM thread
@@ -273,6 +280,11 @@
   def(Debug3_lock                  , Mutex  , nonleaf+4,   true );
   def(ProfileVM_lock               , Monitor, nonleaf+4,   false); // used for profiling of the VMThread
   def(CompileThread_lock           , Monitor, nonleaf+5,   false );
+
+  def(JfrQuery_lock                , Monitor, nonleaf,     true);  // JFR locks, keep these in consecutive order
+  def(JfrMsg_lock                  , Monitor, nonleaf+2,   true);
+  def(JfrBuffer_lock               , Mutex,   nonleaf+3,   true);
+  def(JfrStream_lock               , Mutex,   nonleaf+4,   true);
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -136,6 +136,12 @@
 
 extern Mutex*   Management_lock;                 // a lock used to serialize JVM management
 extern Monitor* Service_lock;                    // a lock used for service thread operation
+extern Mutex*   Stacktrace_lock;                 // used to guard access to the stacktrace table
+
+extern Monitor* JfrQuery_lock;                   // protects JFR use
+extern Monitor* JfrMsg_lock;                     // protects JFR messaging
+extern Mutex*   JfrBuffer_lock;                  // protects JFR buffer operations
+extern Mutex*   JfrStream_lock;                  // protects JFR stream access
 
 // A MutexLocker provides mutual exclusion with respect to a given mutex
 // for the scope which contains the locker.  The lock is an OS lock, not
--- a/hotspot/src/share/vm/runtime/os.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/os.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1101,6 +1101,7 @@
         "%/lib/jsse.jar:"
         "%/lib/jce.jar:"
         "%/lib/charsets.jar:"
+        "%/lib/jfr.jar:"
 #ifdef __APPLE__
         "%/lib/JObjC.jar:"
 #endif
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -121,7 +121,6 @@
 void SharedRuntime::generate_ricochet_blob() {
   if (!EnableInvokeDynamic)  return;  // leave it as a null
 
-#ifndef TARGET_ARCH_NYI_6939861
   // allocate space for the code
   ResourceMark rm;
   // setup code generation tools
@@ -142,7 +141,6 @@
   }
 
   _ricochet_blob = RicochetBlob::create(&buffer, bounce_offset, exception_offset, frame_size_in_words);
-#endif
 }
 
 
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -177,13 +177,11 @@
 }
 
 nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
-                                      int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) {
+                                      int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
   if (comp_level == CompLevel_none &&
-      JvmtiExport::can_post_interpreter_events()) {
-    assert(THREAD->is_Java_thread(), "Should be java thread");
-    if (((JavaThread*)THREAD)->is_interp_only_mode()) {
-      return NULL;
-    }
+      JvmtiExport::can_post_interpreter_events() &&
+      thread->is_interp_only_mode()) {
+    return NULL;
   }
   nmethod *osr_nm = NULL;
 
@@ -197,9 +195,9 @@
   }
 
   if (bci == InvocationEntryBci) {
-    method_invocation_event(method, inlinee, comp_level, nm, THREAD);
+    method_invocation_event(method, inlinee, comp_level, nm, thread);
   } else {
-    method_back_branch_event(method, inlinee, bci, comp_level, nm, THREAD);
+    method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
     // method == inlinee if the event originated in the main method
     int highest_level = inlinee->highest_osr_comp_level();
     if (highest_level > comp_level) {
@@ -210,7 +208,7 @@
 }
 
 // Check if the method can be compiled, change level if necessary
-void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, TRAPS) {
+void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
   assert(level <= TieredStopAtLevel, "Invalid compilation level");
   if (level == CompLevel_none) {
     return;
@@ -221,7 +219,7 @@
   // pure C1.
   if (!can_be_compiled(mh, level)) {
     if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) {
-        compile(mh, bci, CompLevel_simple, THREAD);
+        compile(mh, bci, CompLevel_simple, thread);
     }
     return;
   }
@@ -232,14 +230,14 @@
     if (PrintTieredEvents) {
       print_event(COMPILE, mh, mh, bci, level);
     }
-    submit_compile(mh, bci, level, THREAD);
+    submit_compile(mh, bci, level, thread);
   }
 }
 
 // Tell the broker to compile the method
-void SimpleThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS) {
+void SimpleThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
   int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
-  CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD);
+  CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
 }
 
 // Call and loop predicates determine whether a transition to a higher
@@ -366,11 +364,11 @@
 
 // Handle the invocation event.
 void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
-                                              CompLevel level, nmethod* nm, TRAPS) {
+                                              CompLevel level, nmethod* nm, JavaThread* thread) {
   if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
     CompLevel next_level = call_event(mh(), level);
     if (next_level != level) {
-      compile(mh, InvocationEntryBci, next_level, THREAD);
+      compile(mh, InvocationEntryBci, next_level, thread);
     }
   }
 }
@@ -378,7 +376,7 @@
 // Handle the back branch event. Notice that we can compile the method
 // with a regular entry from here.
 void SimpleThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
-                                                     int bci, CompLevel level, nmethod* nm, TRAPS) {
+                                                     int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
   // If the method is already compiling, quickly bail out.
   if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) {
     // Use loop event as an opportinity to also check there's been
@@ -391,13 +389,13 @@
                       next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level);
     bool is_compiling = false;
     if (next_level != cur_level) {
-      compile(mh, InvocationEntryBci, next_level, THREAD);
+      compile(mh, InvocationEntryBci, next_level, thread);
       is_compiling = true;
     }
 
     // Do the OSR version
     if (!is_compiling && next_osr_level != level) {
-      compile(mh, bci, next_osr_level, THREAD);
+      compile(mh, bci, next_osr_level, thread);
     }
   }
 }
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -67,9 +67,9 @@
   // Print policy-specific information if necessary
   virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { }
   // Check if the method can be compiled, change level if necessary
-  void compile(methodHandle mh, int bci, CompLevel level, TRAPS);
+  void compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
   // Submit a given method for compilation
-  virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS);
+  virtual void submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
   // Simple methods are as good being compiled with C1 as C2.
   // This function tells if it's such a function.
   inline bool is_trivial(methodOop method);
@@ -88,9 +88,9 @@
     return CompLevel_none;
   }
   virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
-                                       CompLevel level, nmethod* nm, TRAPS);
+                                       CompLevel level, nmethod* nm, JavaThread* thread);
   virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
-                                        int bci, CompLevel level, nmethod* nm, TRAPS);
+                                        int bci, CompLevel level, nmethod* nm, JavaThread* thread);
 public:
   SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { }
   virtual int compiler_count(CompLevel comp_level) {
@@ -104,7 +104,7 @@
   virtual void disable_compilation(methodOop method) { }
   virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
   virtual nmethod* event(methodHandle method, methodHandle inlinee,
-                         int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS);
+                         int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
   // Select task is called by CompileBroker. We should return a task or NULL.
   virtual CompileTask* select_task(CompileQueue* compile_queue);
   // Tell the runtime if we think a given method is adequately profiled.
--- a/hotspot/src/share/vm/runtime/thread.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -73,6 +73,7 @@
 #include "services/attachListener.hpp"
 #include "services/management.hpp"
 #include "services/threadService.hpp"
+#include "trace/traceEventTypes.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
@@ -232,6 +233,7 @@
   CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
   _jvmti_env_iteration_count = 0;
   set_allocated_bytes(0);
+  set_trace_buffer(NULL);
   _vm_operation_started_count = 0;
   _vm_operation_completed_count = 0;
   _current_pending_monitor = NULL;
@@ -1512,6 +1514,10 @@
     JvmtiExport::post_thread_start(this);
   }
 
+  EVENT_BEGIN(TraceEventThreadStart, event);
+  EVENT_COMMIT(event,
+     EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));
+
   // We call another function to do the rest so we are sure that the stack addresses used
   // from there will be lower than the stack base just computed
   thread_main_inner();
@@ -1641,6 +1647,15 @@
       }
     }
 
+    // Called before the java thread exit since we want to read info
+    // from java_lang_Thread object
+    EVENT_BEGIN(TraceEventThreadEnd, event);
+    EVENT_COMMIT(event,
+        EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));
+
+    // Call after last event on thread
+    EVENT_THREAD_EXIT(this);
+
     // Call Thread.exit(). We try 3 times in case we got another Thread.stop during
     // the execution of the method. If that is not enough, then we don't really care. Thread.stop
     // is deprecated anyhow.
@@ -3186,6 +3201,11 @@
     return status;
   }
 
+  // Must be run after init_ft which initializes ft_enabled
+  if (TRACE_INITIALIZE() != JNI_OK) {
+    vm_exit_during_initialization("Failed to initialize tracing backend");
+  }
+
   // Should be done after the heap is fully created
   main_thread->cache_global_variables();
 
@@ -3423,6 +3443,10 @@
     create_vm_init_libraries();
   }
 
+  if (!TRACE_START()) {
+    vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
+  }
+
   // Notify JVMTI agents that VM initialization is complete - nop if no agents.
   JvmtiExport::post_vm_initialized();
 
--- a/hotspot/src/share/vm/runtime/thread.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -41,6 +41,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/threadLocalStorage.hpp"
 #include "runtime/unhandledOops.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/top.hpp"
 #ifndef SERIALGC
@@ -246,6 +247,8 @@
   jlong _allocated_bytes;                       // Cumulative number of bytes allocated on
                                                 // the Java heap
 
+  TRACE_BUFFER _trace_buffer;                   // Thread-local buffer for tracing
+
   int   _vm_operation_started_count;            // VM_Operation support
   int   _vm_operation_completed_count;          // VM_Operation support
 
@@ -414,6 +417,9 @@
     return allocated_bytes;
   }
 
+  TRACE_BUFFER trace_buffer()              { return _trace_buffer; }
+  void set_trace_buffer(TRACE_BUFFER buf)  { _trace_buffer = buf; }
+
   // VM operation support
   int vm_operation_ticket()                      { return ++_vm_operation_started_count; }
   int vm_operation_completed_count()             { return _vm_operation_completed_count; }
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -93,6 +93,7 @@
   template(HeapWalkOperation)                     \
   template(HeapIterateOperation)                  \
   template(ReportJavaOutOfMemory)                 \
+  template(JFRCheckpoint)                         \
   template(Exit)                                  \
 
 class VM_Operation: public CHeapObj {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/trace/traceEventTypes.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP
+#define SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP
+
+/* Empty, just a placeholder for tracing events */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_TRACE_TRACE_MACRO_HPP
+#define SHARE_VM_TRACE_TRACE_MACRO_HPP
+
+#define EVENT_BEGIN(type, name)
+#define EVENT_SET(name, field, value)
+#define EVENT_COMMIT(name, ...)
+#define EVENT_STARTED(name, time)
+#define EVENT_ENDED(name, time)
+#define EVENT_THREAD_EXIT(thread)
+
+#define TRACE_ENABLED 0
+
+#define TRACE_INIT_ID(k)
+#define TRACE_BUFFER void*
+
+#define TRACE_START() true
+#define TRACE_INITIALIZE() 0
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/trace/tracing.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_TRACE_TRACING_HPP
+#define SHARE_VM_TRACE_TRACING_HPP
+
+#include "trace/traceMacros.hpp"
+
+#endif
--- a/hotspot/src/share/vm/utilities/decoder.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/decoder.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -24,80 +24,85 @@
 
 #include "precompiled.hpp"
 #include "prims/jvm.h"
+#include "runtime/mutexLocker.hpp"
 #include "utilities/decoder.hpp"
 
-Decoder::decoder_status  Decoder::_decoder_status = Decoder::no_error;
-bool                     Decoder::_initialized = false;
+#if defined(_WINDOWS)
+  #include "decoder_windows.hpp"
+#elif defined(__APPLE__)
+  #include "decoder_machO.hpp"
+#else
+  #include "decoder_elf.hpp"
+#endif
 
-#if !defined(_WINDOWS) && !defined(__APPLE__)
+NullDecoder*  Decoder::_decoder = NULL;
+NullDecoder   Decoder::_do_nothing_decoder;
+Mutex*           Decoder::_decoder_lock = new Mutex(Mutex::safepoint,
+                                "DecoderLock");
 
-// Implementation of common functionalities among Solaris and Linux
-#include "utilities/elfFile.hpp"
+// _decoder_lock should already acquired before enter this method
+NullDecoder* Decoder::get_decoder() {
+  assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
+    "Require DecoderLock to enter");
 
-ElfFile* Decoder::_opened_elf_files = NULL;
+  if (_decoder != NULL) {
+    return _decoder;
+  }
+
+  // Decoder is a secondary service. Although, it is good to have,
+  // but we can live without it.
+#if defined(_WINDOWS)
+  _decoder = new (std::nothrow) WindowsDecoder();
+#elif defined (__APPLE__)
+    _decoder = new (std::nothrow)MachODecoder();
+#else
+    _decoder = new (std::nothrow)ElfDecoder();
+#endif
+
+  if (_decoder == NULL || _decoder->has_error()) {
+    if (_decoder != NULL) {
+      delete _decoder;
+    }
+    _decoder = &_do_nothing_decoder;
+  }
+  return _decoder;
+}
+
+bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
+  assert(_decoder_lock != NULL, "Just check");
+  MutexLockerEx locker(_decoder_lock, true);
+  NullDecoder* decoder = get_decoder();
+  assert(decoder != NULL, "null decoder");
+
+  return decoder->decode(addr, buf, buflen, offset, modulepath);
+}
+
+bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
+  assert(_decoder_lock != NULL, "Just check");
+  MutexLockerEx locker(_decoder_lock, true);
+  NullDecoder* decoder = get_decoder();
+  assert(decoder != NULL, "null decoder");
+  return decoder->demangle(symbol, buf, buflen);
+}
 
 bool Decoder::can_decode_C_frame_in_vm() {
-  return true;
+  assert(_decoder_lock != NULL, "Just check");
+  MutexLockerEx locker(_decoder_lock, true);
+  NullDecoder* decoder = get_decoder();
+  assert(decoder != NULL, "null decoder");
+  return decoder->can_decode_C_frame_in_vm();
 }
 
-void Decoder::initialize() {
-  _initialized = true;
+// shutdown real decoder and replace it with
+// _do_nothing_decoder
+void Decoder::shutdown() {
+  assert(_decoder_lock != NULL, "Just check");
+  MutexLockerEx locker(_decoder_lock, true);
+
+  if (_decoder != NULL && _decoder != &_do_nothing_decoder) {
+    delete _decoder;
+  }
+
+  _decoder = &_do_nothing_decoder;
 }
 
-void Decoder::uninitialize() {
-  if (_opened_elf_files != NULL) {
-    delete _opened_elf_files;
-    _opened_elf_files = NULL;
-  }
-  _initialized = false;
-}
-
-Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
-  if (_decoder_status != no_error) {
-    return _decoder_status;
-  }
-
-  ElfFile* file = get_elf_file(filepath);
-  if (_decoder_status != no_error) {
-    return _decoder_status;
-  }
-
-  const char* symbol = file->decode(addr, offset);
-  if (file->get_status() == out_of_memory) {
-    _decoder_status = out_of_memory;
-    return _decoder_status;
-  } else if (symbol != NULL) {
-    if (!demangle(symbol, buf, buflen)) {
-      jio_snprintf(buf, buflen, "%s", symbol);
-    }
-    return no_error;
-  } else {
-    return symbol_not_found;
-  }
-}
-
-ElfFile* Decoder::get_elf_file(const char* filepath) {
-  if (_decoder_status != no_error) {
-    return NULL;
-  }
-  ElfFile* file = _opened_elf_files;
-  while (file != NULL) {
-    if (file->same_elf_file(filepath)) {
-      return file;
-    }
-    file = file->m_next;
-  }
-
-  file = new ElfFile(filepath);
-  if (file == NULL) {
-    _decoder_status = out_of_memory;
-  }
-  if (_opened_elf_files != NULL) {
-    file->m_next = _opened_elf_files;
-  }
-
-  _opened_elf_files = file;
-  return file;
-}
-
-#endif
--- a/hotspot/src/share/vm/utilities/decoder.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/decoder.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,83 +23,78 @@
  */
 
 
-#ifndef __DECODER_HPP
-#define __DECODER_HPP
+#ifndef SHARE_VM_UTILITIES_DECODER_HPP
+#define SHARE_VM_UTILITIES_DECODER_HPP
 
 #include "memory/allocation.hpp"
+#include "runtime/mutex.hpp"
 
-#ifdef _WINDOWS
-#include <windows.h>
-#include <imagehlp.h>
-
-// functions needed for decoding symbols
-typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
-typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
-typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
-typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
-
-#elif defined(__APPLE__)
-
-#else
-
-class ElfFile;
-
-#endif // _WINDOWS
-
-
-class Decoder: public StackObj {
-
- public:
+class NullDecoder: public CHeapObj {
+public:
   // status code for decoding native C frame
   enum decoder_status {
-         no_error,             // successfully decoded frames
+         not_available = -10,  // real decoder is not available
+         no_error = 0,         // successfully decoded frames
          out_of_memory,        // out of memory
          file_invalid,         // invalid elf file
          file_not_found,       // could not found symbol file (on windows), such as jvm.pdb or jvm.map
          helper_not_found,     // could not load dbghelp.dll (Windows only)
          helper_func_error,    // decoding functions not found (Windows only)
-         helper_init_error,    // SymInitialize failed (Windows only)
-         symbol_not_found      // could not find the symbol
+         helper_init_error     // SymInitialize failed (Windows only)
   };
 
- public:
-  Decoder() { initialize(); };
-  ~Decoder() { uninitialize(); };
+  NullDecoder() {
+    _decoder_status = not_available;
+  }
 
+  ~NullDecoder() {};
+
+  virtual bool decode(address pc, char* buf, int buflen, int* offset,
+    const char* modulepath = NULL) {
+    return false;
+  }
+
+  virtual bool demangle(const char* symbol, char* buf, int buflen) {
+    return false;
+  }
+
+  virtual bool can_decode_C_frame_in_vm() const {
+    return false;
+  }
+
+  virtual decoder_status status() const {
+    return _decoder_status;
+  }
+
+  virtual bool has_error() const {
+    return is_error(_decoder_status);
+  }
+
+  static bool is_error(decoder_status status) {
+    return (status > 0);
+  }
+
+protected:
+  decoder_status  _decoder_status;
+};
+
+
+class Decoder: AllStatic {
+public:
+  static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
+  static bool demangle(const char* symbol, char* buf, int buflen);
   static bool can_decode_C_frame_in_vm();
 
-  static void initialize();
-  static void uninitialize();
+  static void shutdown();
+protected:
+  static NullDecoder* get_decoder();
 
-#ifdef _WINDOWS
-  static decoder_status    decode(address addr, char *buf, int buflen, int *offset);
-#else
-  static decoder_status    decode(address addr, const char* filepath, char *buf, int buflen, int *offset);
-#endif
+private:
+  static NullDecoder*     _decoder;
+  static NullDecoder      _do_nothing_decoder;
 
-  static bool              demangle(const char* symbol, char *buf, int buflen);
-
-  static decoder_status    get_status() { return _decoder_status; };
-
-#if !defined(_WINDOWS) && !defined(__APPLE__)
- private:
-  static ElfFile*         get_elf_file(const char* filepath);
-#endif // _WINDOWS
-
-
- private:
-  static decoder_status     _decoder_status;
-  static bool               _initialized;
-
-#ifdef _WINDOWS
-  static HMODULE                   _dbghelp_handle;
-  static bool                      _can_decode_in_vm;
-  static pfn_SymGetSymFromAddr64   _pfnSymGetSymFromAddr64;
-  static pfn_UndecorateSymbolName  _pfnUndecorateSymbolName;
-#elif __APPLE__
-#else
-  static ElfFile*                  _opened_elf_files;
-#endif // _WINDOWS
+protected:
+  static Mutex*       _decoder_lock;
 };
 
-#endif // __DECODER_HPP
+#endif // SHARE_VM_UTILITIES_DECODER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/decoder_elf.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#if !defined(_WINDOWS) && !defined(__APPLE__)
+#include "decoder_elf.hpp"
+
+ElfDecoder::~ElfDecoder() {
+  if (_opened_elf_files != NULL) {
+    delete _opened_elf_files;
+    _opened_elf_files = NULL;
+  }
+}
+
+bool ElfDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* filepath) {
+  assert(filepath, "null file path");
+  assert(buf != NULL && buflen > 0, "Invalid buffer");
+  if (has_error()) return false;
+  ElfFile* file = get_elf_file(filepath);
+  if (file == NULL) {
+    return false;
+  }
+
+  if (!file->decode(addr, buf, buflen, offset)) {
+    return false;
+  }
+  if (buf[0] != '\0') {
+    demangle(buf, buf, buflen);
+  }
+  return true;
+}
+
+ElfFile* ElfDecoder::get_elf_file(const char* filepath) {
+  ElfFile* file;
+
+  file = _opened_elf_files;
+  while (file != NULL) {
+    if (file->same_elf_file(filepath)) {
+      return file;
+    }
+    file = file->next();
+  }
+
+  file = new (std::nothrow)ElfFile(filepath);
+  if (file != NULL) {
+    if (_opened_elf_files != NULL) {
+      file->set_next(_opened_elf_files);
+    }
+    _opened_elf_files = file;
+  }
+
+  return file;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/decoder_elf.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_UTILITIES_DECODER_ELF_HPP
+#define SHARE_VM_UTILITIES_DECODER_ELF_HPP
+
+#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+#include "utilities/decoder.hpp"
+#include "utilities/elfFile.hpp"
+
+class ElfDecoder: public NullDecoder {
+
+public:
+  ElfDecoder() {
+    _opened_elf_files = NULL;
+    _decoder_status = no_error;
+  }
+  ~ElfDecoder();
+
+  bool can_decode_C_frame_in_vm() const { return true; }
+
+  bool demangle(const char* symbol, char *buf, int buflen);
+  bool decode(address addr, char *buf, int buflen, int* offset, const char* filepath = NULL);
+
+private:
+  ElfFile*         get_elf_file(const char* filepath);
+
+private:
+  ElfFile*         _opened_elf_files;
+};
+
+#endif
+#endif // SHARE_VM_UTILITIES_DECODER_ELF_HPP
--- a/hotspot/src/share/vm/utilities/elfFile.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/elfFile.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -44,7 +44,7 @@
   m_string_tables = NULL;
   m_symbol_tables = NULL;
   m_next = NULL;
-  m_status = Decoder::no_error;
+  m_status = NullDecoder::no_error;
 
   int len = strlen(filepath) + 1;
   m_filepath = (const char*)os::malloc(len * sizeof(char));
@@ -54,10 +54,10 @@
     if (m_file != NULL) {
       load_tables();
     } else {
-      m_status = Decoder::file_not_found;
+      m_status = NullDecoder::file_not_found;
     }
   } else {
-    m_status = Decoder::out_of_memory;
+    m_status = NullDecoder::out_of_memory;
   }
 }
 
@@ -96,41 +96,41 @@
 
 bool ElfFile::load_tables() {
   assert(m_file, "file not open");
-  assert(m_status == Decoder::no_error, "already in error");
+  assert(!NullDecoder::is_error(m_status), "already in error");
 
   // read elf file header
   if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
-    m_status = Decoder::file_invalid;
+    m_status = NullDecoder::file_invalid;
     return false;
   }
 
   if (!is_elf_file(m_elfHdr)) {
-    m_status = Decoder::file_invalid;
+    m_status = NullDecoder::file_invalid;
     return false;
   }
 
   // walk elf file's section headers, and load string tables
   Elf_Shdr shdr;
   if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
-    if (m_status != Decoder::no_error) return false;
+    if (NullDecoder::is_error(m_status)) return false;
 
     for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
       if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
-        m_status = Decoder::file_invalid;
+        m_status = NullDecoder::file_invalid;
         return false;
       }
       // string table
       if (shdr.sh_type == SHT_STRTAB) {
         ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
         if (table == NULL) {
-          m_status = Decoder::out_of_memory;
+          m_status = NullDecoder::out_of_memory;
           return false;
         }
         add_string_table(table);
       } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
         ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
         if (table == NULL) {
-          m_status = Decoder::out_of_memory;
+          m_status = NullDecoder::out_of_memory;
           return false;
         }
         add_symbol_table(table);
@@ -140,32 +140,33 @@
   return true;
 }
 
-const char* ElfFile::decode(address addr, int* offset) {
+bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
   // something already went wrong, just give up
-  if (m_status != Decoder::no_error) {
-    return NULL;
+  if (NullDecoder::is_error(m_status)) {
+    return false;
   }
-
   ElfSymbolTable* symbol_table = m_symbol_tables;
   int string_table_index;
   int pos_in_string_table;
   int off = INT_MAX;
   bool found_symbol = false;
   while (symbol_table != NULL) {
-    if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
+    if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
       found_symbol = true;
     }
     symbol_table = symbol_table->m_next;
   }
-  if (!found_symbol) return NULL;
+  if (!found_symbol) return false;
 
   ElfStringTable* string_table = get_string_table(string_table_index);
+
   if (string_table == NULL) {
-    m_status = Decoder::file_invalid;
-    return NULL;
+    m_status = NullDecoder::file_invalid;
+    return false;
   }
   if (offset) *offset = off;
-  return string_table->string_at(pos_in_string_table);
+
+  return string_table->string_at(pos_in_string_table, buf, buflen);
 }
 
 
--- a/hotspot/src/share/vm/utilities/elfFile.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/elfFile.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef __ELF_FILE_HPP
-#define __ELF_FILE_HPP
+#ifndef SHARE_VM_UTILITIES_ELF_FILE_HPP
+#define SHARE_VM_UTILITIES_ELF_FILE_HPP
 
 #if !defined(_WINDOWS) && !defined(__APPLE__)
 
@@ -83,12 +83,12 @@
 // part of code to be very defensive, and bait out if anything went wrong.
 
 class ElfFile: public CHeapObj {
-  friend class Decoder;
+  friend class ElfDecoder;
  public:
   ElfFile(const char* filepath);
   ~ElfFile();
 
-  const char* decode(address addr, int* offset);
+  bool decode(address addr, char* buf, int buflen, int* offset);
   const char* filepath() {
     return m_filepath;
   }
@@ -99,7 +99,7 @@
     return (m_filepath && !strcmp(filepath, m_filepath));
   }
 
-  Decoder::decoder_status get_status() {
+  NullDecoder::decoder_status get_status() {
     return m_status;
   }
 
@@ -119,8 +119,9 @@
   // return a string table at specified section index
   ElfStringTable* get_string_table(int index);
 
-  // look up an address and return the nearest symbol
-  const char* look_up(Elf_Shdr shdr, address addr, int* offset);
+protected:
+   ElfFile*  next() const { return m_next; }
+   void set_next(ElfFile* file) { m_next = file; }
 
  protected:
     ElfFile*         m_next;
@@ -131,17 +132,17 @@
   FILE* m_file;
 
   // Elf header
-  Elf_Ehdr            m_elfHdr;
+  Elf_Ehdr                     m_elfHdr;
 
   // symbol tables
-  ElfSymbolTable*     m_symbol_tables;
+  ElfSymbolTable*              m_symbol_tables;
 
   // string tables
-  ElfStringTable*     m_string_tables;
+  ElfStringTable*              m_string_tables;
 
-  Decoder::decoder_status  m_status;
+  NullDecoder::decoder_status  m_status;
 };
 
 #endif // _WINDOWS
 
-#endif // __ELF_FILE_HPP
+#endif // SHARE_VM_UTILITIES_ELF_FILE_HPP
--- a/hotspot/src/share/vm/utilities/elfStringTable.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/elfStringTable.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -38,7 +38,7 @@
   m_index = index;
   m_next = NULL;
   m_file = file;
-  m_status = Decoder::no_error;
+  m_status = NullDecoder::no_error;
 
   // try to load the string table
   long cur_offset = ftell(file);
@@ -48,7 +48,7 @@
     if (fseek(file, shdr.sh_offset, SEEK_SET) ||
       fread((void*)m_table, shdr.sh_size, 1, file) != 1 ||
       fseek(file, cur_offset, SEEK_SET)) {
-      m_status = Decoder::file_invalid;
+      m_status = NullDecoder::file_invalid;
       os::free((void*)m_table);
       m_table = NULL;
     }
@@ -67,22 +67,23 @@
   }
 }
 
-const char* ElfStringTable::string_at(int pos) {
-  if (m_status != Decoder::no_error) {
-    return NULL;
+bool ElfStringTable::string_at(int pos, char* buf, int buflen) {
+  if (NullDecoder::is_error(m_status)) {
+    return false;
   }
   if (m_table != NULL) {
-    return (const char*)(m_table + pos);
+    jio_snprintf(buf, buflen, "%s", (const char*)(m_table + pos));
+    return true;
   } else {
     long cur_pos = ftell(m_file);
     if (cur_pos == -1 ||
       fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) ||
-      fread(m_symbol, 1, MAX_SYMBOL_LEN, m_file) <= 0 ||
+      fread(buf, 1, buflen, m_file) <= 0 ||
       fseek(m_file, cur_pos, SEEK_SET)) {
-      m_status = Decoder::file_invalid;
-      return NULL;
+      m_status = NullDecoder::file_invalid;
+      return false;
     }
-    return (const char*)m_symbol;
+    return true;
   }
 }
 
--- a/hotspot/src/share/vm/utilities/elfStringTable.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/elfStringTable.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef __ELF_STRING_TABLE_HPP
-#define __ELF_STRING_TABLE_HPP
+#ifndef SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
+#define SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
 
 #if !defined(_WINDOWS) && !defined(__APPLE__)
 
@@ -35,9 +35,6 @@
 // The string table represents a string table section in an elf file.
 // Whenever there is enough memory, it will load whole string table as
 // one blob. Otherwise, it will load string from file when requested.
-
-#define MAX_SYMBOL_LEN  256
-
 class ElfStringTable: CHeapObj {
   friend class ElfFile;
  public:
@@ -48,10 +45,10 @@
   int index() { return m_index; };
 
   // get string at specified offset
-  const char* string_at(int offset);
+  bool string_at(int offset, char* buf, int buflen);
 
   // get status code
-  Decoder::decoder_status get_status() { return m_status; };
+  NullDecoder::decoder_status get_status() { return m_status; };
 
  protected:
   ElfStringTable*        m_next;
@@ -69,13 +66,10 @@
   // section header
   Elf_Shdr                 m_shdr;
 
-  // buffer for reading individual string
-  char                     m_symbol[MAX_SYMBOL_LEN];
-
   // error code
-  Decoder::decoder_status  m_status;
+  NullDecoder::decoder_status  m_status;
 };
 
-#endif // _WINDOWS
+#endif // _WINDOWS and _APPLE
 
-#endif // __ELF_STRING_TABLE_HPP
+#endif // SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
--- a/hotspot/src/share/vm/utilities/elfSymbolTable.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/elfSymbolTable.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -34,7 +34,7 @@
   m_symbols = NULL;
   m_next = NULL;
   m_file = file;
-  m_status = Decoder::no_error;
+  m_status = NullDecoder::no_error;
 
   // try to load the string table
   long cur_offset = ftell(file);
@@ -45,16 +45,16 @@
       if (fseek(file, shdr.sh_offset, SEEK_SET) ||
         fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
         fseek(file, cur_offset, SEEK_SET)) {
-        m_status = Decoder::file_invalid;
+        m_status = NullDecoder::file_invalid;
         os::free(m_symbols);
         m_symbols = NULL;
       }
     }
-    if (m_status == Decoder::no_error) {
+    if (!NullDecoder::is_error(m_status)) {
       memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
     }
   } else {
-    m_status = Decoder::file_invalid;
+    m_status = NullDecoder::file_invalid;
   }
 }
 
@@ -68,13 +68,13 @@
   }
 }
 
-Decoder::decoder_status ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
+bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
   assert(stringtableIndex, "null string table index pointer");
   assert(posIndex, "null string table offset pointer");
   assert(offset, "null offset pointer");
 
-  if (m_status != Decoder::no_error) {
-    return m_status;
+  if (NullDecoder::is_error(m_status)) {
+    return false;
   }
 
   address pc = 0;
@@ -97,8 +97,8 @@
     long cur_pos;
     if ((cur_pos = ftell(m_file)) == -1 ||
       fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
-      m_status = Decoder::file_invalid;
-      return m_status;
+      m_status = NullDecoder::file_invalid;
+      return false;
     }
 
     Elf_Sym sym;
@@ -114,13 +114,13 @@
           }
         }
       } else {
-        m_status = Decoder::file_invalid;
-        return m_status;
+        m_status = NullDecoder::file_invalid;
+        return false;
       }
     }
     fseek(m_file, cur_pos, SEEK_SET);
   }
-  return m_status;
+  return true;
 }
 
 #endif // _WINDOWS
--- a/hotspot/src/share/vm/utilities/elfSymbolTable.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/elfSymbolTable.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef __ELF_SYMBOL_TABLE_HPP
-#define __ELF_SYMBOL_TABLE_HPP
+#ifndef SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
+#define SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
 
 #if !defined(_WINDOWS) && !defined(__APPLE__)
 
@@ -45,9 +45,9 @@
   ~ElfSymbolTable();
 
   // search the symbol that is nearest to the specified address.
-  Decoder::decoder_status lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
+  bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
 
-  Decoder::decoder_status get_status() { return m_status; };
+  NullDecoder::decoder_status get_status() { return m_status; };
 
  protected:
   ElfSymbolTable*  m_next;
@@ -62,9 +62,9 @@
   // section header
   Elf_Shdr            m_shdr;
 
-  Decoder::decoder_status  m_status;
+  NullDecoder::decoder_status  m_status;
 };
 
-#endif // _WINDOWS
+#endif // _WINDOWS and _APPLE
 
-#endif // __ELF_SYMBOL_TABLE_HPP
+#endif // SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
--- a/hotspot/src/share/vm/utilities/exceptions.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -189,6 +189,13 @@
 #define CHECK_NULL                               CHECK_(NULL)
 #define CHECK_false                              CHECK_(false)
 
+#define CHECK_AND_CLEAR                         THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return;        } (0
+#define CHECK_AND_CLEAR_(result)                THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return result; } (0
+#define CHECK_AND_CLEAR_0                       CHECK_AND_CLEAR_(0)
+#define CHECK_AND_CLEAR_NH                      CHECK_AND_CLEAR_(Handle())
+#define CHECK_AND_CLEAR_NULL                    CHECK_AND_CLEAR_(NULL)
+#define CHECK_AND_CLEAR_false                   CHECK_AND_CLEAR_(false)
+
 // The THROW... macros should be used to throw an exception. They require a THREAD variable to be
 // visible within the scope containing the THROW. Usually this is achieved by declaring the function
 // with a TRAPS argument.
@@ -258,7 +265,6 @@
     ShouldNotReachHere();                  \
   } (0
 
-
 // ExceptionMark is a stack-allocated helper class for local exception handling.
 // It is used with the EXCEPTION_MARK macro.
 
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Fri Jan 27 09:04:57 2012 +0100
@@ -298,6 +298,11 @@
 const juint   max_juint   = (juint)-1;   // 0xFFFFFFFF largest juint
 const julong  max_julong  = (julong)-1;  // 0xFF....FF largest julong
 
+typedef jbyte  s1;
+typedef jshort s2;
+typedef jint   s4;
+typedef jlong  s8;
+
 //----------------------------------------------------------------------------------------------------
 // JVM spec restrictions
 
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Fri Jan 27 09:04:57 2012 +0100
@@ -571,8 +571,6 @@
        if (fr.pc()) {
           st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
 
-          // initialize decoder to decode C frames
-          Decoder decoder;
 
           int count = 0;
           while (count++ < StackPrintLimit) {
--- a/hotspot/test/compiler/7116216/StackOverflow.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/hotspot/test/compiler/7116216/StackOverflow.java	Fri Jan 27 09:04:57 2012 +0100
@@ -30,7 +30,7 @@
  * @run main/othervm -Xcomp -Xbatch StackOverflow
  */
 
-class StackOverflow {
+public class StackOverflow {
     static String stackOverflow_largeFrame_liveOopForGC;
 
     public static int stackOverflow_largeFrame(int call_count, String liveOopForGC) {
--- a/jaxp/.hgtags	Thu Jan 26 14:14:55 2012 -0800
+++ b/jaxp/.hgtags	Fri Jan 27 09:04:57 2012 +0100
@@ -140,3 +140,7 @@
 09eb517404b059607aca30cdd1af83ffc57eafeb jdk8-b17
 09eb517404b059607aca30cdd1af83ffc57eafeb jdk8-b16
 ebec6a7e8d4e481d205a2109ddeea8121d76db7f jdk8-b18
+dffeb62b1a7fc8b316bf58fe5479323f3661894e jdk8-b19
+f052abb8f37444ba77858913887d0d92795dd6b8 jdk8-b20
+d41eeadf5c1344b88c5051a997aec9e1ad7ce1db jdk8-b21
+cf9d6ec44f891236ad18451021d6dcd57dc82f7b jdk8-b22
--- a/jaxws/.hgtags	Thu Jan 26 14:14:55 2012 -0800
+++ b/jaxws/.hgtags	Fri Jan 27 09:04:57 2012 +0100
@@ -140,3 +140,7 @@
 3d45ab79643d5b4cc7e050ae2d9c08b4d89d665e jdk8-b17
 3d45ab79643d5b4cc7e050ae2d9c08b4d89d665e jdk8-b16
 54928c8850f5498670dd43d6c9299f36de1a6746 jdk8-b18
+b73b733214aa43648d69a2da51e6b48fda902a2d jdk8-b19
+2b2818e3386f4510c390f6aea90d77e1c6a5bf9e jdk8-b20
+c266cab0e3fff05f2048c23046c14d60f7102175 jdk8-b21
+8d3df89b0f2d3c603b2edb0f5e24af1245397cc6 jdk8-b22
--- a/jaxws/build-defs.xml	Thu Jan 26 14:14:55 2012 -0800
+++ b/jaxws/build-defs.xml	Fri Jan 27 09:04:57 2012 +0100
@@ -96,6 +96,10 @@
         </replaceregexp>
 
         <mkdir dir="${build.classes.dir}/META-INF/services"/>
+        <copy todir="${build.classes.dir}/META-INF"
+              file="${secondary.src.dir}/META-INF/mailcap.default"/>
+        <copy todir="${build.classes.dir}/META-INF"
+              file="${secondary.src.dir}/META-INF/mimetypes.default"/>
         <copy todir="${build.classes.dir}/META-INF/services"
               file="${primary.src.dir}/com/sun/tools/etc/META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory"/>
         <copy todir="${build.classes.dir}/META-INF/services"
@@ -118,6 +122,7 @@
     <!-- Set up source to use drop.dir. -->
     <target name="-use-drop" depends="-set-props">
         <property name="primary.src.dir" value="${jaxws_src.src.dir}"/>
+        <property name="secondary.src.dir" value="${jaf_src.src.dir}"/>
         <path id="src.dir.id">
             <pathelement path="${primary.src.dir}"/>
             <pathelement path="${jaf_src.src.dir}"/>
--- a/jdk/.hgtags	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/.hgtags	Fri Jan 27 09:04:57 2012 +0100
@@ -140,3 +140,7 @@
 b71d1acfae5240d8c1359443cd02b5ddb587231c jdk8-b17
 929597c6e777f742ad252660045ebaa4a3ea4772 jdk8-b16
 334bd51fb3f321cd6777416ae7bafac71a84140a jdk8-b18
+3778f85773055e81eab6c5ef828935ecca241810 jdk8-b19
+39e938cd1b82ec3aab0a9aa66fd8a0457cd0c9c2 jdk8-b20
+664fa4fb0ee411ef048903c479f8b962fcdb2f4b jdk8-b21
+dda27c73d8db4a9c7a23872b6f0c5106edcb2021 jdk8-b22
--- a/jdk/make/com/oracle/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/com/oracle/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,24 @@
 
 BUILDDIR = ../..
 PRODUCT = oracle
+#SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true
+#SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true
+#SUBDIRS_MAKEFLAGS += JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation,-path
 include $(BUILDDIR)/common/Defs.gmk
 
-#
-# Files to compile
-#
-AUTO_FILES_JAVA_DIRS = com/oracle
+# build com/oracle/security/ucrypto on Solaris platform for non-OpenJDK builds
+UCRYPTO =
+ifndef OPENJDK
+  ifeq ($(PLATFORM), solaris)
+    UCRYPTO = security/ucrypto
+  endif
+endif
 
-#
-# Rules
-#
-include $(BUILDDIR)/common/Classes.gmk
 
+SUBDIRS = net nio util $(UCRYPTO)
+
+include $(BUILDDIR)/common/Subdirs.gmk
+
+all build clean clobber::
+	$(SUBDIRS-loop)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/net/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+BUILDDIR = ../../..
+PACKAGE = com.oracle.net
+PRODUCT = oracle
+include $(BUILDDIR)/common/Defs.gmk
+
+#
+# Files
+#
+AUTO_FILES_JAVA_DIRS = com/oracle/net
+
+#
+# Rules
+#
+include $(BUILDDIR)/common/Classes.gmk
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/nio/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+BUILDDIR = ../../..
+PACKAGE = com.oracle.nio
+PRODUCT = oracle
+include $(BUILDDIR)/common/Defs.gmk
+
+#
+# Files
+#
+AUTO_FILES_JAVA_DIRS = com/oracle/nio
+
+#
+# Rules
+#
+include $(BUILDDIR)/common/Classes.gmk
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/security/ucrypto/FILES_c.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+ifndef OPENJDK
+FILES_c = \
+        nativeFunc.c \
+	nativeCrypto.c
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/security/ucrypto/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,270 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for building ucrypto.jar and its native libraries.
+#
+# This file was modified from make/sun/security/pkcs11/Makefile.
+#
+#
+# (The terms "OpenJDK" and "JDK" below refer to OpenJDK and Oracle
+# JDK builds respectively.)
+#
+# This Makefile does the "real" build of the Ucrypto provider files.
+# Since the sources are unavailable for OpenJDK, this Makefile is only
+# useful for JDK.
+#
+#
+# Main Targets (JDK on Solaris):
+#
+#     all                      The usual, ucrypto.jar plus the native libraries.
+#                                  builds and installs the prebuilt/signed jar.
+#
+#     clobber/clean            Cleans up the temp directory, ucrypto.jar, the
+#                              native libraries, and the config file from the
+#                              build area
+#
+#     jar                      Builds, signs and installs ucrypto.jar
+#                              (Can only be done on machines with access to
+#                               the signing keystore)
+#
+# Other lesser-used Targets (JDK on Solaris):
+#
+#     build-jar                Builds ucrypto.jar (no sign/install)
+#
+#     sign                     Builds/signs ucrypto.jar (no install)
+#
+#     release                  Builds all targets in preparation
+#                              for workspace integration.
+#                              (Can only be done on machines with access to
+#                               the signing keystore)
+#
+#     install-prebuilt         Installs the pre-built jar files
+#
+# NOTE: None of the above target will update the prebuilt provider binary
+# under the closed workspace. To update it, you must explicitly copy the
+# binary from either the tmp/signed or lib/ext directory.
+#
+# This makefile was written to support parallel target execution.
+#
+
+BUILDDIR = ../../../..
+
+include $(BUILDDIR)/common/Defs.gmk
+
+ifndef OPENJDK
+  ifneq ($(PLATFORM), solaris)
+    all:
+  else
+    PACKAGE = com.oracle.security.ucrypto
+  LIBRARY = j2ucrypto
+  PRODUCT = oracle
+
+  #
+  # The following is for when we need to do postprocessing
+  # (signing/obfuscation) against a read-only build.  If the OUTPUTDIR
+  # isn't writable, the build currently crashes out.
+  #
+  ifdef ALT_JCE_BUILD_DIR
+    # =====================================================
+    # Where to place the output, in case we're building from a read-only
+    # build area.  (e.g. a release engineering build.)
+    JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
+    IGNORE_WRITABLE_OUTPUTDIR_TEST=true
+  else
+    JCE_BUILD_DIR=${TEMPDIR}
+  endif
+
+  JAVAC_MAX_WARNINGS=false
+  JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation
+  JAVAC_WARNINGS_FATAL=true
+
+  #
+  # C and Java Files
+  #
+  include FILES_c.gmk
+
+  #
+  # Subdirectories of these are automatically included.
+  #
+  AUTO_FILES_JAVA_DIRS = com/oracle/security/ucrypto
+
+  #
+  # Java files that define native methods
+  #
+  FILES_export = \
+      com/oracle/security/ucrypto/UcryptoProvider.java \
+      com/oracle/security/ucrypto/NativeCipher.java \
+      com/oracle/security/ucrypto/NativeDigest.java \
+      com/oracle/security/ucrypto/NativeKey.java \
+      com/oracle/security/ucrypto/NativeRSASignature.java \
+      com/oracle/security/ucrypto/NativeRSACipher.java
+
+  #
+  # Find native code
+  #
+  vpath %.c \
+    $(CLOSED_PLATFORM_SRC)/native/com/oracle/security/ucrypto
+
+  #
+  # Find include files
+  #
+  OTHER_INCLUDES += \
+    -I$(CLOSED_PLATFORM_SRC)/native/com/oracle/security/ucrypto
+
+  #
+  # Rules
+  #
+  CLASSDESTDIR = $(TEMPDIR)/classes
+  JAVAHFLAGS = -bootclasspath \
+    "$(CLASSDESTDIR)$(CLASSPATH_SEPARATOR)$(CLASSBINDIR)"
+
+  include $(BUILDDIR)/common/Mapfile-vers.gmk
+  include $(BUILDDIR)/common/Library.gmk
+
+  #
+  # Libraries to link
+  #
+  OTHER_LDLIBS = -ldl
+
+  # Default config file
+  UCRYPTO_CFG_SRC   = $(CLOSED_SRC)/share/lib/security/ucrypto-solaris.cfg
+  UCRYPTO_CFG_BUILD = $(LIBDIR)/security/ucrypto-solaris.cfg
+
+  #
+  # We use a variety of subdirectories in the $(TEMPDIR) depending on what
+  # part of the build we're doing.  Build is initially done in the unsigned
+  # area and when files are signed, they will be placed in the appropriate area.
+  #
+  UNSIGNED_DIR = $(TEMPDIR)/unsigned
+
+  #
+  # Rules
+  #
+  all: ucrypto-cfg build-jar install-prebuilt
+	$(build-warning)
+
+  ucrypto-cfg: $(UCRYPTO_CFG_BUILD)
+
+  $(UCRYPTO_CFG_BUILD): $(UCRYPTO_CFG_SRC)
+	$(install-file)
+
+  include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
+
+
+  # =====================================================
+  # Build the unsigned ucrypto.jar file.
+  #
+
+  JAR_DESTFILE = $(EXTDIR)/ucrypto.jar
+
+  #
+  # The ucrypto.jar needs to be in the extension class directory,
+  # therefore none of its classes can appear in $(CLASSBINDIR).
+  # Currently no one is using any of the internals, so these files
+  # should not have been built.
+  #
+
+  #
+  # Since the -C option to jar is used below, each directory entry must be
+  # preceded with the appropriate directory to "cd" into.
+  #
+  JAR_DIRS = $(patsubst %, -C $(CLASSDESTDIR) %, $(AUTO_FILES_JAVA_DIRS))
+
+  build-jar: $(UNSIGNED_DIR)/ucrypto.jar
+
+  #
+  # Build ucrypto.jar.
+  #
+  $(UNSIGNED_DIR)/ucrypto.jar: build
+	$(prep-target)
+	$(BOOT_JAR_CMD) cf $@ $(JAR_DIRS) \
+	    $(BOOT_JAR_JFLAGS)
+	@$(java-vm-cleanup)
+
+  #
+  # Sign ucrypto.jar
+  #
+  SIGNED_DIR = $(JCE_BUILD_DIR)/signed
+
+  sign: $(SIGNED_DIR)/ucrypto.jar
+
+  ifndef ALT_JCE_BUILD_DIR
+    $(SIGNED_DIR)/ucrypto.jar: $(UNSIGNED_DIR)/ucrypto.jar
+  else
+    #
+    # We have to remove the build dependency, otherwise, we'll try to rebuild it
+    # which we can't do on a read-only filesystem.
+    #
+    $(SIGNED_DIR)/ucrypto.jar:
+	@if [ ! -r $(UNSIGNED_DIR)/ucrypto.jar ] ; then \
+            $(ECHO) "Couldn't find $(UNSIGNED_DIR)/ucrypto.jar"; \
+            exit 1; \
+        fi
+  endif
+	$(call sign-file, $(UNSIGNED_DIR)/ucrypto.jar)
+
+
+  # =====================================================
+  # Create the Release Engineering files.  Signed builds, etc.
+  #
+
+  release: $(SIGNED_DIR)/ucrypto.jar
+	$(RM) $(JCE_BUILD_DIR)/release/ucrypto.jar
+	$(MKDIR) -p $(JCE_BUILD_DIR)/release
+	$(CP) $(SIGNED_DIR)/ucrypto.jar $(JCE_BUILD_DIR)/release
+	$(release-warning)
+
+
+  # =====================================================
+  # Install routines.
+  #
+
+  #
+  # Install ucrypto.jar, depending on which type is requested.
+  #
+  jar: $(JAR_DESTFILE)
+	$(release-warning)
+
+  $(JAR_DESTFILE): $(SIGNED_DIR)/ucrypto.jar
+	$(install-file)
+
+  install-prebuilt:
+	@$(ECHO) "\n>>>Installing prebuilt OracleUcrypto provider..."
+	$(RM) $(JAR_DESTFILE)
+	$(CP) $(PREBUILT_DIR)/ucrypto/ucrypto.jar $(JAR_DESTFILE)
+
+
+  # =====================================================
+  # Support routines.
+  #
+  clobber clean::
+	$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
+	$(RM) -r $(UCRYPTO_CFG_BUILD)
+
+  .PHONY: build-jar jar sign release install-prebuilt
+
+  endif #ifneq ($(PLATFORM), solaris)
+endif #ifndef OPENJDK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/security/ucrypto/mapfile-vers	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Define public interface.
+
+SUNWprivate_1.1 {
+	global:
+                JNI_OnLoad;
+                Java_com_oracle_security_ucrypto_UcryptoProvider_loadLibraries;
+                Java_com_oracle_security_ucrypto_UcryptoProvider_getMechList;
+		Java_com_oracle_security_ucrypto_NativeDigest_nativeInit;
+                Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate;
+                Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest;
+                Java_com_oracle_security_ucrypto_NativeDigest_nativeClone;
+                Java_com_oracle_security_ucrypto_NativeDigest_nativeFree;
+		Java_com_oracle_security_ucrypto_NativeCipher_nativeInit;
+		Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate;
+		Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal;
+                Java_com_oracle_security_ucrypto_NativeKey_nativeFree;
+                Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit;
+                Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit;
+		Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
+		Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
+		Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
+		Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
+		Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic;
+
+                JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit;
+                JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate;
+                JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest;
+                JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone;
+                JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree;
+                JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit;
+                JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate;
+                JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal;
+                JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree;
+                JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit;
+                JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit;
+		JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
+		JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
+		JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
+		JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
+                JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic;
+
+	local:
+		*;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/util/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+BUILDDIR = ../../..
+PACKAGE = com.oracle.util
+PRODUCT = oracle
+include $(BUILDDIR)/common/Defs.gmk
+
+#
+# Files
+#
+AUTO_FILES_JAVA_DIRS = com/oracle/util
+
+#
+# Rules
+#
+include $(BUILDDIR)/common/Classes.gmk
+
--- a/jdk/make/com/sun/demo/jvmti/hprof/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/com/sun/demo/jvmti/hprof/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -32,6 +32,9 @@
 BUILDDIR = ../../../../..
 PACKAGE = com.sun.demo.jvmti.hprof
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/com/sun/java/browser/net/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/com/sun/java/browser/net/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -28,6 +28,9 @@
 BUILDDIR = ../../../../..
 PACKAGE = com.sun.java.browser.net
 PRODUCT = plugin
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/com/sun/tools/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/com/sun/tools/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -30,6 +30,9 @@
 BUILDDIR = ../../..
 PACKAGE = com.sun.tools
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 AUTO_FILES_JAVA_DIRS = com/sun/tools/extcheck
--- a/jdk/make/com/sun/tools/attach/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/com/sun/tools/attach/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -28,6 +28,9 @@
 PACKAGE = com.sun.tools.attach
 LIBRARY = attach
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 ifeq ($(PLATFORM), solaris)
--- a/jdk/make/com/sun/tracing/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/com/sun/tracing/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -30,6 +30,9 @@
 BUILDDIR = ../../..
 PACKAGE = com.sun.tracing
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 SUBDIRS = dtrace
--- a/jdk/make/com/sun/tracing/dtrace/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/com/sun/tracing/dtrace/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -29,6 +29,9 @@
 BUILDDIR = ../../../..
 PACKAGE = com.sun.tracing.dtrace
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 AUTO_FILES_JAVA_DIRS = com/sun/tracing/dtrace
--- a/jdk/make/common/Defs-linux.gmk	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/common/Defs-linux.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -72,7 +72,6 @@
 SCRIPT_SUFFIX =
 # CC compiler object code output directive flag value
 CC_OBJECT_OUTPUT_FLAG = -o #trailing blank required!
-CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required!
 
 # Default OBJCOPY comes from GNU Binutils on Linux:
 DEF_OBJCOPY=/usr/bin/objcopy
--- a/jdk/make/common/Defs-solaris.gmk	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/common/Defs-solaris.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -72,7 +72,6 @@
 SCRIPT_SUFFIX =
 # CC compiler object code output directive flag value
 CC_OBJECT_OUTPUT_FLAG = -o #trailing blank required!
-CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required!
 
 ifdef ENABLE_FULL_DEBUG_SYMBOLS
 # Only check for Full Debug Symbols support on Solaris if it is
--- a/jdk/make/common/Defs-windows.gmk	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/common/Defs-windows.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -36,7 +36,6 @@
 
 # CC compiler object code output directive flag value
 CC_OBJECT_OUTPUT_FLAG = -Fo
-CC_PROGRAM_OUTPUT_FLAG = -Fe
 
 # The suffix applied to the library name for FDLIBM
 FDDLIBM_SUFFIX = lib
--- a/jdk/make/common/Demo.gmk	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/common/Demo.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -319,9 +319,12 @@
 	@$(prep-target)
   ifeq ($(PLATFORM),windows)
 	$(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(DEMO_VERSION_INFO) $(VERSIONINFO_RESOURCE)
+	$(LINK.demo) $(SHARED_LIBRARY_FLAG) -Fe$@ \
+	    $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
+  else
+	$(LINK.demo) $(SHARED_LIBRARY_FLAG) -o $@ \
+	    $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
   endif
-	$(LINK.demo) $(SHARED_LIBRARY_FLAG) $(CC_PROGRAM_OUTPUT_FLAG)$@ \
-	    $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
 	@$(call binary_file_verification,$@)
 
   # Generation of any javah include file, make sure objects are dependent on it
--- a/jdk/make/common/Release.gmk	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/common/Release.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -82,11 +82,13 @@
   SHARE_JRE_DOC_SRC = $(JDK_TOPDIR)
   # Same files for jdk and jre, no name changes
   IMAGE_DOCLIST_JDK = LICENSE ASSEMBLY_EXCEPTION THIRD_PARTY_README
+  IMAGE_DOCLIST_JDK_DEMOS_AND_SAMPLES =
   IMAGE_DOCLIST_JRE = LICENSE ASSEMBLY_EXCEPTION THIRD_PARTY_README
 else
   # make/closed/common/Defs.gmk for closed location of SHARE_JDK_DOC_SRC
 
   IMAGE_DOCLIST_JDK = COPYRIGHT README.html  LICENSE THIRDPARTYLICENSEREADME.txt
+  IMAGE_DOCLIST_JDK_DEMOS_AND_SAMPLES = demo/DEMOS_LICENSE sample/SAMPLES_LICENSE
   IMAGE_DOCLIST_JRE = COPYRIGHT Welcome.html LICENSE THIRDPARTYLICENSEREADME.txt
   ifeq ($(PLATFORM), windows)
     IMAGE_DOCLIST_JRE += README.txt
@@ -98,6 +100,7 @@
 # Paths to these files we need
 JDK_DOCFILES   = $(IMAGE_DOCLIST_JDK:%=$(JDK_IMAGE_DIR)/%)
 JRE_DOCFILES   = $(IMAGE_DOCLIST_JRE:%=$(JRE_IMAGE_DIR)/%)
+JDK_DEMOS_AND_SAMPLES_DOCFILES = $(IMAGE_DOCLIST_JDK_DEMOS_AND_SAMPLES:%=$(JDK_IMAGE_DIR)/%)
 
 # absolute directory names: note, these must exist prior to build
 # time - they are created in the main Makefile.
@@ -320,6 +323,7 @@
 	sun/tools/jar		\
 	sun/tools/java		\
 	sun/tools/javac		\
+	sun/tools/jcmd		\
 	sun/tools/jps		\
 	sun/tools/jstat		\
 	sun/tools/jstatd	\
@@ -432,6 +436,7 @@
 	apt$(EXE_SUFFIX) \
 	javah$(EXE_SUFFIX) \
 	javap$(EXE_SUFFIX) \
+	jcmd$(EXE_SUFFIX) \
 	jdb$(EXE_SUFFIX) \
 	jps$(EXE_SUFFIX) \
 	jrunscript$(EXE_SUFFIX) \
@@ -484,6 +489,12 @@
 $(JDK_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%
 	$(process-doc-file)
 
+$(JDK_IMAGE_DIR)/demo/DEMOS_LICENSE: $(SHARE_JDK_DOC_SRC)/DEMOS_LICENSE
+	$(process-doc-file)
+
+$(JDK_IMAGE_DIR)/sample/SAMPLES_LICENSE: $(SHARE_JDK_DOC_SRC)/SAMPLES_LICENSE
+	$(process-doc-file)
+
 # JRE files 
 $(JRE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%
 	$(process-doc-file)
@@ -535,6 +546,7 @@
 	$(ECHO) "sun/tools/javac/" >> $@
 	$(ECHO) "com/sun/tools/classfile/" >> $@
 	$(ECHO) "com/sun/tools/javap/" >> $@
+	$(ECHO) "sun/tools/jcmd/" >> $@
 	$(ECHO) "sun/tools/jconsole/" >> $@
 	$(ECHO) "sun/tools/jps/" >> $@
 	$(ECHO) "sun/tools/jstat/" >> $@
@@ -911,7 +923,8 @@
 # Standard jdk image
 initial-image-jdk:: initial-image-jdk-setup \
 		    initial-image-jdk-db \
-		    $(JDK_DOCFILES)
+		    $(JDK_DOCFILES) \
+		    $(JDK_DEMOS_AND_SAMPLES_DOCFILES)
 	$(MKDIR) $(JDK_IMAGE_DIR)/lib
 	@#
 	@# Copy in the jars in lib that only belong in the JDK
--- a/jdk/make/common/shared/Defs-control.gmk	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/common/shared/Defs-control.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -75,9 +75,11 @@
 SRC_BUNDLEDIR       = $(OUTPUTDIR)/source-bundles
 ABS_SRC_BUNDLEDIR   = $(ABS_OUTPUTDIR)/source-bundles
 BIN_BUNDLEDIR       = $(OUTPUTDIR)/bundles
+BIN_DEMOS_BUNDLEDIR = $(OUTPUTDIR)/demos-bundles
 ABS_BIN_BUNDLEDIR   = $(ABS_OUTPUTDIR)/bundles
 
 dummy := $(shell $(MKDIR) -p $(BIN_BUNDLEDIR))
+dummy := $(shell $(MKDIR) -p $(BIN_DEMOS_BUNDLEDIR) )
 dummy := $(shell $(MKDIR) -p $(SRC_BUNDLEDIR) )
 
 TEMP_DIR = $(OUTPUTDIR)/tmp
--- a/jdk/make/common/shared/Platform.gmk	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/common/shared/Platform.gmk	Fri Jan 27 09:04:57 2012 +0100
@@ -147,8 +147,8 @@
   endif
   # Suffix for file bundles used in previous release
   BUNDLE_FILE_SUFFIX=.tar
-  # How much RAM does this machine have:
-  MB_OF_MEMORY=$(shell /usr/sbin/prtconf | fgrep 'Memory size:' | expand | cut -d' ' -f3)
+  # How much RAM does this machine have (zones send an error to stderr):
+  MB_OF_MEMORY:=$(shell /usr/sbin/prtconf 2>/dev/null | fgrep 'Memory size:' | expand | cut -d' ' -f3)
 endif
 
 # Platform settings specific to Linux
--- a/jdk/make/java/instrument/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/java/instrument/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -38,6 +38,9 @@
 
 FILES_m = mapfile-vers
 
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 # Use the mapfile-vers (See the mapfile located with this Makefile)
--- a/jdk/make/java/management/mapfile-vers	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/java/management/mapfile-vers	Fri Jan 27 09:04:57 2012 +0100
@@ -54,6 +54,9 @@
 	    Java_sun_management_GcInfoBuilder_getLastGcInfo0;
 	    Java_sun_management_GcInfoBuilder_getNumGcExtAttributes;
 	    Java_sun_management_HotSpotDiagnostic_dumpHeap;
+	    Java_sun_management_HotSpotDiagnostic_executeDiagnosticCommand0;
+	    Java_sun_management_HotSpotDiagnostic_getDiagnosticCommandInfo0;
+	    Java_sun_management_HotSpotDiagnostic_getDiagnosticCommands0;
 	    Java_sun_management_HotspotThread_getInternalThreadCount;
 	    Java_sun_management_HotspotThread_getInternalThreadTimes0;
 	    Java_sun_management_MemoryImpl_getMemoryManagers0;
--- a/jdk/make/java/rmi/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/java/rmi/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -31,6 +31,9 @@
 
 PACKAGE = java.rmi
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 AUTO_FILES_JAVA_DIRS = java/rmi
--- a/jdk/make/java/text/base/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/java/text/base/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -26,6 +26,8 @@
 BUILDDIR = ../../..
 PACKAGE = java.text
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
 
 include $(BUILDDIR)/common/Defs.gmk
 
--- a/jdk/make/java/text/bidi/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/java/text/bidi/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -26,6 +26,9 @@
 BUILDDIR = ../../..
 PACKAGE = java.text
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/java/util/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/java/util/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -32,6 +32,8 @@
 
 PACKAGE = java.util.resources
 PRODUCT = java
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
 
 include $(BUILDDIR)/common/Defs.gmk
 
--- a/jdk/make/javax/accessibility/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/javax/accessibility/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -26,6 +26,9 @@
 BUILDDIR = ../..
 PACKAGE = java.accessibility
 PRODUCT = java
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/javax/others/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/javax/others/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -28,6 +28,9 @@
 #
 
 BUILDDIR = ../..
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/javax/security/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/javax/security/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -28,8 +28,8 @@
 #
 
 BUILDDIR = ../..
-JAVAC_MAX_WARNINGS = true 
-JAVAC_WARNINGS_FATAL = true 
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
 
 include $(BUILDDIR)/common/Defs.gmk
 
--- a/jdk/make/javax/sound/jsoundalsa/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/javax/sound/jsoundalsa/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -65,7 +65,7 @@
 	$(MIDIFILES_export) \
 	$(PORTFILES_export)
 
-LDFLAGS += -lasound
+OTHER_LDLIBS += -lasound
 
 CPPFLAGS += \
 	-DUSE_DAUDIO=TRUE \
--- a/jdk/make/jpda/tty/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/jpda/tty/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -31,6 +31,9 @@
 PACKAGE = com.sun.tools.example.debug.tty
 PRODUCT = jpda
 PROGRAM = jdb
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 # This program must contain a manifest that defines the execution level
--- a/jdk/make/launchers/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/launchers/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -64,6 +64,7 @@
 $(call make-launcher, javadoc, com.sun.tools.javadoc.Main, , )
 $(call make-launcher, javah, com.sun.tools.javah.Main, , )
 $(call make-launcher, javap, com.sun.tools.javap.Main, , )
+$(call make-launcher, jcmd, sun.tools.jcmd.JCmd, , )
 $(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \
   -J-Djconsole.showOutputViewer, )
 $(call make-launcher, jdb, com.sun.tools.example.debug.tty.TTY, , )
--- a/jdk/make/sun/awt/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/sun/awt/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -367,7 +367,8 @@
 FONTCONFIGS_SRC	= $(CLOSED_SRC)/solaris/classes/sun/awt/fontconfigs
 _FONTCONFIGS	= \
 	fontconfig.properties				\
-	fontconfig.RedHat.5.5.properties		\
+	fontconfig.RedHat.5.properties			\
+	fontconfig.RedHat.6.properties			\
 	fontconfig.Turbo.properties			\
 	fontconfig.SuSE.10.properties                   \
 	fontconfig.SuSE.11.properties
--- a/jdk/make/sun/launcher/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/sun/launcher/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -26,6 +26,9 @@
 BUILDDIR = ../..
 PACKAGE = sun.launcher
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/sun/security/pkcs11/mapfile-vers	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/sun/security/pkcs11/mapfile-vers	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -47,8 +47,8 @@
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession;
 #		Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseAllSessions;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionInfo;
-#		Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState;
-#		Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState;
+		Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState;
+		Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject;
--- a/jdk/make/sun/serialver/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/sun/serialver/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -30,6 +30,9 @@
 BUILDDIR = ../..
 PACKAGE = sun.tools.serialver
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/sun/text/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/sun/text/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -31,6 +31,8 @@
 
 PACKAGE = sun.text
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
 
 include $(BUILDDIR)/common/Defs.gmk
 
--- a/jdk/make/sun/tools/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/sun/tools/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -42,6 +42,7 @@
   sun/tools/jstack \
   sun/tools/jstat \
   sun/tools/jstatd \
+  sun/tools/jcmd \
   com/sun/tools/hat \
   com/sun/tools/script/shell \
   sun/jvmstat
--- a/jdk/make/sun/util/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/sun/util/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -26,6 +26,9 @@
 BUILDDIR = ../..
 PACKAGE = sun.util
 PRODUCT = sun
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+
 include $(BUILDDIR)/common/Defs.gmk
 
 #
--- a/jdk/make/tools/freetypecheck/Makefile	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/make/tools/freetypecheck/Makefile	Fri Jan 27 09:04:57 2012 +0100
@@ -40,18 +40,19 @@
   FT_OPTIONS  = /nologo /c
   FREETYPE_DLL = $(FREETYPE_LIB_PATH)/freetype.dll
   FT_LD_OPTIONS  = $(FREETYPE_LIB_PATH)/freetype.lib
-ifdef MT
-  FT_LD_OPTIONS += /manifest
-endif
+  ifdef MT
+    FT_LD_OPTIONS += /manifest
+  endif
 else
   FT_OPTIONS  = $(CFLAGS)
   FT_LD_OPTIONS = -L$(FREETYPE_LIB_PATH)
   # Add runtime lib search path to ensure test will be runnable
-  ifeq ($(PLATFORM), solaris)
-    FT_LD_OPTIONS += -R $(FREETYPE_LIB_PATH) -lfreetype
-  else #linux
-      FT_LD_OPTIONS += -Wl,-rpath -Wl,$(FREETYPE_LIB_PATH) -lfreetype
+  ifeq ($(PLATFORM), linux)
+    FT_LD_OPTIONS += -Wl,-rpath -Wl,$(FREETYPE_LIB_PATH)
+  else # other unix
+    FT_LD_OPTIONS += -R $(FREETYPE_LIB_PATH)
   endif
+  FT_LD_OPTIONS += -lfreetype
 endif
 FT_OPTIONS += -I$(FREETYPE_HEADERS_PATH)
 FT_OPTIONS += -I$(FREETYPE_HEADERS_PATH)/freetype2
@@ -70,12 +71,12 @@
 	$(CC) $(FT_OPTIONS) $(CC_OBJECT_OUTPUT_FLAG)$(FT_OBJ) $<
 	$(LINK) $(FT_LD_OPTIONS) /OUT:$(FT_TEST) $(FT_OBJ)
 	$(CP) $(FREETYPE_DLL) $(@D)/
-ifdef MT
+  ifdef MT
 	$(CP) $(MSVCRNN_DLL_PATH)/$(MSVCRNN_DLL) $(@D)/
 	$(MT) /manifest $(FT_TEST).manifest /outputresource:$(FT_TEST);#1
-endif
+  endif
 else
-	@$(CC) $(FT_OPTIONS) $(CC_PROGRAM_OUTPUT_FLAG)$@ $< $(FT_LD_OPTIONS)
+	@$(CC) $(FT_OPTIONS) -o $@ $< $(FT_LD_OPTIONS)
 endif
 
 else
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/linux/doc/man/jcmd.1	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,124 @@
+." Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+." DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+."
+." This code is free software; you can redistribute it and/or modify it
+." under the terms of the GNU General Public License version 2 only, as
+." published by the Free Software Foundation.
+."
+." This code is distributed in the hope that it will be useful, but WITHOUT
+." ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+." FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+." version 2 for more details (a copy is included in the LICENSE file that
+." accompanied this code).
+."
+." You should have received a copy of the GNU General Public License version
+." 2 along with this work; if not, write to the Free Software Foundation,
+." Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+."
+." Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+." or visit www.oracle.com if you need additional information or have any
+." questions.
+."
+.TH jcmd 1 "22 Novembre 2011"
+
+.LP
+.SH "Name"
+jcmd \- Diagnostic Command
+.br
+
+.LP
+.SH "SYNOPSIS"
+.LP
+.nf
+\f3
+.fl
+\fP\f3jcmd\fP [ option ]
+.fl
+\f3jcmd\fP <\fIpid\fR | \fImain class\fR> PerfCounter.print
+.fl
+\f3jcmd\fP <\fIpid\fR | \fImain class\fR> \fIcommand\fR [\fIarguments\fR]
+.fl
+\f3jcmd\fP <\fIpid\fR | \fImain class\fR> -f \fIfile\fR
+.fl
+.fl
+.fi
+
+.LP
+.SH "DESCRIPTION"
+.LP
+.LP
+\f3jcmd\fP is a utility to send diagnostic command requests to a Java 
+Virtual Machine supporting this feature. Used without arguments or with the \-l option, jcmd prints the list of running Java processes with their process id, their main class and their command line arguments. When a process id is specified on the command line, jcmd sends the diagnostic command request to the process with this id. When a main class is specified on the command line, jcmd sends the diagnostic command request to all Java processes with this main class. With the PerfCounter.print argument, jcmd prints the performance counters available on the targeted Java process(es). With the \-f option, jcmd sends to the targeted Java process(es) the diagnostic commands stored in the file \fIfile\fR.
+.LP
+\fP
+.fi
+
+.SH "OPTIONS"
+.LP
+.LP
+Options are mutually exclusive. Options, if used, should follow immediately after the command name.
+.LP
+.RS 3
+.TP 3
+\-l 
+prints the list of running Java processes with their process id, their
+main class and their command line arguments. 
+.TP 3
+\-h 
+prints a help message.
+.br
+.br
+.TP 3
+\-help 
+prints a help message
+.br
+.RE
+
+.LP
+.SH "PARAMETERS"
+.LP
+.RS 3
+.TP 3
+\fIpid\fR
+Identifies the process which will receive the diagnostic command requests. The process must be a Java process. To get a list of Java processes running on a machine, jps(1) or jcmd(1) may be used. 
+.RE
+.LP
+.RS 3
+.TP 3
+\fImain class\fR
+Main class of the process which will receive the diagnostic command requests. If several running Java processes share this main class, the diagnostic command request will be sent to all these processes. To get a list of Java processes running on a machine, jps(1) or jcmd(1) may be used. 
+.RE
+.RS 3
+.TP 3
+\fIcommand\fR [\fIarguments\fR]
+Invoke the diagnostic command called \fIcommand\fR on the targeted Java
+process(es). The list of available diagnostic commands for a given
+process can be obtained by invoking the 'help' command on this process.
+Each diagnostic command has its own set of \fIarguments\fR which can be 
+obtained by invoking the 'help' command followed by the command name.
+.RE
+.RS 3
+.TP 3
+\fIPerfCounter.print\fR
+Print the performance counters available on the targeted Java
+process(es). The list of performance counters may vary with the Java
+process.
+.RE
+.RS 3
+.TP 3
+\fI-f file\fR
+Read commands from \fIfile\fR and invoke them on the targeted Java
+process(es). In  \fIfile\fR, each command must be written on a single line. 
+Lines starting with # are ignored. Processing of \fIfile\fR ends when
+all lines have been invoked or when a line containing the 'stop' keyword
+is read.
+.LP
+.SH "SEE ALSO"
+.LP
+.RS 3
+.TP 2
+o
+jps(1) 
+.RE
+
+ 
--- a/jdk/src/share/bin/java.c	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/bin/java.c	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -382,6 +382,11 @@
         exit(1);
     }
 
+    if (showSettings != NULL) {
+        ShowSettings(env, showSettings);
+        CHECK_EXCEPTION_LEAVE(1);
+    }
+
     if (printVersion || showVersion) {
         PrintJavaVersion(env, showVersion);
         CHECK_EXCEPTION_LEAVE(0);
@@ -390,10 +395,6 @@
         }
     }
 
-    if (showSettings != NULL) {
-        ShowSettings(env, showSettings);
-        CHECK_EXCEPTION_LEAVE(1);
-    }
     /* If the user specified neither a class name nor a JAR file */
     if (printXUsage || printUsage || what == 0 || mode == LM_UNKNOWN) {
         PrintUsage(env, printXUsage);
@@ -1224,14 +1225,7 @@
                 "checkAndLoadMain",
                 "(ZILjava/lang/String;)Ljava/lang/Class;"));
 
-    switch (mode) {
-        case LM_CLASS:
-            str = NewPlatformString(env, name);
-            break;
-        default:
-            str = (*env)->NewStringUTF(env, name);
-            break;
-    }
+    str = NewPlatformString(env, name);
     result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);
 
     if (JLI_IsTraceLauncher()) {
--- a/jdk/src/share/classes/com/sun/beans/TypeResolver.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/com/sun/beans/TypeResolver.java	Fri Jan 27 09:04:57 2012 +0100
@@ -154,7 +154,7 @@
      * @see #resolve(Type)
      */
     public static Type resolve(Type actual, Type formal) {
-        return new TypeResolver(actual).resolve(formal);
+        return getTypeResolver(actual).resolve(formal);
     }
 
     /**
@@ -169,7 +169,7 @@
      * @see #resolve(Type[])
      */
     public static Type[] resolve(Type actual, Type[] formals) {
-        return new TypeResolver(actual).resolve(formals);
+        return getTypeResolver(actual).resolve(formals);
     }
 
     /**
@@ -228,9 +228,20 @@
         return classes;
     }
 
+    public static TypeResolver getTypeResolver(Type type) {
+        synchronized (CACHE) {
+            TypeResolver resolver = CACHE.get(type);
+            if (resolver == null) {
+                resolver = new TypeResolver(type);
+                CACHE.put(type, resolver);
+            }
+            return resolver;
+        }
+    }
 
-    private final Map<TypeVariable<?>, Type> map
-        = new HashMap<TypeVariable<?>, Type>();
+    private static final WeakCache<Type, TypeResolver> CACHE = new WeakCache<>();
+
+    private final Map<TypeVariable<?>, Type> map = new HashMap<>();
 
     /**
      * Constructs the type resolver for the given actual type.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/management/DiagnosticCommandArgumentInfo.java	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * Diagnostic Command Argument information. It contains the description
+ * of one parameter of the diagnostic command. A parameter can either be an
+ * option or an argument. Options are identified by the option name while
+ * arguments are identified by their position in the command line. The generic
+ * syntax of a diagnostic command is:
+ *  <blockquote>
+ *    &lt;command name&gt; [&lt;option&gt;=&lt;value&gt;] [&lt;argument_value&gt;]
+ * </blockquote>
+ * Example:
+ * <blockquote>
+ * command_name option1=value1 option2=value argumentA argumentB argumentC
+ * </blockquote>
+ * In this command line, the diagnostic command receives five parameters, two
+ * options named {@code option1} and {@code option2}, and three arguments.
+ * argumentA's position is 0, argumentB's position is 1 and argumentC's
+ * position is 2.
+ *
+ * @author  Frederic Parain
+ * @since   7u4
+ */
+
+public class DiagnosticCommandArgumentInfo {
+    private final String name;
+    private final String description;
+    private final String type;
+    private final String defaultValue;
+    private final boolean mandatory;
+    private final boolean option;
+    private final int position;
+
+    /**
+     * Returns the argument name
+     *
+     * @return the argument name
+     */
+    public String getName() {
+        return name;
+    }
+
+   /**
+     * Returns the argument description
+     *
+     * @return the argument description
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Returns the argument type
+     *
+     * @return the argument type
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Returns the default value as a String if a default value
+     * is defined, null otherwise.
+     *
+     * @return the default value as a String if a default value
+     * is defined, null otherwise.
+     */
+    public String getDefault() {
+        return defaultValue;
+    }
+
+    /**
+     * Returns {@code true} if the argument is mandatory,
+     *         {@code false} otherwise
+     *
+     * @return {@code true} if the argument is mandatory,
+     *         {@code false} otherwise
+     */
+    public boolean isMandatory() {
+        return mandatory;
+    }
+
+    /**
+     * Returns {@code true} if the argument is an option,
+     *         {@code false} otherwise. Options have to be specified using the
+     *         &lt;key&gt;=&lt;value&gt; syntax on the command line, while other
+     *         arguments are specified with a single &lt;value&gt; field and are
+     *         identified by their position on command line.
+     *
+     * @return {@code true} if the argument is an option,
+     *         {@code false} otherwise
+     */
+    public boolean isOption() {
+        return option;
+    }
+
+    /**
+     * Returns the expected position of this argument if it is not an option,
+     *         -1 otherwise. Argument position if defined from left to right,
+     *         starting at zero and ignoring the diagnostic command name and
+     *         options.
+     *
+     * @return the expected position of this argument if it is not an option,
+     *         -1 otherwise.
+     */
+    public int getPosition() {
+        return position;
+    }
+
+    @ConstructorProperties({"name","description","type","default",
+                "mandatory","option","position"})
+    public DiagnosticCommandArgumentInfo(String name, String description,
+                                         String type, String defaultValue,
+                                         boolean mandatory, boolean option,
+                                         int position) {
+        this.name = name;
+        this.description = description;
+        this.type = type;
+        this.defaultValue = defaultValue;
+        this.mandatory = mandatory;
+        this.option = option;
+        this.position = position;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/management/DiagnosticCommandInfo.java	Fri Jan 27 09:04:57 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import java.beans.ConstructorProperties;
+import java.util.List;
+
+/**
+ * Diagnostic command information. It contains the description of a
+ * diagnostic command.
+ *
+ * @author  Frederic Parain
+ * @since   7u4
+ */
+
+public class DiagnosticCommandInfo {
+    private final String name;
+    private final String description;
+    private final String impact;
+    private final boolean enabled;
+    private final List<DiagnosticCommandArgumentInfo> arguments;
+
+    /**
+     * Returns the diagnostic command name
+     *
+     * @return the diagnostic command name
+     */
+    public String getName() {
+        return name;
+    }
+
+   /**
+     * Returns the diagnostic command description
+     *
+     * @return the diagnostic command description
+     */
+    public String getDescription() {
+        return description;
+    }
+
+     /**
+     * Returns the potential impact of the diagnostic command execution
+     *         on the Java virtual machine behavior
+     *
+     * @return the potential impact of the diagnostic command execution
+     *         on the Java virtual machine behavior
+     */
+    public String getImpact() {
+        return impact;
+    }
+
+    /**
+     * Returns {@code true} if the diagnostic command is enabled,
+     *         {@code false} otherwise. The enabled/disabled
+     *         status of a diagnostic command can evolve during
+     *         the lifetime of the Java virtual machine.
+     *
+     * @return {@code true} if the diagnostic command is enabled,
+     *         {@code false} otherwise
+     */
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    /**
+     * Returns the list of the diagnostic command arguments description.
+     * If the diagnostic command has no arguments, it returns an empty list.
+     *
+     * @return a list of the diagnostic command arguments description
+     */
+    public List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
+        return arguments;
+    }
+
+    @ConstructorProperties({"name", "description","impact","enabled",
+                "argumentsInfo"})
+    public DiagnosticCommandInfo(String name, String description,
+                                 String impact, boolean enabled,
+                                 List<DiagnosticCommandArgumentInfo> arguments)
+    {
+        this.name = name;
+        this.description = description;
+        this.impact = impact;
+        this.enabled = enabled;
+        this.arguments = arguments;
+    }
+}
--- a/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java	Fri Jan 27 09:04:57 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,18 @@
 
 package com.sun.management;
 
+import java.util.List;
 import java.lang.management.PlatformManagedObject;
 
 /**
  * Diagnostic management interface for the HotSpot Virtual Machine.
- * The diagnostic MBean is registered to the platform MBeanServer
+ *
+ * <p>{@linkplain #getDiagnosticCommands Diagnostic commands}
+ * are actions that can be invoked dynamically and
+ * executed in a target Java virtual machine, mainly for troubleshooting
+ * and diagnosis.
+ *
+ * <p>The diagnostic MBean is registered to the platform MBeanServer
  * as are other platform MBeans.
  *
  * <p>The <tt>ObjectName</tt> for uniquely identifying the diagnostic
@@ -41,6 +48,9 @@
  * It can be obtained by calling the
  * {@link PlatformManagedObject#getObjectName} method.
  *
+ * All methods throw a {@code NullPointerException} if any input argument is
+ * {@code null} unless it's stated otherwise.
+ *
  * @see ManagementFactory#getPlatformMXBeans(Class)
  */
 public interface HotSpotDiagnosticMXBean extends PlatformManagedObject {
@@ -101,9 +111,113 @@
      * @throws IllegalArgumentException if the VM option is not writeable.
      * @throws NullPointerException if name or value is <tt>null</tt>.
      *
-     * @throws  java.security.SecurityException
+     * @throws  java.lang.SecurityException
      *     if a security manager exists and the caller does not have
      *     ManagementPermission("control").
      */
     public void setVMOption(String name, String value);
+
+    /**
+     * Returns the {@linkplain DiagnosticCommandInfo#getName() names}
+     * of all diagnostic commands.
+     * A diagnostic command is an action that can be invoked dynamically
+     * mainly for troubleshooting and diagnosis.  The list of diagnostic
+     * commands may change at runtime.  A diagnostic command may be
+     * {@linkplain DiagnosticCommandInfo#isEnabled disabled} but will
+     * not be removed from a previously returned list.
+     *
+     * @return the names of all diagnostic commands.
+     *
+     * @since 7u4
+     */
+    public List<String> getDiagnosticCommands();
+
+    /**
+     * Returns a {@code DiagnosticCommandInfo} object describing the
+     * diagnostic command of the specified name {@code command}
+     *
+     * @param command a diagnostic command name
+     * @return a {@code DiagnosticCommandInfo} object
+     * @throws java.lang.IllegalArgumentException if the {@code command}
+     *         doesn't match any diagnostic command registered in the
+     *         targeted Java virtual machine.
+     *
+     * @since 7u4
+     */
+    public DiagnosticCommandInfo getDiagnosticCommandInfo(String command);
+
+    /**
+     * Returns a list of {@code DiagnosticCommandInfo} object describing
+     * all diagnostic commands available on the targeted Java virtual machine
+     *
+     * @return a list of {@code DiagnosticCommandInfo} objects
+     *
+     * @since 7u4
+     */
+    public List<DiagnosticCommandInfo> getDiagnosticCommandInfo();
+
+    /**
+     * Returns a list of {@code DiagnosticCommandInfo} object describing
+     * all diagnostic commands specified in the {@code commands} list.
+     *
+     * @param commands {@code List} of {@code String} containing diagnostic
+     *        command names
+     * @return a {@code List} of {@code DiagnosticCommandInfo} objects
+     *
+     * @throws java.lang.IllegalArgumentException if at least one
+     *         command specified in the {@code commands } list
+     *         doesn't match any diagnostic command registered in the
+     *         targeted Java virtual machine.
+     *
+     * @since 7u4
+     */
+    public List<DiagnosticCommandInfo> getDiagnosticCommandInfo(List<String> commands);
+
+    /**
+     * Executes the command line {@code commandLine}. The command line must
+     * start with a diagnostic command name, optionally followed by parameters.
+     * Each command has its own syntax but the generic syntax for a diagnostic
+     * command line is:
+     * <blockquote>
+     *    &lt;command name&gt; [&lt;option&gt;=&lt;value&gt;] [&lt;argument_value&gt;]
+     * </blockquote>
+     *
+     * @param commandLine command line to execute
+     * @return a {@code String} object containing the diagnostic command
+     *         output.
+     *
+     * @throws java.lang.IllegalArgumentException if the command line doesn't
+     *         match any diagnostic command registered in the virtual machine
+     *         of if the parameters don't match the diagnostic command syntax.
+     * @throws java.lang.SecurityException
+     *         if a security manager exists and the caller does not have
+     *         ManagementPermission("control").
+     *
+     * @since 7u4
+     */
+    public String execute(String commandLine);
+
+    /**
+     * Invokes the diagnostic command named {@code cmd} with the parameters
+     * specified in {@code args}. Each command has its own syntax but
+     * the generic syntax for parameters is:
+     * <blockquote>
+     *    [&lt;option&gt;=&lt;value&gt;] [&lt;argument_value&gt;]
+     * </blockquote>
+     *
+     * @param cmd a diagnostic command name
+     * @param args the command parameters
+     * @return a {@code String} object containing the diagnostic command
+     *         output.
+     *
+     * @throws java.lang.IllegalArgumentException if the command line doesn't
+     *         match any diagnostic command registered in the virtual machine
+     *         of if the parameters don't match the diagnostic command syntax.
+     * @throws java.lang.SecurityException
+     *         if a security manager exists and the caller does not have
+     *         ManagementPermission("control").
+     *
+     * @since 7u4
+     */
+    public String execute(String cmd, String... args);
 }
--- a/jdk/src/share/classes/java/awt/AWTKeyStroke.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/awt/AWTKeyStroke.java	Fri Jan 27 09:04:57 2012 +0100
@@ -802,8 +802,11 @@
      */
     protected Object readResolve() throws java.io.ObjectStreamException {
         synchronized (AWTKeyStroke.class) {
-            return getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
+            if (getClass().equals(getAWTKeyStrokeClass())) {
+                return  getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
+            }
         }
+        return this;
     }
 
     private static int mapOldModifiers(int modifiers) {
--- a/jdk/src/share/classes/java/lang/Class.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/Class.java	Fri Jan 27 09:04:57 2012 +0100
@@ -3118,4 +3118,9 @@
     AnnotationType getAnnotationType() {
         return annotationType;
     }
+
+    /* Backing store of user-defined values pertaining to this class.
+     * Maintained by the ClassValue class.
+     */
+    transient ClassValue.ClassValueMap classValueMap;
 }
--- a/jdk/src/share/classes/java/lang/ClassValue.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/ClassValue.java	Fri Jan 27 09:04:57 2012 +0100
@@ -25,9 +25,14 @@
 
 package java.lang;
 
+import java.lang.ClassValue.ClassValueMap;
 import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import static java.lang.ClassValue.ClassValueMap.probeHomeLocation;
+import static java.lang.ClassValue.ClassValueMap.probeBackupLocations;
+
 /**
  * Lazily associate a computed value with (potentially) every type.
  * For example, if a dynamic language needs to construct a message dispatch
@@ -92,14 +97,22 @@
      * @see #computeValue
      */
     public T get(Class<?> type) {
-        ClassValueMap map = getMap(type);
-        if (map != null) {
-            Object x = map.get(this);
-            if (x != null) {
-                return (T) map.unmaskNull(x);
-            }
-        }
-        return setComputedValue(type);
+        // non-racing this.hashCodeForCache : final int
+        Entry<?>[] cache;
+        Entry<T> e = probeHomeLocation(cache = getCacheCarefully(type), this);
+        // racing e : current value <=> stale value from current cache or from stale cache
+        // invariant:  e is null or an Entry with readable Entry.version and Entry.value
+        if (match(e))
+            // invariant:  No false positive matches.  False negatives are OK if rare.
+            // The key fact that makes this work: if this.version == e.version,
+            // then this thread has a right to observe (final) e.value.
+            return e.value();
+        // The fast path can fail for any of these reasons:
+        // 1. no entry has been computed yet
+        // 2. hash code collision (before or after reduction mod cache.length)
+        // 3. an entry has been removed (either on this type or another)
+        // 4. the GC has somehow managed to delete e.version and clear the reference
+        return getFromBackup(cache, type);
     }
 
     /**
@@ -157,83 +170,582 @@
      */
     public void remove(Class<?> type) {
         ClassValueMap map = getMap(type);
-        if (map != null) {
-            synchronized (map) {
-                map.remove(this);
+        map.removeEntry(this);
+    }
+
+    // Possible functionality for JSR 292 MR 1
+    /*public*/ void put(Class<?> type, T value) {
+        ClassValueMap map = getMap(type);
+        map.changeEntry(this, value);
+    }
+
+    /// --------
+    /// Implementation...
+    /// --------
+
+    /** Return the cache, if it exists, else a dummy empty cache. */
+    private static Entry<?>[] getCacheCarefully(Class<?> type) {
+        // racing type.classValueMap{.cacheArray} : null => new Entry[X] <=> new Entry[Y]
+        ClassValueMap map = type.classValueMap;
+        if (map == null)  return EMPTY_CACHE;
+        Entry<?>[] cache = map.getCache();
+        return cache;
+        // invariant:  returned value is safe to dereference and check for an Entry
+    }
+
+    /** Initial, one-element, empty cache used by all Class instances.  Must never be filled. */
+    private static final Entry<?>[] EMPTY_CACHE = { null };
+
+    /**
+     * Slow tail of ClassValue.get to retry at nearby locations in the cache,
+     * or take a slow lock and check the hash table.
+     * Called only if the first probe was empty or a collision.
+     * This is a separate method, so compilers can process it independently.
+     */
+    private T getFromBackup(Entry<?>[] cache, Class<?> type) {
+        Entry<T> e = probeBackupLocations(cache, this);
+        if (e != null)
+            return e.value();
+        return getFromHashMap(type);
+    }
+
+    // Hack to suppress warnings on the (T) cast, which is a no-op.
+    @SuppressWarnings("unchecked")
+    Entry<T> castEntry(Entry<?> e) { return (Entry<T>) e; }
+
+    /** Called when the fast path of get fails, and cache reprobe also fails.
+     */
+    private T getFromHashMap(Class<?> type) {
+        // The fail-safe recovery is to fall back to the underlying classValueMap.
+        ClassValueMap map = getMap(type);
+        for (;;) {
+            Entry<T> e = map.startEntry(this);
+            if (!e.isPromise())
+                return e.value();
+            try {
+                // Try to make a real entry for the promised version.
+                e = makeEntry(e.version(), computeValue(type));
+            } finally {
+                // Whether computeValue throws or returns normally,
+                // be sure to remove the empty entry.
+                e = map.finishEntry(this, e);
             }
+            if (e != null)
+                return e.value();
+            // else try again, in case a racing thread called remove (so e == null)
         }
     }
 
-    /// Implementation...
-    // FIXME: Use a data structure here similar that of ThreadLocal (7030453).
-
-    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
-
-    /** Slow path for {@link #get}. */
-    private T setComputedValue(Class<?> type) {
-        ClassValueMap map = getMap(type);
-        if (map == null) {
-            map = initializeMap(type);
-        }
-        T value = computeValue(type);
-        STORE_BARRIER.lazySet(0);
-        // All stores pending from computeValue are completed.
-        synchronized (map) {
-            // Warm up the table with a null entry.
-            map.preInitializeEntry(this);
-        }
-        STORE_BARRIER.lazySet(0);
-        // All stores pending from table expansion are completed.
-        synchronized (map) {
-            value = (T) map.initializeEntry(this, value);
-            // One might fear a possible race condition here
-            // if the code for map.put has flushed the write
-            // to map.table[*] before the writes to the Map.Entry
-            // are done.  This is not possible, since we have
-            // warmed up the table with an empty entry.
-        }
-        return value;
+    /** Check that e is non-null, matches this ClassValue, and is live. */
+    boolean match(Entry<?> e) {
+        // racing e.version : null (blank) => unique Version token => null (GC-ed version)
+        // non-racing this.version : v1 => v2 => ... (updates are read faithfully from volatile)
+        return (e != null && e.get() == this.version);
+        // invariant:  No false positives on version match.  Null is OK for false negative.
+        // invariant:  If version matches, then e.value is readable (final set in Entry.<init>)
     }
 
-    // Replace this map by a per-class slot.
-    private static final WeakHashMap<Class<?>, ClassValueMap> ROOT
-        = new WeakHashMap<Class<?>, ClassValueMap>();
+    /** Internal hash code for accessing Class.classValueMap.cacheArray. */
+    final int hashCodeForCache = nextHashCode.getAndAdd(HASH_INCREMENT) & HASH_MASK;
 
-    private static ClassValueMap getMap(Class<?> type) {
-        type.getClass();  // test for null
-        return ROOT.get(type);
+    /** Value stream for hashCodeForCache.  See similar structure in ThreadLocal. */
+    private static final AtomicInteger nextHashCode = new AtomicInteger();
+
+    /** Good for power-of-two tables.  See similar structure in ThreadLocal. */
+    private static final int HASH_INCREMENT = 0x61c88647;
+
+    /** Mask a hash code to be positive but not too large, to prevent wraparound. */
+    static final int HASH_MASK = (-1 >>> 2);
+
+    /**
+     * Private key for retrieval of this object from ClassValueMap.
+     */
+    static class Identity {
+    }
+    /**
+     * This ClassValue's identity, expressed as an opaque object.
+     * The main object {@code ClassValue.this} is incorrect since
+     * subclasses may override {@code ClassValue.equals}, which
+     * could confuse keys in the ClassValueMap.
+     */
+    final Identity identity = new Identity();
+
+    /**
+     * Current version for retrieving this class value from the cache.
+     * Any number of computeValue calls can be cached in association with one version.
+     * But the version changes when a remove (on any type) is executed.
+     * A version change invalidates all cache entries for the affected ClassValue,
+     * by marking them as stale.  Stale cache entries do not force another call
+     * to computeValue, but they do require a synchronized visit to a backing map.
+     * <p>
+     * All user-visible state changes on the ClassValue take place under
+     * a lock inside the synchronized methods of ClassValueMap.
+     * Readers (of ClassValue.get) are notified of such state changes
+     * when this.version is bumped to a new token.
+     * This variable must be volatile so that an unsynchronized reader
+     * will receive the notification without delay.
+     * <p>
+     * If version were not volatile, one thread T1 could persistently hold onto
+     * a stale value this.value == V1, while while another thread T2 advances
+     * (under a lock) to this.value == V2.  This will typically be harmless,
+     * but if T1 and T2 interact causally via some other channel, such that
+     * T1's further actions are constrained (in the JMM) to happen after
+     * the V2 event, then T1's observation of V1 will be an error.
+     * <p>
+     * The practical effect of making this.version be volatile is that it cannot
+     * be hoisted out of a loop (by an optimizing JIT) or otherwise cached.
+     * Some machines may also require a barrier instruction to execute
+     * before this.version.
+     */
+    private volatile Version<T> version = new Version<>(this);
+    Version<T> version() { return version; }
+    void bumpVersion() { version = new Version<>(this); }
+    static class Version<T> {
+        private final ClassValue<T> classValue;
+        private final Entry<T> promise = new Entry<>(this);
+        Version(ClassValue<T> classValue) { this.classValue = classValue; }
+        ClassValue<T> classValue() { return classValue; }
+        Entry<T> promise() { return promise; }
+        boolean isLive() { return classValue.version() == this; }
     }
 
+    /** One binding of a value to a class via a ClassValue.
+     *  States are:<ul>
+     *  <li> promise if value == Entry.this
+     *  <li> else dead if version == null
+     *  <li> else stale if version != classValue.version
+     *  <li> else live </ul>
+     *  Promises are never put into the cache; they only live in the
+     *  backing map while a computeValue call is in flight.
+     *  Once an entry goes stale, it can be reset at any time
+     *  into the dead state.
+     */
+    static class Entry<T> extends WeakReference<Version<T>> {
+        final Object value;  // usually of type T, but sometimes (Entry)this
+        Entry(Version<T> version, T value) {
+            super(version);
+            this.value = value;  // for a regular entry, value is of type T
+        }
+        private void assertNotPromise() { assert(!isPromise()); }
+        /** For creating a promise. */
+        Entry(Version<T> version) {
+            super(version);
+            this.value = this;  // for a promise, value is not of type T, but Entry!
+        }
+        /** Fetch the value.  This entry must not be a promise. */
+        @SuppressWarnings("unchecked")  // if !isPromise, type is T
+        T value() { assertNotPromise(); return (T) value; }
+        boolean isPromise() { return value == this; }
+        Version<T> version() { return get(); }
+        ClassValue<T> classValueOrNull() {
+            Version<T> v = version();
+            return (v == null) ? null : v.classValue();
+        }
+        boolean isLive() {
+            Version<T> v = version();
+            if (v == null)  return false;
+            if (v.isLive())  return true;
+            clear();
+            return false;
+        }
+        Entry<T> refreshVersion(Version<T> v2) {
+            assertNotPromise();
+            @SuppressWarnings("unchecked")  // if !isPromise, type is T
+            Entry<T> e2 = new Entry<>(v2, (T) value);
+            clear();
+            // value = null -- caller must drop
+            return e2;
+        }
+        static final Entry<?> DEAD_ENTRY = new Entry<>(null, null);
+    }
+
+    /** Return the backing map associated with this type. */
+    private static ClassValueMap getMap(Class<?> type) {
+        // racing type.classValueMap : null (blank) => unique ClassValueMap
+        // if a null is observed, a map is created (lazily, synchronously, uniquely)
+        // all further access to that map is synchronized
+        ClassValueMap map = type.classValueMap;
+        if (map != null)  return map;
+        return initializeMap(type);
+    }
+
+    private static final Object CRITICAL_SECTION = new Object();
     private static ClassValueMap initializeMap(Class<?> type) {
-        synchronized (ClassValue.class) {
-            ClassValueMap map = ROOT.get(type);
-            if (map == null)
-                ROOT.put(type, map = new ClassValueMap());
+        ClassValueMap map;
+        synchronized (CRITICAL_SECTION) {  // private object to avoid deadlocks
+            // happens about once per type
+            if ((map = type.classValueMap) == null)
+                type.classValueMap = map = new ClassValueMap(type);
+        }
             return map;
         }
+
+    static <T> Entry<T> makeEntry(Version<T> explicitVersion, T value) {
+        // Note that explicitVersion might be different from this.version.
+        return new Entry<>(explicitVersion, value);
+
+        // As soon as the Entry is put into the cache, the value will be
+        // reachable via a data race (as defined by the Java Memory Model).
+        // This race is benign, assuming the value object itself can be
+        // read safely by multiple threads.  This is up to the user.
+        //
+        // The entry and version fields themselves can be safely read via
+        // a race because they are either final or have controlled states.
+        // If the pointer from the entry to the version is still null,
+        // or if the version goes immediately dead and is nulled out,
+        // the reader will take the slow path and retry under a lock.
     }
 
-    static class ClassValueMap extends WeakHashMap<ClassValue, Object> {
-        /** Make sure this table contains an Entry for the given key, even if it is empty. */
-        void preInitializeEntry(ClassValue key) {
-            if (!this.containsKey(key))
-                this.put(key, null);
-        }
-        /** Make sure this table contains a non-empty Entry for the given key. */
-        Object initializeEntry(ClassValue key, Object value) {
-            Object prior = this.get(key);
-            if (prior != null) {
-                return unmaskNull(prior);
-            }
-            this.put(key, maskNull(value));
-            return value;
+    // The following class could also be top level and non-public:
+
+    /** A backing map for all ClassValues, relative a single given type.
+     *  Gives a fully serialized "true state" for each pair (ClassValue cv, Class type).
+     *  Also manages an unserialized fast-path cache.
+     */
+    static class ClassValueMap extends WeakHashMap<ClassValue.Identity, Entry<?>> {
+        private final Class<?> type;
+        private Entry<?>[] cacheArray;
+        private int cacheLoad, cacheLoadLimit;
+
+        /** Number of entries initially allocated to each type when first used with any ClassValue.
+         *  It would be pointless to make this much smaller than the Class and ClassValueMap objects themselves.
+         *  Must be a power of 2.
+         */
+        private static final int INITIAL_ENTRIES = 32;
+
+        /** Build a backing map for ClassValues, relative the given type.
+         *  Also, create an empty cache array and install it on the class.
+         */
+        ClassValueMap(Class<?> type) {
+            this.type = type;
+            sizeCache(INITIAL_ENTRIES);
         }
 
-        Object maskNull(Object x) {
-            return x == null ? this : x;
+        Entry<?>[] getCache() { return cacheArray; }
+
+        /** Initiate a query.  Store a promise (placeholder) if there is no value yet. */
+        synchronized
+        <T> Entry<T> startEntry(ClassValue<T> classValue) {
+            @SuppressWarnings("unchecked")  // one map has entries for all value types <T>
+            Entry<T> e = (Entry<T>) get(classValue.identity);
+            Version<T> v = classValue.version();
+            if (e == null) {
+                e = v.promise();
+                // The presence of a promise means that a value is pending for v.
+                // Eventually, finishEntry will overwrite the promise.
+                put(classValue.identity, e);
+                // Note that the promise is never entered into the cache!
+                return e;
+            } else if (e.isPromise()) {
+                // Somebody else has asked the same question.
+                // Let the races begin!
+                if (e.version() != v) {
+                    e = v.promise();
+                    put(classValue.identity, e);
+                }
+                return e;
+            } else {
+                // there is already a completed entry here; report it
+                if (e.version() != v) {
+                    // There is a stale but valid entry here; make it fresh again.
+                    // Once an entry is in the hash table, we don't care what its version is.
+                    e = e.refreshVersion(v);
+                    put(classValue.identity, e);
+                }
+                // Add to the cache, to enable the fast path, next time.
+                checkCacheLoad();
+                addToCache(classValue, e);
+                return e;
+            }
         }
-        Object unmaskNull(Object x) {
-            return x == this ? null : x;
+
+        /** Finish a query.  Overwrite a matching placeholder.  Drop stale incoming values. */
+        synchronized
+        <T> Entry<T> finishEntry(ClassValue<T> classValue, Entry<T> e) {
+            @SuppressWarnings("unchecked")  // one map has entries for all value types <T>
+            Entry<T> e0 = (Entry<T>) get(classValue.identity);
+            if (e == e0) {
+                // We can get here during exception processing, unwinding from computeValue.
+                assert(e.isPromise());
+                remove(classValue.identity);
+                return null;
+            } else if (e0 != null && e0.isPromise() && e0.version() == e.version()) {
+                // If e0 matches the intended entry, there has not been a remove call
+                // between the previous startEntry and now.  So now overwrite e0.
+                Version<T> v = classValue.version();
+                if (e.version() != v)
+                    e = e.refreshVersion(v);
+                put(classValue.identity, e);
+                // Add to the cache, to enable the fast path, next time.
+                checkCacheLoad();
+                addToCache(classValue, e);
+                return e;
+            } else {
+                // Some sort of mismatch; caller must try again.
+                return null;
+            }
         }
+
+        /** Remove an entry. */
+        synchronized
+        void removeEntry(ClassValue<?> classValue) {
+            // make all cache elements for this guy go stale:
+            if (remove(classValue.identity) != null) {
+                classValue.bumpVersion();
+                removeStaleEntries(classValue);
+            }
+        }
+
+        /** Change the value for an entry. */
+        synchronized
+        <T> void changeEntry(ClassValue<T> classValue, T value) {
+            @SuppressWarnings("unchecked")  // one map has entries for all value types <T>
+            Entry<T> e0 = (Entry<T>) get(classValue.identity);
+            Version<T> version = classValue.version();
+            if (e0 != null) {
+                if (e0.version() == version && e0.value() == value)
+                    // no value change => no version change needed
+                    return;
+                classValue.bumpVersion();
+                removeStaleEntries(classValue);
+            }
+            Entry<T> e = makeEntry(version, value);
+            put(classValue.identity, e);
+            // Add to the cache, to enable the fast path, next time.
+            checkCacheLoad();
+            addToCache(classValue, e);
+        }
+
+        /// --------
+        /// Cache management.
+        /// --------
+
+        // Statics do not need synchronization.
+
+        /** Load the cache entry at the given (hashed) location. */
+        static Entry<?> loadFromCache(Entry<?>[] cache, int i) {
+            // non-racing cache.length : constant
+            // racing cache[i & (mask)] : null <=> Entry
+            return cache[i & (cache.length-1)];
+            // invariant:  returned value is null or well-constructed (ready to match)
+        }
+
+        /** Look in the cache, at the home location for the given ClassValue. */
+        static <T> Entry<T> probeHomeLocation(Entry<?>[] cache, ClassValue<T> classValue) {
+            return classValue.castEntry(loadFromCache(cache, classValue.hashCodeForCache));
+        }
+
+        /** Given that first probe was a collision, retry at nearby locations. */
+        static <T> Entry<T> probeBackupLocations(Entry<?>[] cache, ClassValue<T> classValue) {
+            if (PROBE_LIMIT <= 0)  return null;
+            // Probe the cache carefully, in a range of slots.
+            int mask = (cache.length-1);
+            int home = (classValue.hashCodeForCache & mask);
+            Entry<?> e2 = cache[home];  // victim, if we find the real guy
+            if (e2 == null) {
+                return null;   // if nobody is at home, no need to search nearby
+            }
+            // assume !classValue.match(e2), but do not assert, because of races
+            int pos2 = -1;
+            for (int i = home + 1; i < home + PROBE_LIMIT; i++) {
+                Entry<?> e = cache[i & mask];
+                if (e == null) {
+                    break;   // only search within non-null runs
+                }
+                if (classValue.match(e)) {
+                    // relocate colliding entry e2 (from cache[home]) to first empty slot
+                    cache[home] = e;
+                    if (pos2 >= 0) {
+                        cache[i & mask] = Entry.DEAD_ENTRY;
+                    } else {
+                        pos2 = i;
+                    }
+                    cache[pos2 & mask] = ((entryDislocation(cache, pos2, e2) < PROBE_LIMIT)
+                                          ? e2                  // put e2 here if it fits
+                                          : Entry.DEAD_ENTRY);
+                    return classValue.castEntry(e);
+                }
+                // Remember first empty slot, if any:
+                if (!e.isLive() && pos2 < 0)  pos2 = i;
+            }
+            return null;
+        }
+
+        /** How far out of place is e? */
+        private static int entryDislocation(Entry<?>[] cache, int pos, Entry<?> e) {
+            ClassValue<?> cv = e.classValueOrNull();
+            if (cv == null)  return 0;  // entry is not live!
+            int mask = (cache.length-1);
+            return (pos - cv.hashCodeForCache) & mask;
+        }
+
+        /// --------
+        /// Below this line all functions are private, and assume synchronized access.
+        /// --------
+
+        private void sizeCache(int length) {
+            assert((length & (length-1)) == 0);  // must be power of 2
+            cacheLoad = 0;
+            cacheLoadLimit = (int) ((double) length * CACHE_LOAD_LIMIT / 100);
+            cacheArray = new Entry<?>[length];
+        }
+
+        /** Make sure the cache load stays below its limit, if possible. */
+        private void checkCacheLoad() {
+            if (cacheLoad >= cacheLoadLimit) {
+                reduceCacheLoad();
+            }
+        }
+        private void reduceCacheLoad() {
+            removeStaleEntries();
+            if (cacheLoad < cacheLoadLimit)
+                return;  // win
+            Entry<?>[] oldCache = getCache();
+            if (oldCache.length > HASH_MASK)
+                return;  // lose
+            sizeCache(oldCache.length * 2);
+            for (Entry<?> e : oldCache) {
+                if (e != null && e.isLive()) {
+                    addToCache(e);
+                }
+            }
+        }
+
+        /** Remove stale entries in the given range.
+         *  Should be executed under a Map lock.
+         */
+        private void removeStaleEntries(Entry<?>[] cache, int begin, int count) {
+            if (PROBE_LIMIT <= 0)  return;
+            int mask = (cache.length-1);
+            int removed = 0;
+            for (int i = begin; i < begin + count; i++) {
+                Entry<?> e = cache[i & mask];
+                if (e == null || e.isLive())
+                    continue;  // skip null and live entries
+                Entry<?> replacement = null;
+                if (PROBE_LIMIT > 1) {
+                    // avoid breaking up a non-null run
+                    replacement = findReplacement(cache, i);
+                }
+                cache[i & mask] = replacement;
+                if (replacement == null)  removed += 1;
+            }
+            cacheLoad = Math.max(0, cacheLoad - removed);
+        }
+
+        /** Clearing a cache slot risks disconnecting following entries
+         *  from the head of a non-null run, which would allow them
+         *  to be found via reprobes.  Find an entry after cache[begin]
+         *  to plug into the hole, or return null if none is needed.
+         */
+        private Entry<?> findReplacement(Entry<?>[] cache, int home1) {
+            Entry<?> replacement = null;
+            int haveReplacement = -1, replacementPos = 0;
+            int mask = (cache.length-1);
+            for (int i2 = home1 + 1; i2 < home1 + PROBE_LIMIT; i2++) {
+                Entry<?> e2 = cache[i2 & mask];
+                if (e2 == null)  break;  // End of non-null run.
+                if (!e2.isLive())  continue;  // Doomed anyway.
+                int dis2 = entryDislocation(cache, i2, e2);
+                if (dis2 == 0)  continue;  // e2 already optimally placed
+                int home2 = i2 - dis2;
+                if (home2 <= home1) {
+                    // e2 can replace entry at cache[home1]
+                    if (home2 == home1) {
+                        // Put e2 exactly where he belongs.
+                        haveReplacement = 1;
+                        replacementPos = i2;
+                        replacement = e2;
+                    } else if (haveReplacement <= 0) {
+                        haveReplacement = 0;
+                        replacementPos = i2;
+                        replacement = e2;
+                    }
+                    // And keep going, so we can favor larger dislocations.
+                }
+            }
+            if (haveReplacement >= 0) {
+                if (cache[(replacementPos+1) & mask] != null) {
+                    // Be conservative, to avoid breaking up a non-null run.
+                    cache[replacementPos & mask] = (Entry<?>) Entry.DEAD_ENTRY;
+                } else {
+                    cache[replacementPos & mask] = null;
+                    cacheLoad -= 1;
+                }
+            }
+            return replacement;
+        }
+
+        /** Remove stale entries in the range near classValue. */
+        private void removeStaleEntries(ClassValue<?> classValue) {
+            removeStaleEntries(getCache(), classValue.hashCodeForCache, PROBE_LIMIT);
+        }
+
+        /** Remove all stale entries, everywhere. */
+        private void removeStaleEntries() {
+            Entry[] cache = getCache();
+            removeStaleEntries(cache, 0, cache.length + PROBE_LIMIT - 1);
+        }
+
+        /** Add the given entry to the cache, in its home location, unless it is out of date. */
+        private <T> void addToCache(Entry<T> e) {
+            ClassValue<T> classValue = e.classValueOrNull();
+            if (classValue != null)
+                addToCache(classValue, e);
+        }
+
+        /** Add the given entry to the cache, in its home location. */
+        private <T> void addToCache(ClassValue<T> classValue, Entry<T> e) {
+            if (PROBE_LIMIT <= 0)  return;  // do not fill cache
+            // Add e to the cache.
+            Entry<?>[] cache = getCache();
+            int mask = (cache.length-1);
+            int home = classValue.hashCodeForCache & mask;
+            Entry<?> e2 = placeInCache(cache, home, e, false);
+            if (e2 == null)  return;  // done
+            if (PROBE_LIMIT > 1) {
+                // try to move e2 somewhere else in his probe range
+                int dis2 = entryDislocation(cache, home, e2);
+                int home2 = home - dis2;
+                for (int i2 = home2; i2 < home2 + PROBE_LIMIT; i2++) {
+                    if (placeInCache(cache, i2 & mask, e2, true) == null) {
+                        return;
+                    }
+                }
+            }
+            // Note:  At this point, e2 is just dropped from the cache.
+        }
+
+        /** Store the given entry.  Update cacheLoad, and return any live victim.
+         *  'Gently' means return self rather than dislocating a live victim.
+         */
+        private Entry<?> placeInCache(Entry<?>[] cache, int pos, Entry<?> e, boolean gently) {
+            Entry<?> e2 = overwrittenEntry(cache[pos]);
+            if (gently && e2 != null) {
+                // do not overwrite a live entry
+                return e;
+            } else {
+                cache[pos] = e;
+                return e2;
+            }
+        }
+
+        /** Note an entry that is about to be overwritten.
+         *  If it is not live, quietly replace it by null.
+         *  If it is an actual null, increment cacheLoad,
+         *  because the caller is going to store something
+         *  in its place.
+         */
+        private <T> Entry<T> overwrittenEntry(Entry<T> e2) {
+            if (e2 == null)  cacheLoad += 1;
+            else if (e2.isLive())  return e2;
+            return null;
+        }
+
+        /** Percent loading of cache before resize. */
+        private static final int CACHE_LOAD_LIMIT = 67;  // 0..100
+        /** Maximum number of probes to attempt. */
+        private static final int PROBE_LIMIT      =  6;       // 1..
+        // N.B.  Set PROBE_LIMIT=0 to disable all fast paths.
     }
 }
--- a/jdk/src/share/classes/java/lang/Math.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/Math.java	Fri Jan 27 09:04:57 2012 +0100
@@ -818,8 +818,9 @@
         return (a >= b) ? a : b;
     }
 
-    private static long negativeZeroFloatBits = Float.floatToIntBits(-0.0f);
-    private static long negativeZeroDoubleBits = Double.doubleToLongBits(-0.0d);
+    // Use raw bit-wise conversions on guaranteed non-NaN arguments.
+    private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
+    private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
 
     /**
      * Returns the greater of two {@code float} values.  That is,
@@ -836,9 +837,12 @@
      * @return  the larger of {@code a} and {@code b}.
      */
     public static float max(float a, float b) {
-        if (a != a) return a;   // a is NaN
-        if ((a == 0.0f) && (b == 0.0f)
-            && (Float.floatToIntBits(a) == negativeZeroFloatBits)) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0f) &&
+            (b == 0.0f) &&
+            (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
             return b;
         }
         return (a >= b) ? a : b;
@@ -859,9 +863,12 @@
      * @return  the larger of {@code a} and {@code b}.
      */
     public static double max(double a, double b) {
-        if (a != a) return a;   // a is NaN
-        if ((a == 0.0d) && (b == 0.0d)
-            && (Double.doubleToLongBits(a) == negativeZeroDoubleBits)) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0d) &&
+            (b == 0.0d) &&
+            (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
             return b;
         }
         return (a >= b) ? a : b;
@@ -910,9 +917,12 @@
      * @return  the smaller of {@code a} and {@code b}.
      */
     public static float min(float a, float b) {
-        if (a != a) return a;   // a is NaN
-        if ((a == 0.0f) && (b == 0.0f)
-            && (Float.floatToIntBits(b) == negativeZeroFloatBits)) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0f) &&
+            (b == 0.0f) &&
+            (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
             return b;
         }
         return (a <= b) ? a : b;
@@ -933,9 +943,12 @@
      * @return  the smaller of {@code a} and {@code b}.
      */
     public static double min(double a, double b) {
-        if (a != a) return a;   // a is NaN
-        if ((a == 0.0d) && (b == 0.0d)
-            && (Double.doubleToLongBits(b) == negativeZeroDoubleBits)) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0d) &&
+            (b == 0.0d) &&
+            (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
             return b;
         }
         return (a <= b) ? a : b;
@@ -1900,7 +1913,7 @@
     /**
      * Returns a floating-point power of two in the normal range.
      */
-    public static float powerOfTwoF(int n) {
+    static float powerOfTwoF(int n) {
         assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT);
         return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) <<
                                      (FloatConsts.SIGNIFICAND_WIDTH-1))
--- a/jdk/src/share/classes/java/lang/Object.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/Object.java	Fri Jan 27 09:04:57 2012 +0100
@@ -58,8 +58,7 @@
      *
      * @return The {@code Class} object that represents the runtime
      *         class of this object.
-     * @see    Class Literals, section 15.8.2 of
-     *         <cite>The Java&trade; Language Specification</cite>.
+     * @jls 15.8.2 Class Literals
      */
     public final native Class<?> getClass();
 
@@ -92,7 +91,7 @@
      * objects. (This is typically implemented by converting the internal
      * address of the object into an integer, but this implementation
      * technique is not required by the
-     * Java<font size="-2"><sup>TM</sup></font> programming language.)
+     * Java&trade; programming language.)
      *
      * @return  a hash code value for this object.
      * @see     java.lang.Object#equals(java.lang.Object)
@@ -203,7 +202,7 @@
      * exception at run time.
      *
      * @return     a clone of this instance.
-     * @exception  CloneNotSupportedException  if the object's class does not
+     * @throws  CloneNotSupportedException  if the object's class does not
      *               support the {@code Cloneable} interface. Subclasses
      *               that override the {@code clone} method can also
      *               throw this exception to indicate that an instance cannot
@@ -264,7 +263,7 @@
      * <p>
      * Only one thread at a time can own an object's monitor.
      *
-     * @exception  IllegalMonitorStateException  if the current thread is not
+     * @throws  IllegalMonitorStateException  if the current thread is not
      *               the owner of this object's monitor.
      * @see        java.lang.Object#notifyAll()
      * @see        java.lang.Object#wait()
@@ -288,7 +287,7 @@
      * description of the ways in which a thread can become the owner of
      * a monitor.
      *
-     * @exception  IllegalMonitorStateException  if the current thread is not
+     * @throws  IllegalMonitorStateException  if the current thread is not
      *               the owner of this object's monitor.
      * @see        java.lang.Object#notify()
      * @see        java.lang.Object#wait()
@@ -368,11 +367,11 @@
      * a monitor.
      *
      * @param      timeout   the maximum time to wait in milliseconds.
-     * @exception  IllegalArgumentException      if the value of timeout is
+     * @throws  IllegalArgumentException      if the value of timeout is
      *               negative.
-     * @exception  IllegalMonitorStateException  if the current thread is not
+     * @throws  IllegalMonitorStateException  if the current thread is not
      *               the owner of the object's monitor.
-     * @exception  InterruptedException if any thread interrupted the
+     * @throws  InterruptedException if any thread interrupted the
      *             current thread before or while the current thread
      *             was waiting for a notification.  The <i>interrupted
      *             status</i> of the current thread is cleared when
@@ -433,12 +432,12 @@
      * @param      timeout   the maximum time to wait in milliseconds.
      * @param      nanos      additional time, in nanoseconds range
      *                       0-999999.
-     * @exception  IllegalArgumentException      if the value of timeout is
+     * @throws  IllegalArgumentException      if the value of timeout is
      *                      negative or the value of nanos is
      *                      not in the range 0-999999.
-     * @exception  IllegalMonitorStateException  if the current thread is not
+     * @throws  IllegalMonitorStateException  if the current thread is not
      *               the owner of this object's monitor.
-     * @exception  InterruptedException if any thread interrupted the
+     * @throws  InterruptedException if any thread interrupted the
      *             current thread before or while the current thread
      *             was waiting for a notification.  The <i>interrupted
      *             status</i> of the current thread is cleared when
@@ -489,9 +488,9 @@
      * description of the ways in which a thread can become the owner of
      * a monitor.
      *
-     * @exception  IllegalMonitorStateException  if the current thread is not
+     * @throws  IllegalMonitorStateException  if the current thread is not
      *               the owner of the object's monitor.
-     * @exception  InterruptedException if any thread interrupted the
+     * @throws  InterruptedException if any thread interrupted the
      *             current thread before or while the current thread
      *             was waiting for a notification.  The <i>interrupted
      *             status</i> of the current thread is cleared when
@@ -510,7 +509,7 @@
      * system resources or to perform other cleanup.
      * <p>
      * The general contract of {@code finalize} is that it is invoked
-     * if and when the Java<font size="-2"><sup>TM</sup></font> virtual
+     * if and when the Java&trade; virtual
      * machine has determined that there is no longer any
      * means by which this object can be accessed by any thread that has
      * not yet died, except as a result of an action taken by the
@@ -549,6 +548,9 @@
      * ignored.
      *
      * @throws Throwable the {@code Exception} raised by this method
+     * @see java.lang.ref.WeakReference
+     * @see java.lang.ref.PhantomReference
+     * @jls 12.6 Finalization of Class Instances
      */
     protected void finalize() throws Throwable { }
 }
--- a/jdk/src/share/classes/java/lang/StrictMath.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/StrictMath.java	Fri Jan 27 09:04:57 2012 +0100
@@ -161,6 +161,8 @@
      *          in radians.
      */
     public static strictfp double toRadians(double angdeg) {
+        // Do not delegate to Math.toRadians(angdeg) because
+        // this method has the strictfp modifier.
         return angdeg / 180.0 * PI;
     }
 
@@ -176,6 +178,8 @@
      *          in degrees.
      */
     public static strictfp double toDegrees(double angrad) {
+        // Do not delegate to Math.toDegrees(angrad) because
+        // this method has the strictfp modifier.
         return angrad * 180.0 / PI;
     }
 
@@ -708,7 +712,7 @@
      * @return  the absolute value of the argument.
      */
     public static int abs(int a) {
-        return (a < 0) ? -a : a;
+        return Math.abs(a);
     }
 
     /**
@@ -725,7 +729,7 @@
      * @return  the absolute value of the argument.
      */
     public static long abs(long a) {
-        return (a < 0) ? -a : a;
+        return Math.abs(a);
     }
 
     /**
@@ -744,7 +748,7 @@
      * @return  the absolute value of the argument.
      */
     public static float abs(float a) {
-        return (a <= 0.0F) ? 0.0F - a : a;
+        return Math.abs(a);
     }
 
     /**
@@ -763,7 +767,7 @@
      * @return  the absolute value of the argument.
      */
     public static double abs(double a) {
-        return (a <= 0.0D) ? 0.0D - a : a;
+        return Math.abs(a);
     }
 
     /**
@@ -777,7 +781,7 @@
      * @return  the larger of {@code a} and {@code b}.
      */
     public static int max(int a, int b) {
-        return (a >= b) ? a : b;
+        return Math.max(a, b);
     }
 
     /**
@@ -791,13 +795,9 @@
      * @return  the larger of {@code a} and {@code b}.
         */
     public static long max(long a, long b) {
-        return (a >= b) ? a : b;
+        return Math.max(a, b);
     }
 
-    // Use raw bit-wise conversions on guaranteed non-NaN arguments.
-    private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
-    private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
-
     /**
      * Returns the greater of two {@code float} values.  That is,
      * the result is the argument closer to positive infinity. If the
@@ -813,15 +813,7 @@
      * @return  the larger of {@code a} and {@code b}.
      */
     public static float max(float a, float b) {
-        if (a != a)
-            return a;   // a is NaN
-        if ((a == 0.0f) &&
-            (b == 0.0f) &&
-            (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
-            // Raw conversion ok since NaN can't map to -0.0.
-            return b;
-        }
-        return (a >= b) ? a : b;
+        return Math.max(a, b);
     }
 
     /**
@@ -839,15 +831,7 @@
      * @return  the larger of {@code a} and {@code b}.
      */
     public static double max(double a, double b) {
-        if (a != a)
-            return a;   // a is NaN
-        if ((a == 0.0d) &&
-            (b == 0.0d) &&
-            (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
-            // Raw conversion ok since NaN can't map to -0.0.
-            return b;
-        }
-        return (a >= b) ? a : b;
+        return Math.max(a, b);
     }
 
     /**
@@ -861,7 +845,7 @@
      * @return  the smaller of {@code a} and {@code b}.
      */
     public static int min(int a, int b) {
-        return (a <= b) ? a : b;
+        return Math.min(a, b);
     }
 
     /**
@@ -875,7 +859,7 @@
      * @return  the smaller of {@code a} and {@code b}.
      */
     public static long min(long a, long b) {
-        return (a <= b) ? a : b;
+        return Math.min(a, b);
     }
 
     /**
@@ -893,15 +877,7 @@
      * @return  the smaller of {@code a} and {@code b.}
      */
     public static float min(float a, float b) {
-        if (a != a)
-            return a;   // a is NaN
-        if ((a == 0.0f) &&
-            (b == 0.0f) &&
-            (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
-            // Raw conversion ok since NaN can't map to -0.0.
-            return b;
-        }
-        return (a <= b) ? a : b;
+        return Math.min(a, b);
     }
 
     /**
@@ -919,15 +895,7 @@
      * @return  the smaller of {@code a} and {@code b}.
      */
     public static double min(double a, double b) {
-        if (a != a)
-            return a;   // a is NaN
-        if ((a == 0.0d) &&
-            (b == 0.0d) &&
-            (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
-            // Raw conversion ok since NaN can't map to -0.0.
-            return b;
-        }
-        return (a <= b) ? a : b;
+        return Math.min(a, b);
     }
 
     /**
--- a/jdk/src/share/classes/java/lang/Throwable.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/Throwable.java	Fri Jan 27 09:04:57 2012 +0100
@@ -625,7 +625,7 @@
      *          at Resource2.close(Resource2.java:20)
      *          at Foo4.main(Foo4.java:5)
      *  Caused by: java.lang.Exception: Rats, you caught me
-     *          at Resource2$CloseFailException.<init>(Resource2.java:45)
+     *          at Resource2$CloseFailException.&lt;init&gt;(Resource2.java:45)
      *          ... 2 more
      * </pre>
      */
--- a/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java	Fri Jan 27 09:04:57 2012 +0100
@@ -378,6 +378,7 @@
     }
 
     /** Construct an adapter conversion descriptor for a single-argument conversion. */
+    @SuppressWarnings("cast")  // some (int) casts below provide clarity but trigger warnings
     private static long makeConv(int convOp, int argnum, int src, int dest) {
         assert(src  == (src  & CONV_TYPE_MASK));
         assert(dest == (dest & CONV_TYPE_MASK));
@@ -390,6 +391,7 @@
                 insertStackMove(stackMove)
                 );
     }
+    @SuppressWarnings("cast")  // some (int) casts below provide clarity but trigger warnings
     private static long makeDupConv(int convOp, int argnum, int stackMove) {
         // simple argument motion, requiring one slot to specify
         assert(convOp == OP_DUP_ARGS || convOp == OP_DROP_ARGS);
@@ -401,6 +403,7 @@
                 insertStackMove(stackMove)
                 );
     }
+    @SuppressWarnings("cast")  // some (int) casts below provide clarity but trigger warnings
     private static long makeSwapConv(int convOp, int srcArg, byte srcType, int destSlot, byte destType) {
         // more complex argument motion, requiring two slots to specify
         assert(convOp == OP_SWAP_ARGS || convOp == OP_ROT_ARGS);
@@ -411,6 +414,7 @@
                 (int)  destSlot << CONV_VMINFO_SHIFT
                 );
     }
+    @SuppressWarnings("cast")  // some (int) casts below provide clarity but trigger warnings
     private static long makeSpreadConv(int convOp, int argnum, int src, int dest, int stackMove) {
         // spreading or collecting, at a particular slot location
         assert(convOp == OP_SPREAD_ARGS || convOp == OP_COLLECT_ARGS || convOp == OP_FOLD_ARGS);
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java	Fri Jan 27 09:04:57 2012 +0100
@@ -353,7 +353,7 @@
         assert(isResolved());
     }
     /** Create a name for the given reflected constructor.  The resulting name will be in a resolved state. */
-    public MemberName(Constructor ctor) {
+    public MemberName(Constructor<?> ctor) {
         Object[] typeInfo = { void.class, ctor.getParameterTypes() };
         init(ctor.getDeclaringClass(), CONSTRUCTOR_NAME, typeInfo, flagsMods(IS_CONSTRUCTOR, ctor.getModifiers()));
         // fill in vmtarget, vmindex while we have ctor in hand:
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java	Fri Jan 27 09:04:57 2012 +0100
@@ -275,7 +275,7 @@
  * generates a single invokevirtual instruction with
  * the symbolic type descriptor indicated in the following comment.
  * In these examples, the helper method {@code assertEquals} is assumed to
- * be a method which calls {@link Objects.equals java.util.Objects#equals}
+ * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals }
  * on its arguments, and asserts that the result is true.
  *
  * <h3>Exceptions</h3>
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Fri Jan 27 09:04:57 2012 +0100
@@ -112,7 +112,7 @@
         assert(cookedConstructor.type().equals(ctype));
         ctype = ctype.dropParameterTypes(0, 1);
         cookedConstructor = AdapterMethodHandle.makeCollectArguments(cookedConstructor, returner, 0, true);
-        MethodHandle allocator = new AllocateObject(allocateClass);
+        AllocateObject allocator = new AllocateObject(allocateClass);
         // allocate() => new C(void)
         assert(allocator.type().equals(MethodType.methodType(allocateClass)));
         ctype = ctype.dropParameterTypes(0, 1);
@@ -120,19 +120,19 @@
         return fold;
     }
 
-    static final class AllocateObject<C> extends BoundMethodHandle {
+    static final class AllocateObject /*<C>*/ extends BoundMethodHandle {
         private static final Unsafe unsafe = Unsafe.getUnsafe();
 
-        private final Class<C> allocateClass;
+        private final Class<?> /*<C>*/ allocateClass;
 
         // for allocation only:
-        private AllocateObject(Class<C> allocateClass) {
+        private AllocateObject(Class<?> /*<C>*/ allocateClass) {
             super(ALLOCATE.asType(MethodType.methodType(allocateClass, AllocateObject.class)));
             this.allocateClass = allocateClass;
         }
         @SuppressWarnings("unchecked")
-        private C allocate() throws InstantiationException {
-            return (C) unsafe.allocateInstance(allocateClass);
+        private Object /*C*/ allocate() throws InstantiationException {
+            return unsafe.allocateInstance(allocateClass);
         }
         static final MethodHandle ALLOCATE;
         static {
@@ -148,8 +148,8 @@
     MethodHandle accessField(MemberName member, boolean isSetter,
                              Class<?> lookupClass) {
         // Use sun. misc.Unsafe to dig up the dirt on the field.
-        MethodHandle mh = new FieldAccessor(member, isSetter);
-        return mh;
+        FieldAccessor accessor = new FieldAccessor(member, isSetter);
+        return accessor;
     }
 
     static
@@ -175,7 +175,7 @@
         return mhs[isSetter ? 1 : 0];
     }
 
-    static final class FieldAccessor<C,V> extends BoundMethodHandle {
+    static final class FieldAccessor /*<C,V>*/ extends BoundMethodHandle {
         private static final Unsafe unsafe = Unsafe.getUnsafe();
         final Object base;  // for static refs only
         final long offset;
@@ -190,26 +190,24 @@
         @Override
         String debugString() { return addTypeString(name, this); }
 
-        int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
-        void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); }
-        long getFieldJ(C obj) { return unsafe.getLong(obj, offset); }
-        void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); }
-        float getFieldF(C obj) { return unsafe.getFloat(obj, offset); }
-        void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); }
-        double getFieldD(C obj) { return unsafe.getDouble(obj, offset); }
-        void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); }
-        boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); }
-        void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
-        byte getFieldB(C obj) { return unsafe.getByte(obj, offset); }
-        void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); }
-        short getFieldS(C obj) { return unsafe.getShort(obj, offset); }
-        void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); }
-        char getFieldC(C obj) { return unsafe.getChar(obj, offset); }
-        void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); }
-        @SuppressWarnings("unchecked")
-        V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); }
-        @SuppressWarnings("unchecked")
-        void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); }
+        int getFieldI(Object /*C*/ obj) { return unsafe.getInt(obj, offset); }
+        void setFieldI(Object /*C*/ obj, int x) { unsafe.putInt(obj, offset, x); }
+        long getFieldJ(Object /*C*/ obj) { return unsafe.getLong(obj, offset); }
+        void setFieldJ(Object /*C*/ obj, long x) { unsafe.putLong(obj, offset, x); }
+        float getFieldF(Object /*C*/ obj) { return unsafe.getFloat(obj, offset); }
+        void setFieldF(Object /*C*/ obj, float x) { unsafe.putFloat(obj, offset, x); }
+        double getFieldD(Object /*C*/ obj) { return unsafe.getDouble(obj, offset); }
+        void setFieldD(Object /*C*/ obj, double x) { unsafe.putDouble(obj, offset, x); }
+        boolean getFieldZ(Object /*C*/ obj) { return unsafe.getBoolean(obj, offset); }
+        void setFieldZ(Object /*C*/ obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
+        byte getFieldB(Object /*C*/ obj) { return unsafe.getByte(obj, offset); }
+        void setFieldB(Object /*C*/ obj, byte x) { unsafe.putByte(obj, offset, x); }
+        short getFieldS(Object /*C*/ obj) { return unsafe.getShort(obj, offset); }
+        void setFieldS(Object /*C*/ obj, short x) { unsafe.putShort(obj, offset, x); }
+        char getFieldC(Object /*C*/ obj) { return unsafe.getChar(obj, offset); }
+        void setFieldC(Object /*C*/ obj, char x) { unsafe.putChar(obj, offset, x); }
+        Object /*V*/ getFieldL(Object /*C*/ obj) { return unsafe.getObject(obj, offset); }
+        void setFieldL(Object /*C*/ obj, Object /*V*/ x) { unsafe.putObject(obj, offset, x); }
         // cast (V) is OK here, since we wrap convertArguments around the MH.
 
         static Object staticBase(final MemberName field) {
@@ -244,8 +242,9 @@
         void setStaticS(short x) { unsafe.putShort(base, offset, x); }
         char getStaticC() { return unsafe.getChar(base, offset); }
         void setStaticC(char x) { unsafe.putChar(base, offset, x); }
-        V getStaticL() { return (V) unsafe.getObject(base, offset); }
-        void setStaticL(V x) { unsafe.putObject(base, offset, x); }
+        @SuppressWarnings("unchecked")  // (V) is for internal clarity but triggers warning
+        Object /*V*/ getStaticL() { return unsafe.getObject(base, offset); }
+        void setStaticL(Object /*V*/ x) { unsafe.putObject(base, offset, x); }
 
         static String fname(Class<?> vclass, boolean isSetter, boolean isStatic) {
             String stem;
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java	Fri Jan 27 09:04:57 2012 +0100
@@ -150,7 +150,7 @@
         }
         return intfc.cast(Proxy.newProxyInstance(
                 intfc.getClassLoader(),
-                new Class[]{ intfc, WrapperInstance.class },
+                new Class<?>[]{ intfc, WrapperInstance.class },
                 new InvocationHandler() {
                     private Object getArg(String name) {
                         if ((Object)name == "getWrapperInstanceTarget")  return target;
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Fri Jan 27 09:04:57 2012 +0100
@@ -948,10 +948,11 @@
         public MethodHandle unreflect(Method m) throws IllegalAccessException {
             MemberName method = new MemberName(m);
             assert(method.isMethod());
-            if (!m.isAccessible())  checkMethod(method.getDeclaringClass(), method, method.isStatic());
+            if (m.isAccessible())
+                return MethodHandleImpl.findMethod(method, true, /*no lookupClass*/ null);
+            checkMethod(method.getDeclaringClass(), method, method.isStatic());
             MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
-            if (!m.isAccessible())  mh = restrictProtectedReceiver(method, mh);
-            return mh;
+            return restrictProtectedReceiver(method, mh);
         }
 
         /**
@@ -1006,11 +1007,17 @@
          *                                is set and {@code asVarargsCollector} fails
          * @throws NullPointerException if the argument is null
          */
+        @SuppressWarnings("rawtypes")  // Will be Constructor<?> after JSR 292 MR
         public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
             MemberName ctor = new MemberName(c);
             assert(ctor.isConstructor());
-            if (!c.isAccessible())  checkAccess(c.getDeclaringClass(), ctor);
-            MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
+            MethodHandle rawCtor;
+            if (c.isAccessible()) {
+                rawCtor = MethodHandleImpl.findMethod(ctor, false, /*no lookupClass*/ null);
+            } else {
+                checkAccess(c.getDeclaringClass(), ctor);
+                rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
+            }
             MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
             return fixVarargs(allocator, rawCtor);
         }
@@ -1225,7 +1232,7 @@
                                                 ? "expected a static field"
                                                 : "expected a non-static field", this);
             if (trusted)
-                return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
+                return MethodHandleImpl.accessField(field, isSetter, /*no lookupClass*/ null);
             checkAccess(refc, field);
             MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
             return restrictProtectedReceiver(field, mh);
--- a/jdk/src/share/classes/java/net/ContentHandler.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/net/ContentHandler.java	Fri Jan 27 09:04:57 2012 +0100
@@ -96,7 +96,7 @@
      * @exception  IOException  if an I/O error occurs while reading the object.
      * @since 1.3
      */
-    public Object getContent(URLConnection urlc, Class<?>[] classes) throws IOException {
+    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
         Object obj = getContent(urlc);
 
         for (int i = 0; i < classes.length; i++) {
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Fri Jan 27 09:04:57 2012 +0100
@@ -92,7 +92,7 @@
             (System.getSecurityManager() == null))
         {
             BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
-            if (!followLinks || !cached.isSymbolicLink())
+            if (cached != null && (!followLinks || !cached.isSymbolicLink()))
                 attrs = cached;
         }
         IOException exc = null;
--- a/jdk/src/share/classes/java/nio/file/Files.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/nio/file/Files.java	Fri Jan 27 09:04:57 2012 +0100
@@ -1431,7 +1431,7 @@
      * <li>It is <i>transitive</i>: for three {@code Paths}
      *     {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
      *     {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
-     *     {@code isSameFile(g,h)} will return return {@code true}.
+     *     {@code isSameFile(f,h)} will return return {@code true}.
      * </ul>
      *
      * @param   path
--- a/jdk/src/share/classes/java/nio/file/Path.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/nio/file/Path.java	Fri Jan 27 09:04:57 2012 +0100
@@ -72,7 +72,7 @@
  * directory and is UTF-8 encoded.
  * <pre>
  *     Path path = FileSystems.getDefault().getPath("logs", "access.log");
- *     BufferReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
+ *     BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
  * </pre>
  *
  * <a name="interop"><h4>Interoperability</h4></a>
--- a/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java	Thu Jan 26 14:14:55 2012 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java	Fri Jan 27 09:04:57 2012 +0100
@@ -175,9 +175,15 @@
          *          AclEntryPermission}
          */
         public Builder setPermissions(Set<AclEntryPermission> perms) {
-            // copy and check for erroneous elements
-