changeset 14392:b5c8a61d7fa0

Merge
author kvn
date Fri, 21 Jun 2013 15:56:24 -0700
parents d2907f74462e (current diff) aaa45012be98 (diff)
children f4f6ae481e1a
files make/Makefile src/os/bsd/vm/os_bsd.cpp src/os/linux/vm/os_linux.cpp src/share/vm/compiler/compileBroker.cpp src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp src/share/vm/opto/compile.cpp src/share/vm/opto/matcher.cpp src/share/vm/runtime/deoptimization.cpp src/share/vm/runtime/frame.cpp src/share/vm/runtime/frame.hpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/sharedRuntime.hpp src/share/vm/runtime/stubRoutines.hpp src/share/vm/runtime/vmStructs.cpp src/share/vm/trace/traceEventTypes.hpp src/share/vm/utilities/macros.hpp
diffstat 297 files changed, 10882 insertions(+), 2416 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Jun 20 16:30:44 2013 -0700
+++ b/.hgtags	Fri Jun 21 15:56:24 2013 -0700
@@ -347,3 +347,8 @@
 38da9f4f67096745f851318d792d6468aa1f6cf8 hs25-b34
 092018493d3bbeb1c24278fd8c40ff3d76e1fed7 jdk8-b92
 573d86d412cd9d3df7912194c1a540be50e9544e jdk8-b93
+b786c04b7be15194febe88dc1f0c9443e737a84b hs25-b35
+3c78a14da19d26d6937af5f98b97e2a21c653b04 hs25-b36
+1beed1f6f9edefe47ba8ed1355fbd3e7606b8288 jdk8-b94
+69689078dff8b21e6df30870464f5d736eebdf72 hs25-b37
+5d65c078cd0ac455aa5e58a09844c7acce54b487 jdk8-b95
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java	Fri Jun 21 15:56:24 2013 -0700
@@ -96,9 +96,10 @@
 
   public boolean containsProtectionDomain(Oop protectionDomain) {
     InstanceKlass ik = (InstanceKlass) klass();
-    if (protectionDomain.equals(ik.getProtectionDomain())) {
-      return true; // Succeeds trivially
-    }
+    // Currently unimplemented and not used.
+    // if (protectionDomain.equals(ik.getJavaMirror().getProtectionDomain())) {
+    //   return true; // Succeeds trivially
+    // }
     for (ProtectionDomainEntry current = pdSet(); current != null;
                                        current = current.next()) {
       if (protectionDomain.equals(current.protectionDomain())) {
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Fri Jun 21 15:56:24 2013 -0700
@@ -75,8 +75,6 @@
     javaFieldsCount      = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
     constants            = new MetadataField(type.getAddressField("_constants"), 0);
     classLoaderData      = type.getAddressField("_class_loader_data");
-    protectionDomain     = new OopField(type.getOopField("_protection_domain"), 0);
-    signers              = new OopField(type.getOopField("_signers"), 0);
     sourceFileName       = type.getAddressField("_source_file_name");
     sourceDebugExtension = type.getAddressField("_source_debug_extension");
     innerClasses         = type.getAddressField("_inner_classes");
@@ -136,8 +134,6 @@
   private static CIntField javaFieldsCount;
   private static MetadataField constants;
   private static AddressField  classLoaderData;
-  private static OopField  protectionDomain;
-  private static OopField  signers;
   private static AddressField  sourceFileName;
   private static AddressField  sourceDebugExtension;
   private static AddressField  innerClasses;
@@ -350,8 +346,6 @@
   public ConstantPool getConstants()        { return (ConstantPool) constants.getValue(this); }
   public ClassLoaderData getClassLoaderData() { return                ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
   public Oop       getClassLoader()         { return                getClassLoaderData().getClassLoader(); }
-  public Oop       getProtectionDomain()    { return                protectionDomain.getValue(this); }
-  public ObjArray  getSigners()             { return (ObjArray)     signers.getValue(this); }
   public Symbol    getSourceFileName()      { return getSymbol(sourceFileName); }
   public String    getSourceDebugExtension(){ return                CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
   public long      getNonstaticFieldSize()  { return                nonstaticFieldSize.getValue(this); }
@@ -541,8 +535,6 @@
     // visitor.doOop(methods, true);
     // visitor.doOop(localInterfaces, true);
     // visitor.doOop(transitiveInterfaces, true);
-      visitor.doOop(protectionDomain, true);
-      visitor.doOop(signers, true);
       visitor.doCInt(nonstaticFieldSize, true);
       visitor.doCInt(staticFieldSize, true);
       visitor.doCInt(staticOopFieldCount, true);
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java	Fri Jun 21 15:56:24 2013 -0700
@@ -204,13 +204,13 @@
                 Oop loader = ik.getClassLoader();
                 writeEdge(instance, loader, "loaded-by");
 
-                // write signers
-                Oop signers = ik.getSigners();
-                writeEdge(instance, signers, "signed-by");
+                // write signers NYI
+                // Oop signers = ik.getJavaMirror().getSigners();
+                writeEdge(instance, null, "signed-by");
 
-                // write protection domain
-                Oop protectionDomain = ik.getProtectionDomain();
-                writeEdge(instance, protectionDomain, "protection-domain");
+                // write protection domain NYI
+                // Oop protectionDomain = ik.getJavaMirror().getProtectionDomain();
+                writeEdge(instance, null, "protection-domain");
 
                 // write edges for static reference fields from this class
                 for (Iterator itr = refFields.iterator(); itr.hasNext();) {
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Fri Jun 21 15:56:24 2013 -0700
@@ -477,8 +477,8 @@
         if (k instanceof InstanceKlass) {
             InstanceKlass ik = (InstanceKlass) k;
             writeObjectID(ik.getClassLoader());
-            writeObjectID(ik.getSigners());
-            writeObjectID(ik.getProtectionDomain());
+            writeObjectID(null);  // ik.getJavaMirror().getSigners());
+            writeObjectID(null);  // ik.getJavaMirror().getProtectionDomain());
             // two reserved id fields
             writeObjectID(null);
             writeObjectID(null);
@@ -516,8 +516,8 @@
                 if (bottomKlass instanceof InstanceKlass) {
                     InstanceKlass ik = (InstanceKlass) bottomKlass;
                     writeObjectID(ik.getClassLoader());
-                    writeObjectID(ik.getSigners());
-                    writeObjectID(ik.getProtectionDomain());
+                    writeObjectID(null); // ik.getJavaMirror().getSigners());
+                    writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
                 } else {
                     writeObjectID(null);
                     writeObjectID(null);
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaInstanceKlass.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaInstanceKlass.java	Fri Jun 21 15:56:24 2013 -0700
@@ -47,8 +47,6 @@
    private static final int FIELD_IS_SYNTHETIC       = 13;
    private static final int FIELD_IS_INTERFACE       = 14;
    private static final int FIELD_CLASS_LOADER       = 15;
-   private static final int FIELD_PROTECTION_DOMAIN  = 16;
-   private static final int FIELD_SIGNERS            = 17;
    private static final int FIELD_STATICS            = 18;
    private static final int FIELD_UNDEFINED          = -1;
 
@@ -100,10 +98,6 @@
          return Boolean.valueOf(ik.isInterface());
       case FIELD_CLASS_LOADER:
          return factory.newJSJavaObject(ik.getClassLoader());
-      case FIELD_PROTECTION_DOMAIN:
-         return factory.newJSJavaObject(ik.getProtectionDomain());
-      case FIELD_SIGNERS:
-         return factory.newJSJavaObject(ik.getSigners());
       case FIELD_STATICS:
          return getStatics();
       case FIELD_UNDEFINED:
@@ -246,8 +240,6 @@
       addField("isSynthetic", FIELD_IS_SYNTHETIC);
       addField("isInterface", FIELD_IS_INTERFACE);
       addField("classLoader", FIELD_CLASS_LOADER);
-      addField("protectionDomain", FIELD_PROTECTION_DOMAIN);
-      addField("signers", FIELD_SIGNERS);
       addField("statics", FIELD_STATICS);
    }
 
--- a/make/Makefile	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/Makefile	Fri Jun 21 15:56:24 2013 -0700
@@ -535,7 +535,7 @@
 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/%
+$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/%
 	$(install-file)
 else
 $(EXPORT_INCLUDE_DIR)/jfr.h:
--- a/make/bsd/makefiles/adlc.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/bsd/makefiles/adlc.make	Fri Jun 21 15:56:24 2013 -0700
@@ -69,7 +69,7 @@
 # CFLAGS_WARN holds compiler options to suppress/enable warnings.
 # Compiler warnings are treated as errors
 ifneq ($(COMPILER_WARNINGS_FATAL),false)
-  CFLAGS_WARN = -Werror
+  CFLAGS_WARN = $(WARNINGS_ARE_ERRORS)
 endif
 CFLAGS += $(CFLAGS_WARN)
 
--- a/make/bsd/makefiles/buildtree.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/bsd/makefiles/buildtree.make	Fri Jun 21 15:56:24 2013 -0700
@@ -47,6 +47,7 @@
 # flags.make	- with macro settings
 # vm.make	- to support making "$(MAKE) -v vm.make" in makefiles
 # adlc.make	-
+# trace.make	- generate tracing event and type definitions
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
 #
@@ -119,6 +120,7 @@
 	$(PLATFORM_DIR)/generated/dependencies \
 	$(PLATFORM_DIR)/generated/adfiles \
 	$(PLATFORM_DIR)/generated/jvmtifiles \
+	$(PLATFORM_DIR)/generated/tracefiles \
 	$(PLATFORM_DIR)/generated/dtracefiles
 
 TARGETS      = debug fastdebug optimized product
@@ -128,7 +130,7 @@
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
 # dtrace.make is used on BSD versions that implement Dtrace (like MacOS X)
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make dtrace.make
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make dtrace.make
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -331,6 +333,16 @@
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
 	) > $@
 
+trace.make: $(BUILDTREE_MAKE)
+	@echo Creating $@ ...
+	$(QUIETLY) ( \
+	$(BUILDTREE_COMMENT); \
+	echo; \
+	echo include flags.make; \
+	echo; \
+	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
+	) > $@
+
 sa.make: $(BUILDTREE_MAKE)
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
--- a/make/bsd/makefiles/gcc.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/bsd/makefiles/gcc.make	Fri Jun 21 15:56:24 2013 -0700
@@ -71,6 +71,11 @@
       CC  = $(CC32)
     endif
 
+    ifeq ($(USE_CLANG), true)
+      CXX = clang++
+      CC  = clang
+    endif
+
     HOSTCXX = $(CXX)
     HOSTCC  = $(CC)
   endif
@@ -79,21 +84,79 @@
 endif
 
 
-# -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
-# prints the numbers (e.g. "2.95", "3.2.1")
-CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
-CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
-
-# check for precompiled headers support
-ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
-# Allow the user to turn off precompiled headers from the command line.
-ifneq ($(USE_PRECOMPILED_HEADER),0)
-PRECOMPILED_HEADER_DIR=.
-PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
-PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
-endif
+ifeq ($(USE_CLANG), true)
+  CC_VER_MAJOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f1)
+  CC_VER_MINOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f2)
+else
+  # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
+  # prints the numbers (e.g. "2.95", "3.2.1")
+  CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
+  CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
 endif
 
+ifeq ($(USE_CLANG), true)
+  # clang has precompiled headers support by default, but the user can switch
+  # it off by using 'USE_PRECOMPILED_HEADER=0'.
+  ifdef LP64
+    ifeq ($(USE_PRECOMPILED_HEADER),)
+      USE_PRECOMPILED_HEADER=1
+    endif
+  else
+    # We don't support precompiled headers on 32-bit builds because there some files are
+    # compiled with -fPIC while others are compiled without (see 'NONPIC_OBJ_FILES' rules.make)
+    # Clang produces an error if the PCH file was compiled with other options than the actual compilation unit.
+    USE_PRECOMPILED_HEADER=0
+  endif
+  
+  ifeq ($(USE_PRECOMPILED_HEADER),1)
+  
+    ifndef LP64
+      $(error " Precompiled Headers only supported on 64-bit platforms!")
+    endif
+  
+    PRECOMPILED_HEADER_DIR=.
+    PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
+    PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.pch
+  
+    PCH_FLAG = -include precompiled.hpp
+    PCH_FLAG/DEFAULT = $(PCH_FLAG)
+    PCH_FLAG/NO_PCH = -DNO_PCH
+    PCH_FLAG/BY_FILE = $(PCH_FLAG/$@)$(PCH_FLAG/DEFAULT$(PCH_FLAG/$@))
+  
+    VM_PCH_FLAG/LIBJVM = $(PCH_FLAG/BY_FILE)
+    VM_PCH_FLAG/AOUT =
+    VM_PCH_FLAG = $(VM_PCH_FLAG/$(LINK_INTO))
+  
+    # We only use precompiled headers for the JVM build
+    CFLAGS += $(VM_PCH_FLAG)
+  
+    # There are some files which don't like precompiled headers
+    # The following files are build with 'OPT_CFLAGS/NOOPT' (-O0) in the opt build.
+    # But Clang doesn't support a precompiled header which was compiled with -O3
+    # to be used in a compilation unit which uses '-O0'. We could also prepare an
+    # extra '-O0' PCH file for the opt build and use it here, but it's probably
+    # not worth the effort as long as only two files need this special handling.
+    PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH)
+    PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH)
+    PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH)
+  
+  endif
+else # ($(USE_CLANG), true)
+  # check for precompiled headers support
+  ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
+    # Allow the user to turn off precompiled headers from the command line.
+    ifneq ($(USE_PRECOMPILED_HEADER),0)
+      PRECOMPILED_HEADER_DIR=.
+      PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
+      PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
+    endif
+  endif
+endif
+
+# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
+ifeq ($(USE_PRECOMPILED_HEADER),0)
+  CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
+endif
 
 #------------------------------------------------------------------------
 # Compiler flags
@@ -115,17 +178,31 @@
 CFLAGS += $(VM_PICFLAG)
 CFLAGS += -fno-rtti
 CFLAGS += -fno-exceptions
-CFLAGS += -pthread
-CFLAGS += -fcheck-new
-# version 4 and above support fvisibility=hidden (matches jni_x86.h file)
-# except 4.1.2 gives pointless warnings that can't be disabled (afaik)
-ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
-CFLAGS += -fvisibility=hidden
+ifeq ($(USE_CLANG),)
+  CFLAGS += -pthread
+  CFLAGS += -fcheck-new
+  # version 4 and above support fvisibility=hidden (matches jni_x86.h file)
+  # except 4.1.2 gives pointless warnings that can't be disabled (afaik)
+  ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
+    CFLAGS += -fvisibility=hidden
+  endif
+else
+  CFLAGS += -fvisibility=hidden
+endif
+
+ifeq ($(USE_CLANG), true)
+  # Before Clang 3.1, we had to pass the stack alignment specification directly to llvm with the help of '-mllvm'
+  # Starting with version 3.1, Clang understands the '-mstack-alignment' (and rejects '-mllvm -stack-alignment')
+  ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 1 \) \))" "0"
+    STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mstack-alignment=16
+  else
+    STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mllvm -stack-alignment=16
+  endif
 endif
 
 ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
 ARCHFLAG/i486    = -m32 -march=i586
-ARCHFLAG/amd64   = -m64
+ARCHFLAG/amd64   = -m64 $(STACK_ALIGNMENT_OPT)
 ARCHFLAG/ia64    =
 ARCHFLAG/sparc   = -m32 -mcpu=v9
 ARCHFLAG/sparcv9 = -m64 -mcpu=v9
@@ -163,14 +240,25 @@
   WARNINGS_ARE_ERRORS = -Werror
 endif
 
-# Except for a few acceptable ones
-# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
-# conversions which might affect the values. To avoid that, we need to turn
-# it off explicitly. 
-ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
+ifeq ($(USE_CLANG), true)
+  # However we need to clean the code up before we can unrestrictedly enable this option with Clang
+  WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
+  WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-compare
+# Not yet supported by clang in Xcode 4.6.2
+#  WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare
+  WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
+  WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
+endif
+
 WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
-else
-WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
+
+ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
+  # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
+  # conversions which might affect the values. Only enable it in earlier versions.
+  WARNING_FLAGS = -Wunused-function
+  ifeq ($(USE_CLANG),)
+    WARNINGS_FLAGS += -Wconversion
+  endif
 endif
 
 CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
@@ -214,14 +302,24 @@
 
 OPT_CFLAGS/NOOPT=-O0
 
-# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation. 
-ifneq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) = 3 \) \))" "0"
-OPT_CFLAGS/mulnode.o += -O0
+# Work around some compiler bugs.
+ifeq ($(USE_CLANG), true)
+  ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1)
+    OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
+  endif
+else
+  # 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
+  ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 3), 1)
+    OPT_CFLAGS/mulnode.o += $(OPT_CFLAGS/NOOPT)
+  endif
 endif
 
 # Flags for generating make dependency flags.
-ifneq ("${CC_VER_MAJOR}", "2")
-DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
+DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
+ifeq ($(USE_CLANG),)
+  ifneq ($(CC_VER_MAJOR), 2)
+    DEPFLAGS += -fpch-deps
+  endif
 endif
 
 # -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
@@ -249,13 +347,15 @@
 # statically link libstdc++.so, work with gcc but ignored by g++
 STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
 
-# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
-ifneq ("${CC_VER_MAJOR}", "2")
-STATIC_LIBGCC += -static-libgcc
-endif
+ifeq ($(USE_CLANG),)
+  # statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
+  ifneq ("${CC_VER_MAJOR}", "2")
+    STATIC_LIBGCC += -static-libgcc
+  endif
 
-ifeq ($(BUILDARCH), ia64)
-LFLAGS += -Wl,-relax
+  ifeq ($(BUILDARCH), ia64)
+    LFLAGS += -Wl,-relax
+  endif
 endif
 
 # Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
@@ -296,25 +396,31 @@
 #------------------------------------------------------------------------
 # Debug flags
 
-# Use the stabs format for debugging information (this is the default
-# on gcc-2.91). It's good enough, has all the information about line
-# numbers and local variables, and libjvm.so is only about 16M.
-# Change this back to "-g" if you want the most expressive format.
-# (warning: that could easily inflate libjvm.so to 150M!)
-# Note: The Itanium gcc compiler crashes when using -gstabs.
-DEBUG_CFLAGS/ia64  = -g
-DEBUG_CFLAGS/amd64 = -g
-DEBUG_CFLAGS/arm   = -g
-DEBUG_CFLAGS/ppc   = -g
-DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
-ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
-DEBUG_CFLAGS += -gstabs
+ifeq ($(USE_CLANG), true)
+  # Restrict the debug information created by Clang to avoid
+  # too big object files and speed the build up a little bit
+  # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+  CFLAGS += -flimit-debug-info
 endif
 
-# DEBUG_BINARIES overrides everything, use full -g debug information
+# DEBUG_BINARIES uses full -g debug information for all configs
 ifeq ($(DEBUG_BINARIES), true)
-  DEBUG_CFLAGS = -g
-  CFLAGS += $(DEBUG_CFLAGS)
+  CFLAGS += -g
+else
+  # Use the stabs format for debugging information (this is the default
+  # on gcc-2.91). It's good enough, has all the information about line
+  # numbers and local variables, and libjvm.so is only about 16M.
+  # Change this back to "-g" if you want the most expressive format.
+  # (warning: that could easily inflate libjvm.so to 150M!)
+  # Note: The Itanium gcc compiler crashes when using -gstabs.
+  DEBUG_CFLAGS/ia64  = -g
+  DEBUG_CFLAGS/amd64 = -g
+  DEBUG_CFLAGS/arm   = -g
+  DEBUG_CFLAGS/ppc   = -g
+  DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
+  ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
+  DEBUG_CFLAGS += -gstabs
+  endif
 endif
 
 # If we are building HEADLESS, pass on to VM
--- a/make/bsd/makefiles/minimal1.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/bsd/makefiles/minimal1.make	Fri Jun 21 15:56:24 2013 -0700
@@ -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.
-#  
+#
 #
 
 TYPE=MINIMAL1
@@ -32,6 +32,7 @@
 INCLUDE_MANAGEMENT ?= false
 INCLUDE_ALL_GCS ?= false
 INCLUDE_NMT ?= false
+INCLUDE_TRACE ?= false
 INCLUDE_CDS ?= false
 
 CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/make/bsd/makefiles/top.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/bsd/makefiles/top.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@
 	@echo All done.
 
 # This is an explicit dependency for the sake of parallel makes.
-vm_build_preliminaries:  checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff dtrace_stuff
+vm_build_preliminaries:  checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff trace_stuff sa_stuff dtrace_stuff
 	@# We need a null action here, so implicit rules don't get consulted.
 
 $(Cached_plat): $(Plat_File)
@@ -94,6 +94,10 @@
 jvmti_stuff: $(Cached_plat) $(adjust-mflags)
 	@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
 
+# generate trace files
+trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
+	@$(MAKE) -f trace.make $(MFLAGS-adjusted)
+
 ifeq ($(OS_VENDOR), Darwin)
 # generate dtrace header files
 dtrace_stuff: $(Cached_plat) $(adjust-mflags)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/bsd/makefiles/trace.make	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+include $(GAMMADIR)/make/bsd/makefiles/rules.make
+include $(GAMMADIR)/make/altsrc.make
+
+# #########################################################################
+
+HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
+  echo "true"; else echo "false";\
+  fi)
+
+TOPDIR      = $(shell echo `pwd`)
+GENERATED   = $(TOPDIR)/../generated
+JvmtiOutDir = $(GENERATED)/jvmtifiles
+TraceOutDir   = $(GENERATED)/tracefiles
+
+TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
+TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
+
+# set VPATH so make knows where to look for source files
+Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
+VPATH += $(Src_Dirs_V:%=%:)
+
+TraceGeneratedNames =     \
+    traceEventClasses.hpp \
+	traceEventIds.hpp     \
+	traceTypes.hpp
+
+ifeq ($(HAS_ALT_SRC), true)
+TraceGeneratedNames +=  \
+	traceRequestables.hpp \
+    traceEventControl.hpp
+
+ifneq ($(INCLUDE_TRACE), false)
+TraceGeneratedNames += traceProducer.cpp
+endif
+
+endif
+
+
+TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
+
+XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS =  $(TraceSrcDir)/trace.xml  $(TraceSrcDir)/tracetypes.xml \
+	$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+ifeq ($(HAS_ALT_SRC), true)
+	XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+all: $(TraceGeneratedFiles)
+
+GENERATE_CODE= \
+  $(QUIETLY) echo Generating $@; \
+  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
+  test -f $@
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+ifeq ($(HAS_ALT_SRC), false)
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+endif
+
+# #########################################################################
+
+
+clean cleanall:
+	rm $(TraceGeneratedFiles)
+
--- a/make/bsd/makefiles/vm.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/bsd/makefiles/vm.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -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.
-#  
+#
 #
 
 # Rules to build JVM and related libraries, included from vm.make in the build
@@ -52,7 +52,7 @@
 # Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
 # The adfiles directory contains ad_<arch>.[ch]pp.
 # The jvmtifiles directory contains jvmti*.[ch]pp
-Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
+Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
 VPATH += $(Src_Dirs_V:%=%:)
 
 # set INCLUDES for C preprocessor.
@@ -66,7 +66,7 @@
   SYMFLAG =
 endif
 
-# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined 
+# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
 # in $(GAMMADIR)/make/defs.make
 ifeq ($(HOTSPOT_BUILD_VERSION),)
   BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\""
@@ -93,7 +93,7 @@
 
 # This is VERY important! The version define must only be supplied to vm_version.o
 # If not, ccache will not re-use the cache at all, since the version string might contain
-# a time and date. 
+# a time and date.
 CXXFLAGS/vm_version.o += ${JRE_VERSION}
 
 CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
@@ -105,10 +105,6 @@
 CXXFLAGS += -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)
 
@@ -126,7 +122,11 @@
 LFLAGS += -Xlinker -z -Xlinker noexecstack
 endif
 
-LIBS += -lm -pthread
+LIBS += -lm
+
+ifeq ($(USE_CLANG),)
+  LIBS += -pthread
+endif
 
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
@@ -161,15 +161,15 @@
 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 \
+CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
+CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
+
+ifneq ($(INCLUDE_TRACE), false)
+CORE_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
-
 COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
 COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
 
--- a/make/defs.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/defs.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -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.
-#  
+#
 #
 
 # The common definitions for hotspot builds.
@@ -236,7 +236,7 @@
   JDK_IMAGE_DIR=$(ALT_JDK_IMAGE_DIR)
 endif
 
-# The platform dependent defs.make defines platform specific variable such 
+# The platform dependent defs.make defines platform specific variable such
 # as ARCH, EXPORT_LIST etc. We must place the include here after BOOTDIR is defined.
 include $(GAMMADIR)/make/$(OSNAME)/makefiles/defs.make
 
@@ -258,7 +258,7 @@
   #   LIBARCH   - directory name in JDK/JRE
 
   # Use uname output for SRCARCH, but deal with platform differences. If ARCH
-  # is not explicitly listed below, it is treated as x86. 
+  # is not explicitly listed below, it is treated as x86.
   SRCARCH     = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc zero,$(ARCH)))
   ARCH/       = x86
   ARCH/sparc  = sparc
@@ -337,8 +337,5 @@
 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
+.PHONY: $(HS_ALT_MAKE)/defs.make
 
-.PHONY: $(HS_ALT_MAKE)/defs.make
--- a/make/excludeSrc.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/excludeSrc.make	Fri Jun 21 15:56:24 2013 -0700
@@ -19,13 +19,13 @@
 # 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.
-#  
+#
 #
 ifeq ($(INCLUDE_JVMTI), false)
       CXXFLAGS += -DINCLUDE_JVMTI=0
       CFLAGS += -DINCLUDE_JVMTI=0
 
-      Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp forte.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
+      Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
 	jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
 	jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
 	jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
@@ -87,7 +87,7 @@
 	g1BlockOffsetTable.cpp g1CardCounts.cpp g1CollectedHeap.cpp g1CollectorPolicy.cpp \
 	g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \
 	g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp \
-	g1RemSet.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \
+	g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \
 	heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \
 	ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp \
 	adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \
@@ -100,7 +100,7 @@
 	parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \
 	gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \
 	mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp
-endif 
+endif
 
 ifeq ($(INCLUDE_NMT), false)
       CXXFLAGS += -DINCLUDE_NMT=0
@@ -110,3 +110,5 @@
 	 memBaseline.cpp memPtr.cpp memRecorder.cpp memReporter.cpp memSnapshot.cpp memTrackWorker.cpp \
 	 memTracker.cpp nmtDCmd.cpp
 endif
+
+-include $(HS_ALT_MAKE)/excludeSrc.make
--- a/make/hotspot_version	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/hotspot_version	Fri Jun 21 15:56:24 2013 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=34
+HS_BUILD_NUMBER=37
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/make/linux/makefiles/adlc.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/linux/makefiles/adlc.make	Fri Jun 21 15:56:24 2013 -0700
@@ -68,7 +68,7 @@
 
 # CFLAGS_WARN holds compiler options to suppress/enable warnings.
 # Compiler warnings are treated as errors
-CFLAGS_WARN = -Werror
+CFLAGS_WARN = $(WARNINGS_ARE_ERRORS)
 CFLAGS += $(CFLAGS_WARN)
 
 OBJECTNAMES = \
--- a/make/linux/makefiles/buildtree.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/linux/makefiles/buildtree.make	Fri Jun 21 15:56:24 2013 -0700
@@ -47,6 +47,7 @@
 # flags.make	- with macro settings
 # vm.make	- to support making "$(MAKE) -v vm.make" in makefiles
 # adlc.make	-
+# trace.make	- generate tracing event and type definitions
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
 #
@@ -114,7 +115,8 @@
 SIMPLE_DIRS	= \
 	$(PLATFORM_DIR)/generated/dependencies \
 	$(PLATFORM_DIR)/generated/adfiles \
-	$(PLATFORM_DIR)/generated/jvmtifiles
+	$(PLATFORM_DIR)/generated/jvmtifiles \
+	$(PLATFORM_DIR)/generated/tracefiles
 
 TARGETS      = debug fastdebug optimized product
 SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
@@ -122,7 +124,7 @@
 # For dependencies and recursive makes.
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -269,6 +271,8 @@
 	    echo && \
 	    echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
 	    echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \
+	[ -n "$(INCLUDE_TRACE)" ] && \
+	    echo && echo "INCLUDE_TRACE = $(INCLUDE_TRACE)"; \
 	echo; \
 	[ -n "$(SPEC)" ] && \
 	    echo "include $(SPEC)"; \
@@ -337,6 +341,16 @@
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
 	) > $@
 
+trace.make: $(BUILDTREE_MAKE)
+	@echo Creating $@ ...
+	$(QUIETLY) ( \
+	$(BUILDTREE_COMMENT); \
+	echo; \
+	echo include flags.make; \
+	echo; \
+	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
+	) > $@
+
 sa.make: $(BUILDTREE_MAKE)
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
--- a/make/linux/makefiles/gcc.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/linux/makefiles/gcc.make	Fri Jun 21 15:56:24 2013 -0700
@@ -36,8 +36,14 @@
     HOSTCC  = gcc
     STRIP = $(ALT_COMPILER_PATH)/strip
   else
-    CXX = g++
-    CC  = gcc
+    ifeq ($(USE_CLANG), true)
+      CXX = clang++
+      CC  = clang
+    else
+      CXX = g++
+      CC  = gcc
+    endif
+
     HOSTCXX = $(CXX)
     HOSTCC  = $(CC)
     STRIP = strip
@@ -46,19 +52,79 @@
 endif
 
 
-# -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
-# prints the numbers (e.g. "2.95", "3.2.1")
-CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
-CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
+ifeq ($(USE_CLANG), true)
+  CC_VER_MAJOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f1)
+  CC_VER_MINOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f2)
+else
+  # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
+  # prints the numbers (e.g. "2.95", "3.2.1")
+  CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
+  CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
+endif
+
+
+ifeq ($(USE_CLANG), true)
+  # Clang has precompiled headers support by default, but the user can switch
+  # it off by using 'USE_PRECOMPILED_HEADER=0'.
+  ifdef LP64
+    ifeq ($(USE_PRECOMPILED_HEADER),)
+      USE_PRECOMPILED_HEADER=1
+    endif
+  else
+    # We don't support precompiled headers on 32-bit builds because there some files are
+    # compiled with -fPIC while others are compiled without (see 'NONPIC_OBJ_FILES' rules.make)
+    # Clang produces an error if the PCH file was compiled with other options than the actual compilation unit.
+    USE_PRECOMPILED_HEADER=0
+  endif
+
+  ifeq ($(USE_PRECOMPILED_HEADER),1)
+
+    ifndef LP64
+      $(error " Precompiled Headers only supported on 64-bit platforms!")
+    endif
+
+    PRECOMPILED_HEADER_DIR=.
+    PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
+    PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.pch
 
-# check for precompiled headers support
-ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
-# Allow the user to turn off precompiled headers from the command line.
-ifneq ($(USE_PRECOMPILED_HEADER),0)
-PRECOMPILED_HEADER_DIR=.
-PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
-PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
+    PCH_FLAG = -include precompiled.hpp
+    PCH_FLAG/DEFAULT = $(PCH_FLAG)
+    PCH_FLAG/NO_PCH = -DNO_PCH
+    PCH_FLAG/BY_FILE = $(PCH_FLAG/$@)$(PCH_FLAG/DEFAULT$(PCH_FLAG/$@))
+
+    VM_PCH_FLAG/LIBJVM = $(PCH_FLAG/BY_FILE)
+    VM_PCH_FLAG/AOUT =
+    VM_PCH_FLAG = $(VM_PCH_FLAG/$(LINK_INTO))
+
+    # We only use precompiled headers for the JVM build
+    CFLAGS += $(VM_PCH_FLAG)
+
+    # There are some files which don't like precompiled headers
+    # The following files are build with 'OPT_CFLAGS/NOOPT' (-O0) in the opt build.
+    # But Clang doesn't support a precompiled header which was compiled with -O3
+    # to be used in a compilation unit which uses '-O0'. We could also prepare an
+    # extra '-O0' PCH file for the opt build and use it here, but it's probably
+    # not worth the effoert as long as only two files need this special handling.
+    PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH)
+    PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH)
+    PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH)
+
+  endif
+else # ($(USE_CLANG), true)
+  # check for precompiled headers support
+  ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
+    # Allow the user to turn off precompiled headers from the command line.
+    ifneq ($(USE_PRECOMPILED_HEADER),0)
+      PRECOMPILED_HEADER_DIR=.
+      PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
+      PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
+    endif
+  endif
 endif
+
+# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
+ifeq ($(USE_PRECOMPILED_HEADER),0)
+  CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
 endif
 
 
@@ -83,16 +149,30 @@
 CFLAGS += -fno-rtti
 CFLAGS += -fno-exceptions
 CFLAGS += -D_REENTRANT
-CFLAGS += -fcheck-new
-# version 4 and above support fvisibility=hidden (matches jni_x86.h file)
-# except 4.1.2 gives pointless warnings that can't be disabled (afaik)
-ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
-CFLAGS += -fvisibility=hidden
+ifeq ($(USE_CLANG),)
+  CFLAGS += -fcheck-new
+  # version 4 and above support fvisibility=hidden (matches jni_x86.h file)
+  # except 4.1.2 gives pointless warnings that can't be disabled (afaik)
+  ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
+    CFLAGS += -fvisibility=hidden
+  endif
+else
+  CFLAGS += -fvisibility=hidden
+endif
+
+ifeq ($(USE_CLANG), true)
+  # Before Clang 3.1, we had to pass the stack alignment specification directly to llvm with the help of '-mllvm'
+  # Starting with version 3.1, Clang understands the '-mstack-alignment' (and rejects '-mllvm -stack-alignment')
+  ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 1 \) \))" "0"
+    STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mstack-alignment=16
+  else
+    STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mllvm -stack-alignment=16
+  endif
 endif
 
 ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
 ARCHFLAG/i486    = -m32 -march=i586
-ARCHFLAG/amd64   = -m64
+ARCHFLAG/amd64   = -m64 $(STACK_ALIGNMENT_OPT)
 ARCHFLAG/ia64    =
 ARCHFLAG/sparc   = -m32 -mcpu=v9
 ARCHFLAG/sparcv9 = -m64 -mcpu=v9
@@ -126,12 +206,22 @@
 # Compiler warnings are treated as errors
 WARNINGS_ARE_ERRORS = -Werror
 
+ifeq ($(USE_CLANG), true)
+  # However we need to clean the code up before we can unrestrictedly enable this option with Clang
+  WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
+  WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare
+  WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
+  WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
+endif
+
 WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function
 
-# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
-# conversions which might affect the values. Only enable it in earlier versions.
-ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
-WARNING_FLAGS += -Wconversion
+ifeq ($(USE_CLANG),)
+  # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
+  # conversions which might affect the values. Only enable it in earlier versions.
+  ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
+    WARNING_FLAGS += -Wconversion
+  endif
 endif
 
 CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
@@ -165,19 +255,24 @@
 
 OPT_CFLAGS/NOOPT=-O0
 
-# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation. 
-ifneq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) = 3 \) \))" "0"
-OPT_CFLAGS/mulnode.o += -O0
+# Work around some compiler bugs.
+ifeq ($(USE_CLANG), true)
+  ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1)
+    OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
+  endif
+else
+  # 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
+  ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 3), 1)
+    OPT_CFLAGS/mulnode.o += $(OPT_CFLAGS/NOOPT)
+  endif
 endif
 
 # Flags for generating make dependency flags.
-ifneq ("${CC_VER_MAJOR}", "2")
-DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
-endif
-
-# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
-ifeq ($(USE_PRECOMPILED_HEADER),0)
-CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
+DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
+ifeq ($(USE_CLANG),)
+  ifneq ("${CC_VER_MAJOR}", "2")
+    DEPFLAGS += -fpch-deps
+  endif
 endif
 
 #------------------------------------------------------------------------
@@ -186,24 +281,33 @@
 # statically link libstdc++.so, work with gcc but ignored by g++
 STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
 
-# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
-ifneq ("${CC_VER_MAJOR}", "2")
-STATIC_LIBGCC += -static-libgcc
-endif
+ifeq ($(USE_CLANG),)
+  # statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
+  ifneq ("${CC_VER_MAJOR}", "2")
+    STATIC_LIBGCC += -static-libgcc
+  endif
 
-ifeq ($(BUILDARCH), ia64)
-LFLAGS += -Wl,-relax
+  ifeq ($(BUILDARCH), ia64)
+    LFLAGS += -Wl,-relax
+  endif
 endif
 
 # Enable linker optimization
 LFLAGS += -Xlinker -O1
 
-# If this is a --hash-style=gnu system, use --hash-style=both
-#   The gnu .hash section won't work on some Linux systems like SuSE 10.
-_HAS_HASH_STYLE_GNU:=$(shell $(CC) -dumpspecs | grep -- '--hash-style=gnu')
-ifneq ($(_HAS_HASH_STYLE_GNU),)
+ifeq ($(USE_CLANG),)
+  # If this is a --hash-style=gnu system, use --hash-style=both
+  #   The gnu .hash section won't work on some Linux systems like SuSE 10.
+  _HAS_HASH_STYLE_GNU:=$(shell $(CC) -dumpspecs | grep -- '--hash-style=gnu')
+  ifneq ($(_HAS_HASH_STYLE_GNU),)
+    LDFLAGS_HASH_STYLE = -Wl,--hash-style=both
+  endif
+else
+  # Don't know how to find out the 'hash style' of a system as '-dumpspecs'
+  # doesn't work for Clang. So for now we'll alwys use --hash-style=both
   LDFLAGS_HASH_STYLE = -Wl,--hash-style=both
 endif
+
 LFLAGS += $(LDFLAGS_HASH_STYLE)
 
 # Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
@@ -221,6 +325,13 @@
 #------------------------------------------------------------------------
 # Debug flags
 
+ifeq ($(USE_CLANG), true)
+  # Restrict the debug information created by Clang to avoid
+  # too big object files and speed the build up a little bit
+  # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+  CFLAGS += -flimit-debug-info
+endif
+
 # DEBUG_BINARIES uses full -g debug information for all configs
 ifeq ($(DEBUG_BINARIES), true)
   CFLAGS += -g
@@ -237,7 +348,12 @@
   DEBUG_CFLAGS/ppc   = -g
   DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
   ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
-    DEBUG_CFLAGS += -gstabs
+      ifeq ($(USE_CLANG), true)
+        # Clang doesn't understand -gstabs
+        OPT_CFLAGS += -g
+      else
+        OPT_CFLAGS += -gstabs
+      endif
   endif
   
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
@@ -247,7 +363,12 @@
     FASTDEBUG_CFLAGS/ppc   = -g
     FASTDEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
     ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),)
-      FASTDEBUG_CFLAGS += -gstabs
+      ifeq ($(USE_CLANG), true)
+        # Clang doesn't understand -gstabs
+        OPT_CFLAGS += -g
+      else
+        OPT_CFLAGS += -gstabs
+      endif
     endif
   
     OPT_CFLAGS/ia64  = -g
@@ -256,7 +377,12 @@
     OPT_CFLAGS/ppc   = -g
     OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH))
     ifeq ($(OPT_CFLAGS/$(BUILDARCH)),)
-      OPT_CFLAGS += -gstabs
+      ifeq ($(USE_CLANG), true)
+        # Clang doesn't understand -gstabs
+        OPT_CFLAGS += -g
+      else
+        OPT_CFLAGS += -gstabs
+      endif
     endif
   endif
 endif
--- a/make/linux/makefiles/minimal1.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/linux/makefiles/minimal1.make	Fri Jun 21 15:56:24 2013 -0700
@@ -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.
-#  
+#
 #
 
 TYPE=MINIMAL1
@@ -32,6 +32,7 @@
 INCLUDE_MANAGEMENT ?= false
 INCLUDE_ALL_GCS ?= false
 INCLUDE_NMT ?= false
+INCLUDE_TRACE ?= false
 INCLUDE_CDS ?= false
 
 CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/make/linux/makefiles/top.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/linux/makefiles/top.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@
 	@echo All done.
 
 # This is an explicit dependency for the sake of parallel makes.
-vm_build_preliminaries:  checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff
+vm_build_preliminaries:  checks $(Cached_plat) $(AD_Files_If_Required) trace_stuff jvmti_stuff sa_stuff
 	@# We need a null action here, so implicit rules don't get consulted.
 
 $(Cached_plat): $(Plat_File)
@@ -94,6 +94,10 @@
 jvmti_stuff: $(Cached_plat) $(adjust-mflags)
 	@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
 
+# generate trace files
+trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
+	@$(MAKE) -f trace.make $(MFLAGS-adjusted)
+
 # generate SA jar files and native header
 sa_stuff:
 	@$(MAKE) -f sa.make $(MFLAGS-adjusted)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/linux/makefiles/trace.make	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,120 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+include $(GAMMADIR)/make/linux/makefiles/rules.make
+include $(GAMMADIR)/make/altsrc.make
+
+# #########################################################################
+
+HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
+  echo "true"; else echo "false";\
+  fi)
+
+TOPDIR      = $(shell echo `pwd`)
+GENERATED   = $(TOPDIR)/../generated
+JvmtiOutDir = $(GENERATED)/jvmtifiles
+TraceOutDir   = $(GENERATED)/tracefiles
+
+TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
+TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
+
+# set VPATH so make knows where to look for source files
+Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
+VPATH += $(Src_Dirs_V:%=%:)
+
+TraceGeneratedNames =     \
+    traceEventClasses.hpp \
+	traceEventIds.hpp     \
+	traceTypes.hpp
+
+ifeq ($(HAS_ALT_SRC), true)
+TraceGeneratedNames +=  \
+	traceRequestables.hpp \
+    traceEventControl.hpp
+
+ifneq ($(INCLUDE_TRACE), false)
+TraceGeneratedNames += traceProducer.cpp
+endif
+
+endif
+
+TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
+
+XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS =  $(TraceSrcDir)/trace.xml  $(TraceSrcDir)/tracetypes.xml \
+	$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+ifeq ($(HAS_ALT_SRC), true)
+	XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+all: $(TraceGeneratedFiles)
+
+GENERATE_CODE= \
+  $(QUIETLY) echo Generating $@; \
+  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
+  test -f $@
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+ifeq ($(HAS_ALT_SRC), false)
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+endif
+
+# #########################################################################
+
+clean cleanall:
+	rm $(TraceGeneratedFiles)
+
+
--- a/make/linux/makefiles/vm.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/linux/makefiles/vm.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -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.
-#  
+#
 #
 
 # Rules to build JVM and related libraries, included from vm.make in the build
@@ -52,7 +52,7 @@
 # Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
 # The adfiles directory contains ad_<arch>.[ch]pp.
 # The jvmtifiles directory contains jvmti*.[ch]pp
-Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
+Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
 VPATH += $(Src_Dirs_V:%=%:)
 
 # set INCLUDES for C preprocessor.
@@ -72,7 +72,7 @@
   endif
 endif
 
-# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined 
+# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
 # in $(GAMMADIR)/make/defs.make
 ifeq ($(HOTSPOT_BUILD_VERSION),)
   BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\""
@@ -99,7 +99,7 @@
 
 # This is VERY important! The version define must only be supplied to vm_version.o
 # If not, ccache will not re-use the cache at all, since the version string might contain
-# a time and date. 
+# a time and date.
 CXXFLAGS/vm_version.o += ${JRE_VERSION}
 
 CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
@@ -108,12 +108,6 @@
 CXXFLAGS += $(CXXFLAGS/BYFILE)
 
 
-ifndef JAVASE_EMBEDDED 
-ifneq (${ARCH},arm)
-CFLAGS += -DINCLUDE_TRACE
-endif
-endif
-
 # CFLAGS_WARN holds compiler options to suppress/enable warnings.
 CFLAGS += $(CFLAGS_WARN/BYFILE)
 
@@ -158,16 +152,14 @@
 SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
 
-ifndef JAVASE_EMBEDDED 
-ifneq (${ARCH},arm)
-SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
+CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
+
+ifneq ($(INCLUDE_TRACE), false)
+CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
   find $(HS_ALT_SRC)/share/vm/jfr -type d; \
   fi)
 endif
-endif
-
-CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
-CORE_PATHS+=$(GENERATED)/jvmtifiles
 
 COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
 COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
@@ -316,7 +308,7 @@
 # With more recent Redhat releases (or the cutting edge version Fedora), if
 # SELinux is configured to be enabled, the runtime linker will fail to apply
 # the text relocation to libjvm.so considering that it is built as a non-PIC
-# DSO. To workaround that, we run chcon to libjvm.so after it is built. See 
+# DSO. To workaround that, we run chcon to libjvm.so after it is built. See
 # details in bug 6538311.
 $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
 	$(QUIETLY) {                                                    \
--- a/make/solaris/makefiles/buildtree.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/solaris/makefiles/buildtree.make	Fri Jun 21 15:56:24 2013 -0700
@@ -47,6 +47,7 @@
 # flags.make	- with macro settings
 # vm.make	- to support making "$(MAKE) -v vm.make" in makefiles
 # adlc.make	-
+# trace.make	- generate tracing event and type definitions
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
 #
@@ -107,7 +108,8 @@
 SIMPLE_DIRS	= \
 	$(PLATFORM_DIR)/generated/dependencies \
 	$(PLATFORM_DIR)/generated/adfiles \
-	$(PLATFORM_DIR)/generated/jvmtifiles
+	$(PLATFORM_DIR)/generated/jvmtifiles \
+	$(PLATFORM_DIR)/generated/tracefiles
 
 TARGETS      = debug fastdebug optimized product
 SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
@@ -115,7 +117,7 @@
 # For dependencies and recursive makes.
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -327,6 +329,16 @@
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
 	) > $@
 
+trace.make: $(BUILDTREE_MAKE)
+	@echo Creating $@ ...
+	$(QUIETLY) ( \
+	$(BUILDTREE_COMMENT); \
+	echo; \
+	echo include flags.make; \
+	echo; \
+	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
+	) > $@
+
 sa.make: $(BUILDTREE_MAKE)
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
--- a/make/solaris/makefiles/top.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/solaris/makefiles/top.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,7 @@
 	@echo All done.
 
 # This is an explicit dependency for the sake of parallel makes.
-vm_build_preliminaries:  checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff
+vm_build_preliminaries:  checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff trace_stuff sa_stuff
 	@# We need a null action here, so implicit rules don't get consulted.
 
 $(Cached_plat): $(Plat_File)
@@ -87,6 +87,10 @@
 jvmti_stuff: $(Cached_plat) $(adjust-mflags)
 	@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
 
+# generate trace files 
+trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
+	@$(MAKE) -f trace.make $(MFLAGS-adjusted)
+
 # generate SA jar files and native header
 sa_stuff:
 	@$(MAKE) -f sa.make $(MFLAGS-adjusted)
@@ -127,5 +131,5 @@
 	rm -fr $(GENERATED)
 
 .PHONY: default vm_build_preliminaries
-.PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean
+.PHONY: lists ad_stuff jvmti_stuff trace_stuff sa_stuff the_vm clean realclean
 .PHONY: checks check_os_version install
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/solaris/makefiles/trace.make	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,116 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+include $(GAMMADIR)/make/solaris/makefiles/rules.make
+include $(GAMMADIR)/make/altsrc.make
+
+# #########################################################################
+
+HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
+  echo "true"; else echo "false";\
+  fi)
+
+TOPDIR      = $(shell echo `pwd`)
+GENERATED   = $(TOPDIR)/../generated
+JvmtiOutDir = $(GENERATED)/jvmtifiles
+TraceOutDir   = $(GENERATED)/tracefiles
+
+TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
+TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
+
+# set VPATH so make knows where to look for source files
+Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
+VPATH += $(Src_Dirs_V:%=%:)
+
+TraceGeneratedNames =     \
+    traceEventClasses.hpp \
+	traceEventIds.hpp     \
+	traceTypes.hpp
+
+ifeq ($(HAS_ALT_SRC), true)
+TraceGeneratedNames +=  \
+	traceRequestables.hpp \
+    traceEventControl.hpp \
+    traceProducer.cpp
+endif
+
+TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
+
+XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS =  $(TraceSrcDir)/trace.xml  $(TraceSrcDir)/tracetypes.xml \
+	$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+ifeq ($(HAS_ALT_SRC), true)
+	XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+all: $(TraceGeneratedFiles)
+
+GENERATE_CODE= \
+  $(QUIETLY) echo Generating $@; \
+  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
+  test -f $@
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+ifeq ($(HAS_ALT_SRC), false)
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+	$(GENERATE_CODE)
+
+endif
+
+# #########################################################################
+
+clean cleanall:
+	rm $(TraceGeneratedFiles)
+
+
--- a/make/solaris/makefiles/vm.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/solaris/makefiles/vm.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -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.
-#  
+#
 #
 
 # Rules to build JVM and related libraries, included from vm.make in the build
@@ -48,7 +48,7 @@
 # Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
 # The adfiles directory contains ad_<arch>.[ch]pp.
 # The jvmtifiles directory contains jvmti*.[ch]pp
-Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
+Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
 VPATH += $(Src_Dirs_V:%=%:)
 
 # set INCLUDES for C preprocessor
@@ -87,7 +87,7 @@
 
 # This is VERY important! The version define must only be supplied to vm_version.o
 # If not, ccache will not re-use the cache at all, since the version string might contain
-# a time and date. 
+# a time and date.
 CXXFLAGS/vm_version.o += ${JRE_VERSION}
 
 CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
@@ -103,7 +103,7 @@
 CFLAGS += $(CFLAGS/NOEX)
 
 # Extra flags from gnumake's invocation or environment
-CFLAGS += $(EXTRA_CFLAGS) -DINCLUDE_TRACE
+CFLAGS += $(EXTRA_CFLAGS)
 
 # Math Library (libm.so), do not use -lm.
 #    There might be two versions of libm.so on the build system:
@@ -137,9 +137,7 @@
 LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
 endif # sparcWorks
 
-ifeq ("${Platform_arch}", "sparc")
 LIBS += -lkstat
-endif
 
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
@@ -177,12 +175,14 @@
 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 \
+CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
+CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
+
+ifneq ($(INCLUDE_TRACE), false)
+CORE_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
+endif
 
 COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
 COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
@@ -287,7 +287,7 @@
 LINK_VM = $(LINK_LIB.CXX)
 endif
 # making the library:
-$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE) 
+$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
 ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
 	@echo Linking vm...
 	$(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK)
--- a/make/windows/build.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/windows/build.make	Fri Jun 21 15:56:24 2013 -0700
@@ -196,6 +196,12 @@
 
 # End VERSIONINFO parameters
 
+# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
+!ifndef OPENJDK
+!if !exists($(WorkSpace)\src\closed)
+OPENJDK=true
+!endif
+!endif
 
 # We don't support SA on ia64, and we can't
 # build it if we are using a version of Vis Studio
@@ -273,6 +279,7 @@
 	@ echo HS_COMPANY=$(COMPANY_NAME)			>> $@
 	@ echo HS_FILEDESC=$(HS_FILEDESC)			>> $@
 	@ echo HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO)		>> $@
+	@ if "$(OPENJDK)" NEQ "" echo OPENJDK=$(OPENJDK)	>> $@
 	@ echo HS_COPYRIGHT=$(HOTSPOT_VM_COPYRIGHT)		>> $@
 	@ echo HS_NAME=$(PRODUCT_NAME) $(JDK_MKTG_VERSION)	>> $@
 	@ echo HS_BUILD_VER=$(HS_BUILD_VER)			>> $@
--- a/make/windows/create_obj_files.sh	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/windows/create_obj_files.sh	Fri Jun 21 15:56:24 2013 -0700
@@ -71,13 +71,11 @@
   BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/${sd}"
 done
 
-BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles"
+BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles ${GENERATED}/tracefiles"
 
 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"
+  BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
+  BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/buffers"
 fi
 
 BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods"
--- a/make/windows/makefiles/generated.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/windows/makefiles/generated.make	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -30,15 +30,19 @@
 JvmtiOutDir=jvmtifiles
 !include $(WorkSpace)/make/windows/makefiles/jvmti.make
 
+# Pick up rules for building trace
+TraceOutDir=tracefiles
+!include $(WorkSpace)/make/windows/makefiles/trace.make
+
 # Pick up rules for building SA
 !include $(WorkSpace)/make/windows/makefiles/sa.make
 
 AdlcOutDir=adfiles
 
 !if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
-default:: $(AdlcOutDir)/ad_$(Platform_arch_model).cpp $(AdlcOutDir)/dfa_$(Platform_arch_model).cpp $(JvmtiGeneratedFiles) buildobjfiles
+default:: $(AdlcOutDir)/ad_$(Platform_arch_model).cpp $(AdlcOutDir)/dfa_$(Platform_arch_model).cpp $(JvmtiGeneratedFiles) $(TraceGeneratedFiles) buildobjfiles
 !else
-default:: $(JvmtiGeneratedFiles) buildobjfiles
+default:: $(JvmtiGeneratedFiles) $(TraceGeneratedFiles) buildobjfiles
 !endif
 
 buildobjfiles:
--- a/make/windows/makefiles/projectcreator.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/windows/makefiles/projectcreator.make	Fri Jun 21 15:56:24 2013 -0700
@@ -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.
-#  
+#
 #
 
 !include $(WorkSpace)/make/windows/makefiles/rules.make
@@ -72,7 +72,7 @@
         -ignorePath ppc \
         -ignorePath zero \
         -hidePath .hg
-	
+
 
 # This is referenced externally by both the IDE and batch builds
 ProjectCreatorOptions=
@@ -89,7 +89,7 @@
         -disablePch        bytecodeInterpreter.cpp \
         -disablePch        bytecodeInterpreterWithChecks.cpp \
         -disablePch        getThread_windows_$(Platform_arch).cpp \
-        -disablePch_compiler2     opcodes.cpp    
+        -disablePch_compiler2     opcodes.cpp
 
 # Common options for the IDE builds for core, c1, and c2
 ProjectCreatorIDEOptions=\
@@ -115,7 +115,7 @@
         -define TARGET_OS_ARCH_windows_x86 \
         -define TARGET_OS_FAMILY_windows \
         -define TARGET_COMPILER_visCPP \
-        -define INCLUDE_TRACE \
+        -define INCLUDE_TRACE=1 \
        $(ProjectCreatorIncludesPRIVATE)
 
 # Add in build-specific options
@@ -203,4 +203,12 @@
  -additionalFile jvmtiEnter.cpp \
  -additionalFile jvmtiEnterTrace.cpp \
  -additionalFile jvmti.h \
- -additionalFile bytecodeInterpreterWithChecks.cpp
+ -additionalFile bytecodeInterpreterWithChecks.cpp \
+ -additionalFile traceEventClasses.hpp \
+ -additionalFile traceEventIds.hpp \
+!if "$(OPENJDK)" != "true"
+ -additionalFile traceRequestables.hpp \
+ -additionalFile traceEventControl.hpp \
+ -additionalFile traceProducer.cpp \
+!endif
+ -additionalFile traceTypes.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/windows/makefiles/trace.make	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+!include $(WorkSpace)/make/windows/makefiles/rules.make
+
+# #########################################################################
+
+
+TraceAltSrcDir = $(WorkSpace)/src/closed/share/vm/trace
+TraceSrcDir = $(WorkSpace)/src/share/vm/trace
+
+TraceGeneratedNames =     \
+    traceEventClasses.hpp \
+    traceEventIds.hpp     \
+    traceTypes.hpp
+
+
+!if "$(OPENJDK)" != "true"
+TraceGeneratedNames = $(TraceGeneratedNames) \
+    traceRequestables.hpp \
+    traceEventControl.hpp \
+    traceProducer.cpp
+!endif
+
+
+#Note: TraceGeneratedFiles must be kept in sync with TraceGeneratedNames by hand.
+#Should be equivalent to "TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)"
+TraceGeneratedFiles = \
+    $(TraceOutDir)/traceEventClasses.hpp \
+	$(TraceOutDir)/traceEventIds.hpp     \
+	$(TraceOutDir)/traceTypes.hpp
+
+!if "$(OPENJDK)" != "true"
+TraceGeneratedFiles = $(TraceGeneratedFiles) \
+	$(TraceOutDir)/traceRequestables.hpp \
+    $(TraceOutDir)/traceEventControl.hpp \
+	$(TraceOutDir)/traceProducer.cpp
+!endif
+
+XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
+    $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+
+!if "$(OPENJDK)" != "true"
+XML_DEPS = $(XML_DEPS) $(TraceAltSrcDir)/traceevents.xml
+!endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+default::
+	@if not exist $(TraceOutDir) mkdir $(TraceOutDir)
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+	@echo Generating $@
+	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventIds.xsl -OUT $(TraceOutDir)/traceEventIds.hpp
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+	@echo Generating $@
+	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceTypes.xsl -OUT $(TraceOutDir)/traceTypes.hpp
+
+!if "$(OPENJDK)" == "true"
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	@echo Generating $@
+	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
+
+!else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+	@echo Generating $@
+	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+	@echo Generating $@
+	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+	@echo Generating $@
+	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+	@echo Generating $@
+	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp
+
+!endif
+
+# #########################################################################
+
+cleanall :
+	rm $(TraceGeneratedFiles)
+
+
--- a/make/windows/makefiles/vm.make	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/windows/makefiles/vm.make	Fri Jun 21 15:56:24 2013 -0700
@@ -66,10 +66,6 @@
 CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\""
 CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\""
 
-!ifndef JAVASE_EMBEDDED
-CXX_FLAGS=$(CXX_FLAGS) /D "INCLUDE_TRACE"
-!endif
-
 CXX_FLAGS=$(CXX_FLAGS) $(CXX_INCLUDE_DIRS)
 
 # Define that so jni.h is on correct side
@@ -144,6 +140,7 @@
 VM_PATH=../generated
 VM_PATH=$(VM_PATH);../generated/adfiles
 VM_PATH=$(VM_PATH);../generated/jvmtifiles
+VM_PATH=$(VM_PATH);../generated/tracefiles
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/c1
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/compiler
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/code
@@ -172,10 +169,8 @@
 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
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/buffers
 !endif
 
 VM_PATH={$(VM_PATH)}
@@ -384,16 +379,13 @@
 {..\generated\jvmtifiles}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+{..\generated\tracefiles}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
 {$(ALTSRC)\share\vm\jfr}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
-{$(ALTSRC)\share\vm\jfr\agent}.cpp.obj::
-        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
-
-{$(ALTSRC)\share\vm\jfr\agent\isolated_deps\util}.cpp.obj::
-        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
-
-{$(ALTSRC)\share\vm\jfr\jvm}.cpp.obj::
+{$(ALTSRC)\share\vm\jfr\buffers}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
 default::
--- a/make/windows/projectfiles/common/Makefile	Thu Jun 20 16:30:44 2013 -0700
+++ b/make/windows/projectfiles/common/Makefile	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,12 @@
 !endif
 !endif
 
+# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
+!ifndef OPENJDK
+!if !exists($(WorkSpace)\src\closed)
+OPENJDK=true
+!endif
+!endif
 
 
 !include $(HOTSPOTWORKSPACE)/make/windows/makefiles/projectcreator.make
@@ -54,6 +60,10 @@
 JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
 !include $(HOTSPOTWORKSPACE)/make/windows/makefiles/jvmti.make
 
+# Pick up rules for building trace
+TraceOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\tracefiles
+!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/trace.make
+
 !if "$(Variant)" == "compiler2"
 # Pick up rules for building adlc
 !include $(HOTSPOTWORKSPACE)/make/windows/makefiles/adlc.make
@@ -66,7 +76,7 @@
 
 HS_INTERNAL_NAME=jvm
 
-default:: $(AdditionalTargets) $(JvmtiGeneratedFiles)
+default:: $(AdditionalTargets) $(JvmtiGeneratedFiles) $(TraceGeneratedFiles)
 
 !include $(HOTSPOTWORKSPACE)/make/hotspot_version
 
--- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1065,7 +1065,7 @@
   const int slop_factor = 2*wordSize;
 
   const int fixed_size = ((sizeof(BytecodeInterpreter) + slop_factor) >> LogBytesPerWord) + // what is the slop factor?
-                         //6815692//Method::extra_stack_words() +  // extra push slots for MH adapters
+                         Method::extra_stack_entries() + // extra stack for jsr 292
                          frame::memory_parameter_word_sp_offset +  // register save area + param window
                          (native ?  frame::interpreter_frame_extra_outgoing_argument_words : 0); // JNI, class
 
@@ -1221,9 +1221,7 @@
   // Full size expression stack
   __ ld_ptr(constMethod, O3);
   __ lduh(O3, in_bytes(ConstMethod::max_stack_offset()), O3);
-  guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
-  //6815692//if (EnableInvokeDynamic)
-  //6815692//  __ inc(O3, Method::extra_stack_entries());
+  __ inc(O3, Method::extra_stack_entries());
   __ sll(O3, LogBytesPerWord, O3);
   __ sub(O2, O3, O3);
 //  __ sub(O3, wordSize, O3);                    // so prepush doesn't look out of bounds
@@ -2084,9 +2082,7 @@
 
   const int fixed_size = sizeof(BytecodeInterpreter)/wordSize +           // interpreter state object
                          frame::memory_parameter_word_sp_offset;   // register save area + param window
-  const int extra_stack = 0; //6815692//Method::extra_stack_entries();
   return (round_to(max_stack +
-                   extra_stack +
                    slop_factor +
                    fixed_size +
                    monitor_size +
@@ -2173,8 +2169,7 @@
   // Need +1 here because stack_base points to the word just above the first expr stack entry
   // and stack_limit is supposed to point to the word just below the last expr stack entry.
   // See generate_compute_interpreter_state.
-  int extra_stack = 0; //6815692//Method::extra_stack_entries();
-  to_fill->_stack_limit = stack_base - (method->max_stack() + 1 + extra_stack);
+  to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
   to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
 
   // sparc specific
--- a/src/cpu/sparc/vm/frame_sparc.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/sparc/vm/frame_sparc.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -252,6 +252,16 @@
       return false;
     }
 
+    // Could be a zombie method
+    if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
+      return false;
+    }
+
+    // Could be a zombie method
+    if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
+      return false;
+    }
+
     // It should be safe to construct the sender though it might not be valid
 
     frame sender(_SENDER_SP, younger_sp, adjusted_stack);
@@ -294,10 +304,10 @@
       return jcw_safe;
     }
 
-    // If the frame size is 0 something is bad because every nmethod has a non-zero frame size
+    // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
     // because you must allocate window space
 
-    if (sender_blob->frame_size() == 0) {
+    if (sender_blob->frame_size() <= 0) {
       assert(!sender_blob->is_nmethod(), "should count return address at least");
       return false;
     }
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -521,7 +521,7 @@
   // Compute max expression stack+register save area
   ld_ptr(Lmethod, in_bytes(Method::const_offset()), Gframe_size);
   lduh(Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size);  // Load max stack.
-  add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size );
+  add(Gframe_size, frame::memory_parameter_word_sp_offset+Method::extra_stack_entries(), Gframe_size );
 
   //
   // now set up a stack frame with the size computed above
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -507,7 +507,7 @@
 
   const int extra_space =
     rounded_vm_local_words +                   // frame local scratch space
-    //6815692//Method::extra_stack_words() +       // extra push slots for MH adapters
+    Method::extra_stack_entries() +            // extra stack for jsr 292
     frame::memory_parameter_word_sp_offset +   // register save area
     (native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0);
 
@@ -1558,7 +1558,6 @@
        round_to(callee_extra_locals * Interpreter::stackElementWords, WordsPerLong);
   const int max_stack_words = max_stack * Interpreter::stackElementWords;
   return (round_to((max_stack_words
-                   //6815692//+ Method::extra_stack_words()
                    + rounded_vm_local_words
                    + frame::memory_parameter_word_sp_offset), WordsPerLong)
                    // already rounded
--- a/src/cpu/x86/vm/cppInterpreter_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -539,12 +539,11 @@
 
     // compute full expression stack limit
 
-    const int extra_stack = 0; //6815692//Method::extra_stack_words();
     __ movptr(rdx, Address(rbx, Method::const_offset()));
     __ load_unsigned_short(rdx, Address(rdx, ConstMethod::max_stack_offset())); // get size of expression stack in words
     __ negptr(rdx);                                                       // so we can subtract in next step
     // Allocate expression stack
-    __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack));
+    __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -Method::extra_stack_words()));
     __ movptr(STATE(_stack_limit), rsp);
   }
 
@@ -692,10 +691,9 @@
   // Always give one monitor to allow us to start interp if sync method.
   // Any additional monitors need a check when moving the expression stack
   const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
-  const int extra_stack = 0; //6815692//Method::extra_stack_entries();
   __ movptr(rax, Address(rbx, Method::const_offset()));
   __ load_unsigned_short(rax, Address(rax, ConstMethod::max_stack_offset())); // get size of expression stack in words
-  __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor));
+  __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor+Method::extra_stack_words()));
   __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
 
 #ifdef ASSERT
@@ -2265,8 +2263,7 @@
   const int overhead_size = sizeof(BytecodeInterpreter)/wordSize +
     ( frame::sender_sp_offset - frame::link_offset) + 2;
 
-  const int extra_stack = 0; //6815692//Method::extra_stack_entries();
-  const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
+  const int method_stack = (method->max_locals() + method->max_stack()) *
                            Interpreter::stackElementWords;
   return overhead_size + method_stack + stub_code;
 }
@@ -2331,8 +2328,7 @@
   // Need +1 here because stack_base points to the word just above the first expr stack entry
   // and stack_limit is supposed to point to the word just below the last expr stack entry.
   // See generate_compute_interpreter_state.
-  int extra_stack = 0; //6815692//Method::extra_stack_entries();
-  to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1);
+  to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
   to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
 
   to_fill->_self_link = to_fill;
@@ -2380,8 +2376,7 @@
                                                 monitor_size);
 
   // Now with full size expression stack
-  int extra_stack = 0; //6815692//Method::extra_stack_entries();
-  int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord;
+  int full_frame_size = short_frame_size + method->max_stack() * BytesPerWord;
 
   // and now with only live portion of the expression stack
   short_frame_size = short_frame_size + tempcount * BytesPerWord;
--- a/src/cpu/x86/vm/frame_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/x86/vm/frame_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/monitorChunk.hpp"
+#include "runtime/os.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
@@ -54,16 +55,22 @@
   address   sp = (address)_sp;
   address   fp = (address)_fp;
   address   unextended_sp = (address)_unextended_sp;
-  // sp must be within the stack
-  bool sp_safe = (sp <= thread->stack_base()) &&
-                 (sp >= thread->stack_base() - thread->stack_size());
+
+  // consider stack guards when trying to determine "safe" stack pointers
+  static size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
+  size_t usable_stack_size = thread->stack_size() - stack_guard_size;
+
+  // sp must be within the usable part of the stack (not in guards)
+  bool sp_safe = (sp < thread->stack_base()) &&
+                 (sp >= thread->stack_base() - usable_stack_size);
+
 
   if (!sp_safe) {
     return false;
   }
 
   // unextended sp must be within the stack and above or equal sp
-  bool unextended_sp_safe = (unextended_sp <= thread->stack_base()) &&
+  bool unextended_sp_safe = (unextended_sp < thread->stack_base()) &&
                             (unextended_sp >= sp);
 
   if (!unextended_sp_safe) {
@@ -71,7 +78,8 @@
   }
 
   // an fp must be within the stack and above (but not equal) sp
-  bool fp_safe = (fp <= thread->stack_base()) && (fp > sp);
+  // second evaluation on fp+ is added to handle situation where fp is -1
+  bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
 
   // We know sp/unextended_sp are safe only fp is questionable here
 
@@ -86,6 +94,13 @@
     // other generic buffer blobs are more problematic so we just assume they are
     // ok. adapter blobs never have a frame complete and are never ok.
 
+    // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
+
+    if (!Interpreter::contains(_pc) && _cb->frame_size() <= 0) {
+      //assert(0, "Invalid frame_size");
+      return false;
+    }
+
     if (!_cb->is_frame_complete_at(_pc)) {
       if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
         return false;
@@ -107,7 +122,7 @@
 
       address jcw = (address)entry_frame_call_wrapper();
 
-      bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > fp);
+      bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
 
       return jcw_safe;
 
@@ -134,12 +149,6 @@
       sender_pc = (address) *(sender_sp-1);
     }
 
-    // We must always be able to find a recognizable pc
-    CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
-    if (sender_pc == NULL ||  sender_blob == NULL) {
-      return false;
-    }
-
 
     // If the potential sender is the interpreter then we can do some more checking
     if (Interpreter::contains(sender_pc)) {
@@ -149,7 +158,7 @@
       // is really a frame pointer.
 
       intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
-      bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
+      bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 
       if (!saved_fp_safe) {
         return false;
@@ -163,6 +172,17 @@
 
     }
 
+    // We must always be able to find a recognizable pc
+    CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
+    if (sender_pc == NULL ||  sender_blob == NULL) {
+      return false;
+    }
+
+    // Could be a zombie method
+    if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
+      return false;
+    }
+
     // Could just be some random pointer within the codeBlob
     if (!sender_blob->code_contains(sender_pc)) {
       return false;
@@ -174,10 +194,9 @@
     }
 
     // Could be the call_stub
-
     if (StubRoutines::returns_to_call_stub(sender_pc)) {
       intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
-      bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
+      bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 
       if (!saved_fp_safe) {
         return false;
@@ -190,15 +209,24 @@
       // Validate the JavaCallWrapper an entry frame must have
       address jcw = (address)sender.entry_frame_call_wrapper();
 
-      bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > (address)sender.fp());
+      bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
 
       return jcw_safe;
     }
 
-    // If the frame size is 0 something is bad because every nmethod has a non-zero frame size
+    if (sender_blob->is_nmethod()) {
+        nmethod* nm = sender_blob->as_nmethod_or_null();
+        if (nm != NULL) {
+            if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {
+                return false;
+            }
+        }
+    }
+
+    // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
     // because the return address counts against the callee's frame.
 
-    if (sender_blob->frame_size() == 0) {
+    if (sender_blob->frame_size() <= 0) {
       assert(!sender_blob->is_nmethod(), "should count return address at least");
       return false;
     }
@@ -208,7 +236,9 @@
     // should not be anything but the call stub (already covered), the interpreter (already covered)
     // or an nmethod.
 
-    assert(sender_blob->is_nmethod(), "Impossible call chain");
+    if (!sender_blob->is_nmethod()) {
+        return false;
+    }
 
     // Could put some more validation for the potential non-interpreted sender
     // frame we'd create by calling sender if I could think of any. Wait for next crash in forte...
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1565,8 +1565,7 @@
   // be sure to change this if you add/subtract anything to/from the overhead area
   const int overhead_size = -frame::interpreter_frame_initial_sp_offset;
 
-  const int extra_stack = Method::extra_stack_entries();
-  const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
+  const int method_stack = (method->max_locals() + method->max_stack()) *
                            Interpreter::stackElementWords;
   return overhead_size + method_stack + stub_code;
 }
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1574,8 +1574,7 @@
     -(frame::interpreter_frame_initial_sp_offset) + entry_size;
 
   const int stub_code = frame::entry_frame_after_call_words;
-  const int extra_stack = Method::extra_stack_entries();
-  const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
+  const int method_stack = (method->max_locals() + method->max_stack()) *
                            Interpreter::stackElementWords;
   return (overhead_size + method_stack + stub_code);
 }
--- a/src/os/bsd/vm/osThread_bsd.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/bsd/vm/osThread_bsd.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -94,7 +94,7 @@
   // flags that support signal based suspend/resume on Bsd are in a
   // separate class to avoid confusion with many flags in OSThread that
   // are used by VM level suspend/resume.
-  os::Bsd::SuspendResume sr;
+  os::SuspendResume sr;
 
   // _ucontext and _siginfo are used by SR_handler() to save thread context,
   // and they will later be used to walk the stack or reposition thread PC.
--- a/src/os/bsd/vm/os_bsd.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/bsd/vm/os_bsd.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -626,8 +626,6 @@
 //////////////////////////////////////////////////////////////////////////////
 // create new thread
 
-static address highest_vm_reserved_address();
-
 // check if it's safe to start a new thread
 static bool _thread_safety_check(Thread* thread) {
   return true;
@@ -935,10 +933,10 @@
   return (1000 * 1000);
 }
 
-// XXX: For now, code this as if BSD does not support vtime.
-bool os::supports_vtime() { return false; }
+bool os::supports_vtime() { return true; }
 bool os::enable_vtime()   { return false; }
 bool os::vtime_enabled()  { return false; }
+
 double os::elapsedVTime() {
   // better than nothing, but not much
   return elapsedTime();
@@ -1854,17 +1852,118 @@
 
 // Bsd(POSIX) specific hand shaking semaphore.
 #ifdef __APPLE__
-static semaphore_t sig_sem;
+typedef semaphore_t os_semaphore_t;
 #define SEM_INIT(sem, value)    semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value)
-#define SEM_WAIT(sem)           semaphore_wait(sem);
-#define SEM_POST(sem)           semaphore_signal(sem);
+#define SEM_WAIT(sem)           semaphore_wait(sem)
+#define SEM_POST(sem)           semaphore_signal(sem)
+#define SEM_DESTROY(sem)        semaphore_destroy(mach_task_self(), sem)
 #else
-static sem_t sig_sem;
+typedef sem_t os_semaphore_t;
 #define SEM_INIT(sem, value)    sem_init(&sem, 0, value)
-#define SEM_WAIT(sem)           sem_wait(&sem);
-#define SEM_POST(sem)           sem_post(&sem);
+#define SEM_WAIT(sem)           sem_wait(&sem)
+#define SEM_POST(sem)           sem_post(&sem)
+#define SEM_DESTROY(sem)        sem_destroy(&sem)
 #endif
 
+class Semaphore : public StackObj {
+  public:
+    Semaphore();
+    ~Semaphore();
+    void signal();
+    void wait();
+    bool trywait();
+    bool timedwait(unsigned int sec, int nsec);
+  private:
+    jlong currenttime() const;
+    semaphore_t _semaphore;
+};
+
+Semaphore::Semaphore() : _semaphore(0) {
+  SEM_INIT(_semaphore, 0);
+}
+
+Semaphore::~Semaphore() {
+  SEM_DESTROY(_semaphore);
+}
+
+void Semaphore::signal() {
+  SEM_POST(_semaphore);
+}
+
+void Semaphore::wait() {
+  SEM_WAIT(_semaphore);
+}
+
+jlong Semaphore::currenttime() const {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
+}
+
+#ifdef __APPLE__
+bool Semaphore::trywait() {
+  return timedwait(0, 0);
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+  kern_return_t kr = KERN_ABORTED;
+  mach_timespec_t waitspec;
+  waitspec.tv_sec = sec;
+  waitspec.tv_nsec = nsec;
+
+  jlong starttime = currenttime();
+
+  kr = semaphore_timedwait(_semaphore, waitspec);
+  while (kr == KERN_ABORTED) {
+    jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec;
+
+    jlong current = currenttime();
+    jlong passedtime = current - starttime;
+
+    if (passedtime >= totalwait) {
+      waitspec.tv_sec = 0;
+      waitspec.tv_nsec = 0;
+    } else {
+      jlong waittime = totalwait - (current - starttime);
+      waitspec.tv_sec = waittime / NANOSECS_PER_SEC;
+      waitspec.tv_nsec = waittime % NANOSECS_PER_SEC;
+    }
+
+    kr = semaphore_timedwait(_semaphore, waitspec);
+  }
+
+  return kr == KERN_SUCCESS;
+}
+
+#else
+
+bool Semaphore::trywait() {
+  return sem_trywait(&_semaphore) == 0;
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+  struct timespec ts;
+  jlong endtime = unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
+
+  while (1) {
+    int result = sem_timedwait(&_semaphore, &ts);
+    if (result == 0) {
+      return true;
+    } else if (errno == EINTR) {
+      continue;
+    } else if (errno == ETIMEDOUT) {
+      return false;
+    } else {
+      return false;
+    }
+  }
+}
+
+#endif // __APPLE__
+
+static os_semaphore_t sig_sem;
+static Semaphore sr_semaphore;
+
 void os::signal_init_pd() {
   // Initialize signal structures
   ::memset((void*)pending_signals, 0, sizeof(pending_signals));
@@ -2112,10 +2211,6 @@
   return anon_munmap(addr, size);
 }
 
-static address highest_vm_reserved_address() {
-  return _highest_vm_reserved_address;
-}
-
 static bool bsd_mprotect(char* addr, size_t size, int prot) {
   // Bsd wants the mprotect address argument to be page aligned.
   char* bottom = (char*)align_size_down((intptr_t)addr, os::Bsd::page_size());
@@ -2159,43 +2254,6 @@
   return false;
 }
 
-/*
-* Set the coredump_filter bits to include largepages in core dump (bit 6)
-*
-* From the coredump_filter documentation:
-*
-* - (bit 0) anonymous private memory
-* - (bit 1) anonymous shared memory
-* - (bit 2) file-backed private memory
-* - (bit 3) file-backed shared memory
-* - (bit 4) ELF header pages in file-backed private memory areas (it is
-*           effective only if the bit 2 is cleared)
-* - (bit 5) hugetlb private memory
-* - (bit 6) hugetlb shared memory
-*/
-static void set_coredump_filter(void) {
-  FILE *f;
-  long cdm;
-
-  if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
-    return;
-  }
-
-  if (fscanf(f, "%lx", &cdm) != 1) {
-    fclose(f);
-    return;
-  }
-
-  rewind(f);
-
-  if ((cdm & LARGEPAGES_BIT) == 0) {
-    cdm |= LARGEPAGES_BIT;
-    fprintf(f, "%#lx", cdm);
-  }
-
-  fclose(f);
-}
-
 // Large page support
 
 static size_t _large_page_size = 0;
@@ -2659,9 +2717,6 @@
 static void resume_clear_context(OSThread *osthread) {
   osthread->set_ucontext(NULL);
   osthread->set_siginfo(NULL);
-
-  // notify the suspend action is completed, we have now resumed
-  osthread->sr.clear_suspended();
 }
 
 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
@@ -2681,7 +2736,7 @@
 // its signal handlers run and prevents sigwait()'s use with the
 // mutex granting granting signal.
 //
-// Currently only ever called on the VMThread
+// Currently only ever called on the VMThread or JavaThread
 //
 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
   // Save and restore errno to avoid confusing native code with EINTR
@@ -2690,38 +2745,48 @@
 
   Thread* thread = Thread::current();
   OSThread* osthread = thread->osthread();
-  assert(thread->is_VM_thread(), "Must be VMThread");
-  // read current suspend action
-  int action = osthread->sr.suspend_action();
-  if (action == os::Bsd::SuspendResume::SR_SUSPEND) {
+  assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
+  os::SuspendResume::State current = osthread->sr.state();
+  if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
     suspend_save_context(osthread, siginfo, context);
 
-    // Notify the suspend action is about to be completed. do_suspend()
-    // waits until SR_SUSPENDED is set and then returns. We will wait
-    // here for a resume signal and that completes the suspend-other
-    // action. do_suspend/do_resume is always called as a pair from
-    // the same thread - so there are no races
-
-    // notify the caller
-    osthread->sr.set_suspended();
-
-    sigset_t suspend_set;  // signals for sigsuspend()
-
-    // get current set of blocked signals and unblock resume signal
-    pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
-    sigdelset(&suspend_set, SR_signum);
-
-    // wait here until we are resumed
-    do {
-      sigsuspend(&suspend_set);
-      // ignore all returns until we get a resume signal
-    } while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE);
+    // attempt to switch the state, we assume we had a SUSPEND_REQUEST
+    os::SuspendResume::State state = osthread->sr.suspended();
+    if (state == os::SuspendResume::SR_SUSPENDED) {
+      sigset_t suspend_set;  // signals for sigsuspend()
+
+      // get current set of blocked signals and unblock resume signal
+      pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
+      sigdelset(&suspend_set, SR_signum);
+
+      sr_semaphore.signal();
+      // wait here until we are resumed
+      while (1) {
+        sigsuspend(&suspend_set);
+
+        os::SuspendResume::State result = osthread->sr.running();
+        if (result == os::SuspendResume::SR_RUNNING) {
+          sr_semaphore.signal();
+          break;
+        } else if (result != os::SuspendResume::SR_SUSPENDED) {
+          ShouldNotReachHere();
+        }
+      }
+
+    } else if (state == os::SuspendResume::SR_RUNNING) {
+      // request was cancelled, continue
+    } else {
+      ShouldNotReachHere();
+    }
 
     resume_clear_context(osthread);
-
+  } else if (current == os::SuspendResume::SR_RUNNING) {
+    // request was cancelled, continue
+  } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
+    // ignore
   } else {
-    assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action");
-    // nothing special to do - just leave the handler
+    // ignore
   }
 
   errno = old_errno;
@@ -2765,42 +2830,82 @@
   return 0;
 }
 
+static int sr_notify(OSThread* osthread) {
+  int status = pthread_kill(osthread->pthread_id(), SR_signum);
+  assert_status(status == 0, status, "pthread_kill");
+  return status;
+}
+
+// "Randomly" selected value for how long we want to spin
+// before bailing out on suspending a thread, also how often
+// we send a signal to a thread we want to resume
+static const int RANDOMLY_LARGE_INTEGER = 1000000;
+static const int RANDOMLY_LARGE_INTEGER2 = 100;
 
 // returns true on success and false on error - really an error is fatal
 // but this seems the normal response to library errors
 static bool do_suspend(OSThread* osthread) {
+  assert(osthread->sr.is_running(), "thread should be running");
+  assert(!sr_semaphore.trywait(), "semaphore has invalid state");
+
   // mark as suspended and send signal
-  osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND);
-  int status = pthread_kill(osthread->pthread_id(), SR_signum);
-  assert_status(status == 0, status, "pthread_kill");
-
-  // check status and wait until notified of suspension
-  if (status == 0) {
-    for (int i = 0; !osthread->sr.is_suspended(); i++) {
-      os::yield_all(i);
-    }
-    osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
-    return true;
-  }
-  else {
-    osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
+  if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
+    // failed to switch, state wasn't running?
+    ShouldNotReachHere();
     return false;
   }
+
+  if (sr_notify(osthread) != 0) {
+    ShouldNotReachHere();
+  }
+
+  // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
+  while (true) {
+    if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+      break;
+    } else {
+      // timeout
+      os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
+      if (cancelled == os::SuspendResume::SR_RUNNING) {
+        return false;
+      } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
+        // make sure that we consume the signal on the semaphore as well
+        sr_semaphore.wait();
+        break;
+      } else {
+        ShouldNotReachHere();
+        return false;
+      }
+    }
+  }
+
+  guarantee(osthread->sr.is_suspended(), "Must be suspended");
+  return true;
 }
 
 static void do_resume(OSThread* osthread) {
   assert(osthread->sr.is_suspended(), "thread should be suspended");
-  osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE);
-
-  int status = pthread_kill(osthread->pthread_id(), SR_signum);
-  assert_status(status == 0, status, "pthread_kill");
-  // check status and wait unit notified of resumption
-  if (status == 0) {
-    for (int i = 0; osthread->sr.is_suspended(); i++) {
-      os::yield_all(i);
+  assert(!sr_semaphore.trywait(), "invalid semaphore state");
+
+  if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
+    // failed to switch to WAKEUP_REQUEST
+    ShouldNotReachHere();
+    return;
+  }
+
+  while (true) {
+    if (sr_notify(osthread) == 0) {
+      if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+        if (osthread->sr.is_running()) {
+          return;
+        }
+      }
+    } else {
+      ShouldNotReachHere();
     }
   }
-  osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
+
+  guarantee(osthread->sr.is_running(), "Must be running!");
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -3030,6 +3135,19 @@
     sigAct.sa_sigaction = signalHandler;
     sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
   }
+#if __APPLE__
+  // Needed for main thread as XNU (Mac OS X kernel) will only deliver SIGSEGV
+  // (which starts as SIGBUS) on main thread with faulting address inside "stack+guard pages"
+  // if the signal handler declares it will handle it on alternate stack.
+  // Notice we only declare we will handle it on alt stack, but we are not
+  // actually going to use real alt stack - this is just a workaround.
+  // Please see ux_exception.c, method catch_mach_exception_raise for details
+  // link http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/uxkern/ux_exception.c
+  if (sig == SIGSEGV) {
+    sigAct.sa_flags |= SA_ONSTACK;
+  }
+#endif
+
   // Save flags, which are set by ours
   assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
   sigflags[sig] = sigAct.sa_flags;
@@ -3538,7 +3656,40 @@
   return false;
 }
 
+void os::SuspendedThreadTask::internal_do_task() {
+  if (do_suspend(_thread->osthread())) {
+    SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
+    do_task(context);
+    do_resume(_thread->osthread());
+  }
+}
+
 ///
+class PcFetcher : public os::SuspendedThreadTask {
+public:
+  PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
+  ExtendedPC result();
+protected:
+  void do_task(const os::SuspendedThreadTaskContext& context);
+private:
+  ExtendedPC _epc;
+};
+
+ExtendedPC PcFetcher::result() {
+  guarantee(is_done(), "task is not done yet.");
+  return _epc;
+}
+
+void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
+  Thread* thread = context.thread();
+  OSThread* osthread = thread->osthread();
+  if (osthread->ucontext() != NULL) {
+    _epc = os::Bsd::ucontext_get_pc((ucontext_t *) context.ucontext());
+  } else {
+    // NULL context is unexpected, double-check this is the VMThread
+    guarantee(thread->is_VM_thread(), "can only be called for VMThread");
+  }
+}
 
 // Suspends the target using the signal mechanism and then grabs the PC before
 // resuming the target. Used by the flat-profiler only
@@ -3547,22 +3698,9 @@
   assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
   assert(thread->is_VM_thread(), "Can only be called for VMThread");
 
-  ExtendedPC epc;
-
-  OSThread* osthread = thread->osthread();
-  if (do_suspend(osthread)) {
-    if (osthread->ucontext() != NULL) {
-      epc = os::Bsd::ucontext_get_pc(osthread->ucontext());
-    } else {
-      // NULL context is unexpected, double-check this is the VMThread
-      guarantee(thread->is_VM_thread(), "can only be called for VMThread");
-    }
-    do_resume(osthread);
-  }
-  // failure means pthread_kill failed for some reason - arguably this is
-  // a fatal problem, but such problems are ignored elsewhere
-
-  return epc;
+  PcFetcher fetcher(thread);
+  fetcher.run();
+  return fetcher.result();
 }
 
 int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
@@ -4547,3 +4685,4 @@
 
   return n;
 }
+
--- a/src/os/bsd/vm/os_bsd.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/bsd/vm/os_bsd.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -145,36 +145,6 @@
   // BsdThreads work-around for 6292965
   static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
 
-
-  // Bsd suspend/resume support - this helper is a shadow of its former
-  // self now that low-level suspension is barely used, and old workarounds
-  // for BsdThreads are no longer needed.
-  class SuspendResume {
-  private:
-    volatile int  _suspend_action;
-    volatile jint _state;
-  public:
-    // values for suspend_action:
-    enum {
-      SR_NONE              = 0x00,
-      SR_SUSPEND           = 0x01,  // suspend request
-      SR_CONTINUE          = 0x02,  // resume request
-      SR_SUSPENDED         = 0x20   // values for _state: + SR_NONE
-    };
-
-    SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
-
-    int suspend_action() const     { return _suspend_action; }
-    void set_suspend_action(int x) { _suspend_action = x;    }
-
-    // atomic updates for _state
-    inline void set_suspended();
-    inline void clear_suspended();
-    bool is_suspended()            { return _state & SR_SUSPENDED;       }
-
-    #undef SR_SUSPENDED
-  };
-
 private:
   typedef int (*sched_getcpu_func_t)(void);
   typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
@@ -250,7 +220,7 @@
     int  TryPark () ;
     int  park (jlong millis) ;
     void SetAssociation (Thread * a) { _Assoc = a ; }
-} ;
+};
 
 class PlatformParker : public CHeapObj<mtInternal> {
   protected:
@@ -268,6 +238,6 @@
       status = pthread_mutex_init (_mutex, NULL);
       assert_status(status == 0, status, "mutex_init");
     }
-} ;
+};
 
 #endif // OS_BSD_VM_OS_BSD_HPP
--- a/src/os/bsd/vm/os_bsd.inline.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/bsd/vm/os_bsd.inline.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -286,20 +286,4 @@
   return ::setsockopt(fd, level, optname, optval, optlen);
 }
 
-inline void os::Bsd::SuspendResume::set_suspended()           {
-  jint temp, temp2;
-  do {
-    temp = _state;
-    temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
-  } while (temp2 != temp);
-}
-
-inline void os::Bsd::SuspendResume::clear_suspended()        {
-  jint temp, temp2;
-  do {
-    temp = _state;
-    temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
-  } while (temp2 != temp);
-}
-
 #endif // OS_BSD_VM_OS_BSD_INLINE_HPP
--- a/src/os/linux/vm/osThread_linux.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/linux/vm/osThread_linux.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@
   // flags that support signal based suspend/resume on Linux are in a
   // separate class to avoid confusion with many flags in OSThread that
   // are used by VM level suspend/resume.
-  os::Linux::SuspendResume sr;
+  os::SuspendResume sr;
 
   // _ucontext and _siginfo are used by SR_handler() to save thread context,
   // and they will later be used to walk the stack or reposition thread PC.
--- a/src/os/linux/vm/os_linux.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -101,6 +101,12 @@
 # include <inttypes.h>
 # include <sys/ioctl.h>
 
+// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
+// getrusage() is prepared to handle the associated failure.
+#ifndef RUSAGE_THREAD
+#define RUSAGE_THREAD   (1)               /* only the calling thread */
+#endif
+
 #define MAX_PATH    (2 * K)
 
 // for timer info max values which include all bits
@@ -145,6 +151,9 @@
 /* Used to protect dlsym() calls */
 static pthread_mutex_t dl_mutex;
 
+// Declarations
+static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
+
 #ifdef JAVASE_EMBEDDED
 class MemNotifyThread: public Thread {
   friend class VMStructs;
@@ -1338,15 +1347,19 @@
   return (1000 * 1000);
 }
 
-// For now, we say that linux does not support vtime.  I have no idea
-// whether it can actually be made to (DLD, 9/13/05).
-
-bool os::supports_vtime() { return false; }
+bool os::supports_vtime() { return true; }
 bool os::enable_vtime()   { return false; }
 bool os::vtime_enabled()  { return false; }
+
 double os::elapsedVTime() {
-  // better than nothing, but not much
-  return elapsedTime();
+  struct rusage usage;
+  int retval = getrusage(RUSAGE_THREAD, &usage);
+  if (retval == 0) {
+    return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000);
+  } else {
+    // better than nothing, but not much
+    return elapsedTime();
+  }
 }
 
 jlong os::javaTimeMillis() {
@@ -2399,6 +2412,57 @@
   return CAST_FROM_FN_PTR(void*, UserHandler);
 }
 
+class Semaphore : public StackObj {
+  public:
+    Semaphore();
+    ~Semaphore();
+    void signal();
+    void wait();
+    bool trywait();
+    bool timedwait(unsigned int sec, int nsec);
+  private:
+    sem_t _semaphore;
+};
+
+
+Semaphore::Semaphore() {
+  sem_init(&_semaphore, 0, 0);
+}
+
+Semaphore::~Semaphore() {
+  sem_destroy(&_semaphore);
+}
+
+void Semaphore::signal() {
+  sem_post(&_semaphore);
+}
+
+void Semaphore::wait() {
+  sem_wait(&_semaphore);
+}
+
+bool Semaphore::trywait() {
+  return sem_trywait(&_semaphore) == 0;
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+  struct timespec ts;
+  unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
+
+  while (1) {
+    int result = sem_timedwait(&_semaphore, &ts);
+    if (result == 0) {
+      return true;
+    } else if (errno == EINTR) {
+      continue;
+    } else if (errno == ETIMEDOUT) {
+      return false;
+    } else {
+      return false;
+    }
+  }
+}
+
 extern "C" {
   typedef void (*sa_handler_t)(int);
   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
@@ -2438,6 +2502,7 @@
 
 // Linux(POSIX) specific hand shaking semaphore.
 static sem_t sig_sem;
+static Semaphore sr_semaphore;
 
 void os::signal_init_pd() {
   // Initialize signal structures
@@ -3551,9 +3616,6 @@
 static void resume_clear_context(OSThread *osthread) {
   osthread->set_ucontext(NULL);
   osthread->set_siginfo(NULL);
-
-  // notify the suspend action is completed, we have now resumed
-  osthread->sr.clear_suspended();
 }
 
 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
@@ -3573,7 +3635,7 @@
 // its signal handlers run and prevents sigwait()'s use with the
 // mutex granting granting signal.
 //
-// Currently only ever called on the VMThread
+// Currently only ever called on the VMThread and JavaThreads (PC sampling)
 //
 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
   // Save and restore errno to avoid confusing native code with EINTR
@@ -3582,38 +3644,46 @@
 
   Thread* thread = Thread::current();
   OSThread* osthread = thread->osthread();
-  assert(thread->is_VM_thread(), "Must be VMThread");
-  // read current suspend action
-  int action = osthread->sr.suspend_action();
-  if (action == os::Linux::SuspendResume::SR_SUSPEND) {
+  assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
+  os::SuspendResume::State current = osthread->sr.state();
+  if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
     suspend_save_context(osthread, siginfo, context);
 
-    // Notify the suspend action is about to be completed. do_suspend()
-    // waits until SR_SUSPENDED is set and then returns. We will wait
-    // here for a resume signal and that completes the suspend-other
-    // action. do_suspend/do_resume is always called as a pair from
-    // the same thread - so there are no races
-
-    // notify the caller
-    osthread->sr.set_suspended();
-
-    sigset_t suspend_set;  // signals for sigsuspend()
-
-    // get current set of blocked signals and unblock resume signal
-    pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
-    sigdelset(&suspend_set, SR_signum);
-
-    // wait here until we are resumed
-    do {
-      sigsuspend(&suspend_set);
-      // ignore all returns until we get a resume signal
-    } while (osthread->sr.suspend_action() != os::Linux::SuspendResume::SR_CONTINUE);
+    // attempt to switch the state, we assume we had a SUSPEND_REQUEST
+    os::SuspendResume::State state = osthread->sr.suspended();
+    if (state == os::SuspendResume::SR_SUSPENDED) {
+      sigset_t suspend_set;  // signals for sigsuspend()
+
+      // get current set of blocked signals and unblock resume signal
+      pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
+      sigdelset(&suspend_set, SR_signum);
+
+      sr_semaphore.signal();
+      // wait here until we are resumed
+      while (1) {
+        sigsuspend(&suspend_set);
+
+        os::SuspendResume::State result = osthread->sr.running();
+        if (result == os::SuspendResume::SR_RUNNING) {
+          sr_semaphore.signal();
+          break;
+        }
+      }
+
+    } else if (state == os::SuspendResume::SR_RUNNING) {
+      // request was cancelled, continue
+    } else {
+      ShouldNotReachHere();
+    }
 
     resume_clear_context(osthread);
-
+  } else if (current == os::SuspendResume::SR_RUNNING) {
+    // request was cancelled, continue
+  } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
+    // ignore
   } else {
-    assert(action == os::Linux::SuspendResume::SR_CONTINUE, "unexpected sr action");
-    // nothing special to do - just leave the handler
+    // ignore
   }
 
   errno = old_errno;
@@ -3657,42 +3727,82 @@
   return 0;
 }
 
+static int sr_notify(OSThread* osthread) {
+  int status = pthread_kill(osthread->pthread_id(), SR_signum);
+  assert_status(status == 0, status, "pthread_kill");
+  return status;
+}
+
+// "Randomly" selected value for how long we want to spin
+// before bailing out on suspending a thread, also how often
+// we send a signal to a thread we want to resume
+static const int RANDOMLY_LARGE_INTEGER = 1000000;
+static const int RANDOMLY_LARGE_INTEGER2 = 100;
 
 // returns true on success and false on error - really an error is fatal
 // but this seems the normal response to library errors
 static bool do_suspend(OSThread* osthread) {
+  assert(osthread->sr.is_running(), "thread should be running");
+  assert(!sr_semaphore.trywait(), "semaphore has invalid state");
+
   // mark as suspended and send signal
-  osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_SUSPEND);
-  int status = pthread_kill(osthread->pthread_id(), SR_signum);
-  assert_status(status == 0, status, "pthread_kill");
-
-  // check status and wait until notified of suspension
-  if (status == 0) {
-    for (int i = 0; !osthread->sr.is_suspended(); i++) {
-      os::yield_all(i);
+  if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
+    // failed to switch, state wasn't running?
+    ShouldNotReachHere();
+    return false;
+  }
+
+  if (sr_notify(osthread) != 0) {
+    ShouldNotReachHere();
+  }
+
+  // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
+  while (true) {
+    if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+      break;
+    } else {
+      // timeout
+      os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
+      if (cancelled == os::SuspendResume::SR_RUNNING) {
+        return false;
+      } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
+        // make sure that we consume the signal on the semaphore as well
+        sr_semaphore.wait();
+        break;
+      } else {
+        ShouldNotReachHere();
+        return false;
+      }
     }
-    osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
-    return true;
-  }
-  else {
-    osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
-    return false;
-  }
+  }
+
+  guarantee(osthread->sr.is_suspended(), "Must be suspended");
+  return true;
 }
 
 static void do_resume(OSThread* osthread) {
   assert(osthread->sr.is_suspended(), "thread should be suspended");
-  osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_CONTINUE);
-
-  int status = pthread_kill(osthread->pthread_id(), SR_signum);
-  assert_status(status == 0, status, "pthread_kill");
-  // check status and wait unit notified of resumption
-  if (status == 0) {
-    for (int i = 0; osthread->sr.is_suspended(); i++) {
-      os::yield_all(i);
+  assert(!sr_semaphore.trywait(), "invalid semaphore state");
+
+  if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
+    // failed to switch to WAKEUP_REQUEST
+    ShouldNotReachHere();
+    return;
+  }
+
+  while (true) {
+    if (sr_notify(osthread) == 0) {
+      if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+        if (osthread->sr.is_running()) {
+          return;
+        }
+      }
+    } else {
+      ShouldNotReachHere();
     }
   }
-  osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
+
+  guarantee(osthread->sr.is_running(), "Must be running!");
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -4463,6 +4573,40 @@
 
 ///
 
+void os::SuspendedThreadTask::internal_do_task() {
+  if (do_suspend(_thread->osthread())) {
+    SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
+    do_task(context);
+    do_resume(_thread->osthread());
+  }
+}
+
+class PcFetcher : public os::SuspendedThreadTask {
+public:
+  PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
+  ExtendedPC result();
+protected:
+  void do_task(const os::SuspendedThreadTaskContext& context);
+private:
+  ExtendedPC _epc;
+};
+
+ExtendedPC PcFetcher::result() {
+  guarantee(is_done(), "task is not done yet.");
+  return _epc;
+}
+
+void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
+  Thread* thread = context.thread();
+  OSThread* osthread = thread->osthread();
+  if (osthread->ucontext() != NULL) {
+    _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
+  } else {
+    // NULL context is unexpected, double-check this is the VMThread
+    guarantee(thread->is_VM_thread(), "can only be called for VMThread");
+  }
+}
+
 // Suspends the target using the signal mechanism and then grabs the PC before
 // resuming the target. Used by the flat-profiler only
 ExtendedPC os::get_thread_pc(Thread* thread) {
@@ -4470,22 +4614,9 @@
   assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
   assert(thread->is_VM_thread(), "Can only be called for VMThread");
 
-  ExtendedPC epc;
-
-  OSThread* osthread = thread->osthread();
-  if (do_suspend(osthread)) {
-    if (osthread->ucontext() != NULL) {
-      epc = os::Linux::ucontext_get_pc(osthread->ucontext());
-    } else {
-      // NULL context is unexpected, double-check this is the VMThread
-      guarantee(thread->is_VM_thread(), "can only be called for VMThread");
-    }
-    do_resume(osthread);
-  }
-  // failure means pthread_kill failed for some reason - arguably this is
-  // a fatal problem, but such problems are ignored elsewhere
-
-  return epc;
+  PcFetcher fetcher(thread);
+  fetcher.run();
+  return fetcher.result();
 }
 
 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
@@ -5607,4 +5738,5 @@
     new MemNotifyThread(fd);
   }
 }
+
 #endif // JAVASE_EMBEDDED
--- a/src/os/linux/vm/os_linux.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/linux/vm/os_linux.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -210,35 +210,6 @@
   // LinuxThreads work-around for 6292965
   static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
 
-
-  // Linux suspend/resume support - this helper is a shadow of its former
-  // self now that low-level suspension is barely used, and old workarounds
-  // for LinuxThreads are no longer needed.
-  class SuspendResume {
-  private:
-    volatile int  _suspend_action;
-    volatile jint _state;
-  public:
-    // values for suspend_action:
-    enum {
-      SR_NONE              = 0x00,
-      SR_SUSPEND           = 0x01,  // suspend request
-      SR_CONTINUE          = 0x02,  // resume request
-      SR_SUSPENDED         = 0x20   // values for _state: + SR_NONE
-    };
-
-    SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
-
-    int suspend_action() const     { return _suspend_action; }
-    void set_suspend_action(int x) { _suspend_action = x;    }
-
-    // atomic updates for _state
-    inline void set_suspended();
-    inline void clear_suspended();
-    bool is_suspended()            { return _state & SR_SUSPENDED;       }
-
-  };
-
 private:
   typedef int (*sched_getcpu_func_t)(void);
   typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
@@ -333,6 +304,6 @@
       status = pthread_mutex_init (_mutex, NULL);
       assert_status(status == 0, status, "mutex_init");
     }
-} ;
+};
 
 #endif // OS_LINUX_VM_OS_LINUX_HPP
--- a/src/os/linux/vm/os_linux.inline.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/linux/vm/os_linux.inline.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -288,20 +288,4 @@
   return ::setsockopt(fd, level, optname, optval, optlen);
 }
 
-inline void os::Linux::SuspendResume::set_suspended() {
-  jint temp, temp2;
-  do {
-    temp = _state;
-    temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
-  } while (temp2 != temp);
-}
-
-inline void os::Linux::SuspendResume::clear_suspended()        {
-  jint temp, temp2;
-  do {
-    temp = _state;
-    temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
-  } while (temp2 != temp);
-}
-
 #endif // OS_LINUX_VM_OS_LINUX_INLINE_HPP
--- a/src/os/solaris/vm/osThread_solaris.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/solaris/vm/osThread_solaris.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,10 +41,6 @@
   _thread_id                         = 0;
   sigemptyset(&_caller_sigmask);
 
-  _current_callback                  = NULL;
-  _current_callback_lock = VM_Version::supports_compare_and_exchange() ? NULL
-                    : new Mutex(Mutex::suspend_resume, "Callback_lock", true);
-
   _saved_interrupt_thread_state      = _thread_new;
   _vm_created_thread                 = false;
 }
@@ -52,172 +48,6 @@
 void OSThread::pd_destroy() {
 }
 
-// Synchronous interrupt support
-//
-// _current_callback == NULL          no pending callback
-//                   == 1             callback_in_progress
-//                   == other value   pointer to the pending callback
-//
-
-// CAS on v8 is implemented by using a global atomic_memory_operation_lock,
-// which is shared by other atomic functions. It is OK for normal uses, but
-// dangerous if used after some thread is suspended or if used in signal
-// handlers. Instead here we use a special per-thread lock to synchronize
-// updating _current_callback if we are running on v8. Note in general trying
-// to grab locks after a thread is suspended is not safe, but it is safe for
-// updating _current_callback, because synchronous interrupt callbacks are
-// currently only used in:
-// 1. GetThreadPC_Callback - used by WatcherThread to profile VM thread
-// There is no overlap between the callbacks, which means we won't try to
-// grab a thread's sync lock after the thread has been suspended while holding
-// the same lock.
-
-// used after a thread is suspended
-static intptr_t compare_and_exchange_current_callback (
-       intptr_t callback, intptr_t *addr, intptr_t compare_value, Mutex *sync) {
-  if (VM_Version::supports_compare_and_exchange()) {
-    return Atomic::cmpxchg_ptr(callback, addr, compare_value);
-  } else {
-    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
-    if (*addr == compare_value) {
-      *addr = callback;
-      return compare_value;
-    } else {
-      return callback;
-    }
-  }
-}
-
-// used in signal handler
-static intptr_t exchange_current_callback(intptr_t callback, intptr_t *addr, Mutex *sync) {
-  if (VM_Version::supports_compare_and_exchange()) {
-    return Atomic::xchg_ptr(callback, addr);
-  } else {
-    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
-    intptr_t cb = *addr;
-    *addr = callback;
-    return cb;
-  }
-}
-
-// one interrupt at a time. spin if _current_callback != NULL
-int OSThread::set_interrupt_callback(Sync_Interrupt_Callback * cb) {
-  int count = 0;
-  while (compare_and_exchange_current_callback(
-         (intptr_t)cb, (intptr_t *)&_current_callback, (intptr_t)NULL, _current_callback_lock) != NULL) {
-    while (_current_callback != NULL) {
-      count++;
-#ifdef ASSERT
-      if ((WarnOnStalledSpinLock > 0) &&
-          (count % WarnOnStalledSpinLock == 0)) {
-          warning("_current_callback seems to be stalled: %p", _current_callback);
-      }
-#endif
-      os::yield_all(count);
-    }
-  }
-  return 0;
-}
-
-// reset _current_callback, spin if _current_callback is callback_in_progress
-void OSThread::remove_interrupt_callback(Sync_Interrupt_Callback * cb) {
-  int count = 0;
-  while (compare_and_exchange_current_callback(
-         (intptr_t)NULL, (intptr_t *)&_current_callback, (intptr_t)cb, _current_callback_lock) != (intptr_t)cb) {
-#ifdef ASSERT
-    intptr_t p = (intptr_t)_current_callback;
-    assert(p == (intptr_t)callback_in_progress ||
-           p == (intptr_t)cb, "wrong _current_callback value");
-#endif
-    while (_current_callback != cb) {
-      count++;
-#ifdef ASSERT
-      if ((WarnOnStalledSpinLock > 0) &&
-          (count % WarnOnStalledSpinLock == 0)) {
-          warning("_current_callback seems to be stalled: %p", _current_callback);
-      }
-#endif
-      os::yield_all(count);
-    }
-  }
-}
-
-void OSThread::do_interrupt_callbacks_at_interrupt(InterruptArguments *args) {
-  Sync_Interrupt_Callback * cb;
-  cb = (Sync_Interrupt_Callback *)exchange_current_callback(
-        (intptr_t)callback_in_progress, (intptr_t *)&_current_callback, _current_callback_lock);
-
-  if (cb == NULL) {
-    // signal is delivered too late (thread is masking interrupt signal??).
-    // there is nothing we need to do because requesting thread has given up.
-  } else if ((intptr_t)cb == (intptr_t)callback_in_progress) {
-    fatal("invalid _current_callback state");
-  } else {
-    assert(cb->target()->osthread() == this, "wrong target");
-    cb->execute(args);
-    cb->leave_callback();             // notify the requester
-  }
-
-  // restore original _current_callback value
-  intptr_t p;
-  p = exchange_current_callback((intptr_t)cb, (intptr_t *)&_current_callback, _current_callback_lock);
-  assert(p == (intptr_t)callback_in_progress, "just checking");
-}
-
-// Called by the requesting thread to send a signal to target thread and
-// execute "this" callback from the signal handler.
-int OSThread::Sync_Interrupt_Callback::interrupt(Thread * target, int timeout) {
-  // Let signals to the vm_thread go even if the Threads_lock is not acquired
-  assert(Threads_lock->owned_by_self() || (target == VMThread::vm_thread()),
-         "must have threads lock to call this");
-
-  OSThread * osthread = target->osthread();
-
-  // may block if target thread already has a pending callback
-  osthread->set_interrupt_callback(this);
-
-  _target = target;
-
-  int rslt = thr_kill(osthread->thread_id(), os::Solaris::SIGasync());
-  assert(rslt == 0, "thr_kill != 0");
-
-  bool status = false;
-  jlong t1 = os::javaTimeMillis();
-  { // don't use safepoint check because we might be the watcher thread.
-    MutexLockerEx ml(_sync, Mutex::_no_safepoint_check_flag);
-    while (!is_done()) {
-      status = _sync->wait(Mutex::_no_safepoint_check_flag, timeout);
-
-      // status == true if timed out
-      if (status) break;
-
-      // update timeout
-      jlong t2 = os::javaTimeMillis();
-      timeout -= t2 - t1;
-      t1 = t2;
-    }
-  }
-
-  // reset current_callback
-  osthread->remove_interrupt_callback(this);
-
-  return status;
-}
-
-void OSThread::Sync_Interrupt_Callback::leave_callback() {
-  if (!_sync->owned_by_self()) {
-    // notify requesting thread
-    MutexLockerEx ml(_sync, Mutex::_no_safepoint_check_flag);
-    _is_done = true;
-    _sync->notify_all();
-  } else {
-    // Current thread is interrupted while it is holding the _sync lock, trying
-    // to grab it again will deadlock. The requester will timeout anyway,
-    // so just return.
-    _is_done = true;
-  }
-}
-
 // copied from synchronizer.cpp
 
 void OSThread::handle_spinlock_contention(int tries) {
@@ -229,3 +59,7 @@
     os::yield();          // Yield to threads of same or higher priority
   }
 }
+
+void OSThread::SR_handler(Thread* thread, ucontext_t* uc) {
+  os::Solaris::SR_handler(thread, uc);
+}
--- a/src/os/solaris/vm/osThread_solaris.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/solaris/vm/osThread_solaris.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,61 +72,15 @@
  // ***************************************************************
 
  public:
-
-  class InterruptArguments : StackObj {
-   private:
-    Thread*     _thread;   // the thread to signal was dispatched to
-    ucontext_t* _ucontext; // the machine context at the time of the signal
-
-   public:
-    InterruptArguments(Thread* thread, ucontext_t* ucontext) {
-      _thread   = thread;
-      _ucontext = ucontext;
-    }
-
-    Thread*     thread()   const { return _thread;   }
-    ucontext_t* ucontext() const { return _ucontext; }
-  };
-
-  // There are currently no asynchronous callbacks - and we'd better not
-  // support them in the future either, as they need to be deallocated from
-  // the interrupt handler, which is not safe; they also require locks to
-  // protect the callback queue.
-
-  class Sync_Interrupt_Callback : private StackObj {
-   protected:
-    volatile bool _is_done;
-    Monitor*      _sync;
-    Thread*       _target;
-   public:
-    Sync_Interrupt_Callback(Monitor * sync) {
-      _is_done = false;  _target = NULL;  _sync = sync;
-    }
-
-    bool is_done() const               { return _is_done; }
-    Thread* target() const             { return _target;  }
-
-    int interrupt(Thread * target, int timeout);
-
-    // override to implement the callback.
-    virtual void execute(InterruptArguments *args) = 0;
-
-    void leave_callback();
-  };
+  os::SuspendResume sr;
 
  private:
-
-  Sync_Interrupt_Callback * volatile _current_callback;
-  enum {
-    callback_in_progress = 1
-  };
-  Mutex * _current_callback_lock;       // only used on v8
+  ucontext_t* _ucontext;
 
  public:
-
-  int set_interrupt_callback    (Sync_Interrupt_Callback * cb);
-  void remove_interrupt_callback(Sync_Interrupt_Callback * cb);
-  void do_interrupt_callbacks_at_interrupt(InterruptArguments *args);
+  ucontext_t* ucontext() const { return _ucontext; }
+  void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; }
+  static void SR_handler(Thread* thread, ucontext_t* uc);
 
  // ***************************************************************
  // java.lang.Thread.interrupt state.
--- a/src/os/solaris/vm/os_share_solaris.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/solaris/vm/os_share_solaris.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,28 +27,6 @@
 
 // Defines the interfaces to Solaris operating systems that vary across platforms
 
-
-// This is a simple callback that just fetches a PC for an interrupted thread.
-// The thread need not be suspended and the fetched PC is just a hint.
-// Returned PC and nPC are not necessarily consecutive.
-// This one is currently used for profiling the VMThread ONLY!
-
-// Must be synchronous
-class GetThreadPC_Callback : public OSThread::Sync_Interrupt_Callback {
- private:
-  ExtendedPC _addr;
-
- public:
-
-  GetThreadPC_Callback(Monitor *sync) :
-    OSThread::Sync_Interrupt_Callback(sync) { }
-  ExtendedPC addr() const { return _addr; }
-
-  void set_addr(ExtendedPC addr) { _addr = addr; }
-
-  void execute(OSThread::InterruptArguments *args);
-};
-
 // misc
 extern "C" {
   void signalHandler(int, siginfo_t*, void*);
--- a/src/os/solaris/vm/os_solaris.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -240,6 +240,8 @@
   static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
 }
 
+static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
+
 // Thread Local Storage
 // This is common to all Solaris platforms so it is defined here,
 // in this common file.
@@ -2580,6 +2582,57 @@
   return CAST_FROM_FN_PTR(void*, UserHandler);
 }
 
+class Semaphore : public StackObj {
+  public:
+    Semaphore();
+    ~Semaphore();
+    void signal();
+    void wait();
+    bool trywait();
+    bool timedwait(unsigned int sec, int nsec);
+  private:
+    sema_t _semaphore;
+};
+
+
+Semaphore::Semaphore() {
+  sema_init(&_semaphore, 0, NULL, NULL);
+}
+
+Semaphore::~Semaphore() {
+  sema_destroy(&_semaphore);
+}
+
+void Semaphore::signal() {
+  sema_post(&_semaphore);
+}
+
+void Semaphore::wait() {
+  sema_wait(&_semaphore);
+}
+
+bool Semaphore::trywait() {
+  return sema_trywait(&_semaphore) == 0;
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+  struct timespec ts;
+  unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
+
+  while (1) {
+    int result = sema_timedwait(&_semaphore, &ts);
+    if (result == 0) {
+      return true;
+    } else if (errno == EINTR) {
+      continue;
+    } else if (errno == ETIME) {
+      return false;
+    } else {
+      return false;
+    }
+  }
+}
+
 extern "C" {
   typedef void (*sa_handler_t)(int);
   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
@@ -4164,6 +4217,68 @@
   schedctl_start(schedctl_init());
 }
 
+static void resume_clear_context(OSThread *osthread) {
+  osthread->set_ucontext(NULL);
+}
+
+static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
+  osthread->set_ucontext(context);
+}
+
+static Semaphore sr_semaphore;
+
+void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
+  // Save and restore errno to avoid confusing native code with EINTR
+  // after sigsuspend.
+  int old_errno = errno;
+
+  OSThread* osthread = thread->osthread();
+  assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
+  os::SuspendResume::State current = osthread->sr.state();
+  if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
+    suspend_save_context(osthread, uc);
+
+    // attempt to switch the state, we assume we had a SUSPEND_REQUEST
+    os::SuspendResume::State state = osthread->sr.suspended();
+    if (state == os::SuspendResume::SR_SUSPENDED) {
+      sigset_t suspend_set;  // signals for sigsuspend()
+
+      // get current set of blocked signals and unblock resume signal
+      thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set);
+      sigdelset(&suspend_set, os::Solaris::SIGasync());
+
+      sr_semaphore.signal();
+      // wait here until we are resumed
+      while (1) {
+        sigsuspend(&suspend_set);
+
+        os::SuspendResume::State result = osthread->sr.running();
+        if (result == os::SuspendResume::SR_RUNNING) {
+          sr_semaphore.signal();
+          break;
+        }
+      }
+
+    } else if (state == os::SuspendResume::SR_RUNNING) {
+      // request was cancelled, continue
+    } else {
+      ShouldNotReachHere();
+    }
+
+    resume_clear_context(osthread);
+  } else if (current == os::SuspendResume::SR_RUNNING) {
+    // request was cancelled, continue
+  } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
+    // ignore
+  } else {
+    // ignore
+  }
+
+  errno = old_errno;
+}
+
+
 void os::interrupt(Thread* thread) {
   assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
 
@@ -4247,6 +4362,116 @@
   return buf[0] == 'y' || buf[0] == 'Y';
 }
 
+static int sr_notify(OSThread* osthread) {
+  int status = thr_kill(osthread->thread_id(), os::Solaris::SIGasync());
+  assert_status(status == 0, status, "thr_kill");
+  return status;
+}
+
+// "Randomly" selected value for how long we want to spin
+// before bailing out on suspending a thread, also how often
+// we send a signal to a thread we want to resume
+static const int RANDOMLY_LARGE_INTEGER = 1000000;
+static const int RANDOMLY_LARGE_INTEGER2 = 100;
+
+static bool do_suspend(OSThread* osthread) {
+  assert(osthread->sr.is_running(), "thread should be running");
+  assert(!sr_semaphore.trywait(), "semaphore has invalid state");
+
+  // mark as suspended and send signal
+  if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
+    // failed to switch, state wasn't running?
+    ShouldNotReachHere();
+    return false;
+  }
+
+  if (sr_notify(osthread) != 0) {
+    ShouldNotReachHere();
+  }
+
+  // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
+  while (true) {
+    if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) {
+      break;
+    } else {
+      // timeout
+      os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
+      if (cancelled == os::SuspendResume::SR_RUNNING) {
+        return false;
+      } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
+        // make sure that we consume the signal on the semaphore as well
+        sr_semaphore.wait();
+        break;
+      } else {
+        ShouldNotReachHere();
+        return false;
+      }
+    }
+  }
+
+  guarantee(osthread->sr.is_suspended(), "Must be suspended");
+  return true;
+}
+
+static void do_resume(OSThread* osthread) {
+  assert(osthread->sr.is_suspended(), "thread should be suspended");
+  assert(!sr_semaphore.trywait(), "invalid semaphore state");
+
+  if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
+    // failed to switch to WAKEUP_REQUEST
+    ShouldNotReachHere();
+    return;
+  }
+
+  while (true) {
+    if (sr_notify(osthread) == 0) {
+      if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+        if (osthread->sr.is_running()) {
+          return;
+        }
+      }
+    } else {
+      ShouldNotReachHere();
+    }
+  }
+
+  guarantee(osthread->sr.is_running(), "Must be running!");
+}
+
+void os::SuspendedThreadTask::internal_do_task() {
+  if (do_suspend(_thread->osthread())) {
+    SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
+    do_task(context);
+    do_resume(_thread->osthread());
+  }
+}
+
+class PcFetcher : public os::SuspendedThreadTask {
+public:
+  PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
+  ExtendedPC result();
+protected:
+  void do_task(const os::SuspendedThreadTaskContext& context);
+private:
+  ExtendedPC _epc;
+};
+
+ExtendedPC PcFetcher::result() {
+  guarantee(is_done(), "task is not done yet.");
+  return _epc;
+}
+
+void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
+  Thread* thread = context.thread();
+  OSThread* osthread = thread->osthread();
+  if (osthread->ucontext() != NULL) {
+    _epc = os::Solaris::ucontext_get_pc((ucontext_t *) context.ucontext());
+  } else {
+    // NULL context is unexpected, double-check this is the VMThread
+    guarantee(thread->is_VM_thread(), "can only be called for VMThread");
+  }
+}
+
 // A lightweight implementation that does not suspend the target thread and
 // thus returns only a hint. Used for profiling only!
 ExtendedPC os::get_thread_pc(Thread* thread) {
@@ -4254,21 +4479,9 @@
   assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
   // For now, is only used to profile the VM Thread
   assert(thread->is_VM_thread(), "Can only be called for VMThread");
-  ExtendedPC epc;
-
-  GetThreadPC_Callback  cb(ProfileVM_lock);
-  OSThread *osthread = thread->osthread();
-  const int time_to_wait = 400; // 400ms wait for initial response
-  int status = cb.interrupt(thread, time_to_wait);
-
-  if (cb.is_done() ) {
-    epc = cb.addr();
-  } else {
-    DEBUG_ONLY(tty->print_cr("Failed to get pc for thread: %d got %d status",
-                              osthread->thread_id(), status););
-    // epc is already NULL
-  }
-  return epc;
+  PcFetcher fetcher(thread);
+  fetcher.run();
+  return fetcher.result();
 }
 
 
--- a/src/os/solaris/vm/os_solaris.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/solaris/vm/os_solaris.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,6 @@
   static void set_SIGinterrupt(int newsig) { _SIGinterrupt = newsig; }
   static void set_SIGasync(int newsig) { _SIGasync = newsig; }
 
-
  public:
   // Large Page Support--ISM.
   static bool largepage_range(char* addr, size_t size);
@@ -145,6 +144,7 @@
   static intptr_t*   ucontext_get_sp(ucontext_t* uc);
   // ucontext_get_fp() is only used by Solaris X86 (see note below)
   static intptr_t*   ucontext_get_fp(ucontext_t* uc);
+  static address    ucontext_get_pc(ucontext_t* uc);
 
   // For Analyzer Forte AsyncGetCallTrace profiling support:
   // Parameter ret_fp is only used by Solaris X86.
@@ -157,6 +157,8 @@
 
   static void hotspot_sigmask(Thread* thread);
 
+  // SR_handler
+  static void SR_handler(Thread* thread, ucontext_t* uc);
  protected:
   // Solaris-specific interface goes here
   static julong available_memory();
--- a/src/os/windows/vm/os_windows.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -813,15 +813,21 @@
   return result;
 }
 
-// For now, we say that Windows does not support vtime.  I have no idea
-// whether it can actually be made to (DLD, 9/13/05).
-
-bool os::supports_vtime() { return false; }
+bool os::supports_vtime() { return true; }
 bool os::enable_vtime() { return false; }
 bool os::vtime_enabled() { return false; }
+
 double os::elapsedVTime() {
-  // better than nothing, but not much
-  return elapsedTime();
+  FILETIME created;
+  FILETIME exited;
+  FILETIME kernel;
+  FILETIME user;
+  if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) {
+    // the resolution of windows_to_java_time() should be sufficient (ms)
+    return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS;
+  } else {
+    return elapsedTime();
+  }
 }
 
 jlong os::javaTimeMillis() {
@@ -944,6 +950,8 @@
   MINIDUMP_TYPE dumpType;
   static const char* cwd;
 
+// Default is to always create dump for debug builds, on product builds only dump on server versions of Windows.
+#ifndef ASSERT
   // If running on a client version of Windows and user has not explicitly enabled dumping
   if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
     VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
@@ -953,6 +961,12 @@
     VMError::report_coredump_status("Minidump has been disabled from the command line", false);
     return;
   }
+#else
+  if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
+    VMError::report_coredump_status("Minidump has been disabled from the command line", false);
+    return;
+  }
+#endif
 
   dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);
 
@@ -1004,7 +1018,21 @@
   // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
   if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
       _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
-    VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false);
+        DWORD error = GetLastError();
+        LPTSTR msgbuf = NULL;
+
+        if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                      FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS,
+                      NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) {
+
+          jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf);
+          LocalFree(msgbuf);
+        } else {
+          // Call to FormatMessage failed, just include the result from GetLastError
+          jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error);
+        }
+        VMError::report_coredump_status(buffer, false);
   } else {
     VMError::report_coredump_status(buffer, true);
   }
@@ -5020,6 +5048,71 @@
   return ::setsockopt(fd, level, optname, optval, optlen);
 }
 
+// WINDOWS CONTEXT Flags for THREAD_SAMPLING
+#if defined(IA32)
+#  define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
+#elif defined (AMD64)
+#  define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
+#endif
+
+// returns true if thread could be suspended,
+// false otherwise
+static bool do_suspend(HANDLE* h) {
+  if (h != NULL) {
+    if (SuspendThread(*h) != ~0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// resume the thread
+// calling resume on an active thread is a no-op
+static void do_resume(HANDLE* h) {
+  if (h != NULL) {
+    ResumeThread(*h);
+  }
+}
+
+// retrieve a suspend/resume context capable handle
+// from the tid. Caller validates handle return value.
+void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) {
+  if (h != NULL) {
+    *h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);
+  }
+}
+
+//
+// Thread sampling implementation
+//
+void os::SuspendedThreadTask::internal_do_task() {
+  CONTEXT    ctxt;
+  HANDLE     h = NULL;
+
+  // get context capable handle for thread
+  get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id());
+
+  // sanity
+  if (h == NULL || h == INVALID_HANDLE_VALUE) {
+    return;
+  }
+
+  // suspend the thread
+  if (do_suspend(&h)) {
+    ctxt.ContextFlags = sampling_context_flags;
+    // get thread context
+    GetThreadContext(h, &ctxt);
+    SuspendedThreadTaskContext context(_thread, &ctxt);
+    // pass context to Thread Sampling impl
+    do_task(context);
+    // resume thread
+    do_resume(&h);
+  }
+
+  // close handle
+  CloseHandle(h);
+}
+
 
 // Kernel32 API
 typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
--- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,16 @@
 // currently interrupted by SIGPROF
 bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
   void* ucontext, bool isInJava) {
+  assert(Thread::current() == this, "caller must be current thread");
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
 
-  assert(Thread::current() == this, "caller must be current thread");
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
   assert(this->is_Java_thread(), "must be JavaThread");
-
   JavaThread* jt = (JavaThread *)this;
 
   // If we have a last_Java_frame, then we should use it even if
--- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,13 @@
   bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
     bool isInJava);
 
+  bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
+    bool isInJava);
+
+private:
+  bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
+public:
+
   // These routines are only used on cpu architectures that
   // have separate register stacks (Itanium).
   static bool register_stack_overflow() { return false; }
--- a/src/os_cpu/linux_x86/vm/linux_x86_32.s	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/linux_x86/vm/linux_x86_32.s	Fri Jun 21 15:56:24 2013 -0700
@@ -241,7 +241,7 @@
         jbe      2f                   # <= 32 dwords
         rep;     smovl
         jmp      4f
-	.=.+8
+	.space 8
 2:      subl     %esi,%edi
         .p2align 4,,15
 3:      movl     (%esi),%edx
@@ -378,7 +378,7 @@
         rep;     smovl
         jmp      4f 
         # copy aligned dwords
-        .=.+5
+        .space 5
 2:      subl     %esi,%edi 
         .p2align 4,,15
 3:      movl     (%esi),%edx
@@ -454,7 +454,7 @@
         popl     %edi
         popl     %esi
         ret
-        .=.+10
+        .space 10
 2:      subl     %esi,%edi
         jmp      4f
         .p2align 4,,15
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -93,6 +93,10 @@
   register void *esp;
   __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
   return (address) ((char*)esp + sizeof(long)*2);
+#elif defined(__clang__)
+  intptr_t* esp;
+  __asm__ __volatile__ ("mov %%"SPELL_REG_SP", %0":"=r"(esp):);
+  return (address) esp;
 #else
   register void *esp __asm__ (SPELL_REG_SP);
   return (address) esp;
@@ -175,6 +179,9 @@
 #ifdef SPARC_WORKS
   register intptr_t **ebp;
   __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
+#elif defined(__clang__)
+  intptr_t **ebp;
+  __asm__ __volatile__ ("mov %%"SPELL_REG_FP", %0":"=r"(ebp):);
 #else
   register intptr_t **ebp __asm__ (SPELL_REG_FP);
 #endif
--- a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,15 @@
   void* ucontext, bool isInJava) {
 
   assert(Thread::current() == this, "caller must be current thread");
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
   assert(this->is_Java_thread(), "must be JavaThread");
-
   JavaThread* jt = (JavaThread *)this;
 
   // If we have a last_Java_frame, then we should use it even if
--- a/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,11 @@
   bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
     bool isInJava);
 
+  bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
+private:
+  bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
+public:
+
   // These routines are only used on cpu architectures that
   // have separate register stacks (Itanium).
   static bool register_stack_overflow() { return false; }
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -194,6 +194,11 @@
   return NULL;
 }
 
+address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
+  return (address) uc->uc_mcontext.gregs[REG_PC];
+}
+
+
 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 // is currently interrupted by SIGPROF.
 //
@@ -265,22 +270,6 @@
   }
 }
 
-
-void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
-  Thread*     thread = args->thread();
-  ucontext_t* uc     = args->ucontext();
-  intptr_t* sp;
-
-  assert(ProfileVM && thread->is_VM_thread(), "just checking");
-
-  // Skip the mcontext corruption verification. If if occasionally
-  // things get corrupt, it is ok for profiling - we will just get an unresolved
-  // function name
-  ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
-  _addr = new_addr;
-}
-
-
 static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
   char lwpstatusfile[PROCFILE_LENGTH];
   int lwpfd, err;
@@ -358,13 +347,8 @@
   guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
 
   if (sig == os::Solaris::SIGasync()) {
-    if (thread) {
-      OSThread::InterruptArguments args(thread, uc);
-      thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
-      return true;
-    } else if (vmthread) {
-      OSThread::InterruptArguments args(vmthread, uc);
-      vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
+    if (thread || vmthread) {
+      OSThread::SR_handler(t, uc);
       return true;
     } else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
       return true;
--- a/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,11 +36,21 @@
   void* ucontext, bool isInJava) {
 
   assert(Thread::current() == this, "caller must be current thread");
+  return pd_get_top_frame(fr_addr, ucontext, isInJava, true);
+}
+
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+  // get ucontext somehow
+  return pd_get_top_frame(fr_addr, ucontext, isInJava, false);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr,
+  void* ucontext, bool isInJava, bool makeWalkable) {
   assert(this->is_Java_thread(), "must be JavaThread");
 
   JavaThread* jt = (JavaThread *)this;
 
-  if (!isInJava) {
+  if (!isInJava && makeWalkable) {
     // make_walkable flushes register windows and grabs last_Java_pc
     // which can not be done if the ucontext sp matches last_Java_sp
     // stack walking utilities assume last_Java_pc set if marked flushed
--- a/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -93,6 +93,11 @@
   bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
     bool isInJava);
 
+  bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
+private:
+  bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava, bool makeWalkable);
+public:
+
   // These routines are only used on cpu architectures that
   // have separate register stacks (Itanium).
   static bool register_stack_overflow() { return false; }
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -183,6 +183,10 @@
   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
 }
 
+address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
+  return (address) uc->uc_mcontext.gregs[REG_PC];
+}
+
 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 // is currently interrupted by SIGPROF.
 //
@@ -252,22 +256,6 @@
   }
 }
 
-// This is a simple callback that just fetches a PC for an interrupted thread.
-// The thread need not be suspended and the fetched PC is just a hint.
-// This one is currently used for profiling the VMThread ONLY!
-
-// Must be synchronous
-void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
-  Thread*     thread = args->thread();
-  ucontext_t* uc     = args->ucontext();
-  intptr_t* sp;
-
-  assert(ProfileVM && thread->is_VM_thread(), "just checking");
-
-  ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
-  _addr = new_addr;
-}
-
 static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
   char lwpstatusfile[PROCFILE_LENGTH];
   int lwpfd, err;
@@ -419,14 +407,8 @@
   guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
 
   if (sig == os::Solaris::SIGasync()) {
-    if(thread){
-      OSThread::InterruptArguments args(thread, uc);
-      thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
-      return true;
-    }
-    else if(vmthread){
-      OSThread::InterruptArguments args(vmthread, uc);
-      vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
+    if(thread || vmthread){
+      OSThread::SR_handler(t, uc);
       return true;
     } else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
       return true;
--- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,17 @@
 // currently interrupted by SIGPROF
 bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
   void* ucontext, bool isInJava) {
+  assert(Thread::current() == this, "caller must be current thread");
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
 
-  assert(Thread::current() == this, "caller must be current thread");
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr,
+  void* ucontext, bool isInJava) {
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr,
+  void* ucontext, bool isInJava) {
   assert(this->is_Java_thread(), "must be JavaThread");
   JavaThread* jt = (JavaThread *)this;
 
--- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,12 @@
 
   bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
     bool isInJava);
+  bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
+    bool isInJava);
+private:
+  bool pd_get_top_frame(frame* fr_addr, void* ucontext,
+    bool isInJava);
+public:
 
   // These routines are only used on cpu architectures that
   // have separate register stacks (Itanium).
--- a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,15 @@
   void* ucontext, bool isInJava) {
 
   assert(Thread::current() == this, "caller must be current thread");
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+  return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
+
   assert(this->is_Java_thread(), "must be JavaThread");
 
   JavaThread* jt = (JavaThread *)this;
@@ -87,4 +96,3 @@
 }
 
 void JavaThread::cache_global_variables() { }
-
--- a/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,12 @@
   bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
     bool isInJava);
 
+   bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
+
+private:
+  bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
+
+ public:
   // These routines are only used on cpu architectures that
   // have separate register stacks (Itanium).
   static bool register_stack_overflow() { return false; }
--- a/src/share/tools/ProjectCreator/BuildConfig.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/tools/ProjectCreator/BuildConfig.java	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,7 @@
         sysDefines.add("_WINDOWS");
         sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\"");
         sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\"");
-        sysDefines.add("INCLUDE_TRACE");
+        sysDefines.add("INCLUDE_TRACE=1");
         sysDefines.add("_JNI_IMPLEMENTATION_");
         if (vars.get("PlatformName").equals("Win32")) {
             sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\"");
--- a/src/share/vm/adlc/archDesc.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/adlc/archDesc.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -29,8 +29,8 @@
 static FILE *errfile = stderr;
 
 //--------------------------- utility functions -----------------------------
-inline char  toUpper(char lower) {
-  return (('a' <= lower && lower <= 'z') ? (lower + ('A'-'a')) : lower);
+inline char toUpper(char lower) {
+  return (('a' <= lower && lower <= 'z') ? ((char) (lower + ('A'-'a'))) : lower);
 }
 char *toUpper(const char *str) {
   char *upper  = new char[strlen(str)+1];
--- a/src/share/vm/adlc/dict2.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/adlc/dict2.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -64,18 +64,18 @@
   int i;
 
   // Precompute table of null character hashes
-  if( !initflag ) {             // Not initializated yet?
-    xsum[0] = (1<<shft[0])+1;   // Initialize
+  if (!initflag) {              // Not initializated yet?
+    xsum[0] = (short) ((1 << shft[0]) + 1);  // Initialize
     for( i = 1; i < MAXID; i++) {
-      xsum[i] = (1<<shft[i])+1+xsum[i-1];
+      xsum[i] = (short) ((1 << shft[i]) + 1 + xsum[i-1]);
     }
     initflag = 1;               // Never again
   }
 
   _size = 16;                   // Size is a power of 2
   _cnt = 0;                     // Dictionary is empty
-  _bin = (bucket*)_arena->Amalloc_4(sizeof(bucket)*_size);
-  memset(_bin,0,sizeof(bucket)*_size);
+  _bin = (bucket*)_arena->Amalloc_4(sizeof(bucket) * _size);
+  memset(_bin, 0, sizeof(bucket) * _size);
 }
 
 //------------------------------~Dict------------------------------------------
@@ -287,11 +287,11 @@
   register int sum = 0;
   register const char *s = (const char *)t;
 
-  while( ((c = s[k]) != '\0') && (k < MAXID-1) ) { // Get characters till nul
-    c = (c<<1)+1;               // Characters are always odd!
-    sum += c + (c<<shft[k++]);  // Universal hash function
+  while (((c = s[k]) != '\0') && (k < MAXID-1)) { // Get characters till nul
+    c = (char) ((c << 1) + 1);    // Characters are always odd!
+    sum += c + (c << shft[k++]);  // Universal hash function
   }
-  assert( k < (MAXID), "Exceeded maximum name length");
+  assert(k < (MAXID), "Exceeded maximum name length");
   return (int)((sum+xsum[k]) >> 1); // Hash key, un-modulo'd table size
 }
 
--- a/src/share/vm/adlc/formssel.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/adlc/formssel.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -796,11 +796,11 @@
   return num_opnds;
 }
 
-const char *InstructForm::opnd_ident(int idx) {
+const char* InstructForm::opnd_ident(int idx) {
   return _components.at(idx)->_name;
 }
 
-const char *InstructForm::unique_opnd_ident(int idx) {
+const char* InstructForm::unique_opnd_ident(uint idx) {
   uint i;
   for (i = 1; i < num_opnds(); ++i) {
     if (unique_opnds_idx(i) == idx) {
@@ -1315,36 +1315,36 @@
 // Seach through operands to determine parameters unique positions.
 void InstructForm::set_unique_opnds() {
   uint* uniq_idx = NULL;
-  int  nopnds = num_opnds();
+  uint  nopnds = num_opnds();
   uint  num_uniq = nopnds;
-  int i;
+  uint i;
   _uniq_idx_length = 0;
-  if ( nopnds > 0 ) {
+  if (nopnds > 0) {
     // Allocate index array.  Worst case we're mapping from each
     // component back to an index and any DEF always goes at 0 so the
     // length of the array has to be the number of components + 1.
     _uniq_idx_length = _components.count() + 1;
-    uniq_idx = (uint*) malloc(sizeof(uint)*(_uniq_idx_length));
-    for( i = 0; i < _uniq_idx_length; i++ ) {
+    uniq_idx = (uint*) malloc(sizeof(uint) * _uniq_idx_length);
+    for (i = 0; i < _uniq_idx_length; i++) {
       uniq_idx[i] = i;
     }
   }
   // Do it only if there is a match rule and no expand rule.  With an
   // expand rule it is done by creating new mach node in Expand()
   // method.
-  if ( nopnds > 0 && _matrule != NULL && _exprule == NULL ) {
+  if (nopnds > 0 && _matrule != NULL && _exprule == NULL) {
     const char *name;
     uint count;
     bool has_dupl_use = false;
 
     _parameters.reset();
-    while( (name = _parameters.iter()) != NULL ) {
+    while ((name = _parameters.iter()) != NULL) {
       count = 0;
-      int position = 0;
-      int uniq_position = 0;
+      uint position = 0;
+      uint uniq_position = 0;
       _components.reset();
       Component *comp = NULL;
-      if( sets_result() ) {
+      if (sets_result()) {
         comp = _components.iter();
         position++;
       }
@@ -1352,11 +1352,11 @@
       for (; (comp = _components.iter()) != NULL; ++position) {
         // When the first component is not a DEF,
         // leave space for the result operand!
-        if ( position==0 && (! comp->isa(Component::DEF)) ) {
+        if (position==0 && (!comp->isa(Component::DEF))) {
           ++position;
         }
-        if( strcmp(name, comp->_name)==0 ) {
-          if( ++count > 1 ) {
+        if (strcmp(name, comp->_name) == 0) {
+          if (++count > 1) {
             assert(position < _uniq_idx_length, "out of bounds");
             uniq_idx[position] = uniq_position;
             has_dupl_use = true;
@@ -1364,22 +1364,25 @@
             uniq_position = position;
           }
         }
-        if( comp->isa(Component::DEF)
-            && comp->isa(Component::USE) ) {
+        if (comp->isa(Component::DEF) && comp->isa(Component::USE)) {
           ++position;
-          if( position != 1 )
+          if (position != 1)
             --position;   // only use two slots for the 1st USE_DEF
         }
       }
     }
-    if( has_dupl_use ) {
-      for( i = 1; i < nopnds; i++ )
-        if( i != uniq_idx[i] )
+    if (has_dupl_use) {
+      for (i = 1; i < nopnds; i++) {
+        if (i != uniq_idx[i]) {
           break;
-      int  j = i;
-      for( ; i < nopnds; i++ )
-        if( i == uniq_idx[i] )
+        }
+      }
+      uint j = i;
+      for (; i < nopnds; i++) {
+        if (i == uniq_idx[i]) {
           uniq_idx[i] = j++;
+        }
+      }
       num_uniq = j;
     }
   }
@@ -2216,21 +2219,27 @@
 
 
 bool OperandForm::is_bound_register() const {
-  RegClass *reg_class  = get_RegClass();
-  if (reg_class == NULL) return false;
-
-  const char * name = ideal_type(globalAD->globalNames());
-  if (name == NULL) return false;
-
-  int size = 0;
-  if (strcmp(name,"RegFlags")==0) size =  1;
-  if (strcmp(name,"RegI")==0) size =  1;
-  if (strcmp(name,"RegF")==0) size =  1;
-  if (strcmp(name,"RegD")==0) size =  2;
-  if (strcmp(name,"RegL")==0) size =  2;
-  if (strcmp(name,"RegN")==0) size =  1;
-  if (strcmp(name,"RegP")==0) size =  globalAD->get_preproc_def("_LP64") ? 2 : 1;
-  if (size == 0) return false;
+  RegClass* reg_class = get_RegClass();
+  if (reg_class == NULL) {
+    return false;
+  }
+
+  const char* name = ideal_type(globalAD->globalNames());
+  if (name == NULL) {
+    return false;
+  }
+
+  uint size = 0;
+  if (strcmp(name, "RegFlags") == 0) size = 1;
+  if (strcmp(name, "RegI") == 0) size = 1;
+  if (strcmp(name, "RegF") == 0) size = 1;
+  if (strcmp(name, "RegD") == 0) size = 2;
+  if (strcmp(name, "RegL") == 0) size = 2;
+  if (strcmp(name, "RegN") == 0) size = 1;
+  if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
+  if (size == 0) {
+    return false;
+  }
   return size == reg_class->size();
 }
 
--- a/src/share/vm/adlc/formssel.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/adlc/formssel.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -106,7 +106,7 @@
   const char    *_ins_pipe;        // Instruction Scheduling description class
 
   uint          *_uniq_idx;        // Indexes of unique operands
-  int            _uniq_idx_length; // Length of _uniq_idx array
+  uint           _uniq_idx_length; // Length of _uniq_idx array
   uint           _num_uniq;        // Number  of unique operands
   ComponentList  _components;      // List of Components matches MachNode's
                                    // operand structure
@@ -272,14 +272,14 @@
   void                set_unique_opnds();
   uint                num_unique_opnds() { return _num_uniq; }
   uint                unique_opnds_idx(int idx) {
-                        if( _uniq_idx != NULL && idx > 0 ) {
-                          assert(idx < _uniq_idx_length, "out of bounds");
-                          return _uniq_idx[idx];
-                        } else {
-                          return idx;
-                        }
+    if (_uniq_idx != NULL && idx > 0) {
+      assert((uint)idx < _uniq_idx_length, "out of bounds");
+      return _uniq_idx[idx];
+    } else {
+      return idx;
+    }
   }
-  const char         *unique_opnd_ident(int idx);  // Name of operand at unique idx.
+  const char         *unique_opnd_ident(uint idx);  // Name of operand at unique idx.
 
   // Operands which are only KILLs aren't part of the input array and
   // require special handling in some cases.  Their position in this
--- a/src/share/vm/adlc/output_c.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/adlc/output_c.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -463,8 +463,9 @@
   uint resources_used_exclusively = 0;
 
   for (pipeclass->_resUsage.reset();
-       (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; )
+       (piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
     element_count++;
+  }
 
   // Pre-compute the string length
   int templen;
@@ -482,8 +483,8 @@
   for (i = rescount; i > 0; i /= 10)
     maskdigit++;
 
-  static const char * pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
-  static const char * pipeline_use_element    = "Pipeline_Use_Element";
+  static const char* pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
+  static const char* pipeline_use_element    = "Pipeline_Use_Element";
 
   templen = 1 +
     (int)(strlen(pipeline_use_cycle_mask) + (int)strlen(pipeline_use_element) +
@@ -496,11 +497,12 @@
   templen = 0;
 
   for (pipeclass->_resUsage.reset();
-       (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
+       (piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
     int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
 
-    if (!used_mask)
+    if (!used_mask) {
       fprintf(stderr, "*** used_mask is 0 ***\n");
+    }
 
     resources_used |= used_mask;
 
@@ -509,8 +511,9 @@
     for (lb =  0; (used_mask & (1 << lb)) == 0; lb++);
     for (ub = 31; (used_mask & (1 << ub)) == 0; ub--);
 
-    if (lb == ub)
+    if (lb == ub) {
       resources_used_exclusively |= used_mask;
+    }
 
     int formatlen =
       sprintf(&resource_mask[templen], "  %s(0x%0*x, %*d, %*d, %s %s(",
@@ -526,7 +529,7 @@
 
     int cycles = piperesource->_cycles;
     uint stage          = pipeline->_stages.index(piperesource->_stage);
-    if (NameList::Not_in_list == stage) {
+    if ((uint)NameList::Not_in_list == stage) {
       fprintf(stderr,
               "pipeline_res_mask_initializer: "
               "semantic error: "
@@ -534,8 +537,8 @@
               piperesource->_stage);
       exit(1);
     }
-    uint upper_limit    = stage+cycles-1;
-    uint lower_limit    = stage-1;
+    uint upper_limit    = stage + cycles - 1;
+    uint lower_limit    = stage - 1;
     uint upper_idx      = upper_limit >> 5;
     uint lower_idx      = lower_limit >> 5;
     uint upper_position = upper_limit & 0x1f;
@@ -543,7 +546,7 @@
 
     uint mask = (((uint)1) << upper_position) - 1;
 
-    while ( upper_idx > lower_idx ) {
+    while (upper_idx > lower_idx) {
       res_mask[upper_idx--] |= mask;
       mask = (uint)-1;
     }
@@ -565,8 +568,9 @@
   }
 
   resource_mask[templen] = 0;
-  if (last_comma)
+  if (last_comma) {
     last_comma[0] = ' ';
+  }
 
   // See if the same string is in the table
   int ndx = pipeline_res_mask.index(resource_mask);
@@ -580,7 +584,7 @@
       fprintf(fp_cpp, "static const Pipeline_Use_Element pipeline_res_mask_%03d[%d] = {\n%s};\n\n",
         ndx+1, element_count, resource_mask);
 
-    char * args = new char [9 + 2*masklen + maskdigit];
+    char* args = new char [9 + 2*masklen + maskdigit];
 
     sprintf(args, "0x%0*x, 0x%0*x, %*d",
       masklen, resources_used,
@@ -589,8 +593,9 @@
 
     pipeline_res_args.addName(args);
   }
-  else
+  else {
     delete [] resource_mask;
+  }
 
   delete [] res_mask;
 //delete [] res_masks;
@@ -1787,7 +1792,7 @@
       // Skip first unique operands.
       for( i = 1; i < cur_num_opnds; i++ ) {
         comp = node->_components.iter();
-        if( (int)i != node->unique_opnds_idx(i) ) {
+        if (i != node->unique_opnds_idx(i)) {
           break;
         }
         new_num_opnds++;
@@ -1795,7 +1800,7 @@
       // Replace not unique operands with next unique operands.
       for( ; i < cur_num_opnds; i++ ) {
         comp = node->_components.iter();
-        int j = node->unique_opnds_idx(i);
+        uint j = node->unique_opnds_idx(i);
         // unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
         if( j != node->unique_opnds_idx(j) ) {
           fprintf(fp,"  set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -2232,6 +2232,7 @@
       // We still need to continue with the checks.
       if (src.is_constant()) {
         ciObject* src_con = src.get_jobject_constant();
+        guarantee(src_con != NULL, "no source constant");
 
         if (src_con->is_null_object()) {
           // The constant src object is null - We can skip
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -39,6 +39,7 @@
 #include "memory/gcLocker.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/referenceType.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/constantPool.hpp"
 #include "oops/fieldStreams.hpp"
@@ -444,8 +445,8 @@
             break;
           case JVM_REF_invokeStatic:
           case JVM_REF_invokeSpecial:
-            check_property(
-               tag.is_method() || tag.is_interface_method(),
+            check_property(tag.is_method() ||
+                           ((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()),
                "Invalid constant pool index %u in class file %s (not a method)",
                ref_index, CHECK_(nullHandle));
              break;
@@ -3152,7 +3153,6 @@
       }
     }
   }
-  int contended_count = nonstatic_contended_count;
 
 
   // Calculate the starting byte offsets
@@ -3177,35 +3177,52 @@
 
   next_nonstatic_field_offset = nonstatic_fields_start;
 
+  bool is_contended_class     = parsed_annotations->is_contended();
+
   // Class is contended, pad before all the fields
-  if (parsed_annotations->is_contended()) {
+  if (is_contended_class) {
     next_nonstatic_field_offset += ContendedPaddingWidth;
   }
 
-  // Compute the non-contended fields count
+  // Compute the non-contended fields count.
+  // The packing code below relies on these counts to determine if some field
+  // can be squeezed into the alignment gap. Contended fields are obviously
+  // exempt from that.
   unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
   unsigned int nonstatic_word_count   = fac->count[NONSTATIC_WORD]   - fac_contended.count[NONSTATIC_WORD];
   unsigned int nonstatic_short_count  = fac->count[NONSTATIC_SHORT]  - fac_contended.count[NONSTATIC_SHORT];
   unsigned int nonstatic_byte_count   = fac->count[NONSTATIC_BYTE]   - fac_contended.count[NONSTATIC_BYTE];
   unsigned int nonstatic_oop_count    = fac->count[NONSTATIC_OOP]    - fac_contended.count[NONSTATIC_OOP];
 
+  // Total non-static fields count, including every contended field
+  unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
+                                        fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
+                                        fac->count[NONSTATIC_OOP];
+
   bool super_has_nonstatic_fields =
           (_super_klass() != NULL && _super_klass->has_nonstatic_fields());
-  bool has_nonstatic_fields = super_has_nonstatic_fields ||
-          ((nonstatic_double_count + nonstatic_word_count +
-            nonstatic_short_count + nonstatic_byte_count +
-            nonstatic_oop_count) != 0);
+  bool has_nonstatic_fields = super_has_nonstatic_fields || (nonstatic_fields_count != 0);
 
 
   // Prepare list of oops for oop map generation.
+  //
+  // "offset" and "count" lists are describing the set of contiguous oop
+  // regions. offset[i] is the start of the i-th region, which then has
+  // count[i] oops following. Before we know how many regions are required,
+  // we pessimistically allocate the maps to fit all the oops into the
+  // distinct regions.
+  //
+  // TODO: We add +1 to always allocate non-zero resource arrays; we need
+  // to figure out if we still need to do this.
   int* nonstatic_oop_offsets;
   unsigned int* nonstatic_oop_counts;
   unsigned int nonstatic_oop_map_count = 0;
+  unsigned int max_nonstatic_oop_maps  = fac->count[NONSTATIC_OOP] + 1;
 
   nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
-            THREAD, int, nonstatic_oop_count + 1);
+            THREAD, int, max_nonstatic_oop_maps);
   nonstatic_oop_counts  = NEW_RESOURCE_ARRAY_IN_THREAD(
-            THREAD, unsigned int, nonstatic_oop_count + 1);
+            THREAD, unsigned int, max_nonstatic_oop_maps);
 
   first_nonstatic_oop_offset = 0; // will be set for first oop field
 
@@ -3392,9 +3409,11 @@
             int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
             heapOopSize ) {
           // Extend current oop map
+          assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
           nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
         } else {
           // Create new oop map
+          assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
           nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
           nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
           nonstatic_oop_map_count += 1;
@@ -3452,12 +3471,10 @@
   //
   // Additionally, this should not break alignment for the fields, so we round the alignment up
   // for each field.
-  if (contended_count > 0) {
+  if (nonstatic_contended_count > 0) {
 
     // if there is at least one contended field, we need to have pre-padding for them
-    if (nonstatic_contended_count > 0) {
-      next_nonstatic_padded_offset += ContendedPaddingWidth;
-    }
+    next_nonstatic_padded_offset += ContendedPaddingWidth;
 
     // collect all contended groups
     BitMap bm(_cp->size());
@@ -3518,6 +3535,7 @@
             next_nonstatic_padded_offset += heapOopSize;
 
             // Create new oop map
+            assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
             nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
             nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
             nonstatic_oop_map_count += 1;
@@ -3554,18 +3572,17 @@
     // handle static fields
   }
 
-  // Size of instances
-  int notaligned_offset = next_nonstatic_padded_offset;
-
   // Entire class is contended, pad in the back.
   // This helps to alleviate memory contention effects for subclass fields
   // and/or adjacent object.
-  if (parsed_annotations->is_contended()) {
-    notaligned_offset += ContendedPaddingWidth;
+  if (is_contended_class) {
+    next_nonstatic_padded_offset += ContendedPaddingWidth;
   }
 
-  int nonstatic_fields_end      = align_size_up(notaligned_offset, heapOopSize);
-  int instance_end              = align_size_up(notaligned_offset, wordSize);
+  int notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
+
+  int nonstatic_fields_end      = align_size_up(notaligned_nonstatic_fields_end, heapOopSize);
+  int instance_end              = align_size_up(notaligned_nonstatic_fields_end, wordSize);
   int static_fields_end         = align_size_up(next_static_byte_offset, wordSize);
 
   int static_field_size         = (static_fields_end -
@@ -3579,6 +3596,14 @@
          (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize),
           wordSize) / wordSize), "consistent layout helper value");
 
+  // Invariant: nonstatic_field end/start should only change if there are
+  // nonstatic fields in the class, or if the class is contended. We compare
+  // against the non-aligned value, so that end alignment will not fail the
+  // assert without actually having the fields.
+  assert((notaligned_nonstatic_fields_end == nonstatic_fields_start) ||
+         is_contended_class ||
+         (nonstatic_fields_count > 0), "double-check nonstatic start/end");
+
   // Number of non-static oop map blocks allocated at end of klass.
   const unsigned int total_oop_map_count =
     compute_oop_map_count(_super_klass, nonstatic_oop_map_count,
@@ -4040,6 +4065,9 @@
       }
     }
 
+    // Allocate mirror and initialize static fields
+    java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
+
 
 #ifdef ASSERT
     if (ParseAllGenericSignatures) {
@@ -4055,17 +4083,6 @@
           this_klass(), &all_mirandas, CHECK_(nullHandle));
     }
 
-    // Allocate mirror and initialize static fields
-    java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
-
-    // Allocate a simple java object for locking during class initialization.
-    // This needs to be a java object because it can be held across a java call.
-    typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
-    this_klass->set_init_lock(r);
-
-    // TODO: Move these oops to the mirror
-    this_klass->set_protection_domain(protection_domain());
-
     // Update the loader_data graph.
     record_defined_class_dependencies(this_klass, CHECK_NULL);
 
--- a/src/share/vm/classfile/classLoaderData.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/classLoaderData.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -64,6 +64,11 @@
 #include "utilities/growableArray.hpp"
 #include "utilities/ostream.hpp"
 
+#if INCLUDE_TRACE
+ #include "trace/tracing.hpp"
+#endif
+
+
 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
 
 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
@@ -120,6 +125,12 @@
   }
 }
 
+void ClassLoaderData::classes_do(void f(Klass * const)) {
+  for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
+    f(k);
+  }
+}
+
 void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
   for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
     if (k->oop_is_instance()) {
@@ -583,6 +594,19 @@
   }
 }
 
+void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
+  for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+    cld->classes_do(f);
+  }
+}
+
+void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+  for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
+    cld->classes_do(f);
+  }
+}
+
 GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() {
   assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?");
 
@@ -687,6 +711,11 @@
     dead->set_next(_unloading);
     _unloading = dead;
   }
+
+  if (seen_dead_loader) {
+    post_class_unload_events();
+  }
+
   return seen_dead_loader;
 }
 
@@ -702,6 +731,20 @@
   Metaspace::purge();
 }
 
+void ClassLoaderDataGraph::post_class_unload_events(void) {
+#if INCLUDE_TRACE
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+  if (Tracing::enabled()) {
+    if (Tracing::is_event_enabled(TraceClassUnloadEvent)) {
+      assert(_unloading != NULL, "need class loader data unload list!");
+      _class_unload_time = Tracing::time();
+      classes_unloading_do(&class_unload_event);
+    }
+    Tracing::on_unloading_classes();
+  }
+#endif
+}
+
 // CDS support
 
 // Global metaspaces for writing information to the shared archive.  When
@@ -769,3 +812,21 @@
     class_loader()->print_value_on(out);
   }
 }
+
+#if INCLUDE_TRACE
+
+TracingTime ClassLoaderDataGraph::_class_unload_time;
+
+void ClassLoaderDataGraph::class_unload_event(Klass* const k) {
+
+  // post class unload event
+  EventClassUnload event(UNTIMED);
+  event.set_endtime(_class_unload_time);
+  event.set_unloadedClass(k);
+  oop defining_class_loader = k->class_loader();
+  event.set_definingClassLoader(defining_class_loader != NULL ?
+                                defining_class_loader->klass() : (Klass*)NULL);
+  event.commit();
+}
+
+#endif /* INCLUDE_TRACE */
--- a/src/share/vm/classfile/classLoaderData.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/classLoaderData.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -32,6 +32,10 @@
 #include "runtime/mutex.hpp"
 #include "utilities/growableArray.hpp"
 
+#if INCLUDE_TRACE
+# include "trace/traceTime.hpp"
+#endif
+
 //
 // A class loader represents a linkset. Conceptually, a linkset identifies
 // the complete transitive closure of resolved links that a dynamic linker can
@@ -49,6 +53,7 @@
 class JNIMethodBlock;
 class JNIHandleBlock;
 class Metadebug;
+
 // GC root for walking class loader data created
 
 class ClassLoaderDataGraph : public AllStatic {
@@ -63,6 +68,7 @@
   static ClassLoaderData* _saved_head;
 
   static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
+  static void post_class_unload_events(void);
  public:
   static ClassLoaderData* find_or_create(Handle class_loader, TRAPS);
   static void purge();
@@ -71,6 +77,8 @@
   static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
   static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
   static void classes_do(KlassClosure* klass_closure);
+  static void classes_do(void f(Klass* const));
+  static void classes_unloading_do(void f(Klass* const));
   static bool do_unloading(BoolObjectClosure* is_alive);
 
   // CMS support.
@@ -86,6 +94,12 @@
   static bool contains(address x);
   static bool contains_loader_data(ClassLoaderData* loader_data);
 #endif
+
+#if INCLUDE_TRACE
+ private:
+  static TracingTime _class_unload_time;
+  static void class_unload_event(Klass* const k);
+#endif
 };
 
 // ClassLoaderData class
@@ -171,7 +185,7 @@
   void unload();
   bool keep_alive() const       { return _keep_alive; }
   bool is_alive(BoolObjectClosure* is_alive_closure) const;
-
+  void classes_do(void f(Klass*));
   void classes_do(void f(InstanceKlass*));
 
   // Deallocate free list during class unloading.
--- a/src/share/vm/classfile/defaultMethods.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/defaultMethods.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1349,6 +1349,7 @@
 
   // Replace klass methods with new merged lists
   klass->set_methods(merged_methods);
+  klass->set_initial_method_idnum(new_size);
 
   ClassLoaderData* cld = klass->class_loader_data();
   MetadataFactory::free_array(cld, original_methods);
--- a/src/share/vm/classfile/javaClasses.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -512,22 +512,22 @@
 
   // If the offset was read from the shared archive, it was fixed up already
   if (!k->is_shared()) {
-  if (k->oop_is_instance()) {
-    // During bootstrap, java.lang.Class wasn't loaded so static field
-    // offsets were computed without the size added it.  Go back and
-    // update all the static field offsets to included the size.
-      for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
-      if (fs.access_flags().is_static()) {
-        int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
-        fs.set_offset(real_offset);
+    if (k->oop_is_instance()) {
+      // During bootstrap, java.lang.Class wasn't loaded so static field
+      // offsets were computed without the size added it.  Go back and
+      // update all the static field offsets to included the size.
+        for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
+        if (fs.access_flags().is_static()) {
+          int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
+          fs.set_offset(real_offset);
+        }
       }
     }
   }
-  }
-  create_mirror(k, CHECK);
+  create_mirror(k, Handle(NULL), CHECK);
 }
 
-oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
+oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
   assert(k->java_mirror() == NULL, "should only assign mirror once");
   // Use this moment of initialization to cache modifier_flags also,
   // to support Class.getModifiers().  Instance classes recalculate
@@ -563,6 +563,16 @@
       set_array_klass(comp_mirror(), k());
     } else {
       assert(k->oop_is_instance(), "Must be");
+
+      // Allocate a simple java object for a lock.
+      // This needs to be a java object because during class initialization
+      // it can be held across a java call.
+      typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
+      set_init_lock(mirror(), r);
+
+      // Set protection domain also
+      set_protection_domain(mirror(), protection_domain());
+
       // Initialize static fields
       InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
     }
@@ -597,6 +607,34 @@
   java_class->int_field_put(_static_oop_field_count_offset, size);
 }
 
+oop java_lang_Class::protection_domain(oop java_class) {
+  assert(_protection_domain_offset != 0, "must be set");
+  return java_class->obj_field(_protection_domain_offset);
+}
+void java_lang_Class::set_protection_domain(oop java_class, oop pd) {
+  assert(_protection_domain_offset != 0, "must be set");
+  java_class->obj_field_put(_protection_domain_offset, pd);
+}
+
+oop java_lang_Class::init_lock(oop java_class) {
+  assert(_init_lock_offset != 0, "must be set");
+  return java_class->obj_field(_init_lock_offset);
+}
+void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
+  assert(_init_lock_offset != 0, "must be set");
+  java_class->obj_field_put(_init_lock_offset, init_lock);
+}
+
+objArrayOop java_lang_Class::signers(oop java_class) {
+  assert(_signers_offset != 0, "must be set");
+  return (objArrayOop)java_class->obj_field(_signers_offset);
+}
+void java_lang_Class::set_signers(oop java_class, objArrayOop signers) {
+  assert(_signers_offset != 0, "must be set");
+  java_class->obj_field_put(_signers_offset, (oop)signers);
+}
+
+
 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
   // This should be improved by adding a field at the Java level or by
   // introducing a new VM klass (see comment in ClassFileParser)
@@ -923,7 +961,7 @@
 
 // Read thread status value from threadStatus field in java.lang.Thread java class.
 java_lang_Thread::ThreadStatus java_lang_Thread::get_thread_status(oop java_thread) {
-  assert(Thread::current()->is_VM_thread() ||
+  assert(Thread::current()->is_Watcher_thread() || Thread::current()->is_VM_thread() ||
          JavaThread::current()->thread_state() == _thread_in_vm,
          "Java Thread is not running in vm");
   // The threadStatus is only present starting in 1.5
@@ -2934,6 +2972,9 @@
 int java_lang_Class::_array_klass_offset;
 int java_lang_Class::_oop_size_offset;
 int java_lang_Class::_static_oop_field_count_offset;
+int java_lang_Class::_protection_domain_offset;
+int java_lang_Class::_init_lock_offset;
+int java_lang_Class::_signers_offset;
 GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
 int java_lang_Throwable::backtrace_offset;
 int java_lang_Throwable::detailMessage_offset;
--- a/src/share/vm/classfile/javaClasses.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -208,7 +208,10 @@
   macro(java_lang_Class, klass,                  intptr_signature,  false) \
   macro(java_lang_Class, array_klass,            intptr_signature,  false) \
   macro(java_lang_Class, oop_size,               int_signature,     false) \
-  macro(java_lang_Class, static_oop_field_count, int_signature,     false)
+  macro(java_lang_Class, static_oop_field_count, int_signature,     false) \
+  macro(java_lang_Class, protection_domain,      object_signature,  false) \
+  macro(java_lang_Class, init_lock,              object_signature,  false) \
+  macro(java_lang_Class, signers,                object_signature,  false)
 
 class java_lang_Class : AllStatic {
   friend class VMStructs;
@@ -222,15 +225,20 @@
   static int _oop_size_offset;
   static int _static_oop_field_count_offset;
 
+  static int _protection_domain_offset;
+  static int _init_lock_offset;
+  static int _signers_offset;
+
   static bool offsets_computed;
   static int classRedefinedCount_offset;
   static GrowableArray<Klass*>* _fixup_mirror_list;
 
+  static void set_init_lock(oop java_class, oop init_lock);
  public:
   static void compute_offsets();
 
   // Instance creation
-  static oop  create_mirror(KlassHandle k, TRAPS);
+  static oop  create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
   static void fixup_mirror(KlassHandle k, TRAPS);
   static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
   // Conversion
@@ -262,6 +270,13 @@
   static int classRedefinedCount(oop the_class_mirror);
   static void set_classRedefinedCount(oop the_class_mirror, int value);
 
+  // Support for embedded per-class oops
+  static oop  protection_domain(oop java_class);
+  static void set_protection_domain(oop java_class, oop protection_domain);
+  static oop  init_lock(oop java_class);
+  static objArrayOop  signers(oop java_class);
+  static void set_signers(oop java_class, objArrayOop signers);
+
   static int oop_size(oop java_class);
   static void set_oop_size(oop java_class, int size);
   static int static_oop_field_count(oop java_class);
--- a/src/share/vm/classfile/symbolTable.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/symbolTable.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -737,7 +737,7 @@
   return result;
 }
 
-void StringTable::unlink(BoolObjectClosure* is_alive) {
+void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
   // Readers of the table are unlocked, so we should only be removing
   // entries at a safepoint.
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
@@ -745,41 +745,31 @@
     HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
     HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
-      // Shared entries are normally at the end of the bucket and if we run into
-      // a shared entry, then there is nothing more to remove. However, if we
-      // have rehashed the table, then the shared entries are no longer at the
-      // end of the bucket.
-      if (entry->is_shared() && !use_alternate_hashcode()) {
-        break;
-      }
-      assert(entry->literal() != NULL, "just checking");
-      if (entry->is_shared() || is_alive->do_object_b(entry->literal())) {
+      assert(!entry->is_shared(), "CDS not used for the StringTable");
+
+      if (is_alive->do_object_b(entry->literal())) {
+        if (f != NULL) {
+          f->do_oop((oop*)entry->literal_addr());
+        }
         p = entry->next_addr();
       } else {
         *p = entry->next();
         the_table()->free_entry(entry);
       }
-      entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
+      entry = *p;
     }
   }
 }
 
 void StringTable::oops_do(OopClosure* f) {
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
     HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
+      assert(!entry->is_shared(), "CDS not used for the StringTable");
+
       f->do_oop((oop*)entry->literal_addr());
 
-      // Did the closure remove the literal from the table?
-      if (entry->literal() == NULL) {
-        assert(!entry->is_shared(), "immutable hashtable entry?");
-        *p = entry->next();
-        the_table()->free_entry(entry);
-      } else {
-        p = entry->next_addr();
-      }
-      entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
+      entry = entry->next();
     }
   }
 }
--- a/src/share/vm/classfile/symbolTable.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/symbolTable.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -272,7 +272,10 @@
 
   // GC support
   //   Delete pointers to otherwise-unreachable objects.
-  static void unlink(BoolObjectClosure* cl);
+  static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f);
+  static void unlink(BoolObjectClosure* cl) {
+    unlink_or_oops_do(cl, NULL);
+  }
 
   // Invoke "f->do_oop" on the locations of all oops in the table.
   static void oops_do(OopClosure* f);
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/systemDictionary.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -56,6 +56,11 @@
 #include "services/classLoadingService.hpp"
 #include "services/threadService.hpp"
 
+#if INCLUDE_TRACE
+ #include "trace/tracing.hpp"
+ #include "trace/traceMacros.hpp"
+#endif
+
 
 Dictionary*            SystemDictionary::_dictionary          = NULL;
 PlaceholderTable*      SystemDictionary::_placeholders        = NULL;
@@ -586,10 +591,15 @@
 }
 
 
-Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, Handle protection_domain, TRAPS) {
+Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
+                                                        Handle class_loader,
+                                                        Handle protection_domain,
+                                                        TRAPS) {
   assert(name != NULL && !FieldType::is_array(name) &&
          !FieldType::is_obj(name), "invalid class name");
 
+  TracingTime class_load_start_time = Tracing::time();
+
   // UseNewReflection
   // Fix for 4474172; see evaluation for more details
   class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
@@ -804,8 +814,9 @@
             // during compilations.
             MutexLocker mu(Compile_lock, THREAD);
             update_dictionary(d_index, d_hash, p_index, p_hash,
-                            k, class_loader, THREAD);
+                              k, class_loader, THREAD);
           }
+
           if (JvmtiExport::should_post_class_load()) {
             Thread *thread = THREAD;
             assert(thread->is_Java_thread(), "thread->is_Java_thread()");
@@ -861,8 +872,8 @@
       // This brackets the SystemDictionary updates for both defining
       // and initiating loaders
       MutexLocker mu(SystemDictionary_lock, THREAD);
-        placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
-        SystemDictionary_lock->notify_all();
+      placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
+      SystemDictionary_lock->notify_all();
     }
   }
 
@@ -870,6 +881,8 @@
     return NULL;
   }
 
+  post_class_load_event(class_load_start_time, k, class_loader);
+
 #ifdef ASSERT
   {
     ClassLoaderData* loader_data = k->class_loader_data();
@@ -993,6 +1006,8 @@
                                       TRAPS) {
   TempNewSymbol parsed_name = NULL;
 
+  TracingTime class_load_start_time = Tracing::time();
+
   ClassLoaderData* loader_data;
   if (host_klass.not_null()) {
     // Create a new CLD for anonymous class, that uses the same class loader
@@ -1048,6 +1063,8 @@
         assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
         JvmtiExport::post_class_load((JavaThread *) THREAD, k());
     }
+
+    post_class_load_event(class_load_start_time, k, class_loader);
   }
   assert(host_klass.not_null() || cp_patches == NULL,
          "cp_patches only found with host_klass");
@@ -1435,6 +1452,7 @@
       JvmtiExport::post_class_load((JavaThread *) THREAD, k());
 
   }
+
 }
 
 // Support parallel classloading
@@ -1678,6 +1696,7 @@
   }
   return newsize;
 }
+
 // Assumes classes in the SystemDictionary are only unloaded at a safepoint
 // Note: anonymous classes are not in the SD.
 bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) {
@@ -2024,12 +2043,6 @@
     }
   }
 
-  // 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);
-
   // Make a new system dictionary entry.
   Klass* sd_check = find_class(d_index, d_hash, name, loader_data);
   if (sd_check == NULL) {
@@ -2612,6 +2625,27 @@
             "Loaded klasses should be in SystemDictionary");
 }
 
+// utility function for class load event
+void SystemDictionary::post_class_load_event(TracingTime start_time,
+                                             instanceKlassHandle k,
+                                             Handle initiating_loader) {
+#if INCLUDE_TRACE
+  EventClassLoad event(UNTIMED);
+  if (event.should_commit()) {
+    event.set_endtime(Tracing::time());
+    event.set_starttime(start_time);
+    event.set_loadedClass(k());
+    oop defining_class_loader = k->class_loader();
+    event.set_definingClassLoader(defining_class_loader !=  NULL ?
+                                    defining_class_loader->klass() : (Klass*)NULL);
+    oop class_loader = initiating_loader.is_null() ? (oop)NULL : initiating_loader();
+    event.set_initiatingClassLoader(class_loader != NULL ?
+                                      class_loader->klass() : (Klass*)NULL);
+    event.commit();
+  }
+#endif /* INCLUDE_TRACE */
+}
+
 #ifndef PRODUCT
 
 // statistics code
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -31,9 +31,11 @@
 #include "oops/symbol.hpp"
 #include "runtime/java.hpp"
 #include "runtime/reflectionUtils.hpp"
+#include "trace/traceTime.hpp"
 #include "utilities/hashtable.hpp"
 #include "utilities/hashtable.inline.hpp"
 
+
 // The system dictionary stores all loaded classes and maps:
 //
 //   [class name,class loader] -> class   i.e.  [Symbol*,oop] -> Klass*
@@ -636,6 +638,9 @@
   // Setup link to hierarchy
   static void add_to_hierarchy(instanceKlassHandle k, TRAPS);
 
+  // event based tracing
+  static void post_class_load_event(TracingTime start_time, instanceKlassHandle k,
+                                    Handle initiating_loader);
   // We pass in the hashtable index so we can calculate it outside of
   // the SystemDictionary_lock.
 
--- a/src/share/vm/classfile/verifier.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/verifier.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -36,8 +36,10 @@
 class Verifier : AllStatic {
  public:
   enum {
+    STRICTER_ACCESS_CTRL_CHECK_VERSION  = 49,
     STACKMAP_ATTRIBUTE_MAJOR_VERSION    = 50,
-    INVOKEDYNAMIC_MAJOR_VERSION         = 51
+    INVOKEDYNAMIC_MAJOR_VERSION         = 51,
+    NO_RELAX_ACCESS_CTRL_CHECK_VERSION  = 52
   };
   typedef enum { ThrowException, NoException } Mode;
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -392,6 +392,9 @@
   template(array_klass_name,                          "array_klass")                              \
   template(oop_size_name,                             "oop_size")                                 \
   template(static_oop_field_count_name,               "static_oop_field_count")                   \
+  template(protection_domain_name,                    "protection_domain")                        \
+  template(init_lock_name,                            "init_lock")                                \
+  template(signers_name,                              "signers_name")                             \
   template(loader_data_name,                          "loader_data")                              \
   template(dependencies_name,                         "dependencies")                             \
                                                                                                   \
--- a/src/share/vm/code/codeCache.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/code/codeCache.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
 #include "runtime/java.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "services/memoryService.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/xmlstream.hpp"
 
 // Helper class for printing in CodeCache
@@ -114,7 +115,6 @@
   }
 };
 
-
 // CodeCache implementation
 
 CodeHeap * CodeCache::_heap = new CodeHeap();
@@ -126,6 +126,7 @@
 nmethod* CodeCache::_scavenge_root_nmethods = NULL;
 nmethod* CodeCache::_saved_nmethods = NULL;
 
+int CodeCache::_codemem_full_count = 0;
 
 CodeBlob* CodeCache::first() {
   assert_locked_or_safepoint(CodeCache_lock);
@@ -829,6 +830,22 @@
   }
 }
 
+void CodeCache::report_codemem_full() {
+  _codemem_full_count++;
+  EventCodeCacheFull event;
+  if (event.should_commit()) {
+    event.set_startAddress((u8)low_bound());
+    event.set_commitedTopAddress((u8)high());
+    event.set_reservedTopAddress((u8)high_bound());
+    event.set_entryCount(nof_blobs());
+    event.set_methodCount(nof_nmethods());
+    event.set_adaptorCount(nof_adapters());
+    event.set_unallocatedCapacity(unallocated_capacity()/K);
+    event.set_fullCount(_codemem_full_count);
+    event.commit();
+  }
+}
+
 //------------------------------------------------------------------------------------------------
 // Non-product version
 
--- a/src/share/vm/code/codeCache.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/code/codeCache.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,11 +64,15 @@
   static void mark_scavenge_root_nmethods() PRODUCT_RETURN;
   static void verify_perm_nmethods(CodeBlobClosure* f_or_null) PRODUCT_RETURN;
 
+  static int _codemem_full_count;
+
  public:
 
   // Initialization
   static void initialize();
 
+  static void report_codemem_full();
+
   // Allocation/administration
   static CodeBlob* allocate(int size, bool is_critical = false); // allocates a new CodeBlob
   static void commit(CodeBlob* cb);                 // called when the allocated CodeBlob has been filled
@@ -155,6 +159,7 @@
   // The full limits of the codeCache
   static address  low_bound()                    { return (address) _heap->low_boundary(); }
   static address  high_bound()                   { return (address) _heap->high_boundary(); }
+  static address  high()                         { return (address) _heap->high(); }
 
   // Profiling
   static address first_address();                // first address used for CodeBlobs
@@ -186,6 +191,8 @@
 
     // tells how many nmethods have dependencies
   static int number_of_nmethods_with_dependencies();
+
+  static int get_codemem_full_count() { return _codemem_full_count; }
 };
 
 #endif // SHARE_VM_CODE_CODECACHE_HPP
--- a/src/share/vm/code/nmethod.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/code/nmethod.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1976,11 +1976,10 @@
   if (!method()->is_native()) {
     SimpleScopeDesc ssd(this, fr.pc());
     Bytecode_invoke call(ssd.method(), ssd.bci());
-    // compiled invokedynamic call sites have an implicit receiver at
-    // resolution time, so make sure it gets GC'ed.
-    bool has_receiver = !call.is_invokestatic();
+    bool has_receiver = call.has_receiver();
+    bool has_appendix = call.has_appendix();
     Symbol* signature = call.signature();
-    fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
+    fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
   }
 #endif // !SHARK
 }
--- a/src/share/vm/compiler/compileBroker.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/compiler/compileBroker.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
 #include "runtime/os.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/sweeper.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #ifdef COMPILER1
@@ -179,9 +180,11 @@
 int CompileBroker::_sum_nmethod_size             = 0;
 int CompileBroker::_sum_nmethod_code_size        = 0;
 
-CompileQueue* CompileBroker::_c2_method_queue   = NULL;
-CompileQueue* CompileBroker::_c1_method_queue   = NULL;
-CompileTask*  CompileBroker::_task_free_list = NULL;
+long CompileBroker::_peak_compilation_time       = 0;
+
+CompileQueue* CompileBroker::_c2_method_queue    = NULL;
+CompileQueue* CompileBroker::_c1_method_queue    = NULL;
+CompileTask*  CompileBroker::_task_free_list     = NULL;
 
 GrowableArray<CompilerThread*>* CompileBroker::_method_threads = NULL;
 
@@ -1642,42 +1645,37 @@
 // Set up state required by +LogCompilation.
 void CompileBroker::init_compiler_thread_log() {
     CompilerThread* thread = CompilerThread::current();
-    char  fileBuf[4*K];
+    char  file_name[4*K];
     FILE* fp = NULL;
-    char* file = NULL;
     intx thread_id = os::current_thread_id();
     for (int try_temp_dir = 1; try_temp_dir >= 0; try_temp_dir--) {
       const char* dir = (try_temp_dir ? os::get_temp_directory() : NULL);
       if (dir == NULL) {
-        jio_snprintf(fileBuf, sizeof(fileBuf), "hs_c" UINTX_FORMAT "_pid%u.log",
+        jio_snprintf(file_name, sizeof(file_name), "hs_c" UINTX_FORMAT "_pid%u.log",
                      thread_id, os::current_process_id());
       } else {
-        jio_snprintf(fileBuf, sizeof(fileBuf),
+        jio_snprintf(file_name, sizeof(file_name),
                      "%s%shs_c" UINTX_FORMAT "_pid%u.log", dir,
                      os::file_separator(), thread_id, os::current_process_id());
       }
-      fp = fopen(fileBuf, "at");
+
+      fp = fopen(file_name, "at");
       if (fp != NULL) {
-        file = NEW_C_HEAP_ARRAY(char, strlen(fileBuf)+1, mtCompiler);
-        strcpy(file, fileBuf);
-        break;
+        if (LogCompilation && Verbose) {
+          tty->print_cr("Opening compilation log %s", file_name);
+        }
+        CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file_name, fp, thread_id);
+        thread->init_log(log);
+
+        if (xtty != NULL) {
+          ttyLocker ttyl;
+          // Record any per thread log files
+          xtty->elem("thread_logfile thread='%d' filename='%s'", thread_id, file_name);
+        }
+        return;
       }
     }
-    if (fp == NULL) {
-      warning("Cannot open log file: %s", fileBuf);
-    } else {
-      if (LogCompilation && Verbose)
-        tty->print_cr("Opening compilation log %s", file);
-      CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file, fp, thread_id);
-      thread->init_log(log);
-
-      if (xtty != NULL) {
-        ttyLocker ttyl;
-
-        // Record any per thread log files
-        xtty->elem("thread_logfile thread='%d' filename='%s'", thread_id, file);
-      }
-    }
+    warning("Cannot open log file: %s", file_name);
 }
 
 // ------------------------------------------------------------------
@@ -1800,6 +1798,7 @@
     ciMethod* target = ci_env.get_method_from_handle(target_handle);
 
     TraceTime t1("compilation", &time);
+    EventCompilation event;
 
     AbstractCompiler *comp = compiler(task_level);
     if (comp == NULL) {
@@ -1841,6 +1840,16 @@
     }
     // simulate crash during compilation
     assert(task->compile_id() != CICrashAt, "just as planned");
+    if (event.should_commit()) {
+      event.set_method(target->get_Method());
+      event.set_compileID(compile_id);
+      event.set_compileLevel(task->comp_level());
+      event.set_succeded(task->is_success());
+      event.set_isOsr(is_osr);
+      event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size());
+      event.set_inlinedBytes(task->num_inlined_bytecodes());
+      event.commit();
+    }
   }
   pop_jni_handle_block();
 
@@ -1921,6 +1930,10 @@
     }
     warning("CodeCache is full. Compiler has been disabled.");
     warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
+
+    CodeCache::report_codemem_full();
+
+
 #ifndef PRODUCT
     if (CompileTheWorld || ExitOnFullCodeCache) {
       codecache_print(/* detailed= */ true);
@@ -2078,8 +2091,10 @@
     // java.lang.management.CompilationMBean
     _perf_total_compilation->inc(time.ticks());
 
+    _t_total_compilation.add(time);
+    _peak_compilation_time = time.milliseconds() > _peak_compilation_time ? time.milliseconds() : _peak_compilation_time;
+
     if (CITime) {
-      _t_total_compilation.add(time);
       if (is_osr) {
         _t_osr_compilation.add(time);
         _sum_osr_bytes_compiled += method->code_size() + task->num_inlined_bytecodes();
@@ -2177,7 +2192,6 @@
   tty->print_cr("  nmethod total size       : %6d bytes", CompileBroker::_sum_nmethod_size);
 }
 
-
 // Debugging output for failure
 void CompileBroker::print_last_compile() {
   if ( _last_compile_level != CompLevel_none &&
--- a/src/share/vm/compiler/compileBroker.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/compiler/compileBroker.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -299,17 +299,17 @@
   static elapsedTimer _t_osr_compilation;
   static elapsedTimer _t_standard_compilation;
 
+  static int _total_compile_count;
   static int _total_bailout_count;
   static int _total_invalidated_count;
-  static int _total_compile_count;
   static int _total_native_compile_count;
   static int _total_osr_compile_count;
   static int _total_standard_compile_count;
-
   static int _sum_osr_bytes_compiled;
   static int _sum_standard_bytes_compiled;
   static int _sum_nmethod_size;
   static int _sum_nmethod_code_size;
+  static long _peak_compilation_time;
 
   static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS);
   static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
@@ -421,6 +421,19 @@
 
   // compiler name for debugging
   static const char* compiler_name(int comp_level);
+
+  static int get_total_compile_count() {          return _total_compile_count; }
+  static int get_total_bailout_count() {          return _total_bailout_count; }
+  static int get_total_invalidated_count() {      return _total_invalidated_count; }
+  static int get_total_native_compile_count() {   return _total_native_compile_count; }
+  static int get_total_osr_compile_count() {      return _total_osr_compile_count; }
+  static int get_total_standard_compile_count() { return _total_standard_compile_count; }
+  static int get_sum_osr_bytes_compiled() {       return _sum_osr_bytes_compiled; }
+  static int get_sum_standard_bytes_compiled() {  return _sum_standard_bytes_compiled; }
+  static int get_sum_nmethod_size() {             return _sum_nmethod_size;}
+  static int get_sum_nmethod_code_size() {        return _sum_nmethod_code_size; }
+  static long get_peak_compilation_time() {       return _peak_compilation_time; }
+  static long get_total_compilation_time() {      return _t_total_compilation.milliseconds(); }
 };
 
 #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP
--- a/src/share/vm/compiler/compileLog.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/compiler/compileLog.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -34,17 +34,18 @@
 
 // ------------------------------------------------------------------
 // CompileLog::CompileLog
-CompileLog::CompileLog(const char* file, FILE* fp, intx thread_id)
+CompileLog::CompileLog(const char* file_name, FILE* fp, intx thread_id)
   : _context(_context_buffer, sizeof(_context_buffer))
 {
-  initialize(new(ResourceObj::C_HEAP, mtCompiler) fileStream(fp));
-  _file = file;
+  initialize(new(ResourceObj::C_HEAP, mtCompiler) fileStream(fp, true));
   _file_end = 0;
   _thread_id = thread_id;
 
   _identities_limit = 0;
   _identities_capacity = 400;
   _identities = NEW_C_HEAP_ARRAY(char, _identities_capacity, mtCompiler);
+  _file = NEW_C_HEAP_ARRAY(char, strlen(file_name)+1, mtCompiler);
+   strcpy((char*)_file, file_name);
 
   // link into the global list
   { MutexLocker locker(CompileTaskAlloc_lock);
@@ -57,6 +58,7 @@
   delete _out;
   _out = NULL;
   FREE_C_HEAP_ARRAY(char, _identities, mtCompiler);
+  FREE_C_HEAP_ARRAY(char, _file, mtCompiler);
 }
 
 
@@ -188,7 +190,8 @@
   if (called_exit)  return;
   called_exit = true;
 
-  for (CompileLog* log = _first; log != NULL; log = log->_next) {
+  CompileLog* log = _first;
+  while (log != NULL) {
     log->flush();
     const char* partial_file = log->file();
     int partial_fd = open(partial_file, O_RDONLY);
@@ -267,7 +270,11 @@
       close(partial_fd);
       unlink(partial_file);
     }
+    CompileLog* next_log = log->_next;
+    delete log;
+    log = next_log;
   }
+  _first = NULL;
 }
 
 // ------------------------------------------------------------------
--- a/src/share/vm/compiler/compileLog.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/compiler/compileLog.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -57,7 +57,7 @@
   void va_tag(bool push, const char* format, va_list ap);
 
  public:
-  CompileLog(const char* file, FILE* fp, intx thread_id);
+  CompileLog(const char* file_name, FILE* fp, intx thread_id);
   ~CompileLog();
 
   intx          thread_id()                      { return _thread_id; }
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -969,8 +969,8 @@
 }
 
 
-void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
-                                          size_t max_eden_size)
+void CMSAdaptiveSizePolicy::compute_eden_space_size(size_t cur_eden,
+                                                    size_t max_eden_size)
 {
   size_t desired_eden_size = cur_eden;
   size_t eden_limit = max_eden_size;
@@ -978,7 +978,7 @@
   // Printout input
   if (PrintGC && PrintAdaptiveSizePolicy) {
     gclog_or_tty->print_cr(
-      "CMSAdaptiveSizePolicy::compute_young_generation_free_space: "
+      "CMSAdaptiveSizePolicy::compute_eden_space_size: "
       "cur_eden " SIZE_FORMAT,
       cur_eden);
   }
@@ -1024,7 +1024,7 @@
 
   if (PrintGC && PrintAdaptiveSizePolicy) {
     gclog_or_tty->print_cr(
-      "CMSAdaptiveSizePolicy::compute_young_generation_free_space limits:"
+      "CMSAdaptiveSizePolicy::compute_eden_space_size limits:"
       " desired_eden_size: " SIZE_FORMAT
       " old_eden_size: " SIZE_FORMAT,
       desired_eden_size, cur_eden);
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -436,8 +436,8 @@
 
   size_t generation_alignment() { return _generation_alignment; }
 
-  virtual void compute_young_generation_free_space(size_t cur_eden,
-                                                   size_t max_eden_size);
+  virtual void compute_eden_space_size(size_t cur_eden,
+                                       size_t max_eden_size);
   // Calculates new survivor space size;  returns a new tenuring threshold
   // value. Stores new survivor size in _survivor_size.
   virtual uint compute_survivor_space_size_and_threshold(
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -37,8 +37,12 @@
 #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
 #include "gc_implementation/parNew/parNewGeneration.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/allocation.hpp"
 #include "memory/cardTableRS.hpp"
 #include "memory/collectorPolicy.hpp"
 #include "memory/gcLocker.inline.hpp"
@@ -60,7 +64,8 @@
 
 // statics
 CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
-bool          CMSCollector::_full_gc_requested          = false;
+bool CMSCollector::_full_gc_requested = false;
+GCCause::Cause CMSCollector::_full_gc_cause = GCCause::_no_gc;
 
 //////////////////////////////////////////////////////////////////
 // In support of CMS/VM thread synchronization
@@ -591,7 +596,10 @@
   _concurrent_cycles_since_last_unload(0),
   _roots_scanning_options(0),
   _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
-  _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
+  _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
+  _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) CMSTracer()),
+  _gc_timer_cm(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
+  _cms_start_registered(false)
 {
   if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {
     ExplicitGCInvokesConcurrent = true;
@@ -1676,18 +1684,38 @@
   _full_gcs_since_conc_gc++;
 }
 
-void CMSCollector::request_full_gc(unsigned int full_gc_count) {
+void CMSCollector::request_full_gc(unsigned int full_gc_count, GCCause::Cause cause) {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
   unsigned int gc_count = gch->total_full_collections();
   if (gc_count == full_gc_count) {
     MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
     _full_gc_requested = true;
+    _full_gc_cause = cause;
     CGC_lock->notify();   // nudge CMS thread
   } else {
     assert(gc_count > full_gc_count, "Error: causal loop");
   }
 }
 
+bool CMSCollector::is_external_interruption() {
+  GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
+  return GCCause::is_user_requested_gc(cause) ||
+         GCCause::is_serviceability_requested_gc(cause);
+}
+
+void CMSCollector::report_concurrent_mode_interruption() {
+  if (is_external_interruption()) {
+    if (PrintGCDetails) {
+      gclog_or_tty->print(" (concurrent mode interrupted)");
+    }
+  } else {
+    if (PrintGCDetails) {
+      gclog_or_tty->print(" (concurrent mode failure)");
+    }
+    _gc_tracer_cm->report_concurrent_mode_failure();
+  }
+}
+
 
 // The foreground and background collectors need to coordinate in order
 // to make sure that they do not mutually interfere with CMS collections.
@@ -1845,14 +1873,8 @@
   }
 )
 
-  if (PrintGCDetails && first_state > Idling) {
-    GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
-    if (GCCause::is_user_requested_gc(cause) ||
-        GCCause::is_serviceability_requested_gc(cause)) {
-      gclog_or_tty->print(" (concurrent mode interrupted)");
-    } else {
-      gclog_or_tty->print(" (concurrent mode failure)");
-    }
+  if (first_state > Idling) {
+    report_concurrent_mode_interruption();
   }
 
   set_did_compact(should_compact);
@@ -1868,6 +1890,10 @@
     // Reference objects are active.
     ref_processor()->clean_up_discovered_references();
 
+    if (first_state > Idling) {
+      save_heap_summary();
+    }
+
     do_compaction_work(clear_all_soft_refs);
 
     // Has the GC time limit been exceeded?
@@ -1971,7 +1997,14 @@
 // a mark-sweep-compact.
 void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  TraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, gclog_or_tty);
+
+  STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
+  gc_timer->register_gc_start(os::elapsed_counter());
+
+  SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
+  gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
+
+  GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL);
   if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
     gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
       "collections passed to foreground collector", _full_gcs_since_conc_gc);
@@ -2062,6 +2095,10 @@
     size_policy()->msc_collection_end(gch->gc_cause());
   }
 
+  gc_timer->register_gc_end(os::elapsed_counter());
+
+  gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
+
   // For a mark-sweep-compact, compute_new_size() will be called
   // in the heap's do_collection() method.
 }
@@ -2093,7 +2130,7 @@
       // required.
       _collectorState = FinalMarking;
   }
-  collect_in_foreground(clear_all_soft_refs);
+  collect_in_foreground(clear_all_soft_refs, GenCollectedHeap::heap()->gc_cause());
 
   // For a mark-sweep, compute_new_size() will be called
   // in the heap's do_collection() method.
@@ -2153,7 +2190,7 @@
 // one "collect" method between the background collector and the foreground
 // collector but the if-then-else required made it cleaner to have
 // separate methods.
-void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
+void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause) {
   assert(Thread::current()->is_ConcurrentGC_thread(),
     "A CMS asynchronous collection is only allowed on a CMS thread.");
 
@@ -2172,6 +2209,7 @@
     } else {
       assert(_collectorState == Idling, "Should be idling before start.");
       _collectorState = InitialMarking;
+      register_gc_start(cause);
       // Reset the expansion cause, now that we are about to begin
       // a new cycle.
       clear_expansion_cause();
@@ -2184,6 +2222,7 @@
     // ensuing concurrent GC cycle.
     update_should_unload_classes();
     _full_gc_requested = false;           // acks all outstanding full gc requests
+    _full_gc_cause = GCCause::_no_gc;
     // Signal that we are about to start a collection
     gch->increment_total_full_collections();  // ... starting a collection cycle
     _collection_count_start = gch->total_full_collections();
@@ -2263,7 +2302,6 @@
         {
           ReleaseForegroundGC x(this);
           stats().record_cms_begin();
-
           VM_CMS_Initial_Mark initial_mark_op(this);
           VMThread::execute(&initial_mark_op);
         }
@@ -2343,6 +2381,7 @@
           CMSTokenSync        z(true);   // not strictly needed.
           if (_collectorState == Resizing) {
             compute_new_size();
+            save_heap_summary();
             _collectorState = Resetting;
           } else {
             assert(_collectorState == Idling, "The state should only change"
@@ -2401,7 +2440,39 @@
   }
 }
 
-void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
+void CMSCollector::register_foreground_gc_start(GCCause::Cause cause) {
+  if (!_cms_start_registered) {
+    register_gc_start(cause);
+  }
+}
+
+void CMSCollector::register_gc_start(GCCause::Cause cause) {
+  _cms_start_registered = true;
+  _gc_timer_cm->register_gc_start(os::elapsed_counter());
+  _gc_tracer_cm->report_gc_start(cause, _gc_timer_cm->gc_start());
+}
+
+void CMSCollector::register_gc_end() {
+  if (_cms_start_registered) {
+    report_heap_summary(GCWhen::AfterGC);
+
+    _gc_timer_cm->register_gc_end(os::elapsed_counter());
+    _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
+    _cms_start_registered = false;
+  }
+}
+
+void CMSCollector::save_heap_summary() {
+  GenCollectedHeap* gch = GenCollectedHeap::heap();
+  _last_heap_summary = gch->create_heap_summary();
+  _last_metaspace_summary = gch->create_metaspace_summary();
+}
+
+void CMSCollector::report_heap_summary(GCWhen::Type when) {
+  _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary, _last_metaspace_summary);
+}
+
+void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) {
   assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
          "Foreground collector should be waiting, not executing");
   assert(Thread::current()->is_VM_thread(), "A foreground collection"
@@ -2409,8 +2480,8 @@
   assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
          "VM thread should have CMS token");
 
-  NOT_PRODUCT(TraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
-    true, gclog_or_tty);)
+  NOT_PRODUCT(GCTraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
+    true, NULL);)
   if (UseAdaptiveSizePolicy) {
     size_policy()->ms_collection_begin();
   }
@@ -2434,6 +2505,7 @@
     }
     switch (_collectorState) {
       case InitialMarking:
+        register_foreground_gc_start(cause);
         init_mark_was_synchronous = true;  // fact to be exploited in re-mark
         checkpointRootsInitial(false);
         assert(_collectorState == Marking, "Collector state should have changed"
@@ -2482,6 +2554,7 @@
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
           Universe::verify("Verify before reset: ");
         }
+        save_heap_summary();
         reset(false);
         assert(_collectorState == Idling, "Collector state should "
           "have changed");
@@ -3504,6 +3577,9 @@
   check_correct_thread_executing();
   TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
 
+  save_heap_summary();
+  report_heap_summary(GCWhen::BeforeGC);
+
   ReferenceProcessor* rp = ref_processor();
   SpecializationStats::clear();
   assert(_restart_addr == NULL, "Control point invariant");
@@ -3549,8 +3625,8 @@
   // CMS collection cycle.
   setup_cms_unloading_and_verification_state();
 
-  NOT_PRODUCT(TraceTime t("\ncheckpointRootsInitialWork",
-    PrintGCDetails && Verbose, true, gclog_or_tty);)
+  NOT_PRODUCT(GCTraceTime t("\ncheckpointRootsInitialWork",
+    PrintGCDetails && Verbose, true, _gc_timer_cm);)
   if (UseAdaptiveSizePolicy) {
     size_policy()->checkpoint_roots_initial_begin();
   }
@@ -4542,8 +4618,10 @@
     // The code in this method may need further
     // tweaking for better performance and some restructuring
     // for cleaner interfaces.
+    GCTimer *gc_timer = NULL; // Currently not tracing concurrent phases
     rp->preclean_discovered_references(
-          rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl);
+          rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl,
+          gc_timer);
   }
 
   if (clean_survivor) {  // preclean the active survivor space(s)
@@ -4885,8 +4963,8 @@
       // Temporarily set flag to false, GCH->do_collection will
       // expect it to be false and set to true
       FlagSetting fl(gch->_is_gc_active, false);
-      NOT_PRODUCT(TraceTime t("Scavenge-Before-Remark",
-        PrintGCDetails && Verbose, true, gclog_or_tty);)
+      NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark",
+        PrintGCDetails && Verbose, true, _gc_timer_cm);)
       int level = _cmsGen->level() - 1;
       if (level >= 0) {
         gch->do_collection(true,        // full (i.e. force, see below)
@@ -4915,7 +4993,7 @@
 void CMSCollector::checkpointRootsFinalWork(bool asynch,
   bool clear_all_soft_refs, bool init_mark_was_synchronous) {
 
-  NOT_PRODUCT(TraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, gclog_or_tty);)
+  NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm);)
 
   assert(haveFreelistLocks(), "must have free list locks");
   assert_lock_strong(bitMapLock());
@@ -4966,11 +5044,11 @@
       // the most recent young generation GC, minus those cleaned up by the
       // concurrent precleaning.
       if (CMSParallelRemarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
-        TraceTime t("Rescan (parallel) ", PrintGCDetails, false, gclog_or_tty);
+        GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm);
         do_remark_parallel();
       } else {
-        TraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
-                    gclog_or_tty);
+        GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
+                    _gc_timer_cm);
         do_remark_non_parallel();
       }
     }
@@ -4983,7 +5061,7 @@
   verify_overflow_empty();
 
   {
-    NOT_PRODUCT(TraceTime ts("refProcessingWork", PrintGCDetails, false, gclog_or_tty);)
+    NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm);)
     refProcessingWork(asynch, clear_all_soft_refs);
   }
   verify_work_stacks_empty();
@@ -5044,6 +5122,8 @@
     verify_after_remark();
   }
 
+  _gc_tracer_cm->report_object_count_after_gc(&_is_alive_closure);
+
   // Change under the freelistLocks.
   _collectorState = Sweeping;
   // Call isAllClear() under bitMapLock
@@ -5697,7 +5777,7 @@
                               NULL,  // space is set further below
                               &_markBitMap, &_markStack, &mrias_cl);
   {
-    TraceTime t("grey object rescan", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm);
     // Iterate over the dirty cards, setting the corresponding bits in the
     // mod union table.
     {
@@ -5734,7 +5814,7 @@
     Universe::verify();
   }
   {
-    TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5756,7 +5836,7 @@
   }
 
   {
-    TraceTime t("visit unhandled CLDs", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5775,7 +5855,7 @@
   }
 
   {
-    TraceTime t("dirty klass scan", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5977,7 +6057,9 @@
                                 _span, &_markBitMap, &_markStack,
                                 &cmsKeepAliveClosure, false /* !preclean */);
   {
-    TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm);
+
+    ReferenceProcessorStats stats;
     if (rp->processing_is_mt()) {
       // Set the degree of MT here.  If the discovery is done MT, there
       // may have been a different number of threads doing the discovery
@@ -5996,16 +6078,20 @@
       }
       rp->set_active_mt_degree(active_workers);
       CMSRefProcTaskExecutor task_executor(*this);
-      rp->process_discovered_references(&_is_alive_closure,
+      stats = rp->process_discovered_references(&_is_alive_closure,
                                         &cmsKeepAliveClosure,
                                         &cmsDrainMarkingStackClosure,
-                                        &task_executor);
+                                        &task_executor,
+                                        _gc_timer_cm);
     } else {
-      rp->process_discovered_references(&_is_alive_closure,
+      stats = rp->process_discovered_references(&_is_alive_closure,
                                         &cmsKeepAliveClosure,
                                         &cmsDrainMarkingStackClosure,
-                                        NULL);
-    }
+                                        NULL,
+                                        _gc_timer_cm);
+    }
+    _gc_tracer_cm->report_gc_reference_stats(stats);
+
   }
 
   // This is the point where the entire marking should have completed.
@@ -6013,7 +6099,7 @@
 
   if (should_unload_classes()) {
     {
-      TraceTime t("class unloading", PrintGCDetails, false, gclog_or_tty);
+      GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm);
 
       // Unload classes and purge the SystemDictionary.
       bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
@@ -6026,7 +6112,7 @@
     }
 
     {
-      TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
+      GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm);
       // Clean up unreferenced symbols in symbol table.
       SymbolTable::unlink();
     }
@@ -6035,7 +6121,7 @@
   // CMS doesn't use the StringTable as hard roots when class unloading is turned off.
   // Need to check if we really scanned the StringTable.
   if ((roots_scanning_options() & SharedHeap::SO_Strings) == 0) {
-    TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm);
     // Delete entries for dead interned strings.
     StringTable::unlink(&_is_alive_closure);
   }
@@ -6380,12 +6466,14 @@
       _cmsGen->rotate_debug_collection_type();
     }
   )
+
+  register_gc_end();
 }
 
 void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
   gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
   TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  TraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+  GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
   TraceCollectorStats tcs(counters());
 
   switch (op) {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -25,8 +25,10 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 
+#include "gc_implementation/shared/gcHeapSummary.hpp"
 #include "gc_implementation/shared/gSpaceCounters.hpp"
 #include "gc_implementation/shared/gcStats.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_implementation/shared/generationCounters.hpp"
 #include "memory/freeBlockDictionary.hpp"
 #include "memory/generation.hpp"
@@ -53,6 +55,8 @@
 class CMSAdaptiveSizePolicy;
 class CMSConcMarkingTask;
 class CMSGCAdaptivePolicyCounters;
+class CMSTracer;
+class ConcurrentGCTimer;
 class ConcurrentMarkSweepGeneration;
 class ConcurrentMarkSweepPolicy;
 class ConcurrentMarkSweepThread;
@@ -61,6 +65,7 @@
 class PromotionInfo;
 class ScanMarkedObjectsAgainCarefullyClosure;
 class TenuredGeneration;
+class SerialOldTracer;
 
 // A generic CMS bit map. It's the basis for both the CMS marking bit map
 // as well as for the mod union table (in each case only a subset of the
@@ -567,8 +572,9 @@
   bool _completed_initialization;
 
   // In support of ExplicitGCInvokesConcurrent
-  static   bool _full_gc_requested;
-  unsigned int  _collection_count_start;
+  static bool _full_gc_requested;
+  static GCCause::Cause _full_gc_cause;
+  unsigned int _collection_count_start;
 
   // Should we unload classes this concurrent cycle?
   bool _should_unload_classes;
@@ -609,6 +615,20 @@
   AdaptivePaddedAverage _inter_sweep_estimate;
   AdaptivePaddedAverage _intra_sweep_estimate;
 
+  CMSTracer* _gc_tracer_cm;
+  ConcurrentGCTimer* _gc_timer_cm;
+
+  bool _cms_start_registered;
+
+  GCHeapSummary _last_heap_summary;
+  MetaspaceSummary _last_metaspace_summary;
+
+  void register_foreground_gc_start(GCCause::Cause cause);
+  void register_gc_start(GCCause::Cause cause);
+  void register_gc_end();
+  void save_heap_summary();
+  void report_heap_summary(GCWhen::Type when);
+
  protected:
   ConcurrentMarkSweepGeneration* _cmsGen;  // old gen (CMS)
   MemRegion                      _span;    // span covering above two
@@ -827,6 +847,10 @@
   void do_mark_sweep_work(bool clear_all_soft_refs,
     CollectorState first_state, bool should_start_over);
 
+  // Work methods for reporting concurrent mode interruption or failure
+  bool is_external_interruption();
+  void report_concurrent_mode_interruption();
+
   // If the backgrould GC is active, acquire control from the background
   // GC and do the collection.
   void acquire_control_and_collect(bool   full, bool clear_all_soft_refs);
@@ -876,11 +900,11 @@
                bool   clear_all_soft_refs,
                size_t size,
                bool   tlab);
-  void collect_in_background(bool clear_all_soft_refs);
-  void collect_in_foreground(bool clear_all_soft_refs);
+  void collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause);
+  void collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause);
 
   // In support of ExplicitGCInvokesConcurrent
-  static void request_full_gc(unsigned int full_gc_count);
+  static void request_full_gc(unsigned int full_gc_count, GCCause::Cause cause);
   // Should we unload classes in a particular concurrent cycle?
   bool should_unload_classes() const {
     return _should_unload_classes;
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -140,7 +140,9 @@
   while (!_should_terminate) {
     sleepBeforeNextCycle();
     if (_should_terminate) break;
-    _collector->collect_in_background(false);  // !clear_all_soft_refs
+    GCCause::Cause cause = _collector->_full_gc_requested ?
+      _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
+    _collector->collect_in_background(false, cause);
   }
   assert(_should_terminate, "just checking");
   // Check that the state of any protocol for synchronization
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,12 @@
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
 #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
+#include "runtime/os.hpp"
 #include "utilities/dtrace.hpp"
 
 
@@ -60,6 +63,7 @@
 void VM_CMS_Operation::verify_before_gc() {
   if (VerifyBeforeGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
+    GCTraceTime tm("Verify Before", false, false, _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -71,6 +75,7 @@
 void VM_CMS_Operation::verify_after_gc() {
   if (VerifyAfterGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
+    GCTraceTime tm("Verify After", false, false, _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -140,6 +145,8 @@
                                 );
 #endif /* USDT2 */
 
+  _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark", os::elapsed_counter());
+
   GenCollectedHeap* gch = GenCollectedHeap::heap();
   GCCauseSetter gccs(gch, GCCause::_cms_initial_mark);
 
@@ -149,6 +156,9 @@
   _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial, gch->gc_cause());
 
   VM_CMS_Operation::verify_after_gc();
+
+  _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter());
+
 #ifndef USDT2
   HS_DTRACE_PROBE(hs_private, cms__initmark__end);
 #else /* USDT2 */
@@ -172,6 +182,8 @@
                                 );
 #endif /* USDT2 */
 
+  _collector->_gc_timer_cm->register_gc_pause_start("Final Mark", os::elapsed_counter());
+
   GenCollectedHeap* gch = GenCollectedHeap::heap();
   GCCauseSetter gccs(gch, GCCause::_cms_final_remark);
 
@@ -181,6 +193,10 @@
   _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal, gch->gc_cause());
 
   VM_CMS_Operation::verify_after_gc();
+
+  _collector->save_heap_summary();
+  _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter());
+
 #ifndef USDT2
   HS_DTRACE_PROBE(hs_private, cms__remark__end);
 #else /* USDT2 */
@@ -225,7 +241,7 @@
     // In case CMS thread was in icms_wait(), wake it up.
     CMSCollector::start_icms();
     // Nudge the CMS thread to start a concurrent collection.
-    CMSCollector::request_full_gc(_full_gc_count_before);
+    CMSCollector::request_full_gc(_full_gc_count_before, _gc_cause);
   } else {
     assert(_full_gc_count_before < gch->total_full_collections(), "Error");
     FullGCCount_lock->notify_all();  // Inform the Java thread its work is done
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -114,6 +114,14 @@
   }
 }
 
+void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
+  if (_threads != NULL) {
+    for (int i = 0; i < worker_thread_num(); i++) {
+      tc->do_thread(_threads[i]);
+    }
+  }
+}
+
 int ConcurrentG1Refine::thread_num() {
   int n_threads = (G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads
                                                 : ParallelGCThreads;
@@ -126,3 +134,7 @@
     st->cr();
   }
 }
+
+ConcurrentG1RefineThread * ConcurrentG1Refine::sampling_thread() const {
+  return _threads[worker_thread_num()];
+}
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -35,6 +35,7 @@
 class G1CollectedHeap;
 class G1HotCardCache;
 class G1RemSet;
+class DirtyCardQueue;
 
 class ConcurrentG1Refine: public CHeapObj<mtGC> {
   ConcurrentG1RefineThread** _threads;
@@ -78,9 +79,15 @@
 
   void reinitialize_threads();
 
-  // Iterate over the conc refine threads
+  // Iterate over all concurrent refinement threads
   void threads_do(ThreadClosure *tc);
 
+  // Iterate over all worker refinement threads
+  void worker_threads_do(ThreadClosure * tc);
+
+  // The RS sampling thread
+  ConcurrentG1RefineThread * sampling_thread() const;
+
   static int thread_num();
 
   void print_worker_threads_on(outputStream* st) const;
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -36,6 +36,9 @@
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "gc_implementation/shared/vmGCOperations.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/referencePolicy.hpp"
 #include "memory/resourceArea.hpp"
@@ -1342,6 +1345,9 @@
   _remark_times.add((now - start) * 1000.0);
 
   g1p->record_concurrent_mark_remark_end();
+
+  G1CMIsAliveClosure is_alive(g1h);
+  g1h->gc_tracer_cm()->report_object_count_after_gc(&is_alive);
 }
 
 // Base class of the closures that finalize and verify the
@@ -2129,6 +2135,7 @@
   }
 
   g1h->verify_region_sets_optional();
+  g1h->trace_heap_after_concurrent_cycle();
 }
 
 void ConcurrentMark::completeCleanup() {
@@ -2439,7 +2446,7 @@
     if (G1Log::finer()) {
       gclog_or_tty->put(' ');
     }
-    TraceTime t("GC ref-proc", G1Log::finer(), false, gclog_or_tty);
+    GCTraceTime t("GC ref-proc", G1Log::finer(), false, g1h->gc_timer_cm());
 
     ReferenceProcessor* rp = g1h->ref_processor_cm();
 
@@ -2491,10 +2498,13 @@
     rp->set_active_mt_degree(active_workers);
 
     // Process the weak references.
-    rp->process_discovered_references(&g1_is_alive,
-                                      &g1_keep_alive,
-                                      &g1_drain_mark_stack,
-                                      executor);
+    const ReferenceProcessorStats& stats =
+        rp->process_discovered_references(&g1_is_alive,
+                                          &g1_keep_alive,
+                                          &g1_drain_mark_stack,
+                                          executor,
+                                          g1h->gc_timer_cm());
+    g1h->gc_tracer_cm()->report_gc_reference_stats(stats);
 
     // The do_oop work routines of the keep_alive and drain_marking_stack
     // oop closures will set the has_overflown flag if we overflow the
@@ -3227,6 +3237,9 @@
   satb_mq_set.set_active_all_threads(
                                  false, /* new active value */
                                  satb_mq_set.is_active() /* expected_active */);
+
+  _g1h->trace_heap_after_concurrent_cycle();
+  _g1h->register_concurrent_cycle_end();
 }
 
 static void print_ms_time_info(const char* prefix, const char* name,
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -569,8 +569,6 @@
   void clear_has_overflown()     { _has_overflown = false; }
   bool restart_for_overflow()    { return _restart_for_overflow; }
 
-  bool has_aborted()             { return _has_aborted; }
-
   // Methods to enter the two overflow sync barriers
   void enter_first_sync_barrier(uint worker_id);
   void enter_second_sync_barrier(uint worker_id);
@@ -821,6 +819,8 @@
   // Called to abort the marking cycle after a Full GC takes palce.
   void abort();
 
+  bool has_aborted()      { return _has_aborted; }
+
   // This prints the global/local fingers. It is used for debugging.
   NOT_PRODUCT(void print_finger();)
 
--- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -93,7 +93,6 @@
       ResourceMark rm;
       HandleMark   hm;
       double cycle_start = os::elapsedVTime();
-      char verbose_str[128];
 
       // We have to ensure that we finish scanning the root regions
       // before the next GC takes place. To ensure this we have to
@@ -155,8 +154,7 @@
           }
 
           CMCheckpointRootsFinalClosure final_cl(_cm);
-          sprintf(verbose_str, "GC remark");
-          VM_CGC_Operation op(&final_cl, verbose_str, true /* needs_pll */);
+          VM_CGC_Operation op(&final_cl, "GC remark", true /* needs_pll */);
           VMThread::execute(&op);
         }
         if (cm()->restart_for_overflow()) {
@@ -187,8 +185,7 @@
         }
 
         CMCleanUp cl_cl(_cm);
-        sprintf(verbose_str, "GC cleanup");
-        VM_CGC_Operation op(&cl_cl, verbose_str, false /* needs_pll */);
+        VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */);
         VMThread::execute(&op);
       } else {
         // We don't want to update the marking status if a GC pause
@@ -292,6 +289,7 @@
     // called System.gc() with +ExplicitGCInvokesConcurrent).
     _sts.join();
     g1h->increment_old_marking_cycles_completed(true /* concurrent */);
+    g1h->register_concurrent_cycle_end();
     _sts.leave();
   }
   assert(_should_terminate, "just checking");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/evacuationInfo.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_EVACUATIONINFO_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_EVACUATIONINFO_HPP
+
+#include "memory/allocation.hpp"
+
+class EvacuationInfo : public StackObj {
+  uint _collectionset_regions;
+  uint _allocation_regions;
+  size_t _collectionset_used_before;
+  size_t _collectionset_used_after;
+  size_t _alloc_regions_used_before;
+  size_t _bytes_copied;
+  uint   _regions_freed;
+
+public:
+  EvacuationInfo() : _collectionset_regions(0), _allocation_regions(0), _collectionset_used_before(0),
+                     _collectionset_used_after(0), _alloc_regions_used_before(0),
+                     _bytes_copied(0), _regions_freed(0) { }
+
+  void set_collectionset_regions(uint collectionset_regions) {
+    _collectionset_regions = collectionset_regions;
+  }
+
+  void set_allocation_regions(uint allocation_regions) {
+    _allocation_regions = allocation_regions;
+  }
+
+  void set_collectionset_used_before(size_t used) {
+    _collectionset_used_before = used;
+  }
+
+  void increment_collectionset_used_after(size_t used) {
+    _collectionset_used_after += used;
+  }
+
+  void set_alloc_regions_used_before(size_t used) {
+    _alloc_regions_used_before = used;
+  }
+
+  void set_bytes_copied(size_t copied) {
+    _bytes_copied = copied;
+  }
+
+  void set_regions_freed(uint freed) {
+    _regions_freed += freed;
+  }
+
+  uint   collectionset_regions()     { return _collectionset_regions; }
+  uint   allocation_regions()        { return _allocation_regions; }
+  size_t collectionset_used_before() { return _collectionset_used_before; }
+  size_t collectionset_used_after()  { return _collectionset_used_after; }
+  size_t alloc_regions_used_before() { return _alloc_regions_used_before; }
+  size_t bytes_copied()              { return _bytes_copied; }
+  uint   regions_freed()             { return _regions_freed; }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_EVACUATIONINFO_HPP
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -38,10 +38,15 @@
 #include "gc_implementation/g1/g1MarkSweep.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1YCTypes.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "gc_implementation/g1/vm_operations_g1.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "memory/genOopClosures.inline.hpp"
@@ -76,7 +81,7 @@
 // The number of GC workers is passed to heap_region_par_iterate_chunked().
 // It does use run_task() which sets _n_workers in the task.
 // G1ParTask executes g1_process_strong_roots() ->
-// SharedHeap::process_strong_roots() which calls eventuall to
+// SharedHeap::process_strong_roots() which calls eventually to
 // CardTableModRefBS::par_non_clean_card_iterate_work() which uses
 // SequentialSubTasksDone.  SharedHeap::process_strong_roots() also
 // directly uses SubTasksDone (_process_strong_tasks field in SharedHeap).
@@ -457,7 +462,7 @@
 #endif
 
 // Returns true if the reference points to an object that
-// can move in an incremental collecction.
+// can move in an incremental collection.
 bool G1CollectedHeap::is_scavengable(const void* p) {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   G1CollectorPolicy* g1p = g1h->g1_policy();
@@ -548,7 +553,7 @@
       return res;
     }
 
-    // Wait here until we get notifed either when (a) there are no
+    // Wait here until we get notified either when (a) there are no
     // more free regions coming or (b) some regions have been moved on
     // the secondary_free_list.
     SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag);
@@ -623,7 +628,7 @@
   uint first = G1_NULL_HRS_INDEX;
   if (num_regions == 1) {
     // Only one region to allocate, no need to go through the slower
-    // path. The caller will attempt the expasion if this fails, so
+    // path. The caller will attempt the expansion if this fails, so
     // let's not try to expand here too.
     HeapRegion* hr = new_region(word_size, false /* do_expand */);
     if (hr != NULL) {
@@ -688,7 +693,7 @@
   // the first region.
   HeapWord* new_obj = first_hr->bottom();
   // This will be the new end of the first region in the series that
-  // should also match the end of the last region in the seriers.
+  // should also match the end of the last region in the series.
   HeapWord* new_end = new_obj + word_size_sum;
   // This will be the new top of the first region that will reflect
   // this allocation.
@@ -863,7 +868,7 @@
                               bool*  gc_overhead_limit_was_exceeded) {
   assert_heap_not_locked_and_not_at_safepoint();
 
-  // Loop until the allocation is satisified, or unsatisfied after GC.
+  // Loop until the allocation is satisfied, or unsatisfied after GC.
   for (int try_count = 1, gclocker_retry_count = 0; /* we'll return */; try_count += 1) {
     unsigned int gc_count_before;
 
@@ -1003,7 +1008,7 @@
       (*gclocker_retry_count_ret) += 1;
     }
 
-    // We can reach here if we were unsuccessul in scheduling a
+    // We can reach here if we were unsuccessful in scheduling a
     // collection (because another thread beat us to it) or if we were
     // stalled due to the GC locker. In either can we should retry the
     // allocation attempt in case another thread successfully
@@ -1128,7 +1133,7 @@
       (*gclocker_retry_count_ret) += 1;
     }
 
-    // We can reach here if we were unsuccessul in scheduling a
+    // We can reach here if we were unsuccessful in scheduling a
     // collection (because another thread beat us to it) or if we were
     // stalled due to the GC locker. In either can we should retry the
     // allocation attempt in case another thread successfully
@@ -1298,10 +1303,17 @@
     return false;
   }
 
+  STWGCTimer* gc_timer = G1MarkSweep::gc_timer();
+  gc_timer->register_gc_start(os::elapsed_counter());
+
+  SerialOldTracer* gc_tracer = G1MarkSweep::gc_tracer();
+  gc_tracer->report_gc_start(gc_cause(), gc_timer->gc_start());
+
   SvcGCMarker sgcm(SvcGCMarker::FULL);
   ResourceMark rm;
 
   print_heap_before_gc();
+  trace_heap_before_gc(gc_tracer);
 
   size_t metadata_prev_used = MetaspaceAux::allocated_used_bytes();
 
@@ -1322,7 +1334,7 @@
     TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
     {
-      TraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, gclog_or_tty);
+      GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL);
       TraceCollectorStats tcs(g1mm()->full_collection_counters());
       TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
 
@@ -1351,7 +1363,7 @@
 
       verify_before_gc();
 
-      pre_full_gc_dump();
+      pre_full_gc_dump(gc_timer);
 
       COMPILER2_PRESENT(DerivedPointerTable::clear());
 
@@ -1417,8 +1429,6 @@
 
       MemoryService::track_memory_usage();
 
-      verify_after_gc();
-
       assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
       ref_processor_stw()->verify_no_references_recorded();
 
@@ -1435,7 +1445,7 @@
 
       reset_gc_time_stamp();
       // Since everything potentially moved, we will clear all remembered
-      // sets, and clear all cards.  Later we will rebuild remebered
+      // sets, and clear all cards.  Later we will rebuild remembered
       // sets. We will also reset the GC time stamps of the regions.
       clear_rsets_post_compaction();
       check_gc_time_stamps();
@@ -1521,6 +1531,8 @@
       _hrs.verify_optional();
       verify_region_sets_optional();
 
+      verify_after_gc();
+
       // Start a new incremental collection set for the next pause
       assert(g1_policy()->collection_set() == NULL, "must be");
       g1_policy()->start_incremental_cset_building();
@@ -1553,8 +1565,12 @@
     }
 
     print_heap_after_gc();
-
-    post_full_gc_dump();
+    trace_heap_after_gc(gc_tracer);
+
+    post_full_gc_dump(gc_timer);
+
+    gc_timer->register_gc_end(os::elapsed_counter());
+    gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
   }
 
   return true;
@@ -1919,7 +1935,7 @@
   _ref_processor_stw(NULL),
   _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
   _bot_shared(NULL),
-  _evac_failure_scan_stack(NULL) ,
+  _evac_failure_scan_stack(NULL),
   _mark_in_progress(false),
   _cg1r(NULL), _summary_bytes_used(0),
   _g1mm(NULL),
@@ -1939,12 +1955,18 @@
   _surviving_young_words(NULL),
   _old_marking_cycles_started(0),
   _old_marking_cycles_completed(0),
+  _concurrent_cycle_started(false),
   _in_cset_fast_test(NULL),
   _in_cset_fast_test_base(NULL),
   _dirty_cards_region_list(NULL),
   _worker_cset_start_region(NULL),
-  _worker_cset_start_region_time_stamp(NULL) {
-  _g1h = this; // To catch bugs.
+  _worker_cset_start_region_time_stamp(NULL),
+  _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()),
+  _gc_timer_cm(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
+  _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
+  _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
+
+  _g1h = this;
   if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
     vm_exit_during_initialization("Failed necessary allocation.");
   }
@@ -1959,13 +1981,14 @@
 
   _worker_cset_start_region = NEW_C_HEAP_ARRAY(HeapRegion*, n_queues, mtGC);
   _worker_cset_start_region_time_stamp = NEW_C_HEAP_ARRAY(unsigned int, n_queues, mtGC);
+  _evacuation_failed_info_array = NEW_C_HEAP_ARRAY(EvacuationFailedInfo, n_queues, mtGC);
 
   for (int i = 0; i < n_queues; i++) {
     RefToScanQueue* q = new RefToScanQueue();
     q->initialize();
     _task_queues->register_queue(i, q);
-  }
-
+    ::new (&_evacuation_failed_info_array[i]) EvacuationFailedInfo();
+  }
   clear_cset_start_regions();
 
   // Initialize the G1EvacuationFailureALot counters and flags.
@@ -2025,7 +2048,7 @@
                                                  HeapRegion::GrainBytes);
 
   // It is important to do this in a way such that concurrent readers can't
-  // temporarily think somethings in the heap.  (I've actually seen this
+  // temporarily think something is in the heap.  (I've actually seen this
   // happen in asserts: DLD.)
   _reserved.set_word_size(0);
   _reserved.set_start((HeapWord*)heap_rs.base());
@@ -2462,7 +2485,7 @@
   // We need to clear the "in_progress" flag in the CM thread before
   // we wake up any waiters (especially when ExplicitInvokesConcurrent
   // is set) so that if a waiter requests another System.gc() it doesn't
-  // incorrectly see that a marking cyle is still in progress.
+  // incorrectly see that a marking cycle is still in progress.
   if (concurrent) {
     _cmThread->clear_in_progress();
   }
@@ -2474,6 +2497,49 @@
   FullGCCount_lock->notify_all();
 }
 
+void G1CollectedHeap::register_concurrent_cycle_start(jlong start_time) {
+  _concurrent_cycle_started = true;
+  _gc_timer_cm->register_gc_start(start_time);
+
+  _gc_tracer_cm->report_gc_start(gc_cause(), _gc_timer_cm->gc_start());
+  trace_heap_before_gc(_gc_tracer_cm);
+}
+
+void G1CollectedHeap::register_concurrent_cycle_end() {
+  if (_concurrent_cycle_started) {
+    _gc_timer_cm->register_gc_end(os::elapsed_counter());
+
+    if (_cm->has_aborted()) {
+      _gc_tracer_cm->report_concurrent_mode_failure();
+    }
+    _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
+
+    _concurrent_cycle_started = false;
+  }
+}
+
+void G1CollectedHeap::trace_heap_after_concurrent_cycle() {
+  if (_concurrent_cycle_started) {
+    trace_heap_after_gc(_gc_tracer_cm);
+  }
+}
+
+G1YCType G1CollectedHeap::yc_type() {
+  bool is_young = g1_policy()->gcs_are_young();
+  bool is_initial_mark = g1_policy()->during_initial_mark_pause();
+  bool is_during_mark = mark_in_progress();
+
+  if (is_initial_mark) {
+    return InitialMark;
+  } else if (is_during_mark) {
+    return DuringMark;
+  } else if (is_young) {
+    return Normal;
+  } else {
+    return Mixed;
+  }
+}
+
 void G1CollectedHeap::collect(GCCause::Cause cause) {
   assert_heap_not_locked();
 
@@ -2676,13 +2742,13 @@
             break;
           }
 
-          // Noone should have claimed it directly. We can given
+          // No one should have claimed it directly. We can given
           // that we claimed its "starts humongous" region.
           assert(chr->claim_value() != claim_value, "sanity");
           assert(chr->humongous_start_region() == r, "sanity");
 
           if (chr->claimHeapRegion(claim_value)) {
-            // we should always be able to claim it; noone else should
+            // we should always be able to claim it; no one else should
             // be trying to claim this region
 
             bool res2 = cl->doHeapRegion(chr);
@@ -2976,7 +3042,7 @@
   // the min TLAB size.
 
   // Also, this value can be at most the humongous object threshold,
-  // since we can't allow tlabs to grow big enough to accomodate
+  // since we can't allow tlabs to grow big enough to accommodate
   // humongous objects.
 
   HeapRegion* hr = _mutator_alloc_region.get();
@@ -3539,6 +3605,14 @@
 }
 
 void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
+
+  if (G1SummarizeRSetStats &&
+      (G1SummarizeRSetStatsPeriod > 0) &&
+      // we are at the end of the GC. Total collections has already been increased.
+      ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
+    g1_rem_set()->print_periodic_summary_info();
+  }
+
   // FIXME: what is this about?
   // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
   // is set.
@@ -3735,10 +3809,15 @@
     return false;
   }
 
+  _gc_timer_stw->register_gc_start(os::elapsed_counter());
+
+  _gc_tracer_stw->report_gc_start(gc_cause(), _gc_timer_stw->gc_start());
+
   SvcGCMarker sgcm(SvcGCMarker::MINOR);
   ResourceMark rm;
 
   print_heap_before_gc();
+  trace_heap_before_gc(_gc_tracer_stw);
 
   HRSPhaseSetter x(HRSPhaseEvacuation);
   verify_region_sets_optional();
@@ -3763,11 +3842,17 @@
 
   // Inner scope for scope based logging, timers, and stats collection
   {
+    EvacuationInfo evacuation_info;
+
     if (g1_policy()->during_initial_mark_pause()) {
       // We are about to start a marking cycle, so we increment the
       // full collection counter.
       increment_old_marking_cycles_started();
+      register_concurrent_cycle_start(_gc_timer_stw->gc_start());
     }
+
+    _gc_tracer_stw->report_yc_type(yc_type());
+
     TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
     int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
@@ -3877,7 +3962,7 @@
         g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
 #endif // YOUNG_LIST_VERBOSE
 
-        g1_policy()->finalize_cset(target_pause_time_ms);
+        g1_policy()->finalize_cset(target_pause_time_ms, evacuation_info);
 
         _cm->note_start_of_gc();
         // We should not verify the per-thread SATB buffers given that
@@ -3913,10 +3998,10 @@
         setup_surviving_young_words();
 
         // Initialize the GC alloc regions.
-        init_gc_alloc_regions();
+        init_gc_alloc_regions(evacuation_info);
 
         // Actually do the work...
-        evacuate_collection_set();
+        evacuate_collection_set(evacuation_info);
 
         // We do this to mainly verify the per-thread SATB buffers
         // (which have been filtered by now) since we didn't verify
@@ -3928,7 +4013,7 @@
                                  true  /* verify_thread_buffers */,
                                  true  /* verify_fingers */);
 
-        free_collection_set(g1_policy()->collection_set());
+        free_collection_set(g1_policy()->collection_set(), evacuation_info);
         g1_policy()->clear_collection_set();
 
         cleanup_surviving_young_words();
@@ -3956,13 +4041,19 @@
 #endif // YOUNG_LIST_VERBOSE
 
         g1_policy()->record_survivor_regions(_young_list->survivor_length(),
-                                            _young_list->first_survivor_region(),
-                                            _young_list->last_survivor_region());
+                                             _young_list->first_survivor_region(),
+                                             _young_list->last_survivor_region());
 
         _young_list->reset_auxilary_lists();
 
         if (evacuation_failed()) {
           _summary_bytes_used = recalculate_used();
+          uint n_queues = MAX2((int)ParallelGCThreads, 1);
+          for (uint i = 0; i < n_queues; i++) {
+            if (_evacuation_failed_info_array[i].has_failed()) {
+              _gc_tracer_stw->report_evacuation_failed(_evacuation_failed_info_array[i]);
+            }
+          }
         } else {
           // The "used" of the the collection set have already been subtracted
           // when they were freed.  Add in the bytes evacuated.
@@ -4005,7 +4096,7 @@
           }
         }
 
-        // We redo the verificaiton but now wrt to the new CSet which
+        // We redo the verification but now wrt to the new CSet which
         // has just got initialized after the previous CSet was freed.
         _cm->verify_no_cset_oops(true  /* verify_stacks */,
                                  true  /* verify_enqueued_buffers */,
@@ -4018,7 +4109,7 @@
         // investigate this in CR 7178365.
         double sample_end_time_sec = os::elapsedTime();
         double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
-        g1_policy()->record_collection_pause_end(pause_time_ms);
+        g1_policy()->record_collection_pause_end(pause_time_ms, evacuation_info);
 
         MemoryService::track_memory_usage();
 
@@ -4085,20 +4176,19 @@
     TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
 
     print_heap_after_gc();
+    trace_heap_after_gc(_gc_tracer_stw);
 
     // We must call G1MonitoringSupport::update_sizes() in the same scoping level
     // as an active TraceMemoryManagerStats object (i.e. before the destructor for the
     // TraceMemoryManagerStats is called) so that the G1 memory pools are updated
     // before any GC notifications are raised.
     g1mm()->update_sizes();
-  }
-
-  if (G1SummarizeRSetStats &&
-      (G1SummarizeRSetStatsPeriod > 0) &&
-      (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
-    g1_rem_set()->print_summary_info();
-  }
-
+
+    _gc_tracer_stw->report_evacuation_info(&evacuation_info);
+    _gc_tracer_stw->report_tenuring_threshold(_g1_policy->tenuring_threshold());
+    _gc_timer_stw->register_gc_end(os::elapsed_counter());
+    _gc_tracer_stw->report_gc_end(_gc_timer_stw->gc_end(), _gc_timer_stw->time_partitions());
+  }
   // It should now be safe to tell the concurrent mark thread to start
   // without its logging output interfering with the logging output
   // that came from the pause.
@@ -4150,7 +4240,7 @@
   assert(_mutator_alloc_region.get() == NULL, "post-condition");
 }
 
-void G1CollectedHeap::init_gc_alloc_regions() {
+void G1CollectedHeap::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
   assert_at_safepoint(true /* should_be_vm_thread */);
 
   _survivor_gc_alloc_region.init();
@@ -4165,7 +4255,7 @@
   // a cleanup and it should be on the free list now), or
   // d) it's humongous (this means that it was emptied
   // during a cleanup and was added to the free list, but
-  // has been subseqently used to allocate a humongous
+  // has been subsequently used to allocate a humongous
   // object that may be less than the region size).
   if (retained_region != NULL &&
       !retained_region->in_collection_set() &&
@@ -4182,10 +4272,13 @@
     retained_region->note_start_of_copying(during_im);
     _old_gc_alloc_region.set(retained_region);
     _hr_printer.reuse(retained_region);
-  }
-}
-
-void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers) {
+    evacuation_info.set_alloc_regions_used_before(retained_region->used());
+  }
+}
+
+void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) {
+  evacuation_info.set_allocation_regions(_survivor_gc_alloc_region.count() +
+                                         _old_gc_alloc_region.count());
   _survivor_gc_alloc_region.release();
   // If we have an old GC alloc region to release, we'll save it in
   // _retained_old_gc_alloc_region. If we don't
@@ -4268,7 +4361,7 @@
 }
 
 oop
-G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl,
+G1CollectedHeap::handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_state,
                                                oop old) {
   assert(obj_in_cs(old),
          err_msg("obj: "PTR_FORMAT" should still be in the CSet",
@@ -4277,7 +4370,12 @@
   oop forward_ptr = old->forward_to_atomic(old);
   if (forward_ptr == NULL) {
     // Forward-to-self succeeded.
-
+    assert(_par_scan_state != NULL, "par scan state");
+    OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure();
+    uint queue_num = _par_scan_state->queue_num();
+
+    _evacuation_failed = true;
+    _evacuation_failed_info_array[queue_num].register_copy_failure(old->size());
     if (_evac_failure_closure != cl) {
       MutexLockerEx x(EvacFailureStack_lock, Mutex::_no_safepoint_check_flag);
       assert(!_drain_in_progress,
@@ -4308,8 +4406,6 @@
 }
 
 void G1CollectedHeap::handle_evacuation_failure_common(oop old, markOop m) {
-  set_evacuation_failed(true);
-
   preserve_mark_if_necessary(old, m);
 
   HeapRegion* r = heap_region_containing(old);
@@ -4559,8 +4655,7 @@
   if (obj_ptr == NULL) {
     // This will either forward-to-self, or detect that someone else has
     // installed a forwarding pointer.
-    OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure();
-    return _g1->handle_evacuation_failure_par(cl, old);
+    return _g1->handle_evacuation_failure_par(_par_scan_state, old);
   }
 
   oop obj = oop(obj_ptr);
@@ -5164,7 +5259,7 @@
       // will be copied, the reference field set to point to the
       // new location, and the RSet updated. Otherwise we need to
       // use the the non-heap or metadata closures directly to copy
-      // the refernt object and update the pointer, while avoiding
+      // the referent object and update the pointer, while avoiding
       // updating the RSet.
 
       if (_g1h->is_in_g1_reserved(p)) {
@@ -5332,7 +5427,7 @@
   }
 };
 
-// Driver routine for parallel reference enqueing.
+// Driver routine for parallel reference enqueueing.
 // Creates an instance of the ref enqueueing gang
 // task and has the worker threads execute it.
 
@@ -5461,7 +5556,7 @@
   // processor would have seen that the reference object had already
   // been 'discovered' and would have skipped discovering the reference,
   // but would not have treated the reference object as a regular oop.
-  // As a reult the copy closure would not have been applied to the
+  // As a result the copy closure would not have been applied to the
   // referent object.
   //
   // We need to explicitly copy these referent objects - the references
@@ -5537,21 +5632,28 @@
   // Setup the soft refs policy...
   rp->setup_policy(false);
 
+  ReferenceProcessorStats stats;
   if (!rp->processing_is_mt()) {
     // Serial reference processing...
-    rp->process_discovered_references(&is_alive,
-                                      &keep_alive,
-                                      &drain_queue,
-                                      NULL);
+    stats = rp->process_discovered_references(&is_alive,
+                                              &keep_alive,
+                                              &drain_queue,
+                                              NULL,
+                                              _gc_timer_stw);
   } else {
     // Parallel reference processing
     assert(rp->num_q() == no_of_gc_workers, "sanity");
     assert(no_of_gc_workers <= rp->max_num_q(), "sanity");
 
     G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers);
-    rp->process_discovered_references(&is_alive, &keep_alive, &drain_queue, &par_task_executor);
-  }
-
+    stats = rp->process_discovered_references(&is_alive,
+                                              &keep_alive,
+                                              &drain_queue,
+                                              &par_task_executor,
+                                              _gc_timer_stw);
+  }
+
+  _gc_tracer_stw->report_gc_reference_stats(stats);
   // We have completed copying any necessary live referent objects
   // (that were not copied during the actual pause) so we can
   // retire any active alloc buffers
@@ -5575,7 +5677,7 @@
     // Serial reference processing...
     rp->enqueue_discovered_references();
   } else {
-    // Parallel reference enqueuing
+    // Parallel reference enqueueing
 
     assert(no_of_gc_workers == workers()->active_workers(),
            "Need to reset active workers");
@@ -5592,15 +5694,15 @@
   // FIXME
   // CM's reference processing also cleans up the string and symbol tables.
   // Should we do that here also? We could, but it is a serial operation
-  // and could signicantly increase the pause time.
+  // and could significantly increase the pause time.
 
   double ref_enq_time = os::elapsedTime() - ref_enq_start;
   g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
 }
 
-void G1CollectedHeap::evacuate_collection_set() {
+void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
   _expand_heap_after_alloc_failure = true;
-  set_evacuation_failed(false);
+  _evacuation_failed = false;
 
   // Should G1EvacuationFailureALot be in effect for this GC?
   NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
@@ -5689,7 +5791,7 @@
     JNIHandles::weak_oops_do(&is_alive, &keep_alive);
   }
 
-  release_gc_alloc_regions(n_workers);
+  release_gc_alloc_regions(n_workers, evacuation_info);
   g1_rem_set()->cleanup_after_oops_into_collection_set_do();
 
   // Reset and re-enable the hot card cache.
@@ -5712,7 +5814,7 @@
   // Enqueue any remaining references remaining on the STW
   // reference processor's discovered lists. We need to do
   // this after the card table is cleaned (and verified) as
-  // the act of enqueuing entries on to the pending list
+  // the act of enqueueing entries on to the pending list
   // will log these updates (and dirty their associated
   // cards). We need these updates logged to update any
   // RSets.
@@ -5940,7 +6042,7 @@
   g1_policy()->phase_times()->record_clear_ct_time(elapsed * 1000.0);
 }
 
-void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) {
+void G1CollectedHeap::free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info) {
   size_t pre_used = 0;
   FreeRegionList local_free_list("Local List for CSet Freeing");
 
@@ -6026,10 +6128,12 @@
       cur->set_evacuation_failed(false);
       // The region is now considered to be old.
       _old_set.add(cur);
+      evacuation_info.increment_collectionset_used_after(cur->used());
     }
     cur = next;
   }
 
+  evacuation_info.set_regions_freed(local_free_list.length());
   policy->record_max_rs_lengths(rs_lengths);
   policy->cset_regions_freed();
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,12 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
 
 #include "gc_implementation/g1/concurrentMark.hpp"
+#include "gc_implementation/g1/evacuationInfo.hpp"
 #include "gc_implementation/g1/g1AllocRegion.hpp"
 #include "gc_implementation/g1/g1HRPrinter.hpp"
+#include "gc_implementation/g1/g1MonitoringSupport.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
-#include "gc_implementation/g1/g1MonitoringSupport.hpp"
+#include "gc_implementation/g1/g1YCTypes.hpp"
 #include "gc_implementation/g1/heapRegionSeq.hpp"
 #include "gc_implementation/g1/heapRegionSets.hpp"
 #include "gc_implementation/shared/hSpaceCounters.hpp"
@@ -61,7 +63,12 @@
 class ConcurrentMark;
 class ConcurrentMarkThread;
 class ConcurrentG1Refine;
+class ConcurrentGCTimer;
 class GenerationCounters;
+class STWGCTimer;
+class G1NewTracer;
+class G1OldTracer;
+class EvacuationFailedInfo;
 
 typedef OverflowTaskQueue<StarTask, mtGC>         RefToScanQueue;
 typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
@@ -160,7 +167,7 @@
 // An instance is embedded into the G1CH and used as the
 // (optional) _is_alive_non_header closure in the STW
 // reference processor. It is also extensively used during
-// refence processing during STW evacuation pauses.
+// reference processing during STW evacuation pauses.
 class G1STWIsAliveClosure: public BoolObjectClosure {
   G1CollectedHeap* _g1;
 public:
@@ -323,10 +330,10 @@
   void release_mutator_alloc_region();
 
   // It initializes the GC alloc regions at the start of a GC.
-  void init_gc_alloc_regions();
+  void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
 
   // It releases the GC alloc regions at the end of a GC.
-  void release_gc_alloc_regions(uint no_of_gc_workers);
+  void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
 
   // It does any cleanup that needs to be done on the GC alloc regions
   // before a Full GC.
@@ -389,6 +396,8 @@
   // concurrent cycles) we have completed.
   volatile unsigned int _old_marking_cycles_completed;
 
+  bool _concurrent_cycle_started;
+
   // This is a non-product method that is helpful for testing. It is
   // called at the end of a GC and artificially expands the heap by
   // allocating a number of dead regions. This way we can induce very
@@ -593,11 +602,6 @@
   // may not be a humongous - it must fit into a single heap region.
   HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, size_t word_size);
 
-  HeapWord* allocate_during_gc_slow(GCAllocPurpose purpose,
-                                    HeapRegion*    alloc_region,
-                                    bool           par,
-                                    size_t         word_size);
-
   // Ensure that no further allocations can happen in "r", bearing in mind
   // that parallel threads might be attempting allocations.
   void par_allocate_remaining_space(HeapRegion* r);
@@ -739,6 +743,12 @@
     return _old_marking_cycles_completed;
   }
 
+  void register_concurrent_cycle_start(jlong start_time);
+  void register_concurrent_cycle_end();
+  void trace_heap_after_concurrent_cycle();
+
+  G1YCType yc_type();
+
   G1HRPrinter* hr_printer() { return &_hr_printer; }
 
 protected:
@@ -774,7 +784,7 @@
   bool do_collection_pause_at_safepoint(double target_pause_time_ms);
 
   // Actually do the work of evacuating the collection set.
-  void evacuate_collection_set();
+  void evacuate_collection_set(EvacuationInfo& evacuation_info);
 
   // The g1 remembered set of the heap.
   G1RemSet* _g1_rem_set;
@@ -799,7 +809,7 @@
 
   // After a collection pause, make the regions in the CS into free
   // regions.
-  void free_collection_set(HeapRegion* cs_head);
+  void free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info);
 
   // Abandon the current collection set without recording policy
   // statistics or updating free lists.
@@ -868,9 +878,7 @@
   // True iff a evacuation has failed in the current collection.
   bool _evacuation_failed;
 
-  // Set the attribute indicating whether evacuation has failed in the
-  // current collection.
-  void set_evacuation_failed(bool b) { _evacuation_failed = b; }
+  EvacuationFailedInfo* _evacuation_failed_info_array;
 
   // Failed evacuations cause some logical from-space objects to have
   // forwarding pointers to themselves.  Reset them.
@@ -912,7 +920,7 @@
   void finalize_for_evac_failure();
 
   // An attempt to evacuate "obj" has failed; take necessary steps.
-  oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj);
+  oop handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_state, oop obj);
   void handle_evacuation_failure_common(oop obj, markOop m);
 
 #ifndef PRODUCT
@@ -944,13 +952,13 @@
   inline bool evacuation_should_fail();
 
   // Reset the G1EvacuationFailureALot counters.  Should be called at
-  // the end of an evacuation pause in which an evacuation failure ocurred.
+  // the end of an evacuation pause in which an evacuation failure occurred.
   inline void reset_evacuation_should_fail();
 #endif // !PRODUCT
 
   // ("Weak") Reference processing support.
   //
-  // G1 has 2 instances of the referece processor class. One
+  // G1 has 2 instances of the reference processor class. One
   // (_ref_processor_cm) handles reference object discovery
   // and subsequent processing during concurrent marking cycles.
   //
@@ -1000,6 +1008,12 @@
   // The (stw) reference processor...
   ReferenceProcessor* _ref_processor_stw;
 
+  STWGCTimer* _gc_timer_stw;
+  ConcurrentGCTimer* _gc_timer_cm;
+
+  G1OldTracer* _gc_tracer_cm;
+  G1NewTracer* _gc_tracer_stw;
+
   // During reference object discovery, the _is_alive_non_header
   // closure (if non-null) is applied to the referent object to
   // determine whether the referent is live. If so then the
@@ -1145,9 +1159,12 @@
   // The STW reference processor....
   ReferenceProcessor* ref_processor_stw() const { return _ref_processor_stw; }
 
-  // The Concurent Marking reference processor...
+  // The Concurrent Marking reference processor...
   ReferenceProcessor* ref_processor_cm() const { return _ref_processor_cm; }
 
+  ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; }
+  G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; }
+
   virtual size_t capacity() const;
   virtual size_t used() const;
   // This should be called when we're not holding the heap lock. The
@@ -1205,7 +1222,7 @@
 
   // verify_region_sets_optional() is planted in the code for
   // list verification in non-product builds (and it can be enabled in
-  // product builds by definning HEAP_REGION_SET_FORCE_VERIFY to be 1).
+  // product builds by defining HEAP_REGION_SET_FORCE_VERIFY to be 1).
 #if HEAP_REGION_SET_FORCE_VERIFY
   void verify_region_sets_optional() {
     verify_region_sets();
@@ -1271,7 +1288,7 @@
   // The same as above but assume that the caller holds the Heap_lock.
   void collect_locked(GCCause::Cause cause);
 
-  // True iff a evacuation has failed in the most-recent collection.
+  // True iff an evacuation has failed in the most-recent collection.
   bool evacuation_failed() { return _evacuation_failed; }
 
   // It will free a region if it has allocated objects in it that are
@@ -1559,6 +1576,7 @@
 
   // Override; it uses the "prev" marking information
   virtual void verify(bool silent);
+
   virtual void print_on(outputStream* st) const;
   virtual void print_extended_on(outputStream* st) const;
   virtual void print_on_error(outputStream* st) const;
@@ -1733,6 +1751,95 @@
     ParGCAllocBuffer::retire(end_of_gc, retain);
     _retired = true;
   }
+
+  bool is_retired() {
+    return _retired;
+  }
+};
+
+class G1ParGCAllocBufferContainer {
+protected:
+  static int const _priority_max = 2;
+  G1ParGCAllocBuffer* _priority_buffer[_priority_max];
+
+public:
+  G1ParGCAllocBufferContainer(size_t gclab_word_size) {
+    for (int pr = 0; pr < _priority_max; ++pr) {
+      _priority_buffer[pr] = new G1ParGCAllocBuffer(gclab_word_size);
+    }
+  }
+
+  ~G1ParGCAllocBufferContainer() {
+    for (int pr = 0; pr < _priority_max; ++pr) {
+      assert(_priority_buffer[pr]->is_retired(), "alloc buffers should all retire at this point.");
+      delete _priority_buffer[pr];
+    }
+  }
+
+  HeapWord* allocate(size_t word_sz) {
+    HeapWord* obj;
+    for (int pr = 0; pr < _priority_max; ++pr) {
+      obj = _priority_buffer[pr]->allocate(word_sz);
+      if (obj != NULL) return obj;
+    }
+    return obj;
+  }
+
+  bool contains(void* addr) {
+    for (int pr = 0; pr < _priority_max; ++pr) {
+      if (_priority_buffer[pr]->contains(addr)) return true;
+    }
+    return false;
+  }
+
+  void undo_allocation(HeapWord* obj, size_t word_sz) {
+    bool finish_undo;
+    for (int pr = 0; pr < _priority_max; ++pr) {
+      if (_priority_buffer[pr]->contains(obj)) {
+        _priority_buffer[pr]->undo_allocation(obj, word_sz);
+        finish_undo = true;
+      }
+    }
+    if (!finish_undo) ShouldNotReachHere();
+  }
+
+  size_t words_remaining() {
+    size_t result = 0;
+    for (int pr = 0; pr < _priority_max; ++pr) {
+      result += _priority_buffer[pr]->words_remaining();
+    }
+    return result;
+  }
+
+  size_t words_remaining_in_retired_buffer() {
+    G1ParGCAllocBuffer* retired = _priority_buffer[0];
+    return retired->words_remaining();
+  }
+
+  void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) {
+    for (int pr = 0; pr < _priority_max; ++pr) {
+      _priority_buffer[pr]->flush_stats_and_retire(stats, end_of_gc, retain);
+    }
+  }
+
+  void update(bool end_of_gc, bool retain, HeapWord* buf, size_t word_sz) {
+    G1ParGCAllocBuffer* retired_and_set = _priority_buffer[0];
+    retired_and_set->retire(end_of_gc, retain);
+    retired_and_set->set_buf(buf);
+    retired_and_set->set_word_size(word_sz);
+    adjust_priority_order();
+  }
+
+private:
+  void adjust_priority_order() {
+    G1ParGCAllocBuffer* retired_and_set = _priority_buffer[0];
+
+    int last = _priority_max - 1;
+    for (int pr = 0; pr < last; ++pr) {
+      _priority_buffer[pr] = _priority_buffer[pr + 1];
+    }
+    _priority_buffer[last] = retired_and_set;
+  }
 };
 
 class G1ParScanThreadState : public StackObj {
@@ -1743,9 +1850,9 @@
   CardTableModRefBS* _ct_bs;
   G1RemSet* _g1_rem;
 
-  G1ParGCAllocBuffer  _surviving_alloc_buffer;
-  G1ParGCAllocBuffer  _tenured_alloc_buffer;
-  G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
+  G1ParGCAllocBufferContainer  _surviving_alloc_buffer;
+  G1ParGCAllocBufferContainer  _tenured_alloc_buffer;
+  G1ParGCAllocBufferContainer* _alloc_buffers[GCAllocPurposeCount];
   ageTable            _age_table;
 
   size_t           _alloc_buffer_waste;
@@ -1755,7 +1862,7 @@
   G1ParScanHeapEvacClosure*     _evac_cl;
   G1ParScanPartialArrayClosure* _partial_scan_cl;
 
-  int _hash_seed;
+  int  _hash_seed;
   uint _queue_num;
 
   size_t _term_attempts;
@@ -1809,7 +1916,7 @@
   RefToScanQueue*   refs()            { return _refs;             }
   ageTable*         age_table()       { return &_age_table;       }
 
-  G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
+  G1ParGCAllocBufferContainer* alloc_buffer(GCAllocPurpose purpose) {
     return _alloc_buffers[purpose];
   }
 
@@ -1839,15 +1946,13 @@
     HeapWord* obj = NULL;
     size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
     if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
-      G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
-      add_to_alloc_buffer_waste(alloc_buf->words_remaining());
-      alloc_buf->retire(false /* end_of_gc */, false /* retain */);
+      G1ParGCAllocBufferContainer* alloc_buf = alloc_buffer(purpose);
 
       HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
       if (buf == NULL) return NULL; // Let caller handle allocation failure.
-      // Otherwise.
-      alloc_buf->set_word_size(gclab_word_size);
-      alloc_buf->set_buf(buf);
+
+      add_to_alloc_buffer_waste(alloc_buf->words_remaining_in_retired_buffer());
+      alloc_buf->update(false /* end_of_gc */, false /* retain */, buf, gclab_word_size);
 
       obj = alloc_buf->allocate(word_sz);
       assert(obj != NULL, "buffer was definitely big enough...");
@@ -1959,7 +2064,6 @@
     }
   }
 
-public:
   void trim_queue();
 };
 
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -909,7 +909,7 @@
 // Anything below that is considered to be zero
 #define MIN_TIMER_GRANULARITY 0.0000001
 
-void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
+void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, EvacuationInfo& evacuation_info) {
   double end_time_sec = os::elapsedTime();
   assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(),
          "otherwise, the subtraction below does not make sense");
@@ -941,6 +941,9 @@
   _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
                           end_time_sec, false);
 
+  evacuation_info.set_collectionset_used_before(_collection_set_bytes_used_before);
+  evacuation_info.set_bytes_copied(_bytes_copied_during_gc);
+
   if (update_stats) {
     _trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times());
     // this is where we update the allocation rate of the application
@@ -1896,7 +1899,7 @@
 }
 
 
-void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
+void G1CollectorPolicy::finalize_cset(double target_pause_time_ms, EvacuationInfo& evacuation_info) {
   double young_start_time_sec = os::elapsedTime();
 
   YoungList* young_list = _g1->young_list();
@@ -2102,6 +2105,7 @@
 
   double non_young_end_time_sec = os::elapsedTime();
   phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
+  evacuation_info.set_collectionset_regions(cset_region_length());
 }
 
 void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) {
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -671,7 +671,7 @@
 
   // Record the start and end of an evacuation pause.
   void record_collection_pause_start(double start_time_sec);
-  void record_collection_pause_end(double pause_time_ms);
+  void record_collection_pause_end(double pause_time_ms, EvacuationInfo& evacuation_info);
 
   // Record the start and end of a full collection.
   void record_full_collection_start();
@@ -720,7 +720,7 @@
   // Choose a new collection set.  Marks the chosen regions as being
   // "in_collection_set", and links them together.  The head and number of
   // the collection set are available via access methods.
-  void finalize_cset(double target_pause_time_ms);
+  void finalize_cset(double target_pause_time_ms, EvacuationInfo& evacuation_info);
 
   // The head of the list (via "next_in_collection_set()") representing the
   // current collection set.
@@ -879,6 +879,7 @@
   ageTable _survivors_age_table;
 
 public:
+  uint tenuring_threshold() const { return _tenuring_threshold; }
 
   inline GCAllocPurpose
     evacuation_destination(HeapRegion* src_region, uint age, size_t word_sz) {
--- a/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -38,7 +38,7 @@
   NOT_PRODUCT(static const T _uninitialized;)
 
   // We are caching the sum and average to only have to calculate them once.
-  // This is not done in an MT-safe way. It is intetened to allow single
+  // This is not done in an MT-safe way. It is intended to allow single
   // threaded code to call sum() and average() multiple times in any order
   // without having to worry about the cost.
   bool   _has_new_data;
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,10 @@
 #include "code/icBuffer.hpp"
 #include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1MarkSweep.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "memory/gcLocker.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/modRefBarrierSet.hpp"
@@ -119,7 +123,7 @@
 void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
                                     bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  TraceTime tm("phase 1", G1Log::fine() && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer());
   GenMarkSweep::trace(" 1");
 
   SharedHeap* sh = SharedHeap::heap();
@@ -139,10 +143,13 @@
   assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity");
 
   rp->setup_policy(clear_all_softrefs);
-  rp->process_discovered_references(&GenMarkSweep::is_alive,
-                                    &GenMarkSweep::keep_alive,
-                                    &GenMarkSweep::follow_stack_closure,
-                                    NULL);
+  const ReferenceProcessorStats& stats =
+    rp->process_discovered_references(&GenMarkSweep::is_alive,
+                                      &GenMarkSweep::keep_alive,
+                                      &GenMarkSweep::follow_stack_closure,
+                                      NULL,
+                                      gc_timer());
+  gc_tracer()->report_gc_reference_stats(stats);
 
 
   // This is the point where the entire marking should have completed.
@@ -185,6 +192,8 @@
       gclog_or_tty->print_cr("]");
     }
   }
+
+  gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
 }
 
 class G1PrepareCompactClosure: public HeapRegionClosure {
@@ -257,7 +266,7 @@
 
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-  TraceTime tm("phase 2", G1Log::fine() && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer());
   GenMarkSweep::trace("2");
 
   // find the first region
@@ -294,7 +303,7 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // Adjust the pointers to reflect the new locations
-  TraceTime tm("phase 3", G1Log::fine() && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer());
   GenMarkSweep::trace("3");
 
   SharedHeap* sh = SharedHeap::heap();
@@ -353,7 +362,7 @@
   // to use a higher index (saved from phase2) when verifying perm_gen.
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-  TraceTime tm("phase 4", G1Log::fine() && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer());
   GenMarkSweep::trace("4");
 
   G1SpaceCompactClosure blk;
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,9 @@
   static void invoke_at_safepoint(ReferenceProcessor* rp,
                                   bool clear_all_softrefs);
 
+  static STWGCTimer* gc_timer() { return GenMarkSweep::_gc_timer; }
+  static SerialOldTracer* gc_tracer() { return GenMarkSweep::_gc_tracer; }
+
  private:
 
   // Mark live objects
--- a/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -224,6 +224,7 @@
   // Monitoring support used by
   //   MemoryService
   //   jstat counters
+  //   Tracing
 
   size_t overall_reserved()           { return _overall_reserved;     }
   size_t overall_committed()          { return _overall_committed;    }
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -34,6 +34,7 @@
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "memory/iterator.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/intHisto.hpp"
@@ -73,7 +74,8 @@
     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
     _cg1r(g1->concurrent_g1_refine()),
     _cset_rs_update_cl(NULL),
-    _cards_scanned(NULL), _total_cards_scanned(0)
+    _cards_scanned(NULL), _total_cards_scanned(0),
+    _prev_period_summary()
 {
   _seq_task = new SubTasksDone(NumSeqTasks);
   guarantee(n_workers() > 0, "There should be some workers");
@@ -81,6 +83,7 @@
   for (uint i = 0; i < n_workers(); i++) {
     _cset_rs_update_cl[i] = NULL;
   }
+  _prev_period_summary.initialize(this, n_workers());
 }
 
 G1RemSet::~G1RemSet() {
@@ -697,47 +700,29 @@
   return has_refs_into_cset;
 }
 
-class HRRSStatsIter: public HeapRegionClosure {
-  size_t _occupied;
-  size_t _total_mem_sz;
-  size_t _max_mem_sz;
-  HeapRegion* _max_mem_sz_region;
-public:
-  HRRSStatsIter() :
-    _occupied(0),
-    _total_mem_sz(0),
-    _max_mem_sz(0),
-    _max_mem_sz_region(NULL)
-  {}
+void G1RemSet::print_periodic_summary_info() {
+  G1RemSetSummary current;
+  current.initialize(this, n_workers());
 
-  bool doHeapRegion(HeapRegion* r) {
-    if (r->continuesHumongous()) return false;
-    size_t mem_sz = r->rem_set()->mem_size();
-    if (mem_sz > _max_mem_sz) {
-      _max_mem_sz = mem_sz;
-      _max_mem_sz_region = r;
-    }
-    _total_mem_sz += mem_sz;
-    size_t occ = r->rem_set()->occupied();
-    _occupied += occ;
-    return false;
-  }
-  size_t total_mem_sz() { return _total_mem_sz; }
-  size_t max_mem_sz() { return _max_mem_sz; }
-  size_t occupied() { return _occupied; }
-  HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
-};
+  _prev_period_summary.subtract_from(&current);
+  print_summary_info(&_prev_period_summary);
 
-class PrintRSThreadVTimeClosure : public ThreadClosure {
-public:
-  virtual void do_thread(Thread *t) {
-    ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
-    gclog_or_tty->print("    %5.2f", crt->vtime_accum());
-  }
-};
+  _prev_period_summary.set(&current);
+}
 
 void G1RemSet::print_summary_info() {
-  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  G1RemSetSummary current;
+  current.initialize(this, n_workers());
+
+  print_summary_info(&current, " Cumulative RS summary");
+}
+
+void G1RemSet::print_summary_info(G1RemSetSummary * summary, const char * header) {
+  assert(summary != NULL, "just checking");
+
+  if (header != NULL) {
+    gclog_or_tty->print_cr("%s", header);
+  }
 
 #if CARD_REPEAT_HISTO
   gclog_or_tty->print_cr("\nG1 card_repeat count histogram: ");
@@ -745,52 +730,13 @@
   card_repeat_count.print_on(gclog_or_tty);
 #endif
 
-  gclog_or_tty->print_cr("\n Concurrent RS processed %d cards",
-                         _conc_refine_cards);
-  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-  jint tot_processed_buffers =
-    dcqs.processed_buffers_mut() + dcqs.processed_buffers_rs_thread();
-  gclog_or_tty->print_cr("  Of %d completed buffers:", tot_processed_buffers);
-  gclog_or_tty->print_cr("     %8d (%5.1f%%) by conc RS threads.",
-                dcqs.processed_buffers_rs_thread(),
-                100.0*(float)dcqs.processed_buffers_rs_thread()/
-                (float)tot_processed_buffers);
-  gclog_or_tty->print_cr("     %8d (%5.1f%%) by mutator threads.",
-                dcqs.processed_buffers_mut(),
-                100.0*(float)dcqs.processed_buffers_mut()/
-                (float)tot_processed_buffers);
-  gclog_or_tty->print_cr("  Conc RS threads times(s)");
-  PrintRSThreadVTimeClosure p;
-  gclog_or_tty->print("     ");
-  g1->concurrent_g1_refine()->threads_do(&p);
-  gclog_or_tty->print_cr("");
-
-  HRRSStatsIter blk;
-  g1->heap_region_iterate(&blk);
-  gclog_or_tty->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
-                         "  Max = "SIZE_FORMAT"K.",
-                         blk.total_mem_sz()/K, blk.max_mem_sz()/K);
-  gclog_or_tty->print_cr("  Static structures = "SIZE_FORMAT"K,"
-                         " free_lists = "SIZE_FORMAT"K.",
-                         HeapRegionRemSet::static_mem_size() / K,
-                         HeapRegionRemSet::fl_mem_size() / K);
-  gclog_or_tty->print_cr("    "SIZE_FORMAT" occupied cards represented.",
-                         blk.occupied());
-  HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
-  HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
-  gclog_or_tty->print_cr("    Max size region = "HR_FORMAT", "
-                         "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
-                         HR_FORMAT_PARAMS(max_mem_sz_region),
-                         (rem_set->mem_size() + K - 1)/K,
-                         (rem_set->occupied() + K - 1)/K);
-  gclog_or_tty->print_cr("    Did %d coarsenings.",
-                         HeapRegionRemSet::n_coarsenings());
+  summary->print_on(gclog_or_tty);
 }
 
 void G1RemSet::prepare_for_verify() {
   if (G1HRRSFlushLogBuffersOnVerify &&
       (VerifyBeforeGC || VerifyAfterGC)
-      &&  !_g1->full_collection()) {
+      &&  (!_g1->full_collection() || G1VerifyRSetsDuringFullGC)) {
     cleanupHRRS();
     _g1->set_refine_cte_cl_concurrency(false);
     if (SafepointSynchronize::is_at_safepoint()) {
--- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -25,6 +25,8 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
 
+#include "gc_implementation/g1/g1RemSetSummary.hpp"
+
 // A G1RemSet provides ways of iterating over pointers into a selected
 // collection set.
 
@@ -37,9 +39,11 @@
 // so that they can be used to update the individual region remsets.
 
 class G1RemSet: public CHeapObj<mtGC> {
+private:
+  G1RemSetSummary _prev_period_summary;
 protected:
   G1CollectedHeap* _g1;
-  unsigned _conc_refine_cards;
+  size_t _conc_refine_cards;
   uint n_workers();
 
 protected:
@@ -66,6 +70,8 @@
   // references into the collection set.
   OopsInHeapRegionClosure** _cset_rs_update_cl;
 
+  // Print the given summary info
+  virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL);
 public:
   // This is called to reset dual hash tables after the gc pause
   // is finished and the initial hash table is no longer being
@@ -123,11 +129,18 @@
                            int worker_i,
                            bool check_for_refs_into_cset);
 
-  // Print any relevant summary info.
+  // Print accumulated summary info from the start of the VM.
   virtual void print_summary_info();
 
+  // Print accumulated summary info from the last time called.
+  virtual void print_periodic_summary_info();
+
   // Prepare remembered set for verification.
   virtual void prepare_for_verify();
+
+  size_t conc_refine_cards() const {
+    return _conc_refine_cards;
+  }
 };
 
 class CountNonCleanMemRegionClosure: public MemRegionClosure {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/concurrentG1Refine.hpp"
+#include "gc_implementation/g1/concurrentG1RefineThread.hpp"
+#include "gc_implementation/g1/heapRegion.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1RemSetSummary.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
+#include "runtime/thread.inline.hpp"
+
+class GetRSThreadVTimeClosure : public ThreadClosure {
+private:
+  G1RemSetSummary* _summary;
+  uint _counter;
+
+public:
+  GetRSThreadVTimeClosure(G1RemSetSummary * summary) : ThreadClosure(), _summary(summary), _counter(0) {
+    assert(_summary != NULL, "just checking");
+  }
+
+  virtual void do_thread(Thread* t) {
+    ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
+    _summary->set_rs_thread_vtime(_counter, crt->vtime_accum());
+    _counter++;
+  }
+};
+
+void G1RemSetSummary::update() {
+  _num_refined_cards = remset()->conc_refine_cards();
+  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+  _num_processed_buf_mutator = dcqs.processed_buffers_mut();
+  _num_processed_buf_rs_threads = dcqs.processed_buffers_rs_thread();
+
+  _num_coarsenings = HeapRegionRemSet::n_coarsenings();
+
+  ConcurrentG1Refine * cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
+  if (_rs_threads_vtimes != NULL) {
+    GetRSThreadVTimeClosure p(this);
+    cg1r->worker_threads_do(&p);
+  }
+  set_sampling_thread_vtime(cg1r->sampling_thread()->vtime_accum());
+}
+
+void G1RemSetSummary::set_rs_thread_vtime(uint thread, double value) {
+  assert(_rs_threads_vtimes != NULL, "just checking");
+  assert(thread < _num_vtimes, "just checking");
+  _rs_threads_vtimes[thread] = value;
+}
+
+double G1RemSetSummary::rs_thread_vtime(uint thread) const {
+  assert(_rs_threads_vtimes != NULL, "just checking");
+  assert(thread < _num_vtimes, "just checking");
+  return _rs_threads_vtimes[thread];
+}
+
+void G1RemSetSummary::initialize(G1RemSet* remset, uint num_workers) {
+  assert(_rs_threads_vtimes == NULL, "just checking");
+  assert(remset != NULL, "just checking");
+
+  _remset = remset;
+  _num_vtimes = num_workers;
+  _rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC);
+  memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);
+
+  update();
+}
+
+void G1RemSetSummary::set(G1RemSetSummary* other) {
+  assert(other != NULL, "just checking");
+  assert(remset() == other->remset(), "just checking");
+  assert(_num_vtimes == other->_num_vtimes, "just checking");
+
+  _num_refined_cards = other->num_concurrent_refined_cards();
+
+  _num_processed_buf_mutator = other->num_processed_buf_mutator();
+  _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads();
+
+  _num_coarsenings = other->_num_coarsenings;
+
+  memcpy(_rs_threads_vtimes, other->_rs_threads_vtimes, sizeof(double) * _num_vtimes);
+
+  set_sampling_thread_vtime(other->sampling_thread_vtime());
+}
+
+void G1RemSetSummary::subtract_from(G1RemSetSummary* other) {
+  assert(other != NULL, "just checking");
+  assert(remset() == other->remset(), "just checking");
+  assert(_num_vtimes == other->_num_vtimes, "just checking");
+
+  _num_refined_cards = other->num_concurrent_refined_cards() - _num_refined_cards;
+
+  _num_processed_buf_mutator = other->num_processed_buf_mutator() - _num_processed_buf_mutator;
+  _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads() - _num_processed_buf_rs_threads;
+
+  _num_coarsenings = other->num_coarsenings() - _num_coarsenings;
+
+  for (uint i = 0; i < _num_vtimes; i++) {
+    set_rs_thread_vtime(i, other->rs_thread_vtime(i) - rs_thread_vtime(i));
+  }
+
+  _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime;
+}
+
+class HRRSStatsIter: public HeapRegionClosure {
+  size_t _occupied;
+  size_t _total_mem_sz;
+  size_t _max_mem_sz;
+  HeapRegion* _max_mem_sz_region;
+public:
+  HRRSStatsIter() :
+    _occupied(0),
+    _total_mem_sz(0),
+    _max_mem_sz(0),
+    _max_mem_sz_region(NULL)
+  {}
+
+  bool doHeapRegion(HeapRegion* r) {
+    size_t mem_sz = r->rem_set()->mem_size();
+    if (mem_sz > _max_mem_sz) {
+      _max_mem_sz = mem_sz;
+      _max_mem_sz_region = r;
+    }
+    _total_mem_sz += mem_sz;
+    size_t occ = r->rem_set()->occupied();
+    _occupied += occ;
+    return false;
+  }
+  size_t total_mem_sz() { return _total_mem_sz; }
+  size_t max_mem_sz() { return _max_mem_sz; }
+  size_t occupied() { return _occupied; }
+  HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
+};
+
+double calc_percentage(size_t numerator, size_t denominator) {
+  if (denominator != 0) {
+    return (double)numerator / denominator * 100.0;
+  } else {
+    return 0.0f;
+  }
+}
+
+void G1RemSetSummary::print_on(outputStream* out) {
+  out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards",
+                num_concurrent_refined_cards());
+  out->print_cr("  Of %d completed buffers:", num_processed_buf_total());
+  out->print_cr("     %8d (%5.1f%%) by concurrent RS threads.",
+                num_processed_buf_total(),
+                calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total()));
+  out->print_cr("     %8d (%5.1f%%) by mutator threads.",
+                num_processed_buf_mutator(),
+                calc_percentage(num_processed_buf_mutator(), num_processed_buf_total()));
+  out->print_cr("  Concurrent RS threads times (s)");
+  out->print("     ");
+  for (uint i = 0; i < _num_vtimes; i++) {
+    out->print("    %5.2f", rs_thread_vtime(i));
+  }
+  out->cr();
+  out->print_cr("  Concurrent sampling threads times (s)");
+  out->print_cr("         %5.2f", sampling_thread_vtime());
+
+  HRRSStatsIter blk;
+  G1CollectedHeap::heap()->heap_region_iterate(&blk);
+  out->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
+                "  Max = "SIZE_FORMAT"K.",
+                blk.total_mem_sz()/K, blk.max_mem_sz()/K);
+  out->print_cr("  Static structures = "SIZE_FORMAT"K,"
+                " free_lists = "SIZE_FORMAT"K.",
+                HeapRegionRemSet::static_mem_size() / K,
+                HeapRegionRemSet::fl_mem_size() / K);
+  out->print_cr("    "SIZE_FORMAT" occupied cards represented.",
+                blk.occupied());
+  HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
+  HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
+  out->print_cr("    Max size region = "HR_FORMAT", "
+                "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
+                HR_FORMAT_PARAMS(max_mem_sz_region),
+                (rem_set->mem_size() + K - 1)/K,
+                (rem_set->occupied() + K - 1)/K);
+
+  out->print_cr("    Did %d coarsenings.", num_coarsenings());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
+
+#include "utilities/ostream.hpp"
+
+class G1RemSet;
+
+// A G1RemSetSummary manages statistical information about the G1RemSet
+
+class G1RemSetSummary VALUE_OBJ_CLASS_SPEC {
+private:
+  friend class GetRSThreadVTimeClosure;
+
+  G1RemSet* _remset;
+
+  G1RemSet* remset() const {
+    return _remset;
+  }
+
+  size_t _num_refined_cards;
+  size_t _num_processed_buf_mutator;
+  size_t _num_processed_buf_rs_threads;
+
+  size_t _num_coarsenings;
+
+  double* _rs_threads_vtimes;
+  size_t _num_vtimes;
+
+  double _sampling_thread_vtime;
+
+  void set_rs_thread_vtime(uint thread, double value);
+  void set_sampling_thread_vtime(double value) {
+    _sampling_thread_vtime = value;
+  }
+
+  void free_and_null() {
+    if (_rs_threads_vtimes) {
+      FREE_C_HEAP_ARRAY(double, _rs_threads_vtimes, mtGC);
+      _rs_threads_vtimes = NULL;
+      _num_vtimes = 0;
+    }
+  }
+
+  // update this summary with current data from various places
+  void update();
+
+public:
+  G1RemSetSummary() : _remset(NULL), _num_refined_cards(0),
+    _num_processed_buf_mutator(0), _num_processed_buf_rs_threads(0), _num_coarsenings(0),
+    _rs_threads_vtimes(NULL), _num_vtimes(0), _sampling_thread_vtime(0.0f) {
+  }
+
+  ~G1RemSetSummary() {
+    free_and_null();
+  }
+
+  // set the counters in this summary to the values of the others
+  void set(G1RemSetSummary* other);
+  // subtract all counters from the other summary, and set them in the current
+  void subtract_from(G1RemSetSummary* other);
+
+  // initialize and get the first sampling
+  void initialize(G1RemSet* remset, uint num_workers);
+
+  void print_on(outputStream* out);
+
+  double rs_thread_vtime(uint thread) const;
+
+  double sampling_thread_vtime() const {
+    return _sampling_thread_vtime;
+  }
+
+  size_t num_concurrent_refined_cards() const {
+    return _num_refined_cards;
+  }
+
+  size_t num_processed_buf_mutator() const {
+    return _num_processed_buf_mutator;
+  }
+
+  size_t num_processed_buf_rs_threads() const {
+    return _num_processed_buf_rs_threads;
+  }
+
+  size_t num_processed_buf_total() const {
+    return num_processed_buf_mutator() + num_processed_buf_rs_threads();
+  }
+
+  size_t num_coarsenings() const {
+    return _num_coarsenings;
+  }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1YCTypes.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1YCTYPES_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1YCTYPES_HPP
+
+#include "utilities/debug.hpp"
+
+enum G1YCType {
+  Normal,
+  InitialMark,
+  DuringMark,
+  Mixed,
+  G1YCTypeEndSentinel
+};
+
+class G1YCTypeHelper {
+ public:
+  static const char* to_string(G1YCType type) {
+    switch(type) {
+      case Normal: return "Normal";
+      case InitialMark: return "Initial Mark";
+      case DuringMark: return "During Mark";
+      case Mixed: return "Mixed";
+      default: ShouldNotReachHere(); return NULL;
+    }
+  }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1YCTYPES_HPP
--- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -329,7 +329,11 @@
                                                                             \
   develop(bool, G1EvacuationFailureALotDuringMixedGC, true,                 \
           "Force use of evacuation failure handling during mixed "          \
-          "evacuation pauses")
+          "evacuation pauses")                                              \
+                                                                            \
+  diagnostic(bool, G1VerifyRSetsDuringFullGC, false,                        \
+             "If true, perform verification of each heap region's "         \
+             "remembered set when verifying the heap during a full GC.")
 
 G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
 
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -139,7 +139,7 @@
         _n_failures++;
       }
 
-      if (!_g1h->full_collection()) {
+      if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) {
         HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
         HeapRegion* to   = _g1h->heap_region_containing(obj);
         if (from != NULL && to != NULL &&
--- a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
 #include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/vm_operations_g1.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "gc_implementation/g1/vm_operations_g1.hpp"
 #include "runtime/interfaceSupport.hpp"
@@ -227,7 +229,7 @@
 void VM_CGC_Operation::doit() {
   gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
   TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
-  TraceTime t(_printGCMessage, G1Log::fine(), true, gclog_or_tty);
+  GCTraceTime t(_printGCMessage, G1Log::fine(), true, G1CollectedHeap::heap()->gc_timer_cm());
   SharedHeap* sh = SharedHeap::heap();
   // This could go away if CollectedHeap gave access to _gc_is_active...
   if (sh != NULL) {
--- a/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -585,8 +585,7 @@
   size_policy->avg_young_live()->sample(used());
   size_policy->avg_eden_live()->sample(eden()->used());
 
-  size_policy->compute_young_generation_free_space(eden()->capacity(),
-                                                   max_gen_size());
+  size_policy->compute_eden_space_size(eden()->capacity(), max_gen_size());
 
   resize(size_policy->calculated_eden_size_in_bytes(),
          size_policy->calculated_survivor_size_in_bytes());
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,11 @@
 #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
 #include "gc_implementation/shared/ageTable.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "memory/defNewGeneration.inline.hpp"
 #include "memory/genCollectedHeap.hpp"
@@ -75,7 +80,6 @@
                       work_queue_set_, &term_),
   _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this),
   _keep_alive_closure(&_scan_weak_ref_closure),
-  _promotion_failure_size(0),
   _strong_roots_time(0.0), _term_time(0.0)
 {
   #if TASKQUEUE_STATS
@@ -279,13 +283,10 @@
   }
 }
 
-void ParScanThreadState::print_and_clear_promotion_failure_size() {
-  if (_promotion_failure_size != 0) {
-    if (PrintPromotionFailure) {
-      gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
-        _thread_num, _promotion_failure_size);
-    }
-    _promotion_failure_size = 0;
+void ParScanThreadState::print_promotion_failure_size() {
+  if (_promotion_failed_info.has_failed() && PrintPromotionFailure) {
+    gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
+                        _thread_num, _promotion_failed_info.first_size());
   }
 }
 
@@ -305,6 +306,7 @@
 
   inline ParScanThreadState& thread_state(int i);
 
+  void trace_promotion_failed(YoungGCTracer& gc_tracer);
   void reset(int active_workers, bool promotion_failed);
   void flush();
 
@@ -353,13 +355,21 @@
   return ((ParScanThreadState*)_data)[i];
 }
 
+void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) {
+  for (int i = 0; i < length(); ++i) {
+    if (thread_state(i).promotion_failed()) {
+      gc_tracer.report_promotion_failed(thread_state(i).promotion_failed_info());
+      thread_state(i).promotion_failed_info().reset();
+    }
+  }
+}
 
 void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed)
 {
   _term.reset_for_reuse(active_threads);
   if (promotion_failed) {
     for (int i = 0; i < length(); ++i) {
-      thread_state(i).print_and_clear_promotion_failure_size();
+      thread_state(i).print_promotion_failure_size();
     }
   }
 }
@@ -583,14 +593,6 @@
   gch->set_n_termination(active_workers);
 }
 
-// The "i" passed to this method is the part of the work for
-// this thread.  It is not the worker ID.  The "i" is derived
-// from _started_workers which is incremented in internal_note_start()
-// called in GangWorker loop() and which is called under the
-// which is  called under the protection of the gang monitor and is
-// called after a task is started.  So "i" is based on
-// first-come-first-served.
-
 void ParNewGenTask::work(uint worker_id) {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
   // Since this is being done in a separate thread, need new resource
@@ -876,16 +878,45 @@
 }
 
 
+// A Generation that does parallel young-gen collection.
+
 bool ParNewGeneration::_avoid_promotion_undo = false;
 
-// A Generation that does parallel young-gen collection.
+void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) {
+  assert(_promo_failure_scan_stack.is_empty(), "post condition");
+  _promo_failure_scan_stack.clear(true); // Clear cached segments.
+
+  remove_forwarding_pointers();
+  if (PrintGCDetails) {
+    gclog_or_tty->print(" (promotion failed)");
+  }
+  // All the spaces are in play for mark-sweep.
+  swap_spaces();  // Make life simpler for CMS || rescan; see 6483690.
+  from()->set_next_compaction_space(to());
+  gch->set_incremental_collection_failed();
+  // Inform the next generation that a promotion failure occurred.
+  _next_gen->promotion_failure_occurred();
+
+  // Trace promotion failure in the parallel GC threads
+  thread_state_set.trace_promotion_failed(gc_tracer);
+  // Single threaded code may have reported promotion failure to the global state
+  if (_promotion_failed_info.has_failed()) {
+    gc_tracer.report_promotion_failed(_promotion_failed_info);
+  }
+  // Reset the PromotionFailureALot counters.
+  NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
+}
 
 void ParNewGeneration::collect(bool   full,
                                bool   clear_all_soft_refs,
                                size_t size,
                                bool   is_tlab) {
   assert(full || size > 0, "otherwise we don't want to collect");
+
   GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+  _gc_timer->register_gc_start(os::elapsed_counter());
+
   assert(gch->kind() == CollectedHeap::GenCollectedHeap,
     "not a CMS generational heap");
   AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
@@ -906,7 +937,7 @@
     set_avoid_promotion_undo(true);
   }
 
-  // If the next generation is too full to accomodate worst-case promotion
+  // If the next generation is too full to accommodate worst-case promotion
   // from this generation, pass on collection; let the next generation
   // do it.
   if (!collection_attempt_is_safe()) {
@@ -915,6 +946,10 @@
   }
   assert(to()->is_empty(), "Else not collection_attempt_is_safe");
 
+  ParNewTracer gc_tracer;
+  gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
+  gch->trace_heap_before_gc(&gc_tracer);
+
   init_assuming_no_promotion_failure();
 
   if (UseAdaptiveSizePolicy) {
@@ -922,7 +957,7 @@
     size_policy->minor_collection_begin();
   }
 
-  TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
+  GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
   // Capture heap used before collection (for printing).
   size_t gch_prev_used = gch->used();
 
@@ -975,17 +1010,21 @@
   rp->setup_policy(clear_all_soft_refs);
   // Can  the mt_degree be set later (at run_task() time would be best)?
   rp->set_active_mt_degree(active_workers);
+  ReferenceProcessorStats stats;
   if (rp->processing_is_mt()) {
     ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
-    rp->process_discovered_references(&is_alive, &keep_alive,
-                                      &evacuate_followers, &task_executor);
+    stats = rp->process_discovered_references(&is_alive, &keep_alive,
+                                              &evacuate_followers, &task_executor,
+                                              _gc_timer);
   } else {
     thread_state_set.flush();
     gch->set_par_threads(0);  // 0 ==> non-parallel.
     gch->save_marks();
-    rp->process_discovered_references(&is_alive, &keep_alive,
-                                      &evacuate_followers, NULL);
+    stats = rp->process_discovered_references(&is_alive, &keep_alive,
+                                              &evacuate_followers, NULL,
+                                              _gc_timer);
   }
+  gc_tracer.report_gc_reference_stats(stats);
   if (!promotion_failed()) {
     // Swap the survivor spaces.
     eden()->clear(SpaceDecorator::Mangle);
@@ -1010,22 +1049,7 @@
 
     adjust_desired_tenuring_threshold();
   } else {
-    assert(_promo_failure_scan_stack.is_empty(), "post condition");
-    _promo_failure_scan_stack.clear(true); // Clear cached segments.
-
-    remove_forwarding_pointers();
-    if (PrintGCDetails) {
-      gclog_or_tty->print(" (promotion failed)");
-    }
-    // All the spaces are in play for mark-sweep.
-    swap_spaces();  // Make life simpler for CMS || rescan; see 6483690.
-    from()->set_next_compaction_space(to());
-    gch->set_incremental_collection_failed();
-    // Inform the next generation that a promotion failure occurred.
-    _next_gen->promotion_failure_occurred();
-
-    // Reset the PromotionFailureALot counters.
-    NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
+    handle_promotion_failed(gch, thread_state_set, gc_tracer);
   }
   // set new iteration safe limit for the survivor spaces
   from()->set_concurrent_iteration_safe_limit(from()->top());
@@ -1065,6 +1089,13 @@
     rp->enqueue_discovered_references(NULL);
   }
   rp->verify_no_references_recorded();
+
+  gch->trace_heap_after_gc(&gc_tracer);
+  gc_tracer.report_tenuring_threshold(tenuring_threshold());
+
+  _gc_timer->register_gc_end(os::elapsed_counter());
+
+  gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
 }
 
 static int sum;
@@ -1174,8 +1205,7 @@
       new_obj = old;
 
       preserve_mark_if_necessary(old, m);
-      // Log the size of the maiden promotion failure
-      par_scan_state->log_promotion_failure(sz);
+      par_scan_state->register_promotion_failure(sz);
     }
 
     old->forward_to(new_obj);
@@ -1300,8 +1330,7 @@
       failed_to_promote = true;
 
       preserve_mark_if_necessary(old, m);
-      // Log the size of the maiden promotion failure
-      par_scan_state->log_promotion_failure(sz);
+      par_scan_state->register_promotion_failure(sz);
     }
   } else {
     // Is in to-space; do copying ourselves.
@@ -1599,8 +1628,7 @@
 }
 #undef BUSY
 
-void ParNewGeneration::ref_processor_init()
-{
+void ParNewGeneration::ref_processor_init() {
   if (_ref_processor == NULL) {
     // Allocate and initialize a reference processor
     _ref_processor =
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -25,7 +25,9 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 
+#include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "memory/defNewGeneration.hpp"
 #include "utilities/taskqueue.hpp"
 
@@ -105,7 +107,7 @@
 #endif // TASKQUEUE_STATS
 
   // Stats for promotion failure
-  size_t _promotion_failure_size;
+  PromotionFailedInfo _promotion_failed_info;
 
   // Timing numbers.
   double _start;
@@ -180,13 +182,16 @@
   void undo_alloc_in_to_space(HeapWord* obj, size_t word_sz);
 
   // Promotion failure stats
-  size_t promotion_failure_size() { return promotion_failure_size(); }
-  void log_promotion_failure(size_t sz) {
-    if (_promotion_failure_size == 0) {
-      _promotion_failure_size = sz;
-    }
+  void register_promotion_failure(size_t sz) {
+    _promotion_failed_info.register_copy_failure(sz);
   }
-  void print_and_clear_promotion_failure_size();
+  PromotionFailedInfo& promotion_failed_info() {
+    return _promotion_failed_info;
+  }
+  bool promotion_failed() {
+    return _promotion_failed_info.has_failed();
+  }
+  void print_promotion_failure_size();
 
 #if TASKQUEUE_STATS
   TaskQueueStats & taskqueue_stats() const { return _work_queue->stats; }
@@ -337,6 +342,8 @@
   // word being overwritten with a self-forwarding-pointer.
   void preserve_mark_if_necessary(oop obj, markOop m);
 
+  void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer);
+
  protected:
 
   bool _survivor_overflow;
--- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,8 @@
 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 #include "gc_implementation/parallelScavenge/vmPSOperations.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
@@ -642,6 +644,29 @@
   ensure_parsability(false);  // no need to retire TLABs for verification
 }
 
+PSHeapSummary ParallelScavengeHeap::create_ps_heap_summary() {
+  PSOldGen* old = old_gen();
+  HeapWord* old_committed_end = (HeapWord*)old->virtual_space()->committed_high_addr();
+  VirtualSpaceSummary old_summary(old->reserved().start(), old_committed_end, old->reserved().end());
+  SpaceSummary old_space(old->reserved().start(), old_committed_end, old->used_in_bytes());
+
+  PSYoungGen* young = young_gen();
+  VirtualSpaceSummary young_summary(young->reserved().start(),
+    (HeapWord*)young->virtual_space()->committed_high_addr(), young->reserved().end());
+
+  MutableSpace* eden = young_gen()->eden_space();
+  SpaceSummary eden_space(eden->bottom(), eden->end(), eden->used_in_bytes());
+
+  MutableSpace* from = young_gen()->from_space();
+  SpaceSummary from_space(from->bottom(), from->end(), from->used_in_bytes());
+
+  MutableSpace* to = young_gen()->to_space();
+  SpaceSummary to_space(to->bottom(), to->end(), to->used_in_bytes());
+
+  VirtualSpaceSummary heap_summary = create_heap_space_summary();
+  return PSHeapSummary(heap_summary, used(), old_summary, old_space, young_summary, eden_space, from_space, to_space);
+}
+
 void ParallelScavengeHeap::print_on(outputStream* st) const {
   young_gen()->print_on(st);
   old_gen()->print_on(st);
@@ -706,6 +731,12 @@
   }
 }
 
+void ParallelScavengeHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
+  const PSHeapSummary& heap_summary = create_ps_heap_summary();
+  const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
+  gc_tracer->report_gc_heap_summary(when, heap_summary, metaspace_summary);
+}
+
 ParallelScavengeHeap* ParallelScavengeHeap::heap() {
   assert(_psh != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
   assert(_psh->kind() == CollectedHeap::ParallelScavengeHeap, "not a parallel scavenge heap");
--- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,14 +30,18 @@
 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
 #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
 #include "gc_implementation/shared/gcPolicyCounters.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "utilities/ostream.hpp"
 
 class AdjoiningGenerations;
+class CollectorPolicy;
+class GCHeapSummary;
 class GCTaskManager;
-class PSAdaptiveSizePolicy;
 class GenerationSizer;
 class CollectorPolicy;
+class PSAdaptiveSizePolicy;
+class PSHeapSummary;
 
 class ParallelScavengeHeap : public CollectedHeap {
   friend class VMStructs;
@@ -65,6 +69,8 @@
 
   static GCTaskManager*          _gc_task_manager;      // The task manager.
 
+  void trace_heap(GCWhen::Type when, GCTracer* tracer);
+
  protected:
   static inline size_t total_invocations();
   HeapWord* allocate_new_tlab(size_t size);
@@ -116,7 +122,7 @@
 
   // The alignment used for eden and survivors within the young gen
   // and for boundary between young gen and old gen.
-  size_t intra_heap_alignment() const { return 64 * K; }
+  size_t intra_heap_alignment() const { return 64 * K * HeapWordSize; }
 
   size_t capacity() const;
   size_t used() const;
@@ -219,6 +225,7 @@
   jlong millis_since_last_gc();
 
   void prepare_for_verify();
+  PSHeapSummary create_ps_heap_summary();
   virtual void print_on(outputStream* st) const;
   virtual void print_on_error(outputStream* st) const;
   virtual void print_gc_threads_on(outputStream* st) const;
--- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -27,6 +27,8 @@
 #include "code/codeCache.hpp"
 #include "gc_implementation/parallelScavenge/pcTasks.hpp"
 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "memory/universe.hpp"
 #include "oops/objArrayKlass.inline.hpp"
@@ -48,8 +50,8 @@
 
   ResourceMark rm;
 
-  NOT_PRODUCT(TraceTime tm("ThreadRootsMarkingTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+  NOT_PRODUCT(GCTraceTime tm("ThreadRootsMarkingTask",
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
 
@@ -77,8 +79,8 @@
 void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
   assert(Universe::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(TraceTime tm("MarkFromRootsTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+  NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask",
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
@@ -120,6 +122,9 @@
 
     case system_dictionary:
       SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
+      break;
+
+    case class_loader_data:
       ClassLoaderDataGraph::always_strong_oops_do(&mark_and_push_closure, &follow_klass_closure, true);
       break;
 
@@ -145,8 +150,8 @@
 {
   assert(Universe::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(TraceTime tm("RefProcTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+  NOT_PRODUCT(GCTraceTime tm("RefProcTask",
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
@@ -201,8 +206,8 @@
 void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
   assert(Universe::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(TraceTime tm("StealMarkingTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+  NOT_PRODUCT(GCTraceTime tm("StealMarkingTask",
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
@@ -234,8 +239,8 @@
 void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
   assert(Universe::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(TraceTime tm("StealRegionCompactionTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+  NOT_PRODUCT(GCTraceTime tm("StealRegionCompactionTask",
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
@@ -301,8 +306,8 @@
 
 void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
 
-  NOT_PRODUCT(TraceTime tm("UpdateDensePrefixTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+  NOT_PRODUCT(GCTraceTime tm("UpdateDensePrefixTask",
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
@@ -316,8 +321,8 @@
 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
   assert(Universe::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(TraceTime tm("DrainStacksCompactionTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+  NOT_PRODUCT(GCTraceTime tm("DrainStacksCompactionTask",
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
--- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -98,7 +98,8 @@
     management            = 6,
     jvmti                 = 7,
     system_dictionary     = 8,
-    code_cache            = 9
+    class_loader_data     = 9,
+    code_cache            = 10
   };
  private:
   RootType _root_type;
--- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -194,7 +194,7 @@
 
 // If this is not a full GC, only test and modify the young generation.
 
-void PSAdaptiveSizePolicy::compute_generation_free_space(
+void PSAdaptiveSizePolicy::compute_generations_free_space(
                                            size_t young_live,
                                            size_t eden_live,
                                            size_t old_live,
@@ -729,7 +729,7 @@
 
   if (PrintAdaptiveSizePolicy && Verbose) {
     gclog_or_tty->print_cr(
-      "PSAdaptiveSizePolicy::compute_old_gen_free_space "
+      "PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
       "adjusting gen sizes for major pause (avg %f goal %f). "
       "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
       _avg_major_pause->average(), gc_pause_goal_sec(),
@@ -786,7 +786,7 @@
 
   if (PrintAdaptiveSizePolicy && Verbose) {
     gclog_or_tty->print_cr(
-      "PSAdaptiveSizePolicy::compute_eden_space_size "
+      "PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
       "adjusting gen sizes for major pause (avg %f goal %f). "
       "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
       _avg_major_pause->average(), gc_pause_goal_sec(),
@@ -1001,7 +1001,7 @@
 
   if (PrintAdaptiveSizePolicy && Verbose) {
     gclog_or_tty->print_cr(
-      "AdaptiveSizePolicy::compute_generation_free_space "
+      "AdaptiveSizePolicy::adjust_promo_for_footprint "
       "adjusting tenured gen for footprint. "
       "starting promo size " SIZE_FORMAT
       " reduced promo size " SIZE_FORMAT,
@@ -1025,7 +1025,7 @@
 
   if (PrintAdaptiveSizePolicy && Verbose) {
     gclog_or_tty->print_cr(
-      "AdaptiveSizePolicy::compute_generation_free_space "
+      "AdaptiveSizePolicy::adjust_eden_for_footprint "
       "adjusting eden for footprint. "
       " starting eden size " SIZE_FORMAT
       " reduced eden size " SIZE_FORMAT
@@ -1280,7 +1280,7 @@
 
   if (PrintAdaptiveSizePolicy) {
     gclog_or_tty->print(
-                  "AdaptiveSizePolicy::compute_survivor_space_size_and_thresh:"
+                  "AdaptiveSizePolicy::update_averages:"
                   "  survived: "  SIZE_FORMAT
                   "  promoted: "  SIZE_FORMAT
                   "  overflow: %s",
--- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -344,13 +344,13 @@
   // Takes current used space in all generations as input, as well
   // as an indication if a full gc has just been performed, for use
   // in deciding if an OOM error should be thrown.
-  void compute_generation_free_space(size_t young_live,
-                                     size_t eden_live,
-                                     size_t old_live,
-                                     size_t cur_eden,  // current eden in bytes
-                                     size_t max_old_gen_size,
-                                     size_t max_eden_size,
-                                     bool   is_full_gc);
+  void compute_generations_free_space(size_t young_live,
+                                      size_t eden_live,
+                                      size_t old_live,
+                                      size_t cur_eden,  // current eden in bytes
+                                      size_t max_old_gen_size,
+                                      size_t max_eden_size,
+                                      bool   is_full_gc);
 
   void compute_eden_space_size(size_t young_live,
                                size_t eden_live,
--- a/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -119,7 +119,7 @@
       ps_size_policy()->change_old_gen_for_min_pauses());
   }
 
-  // compute_generation_free_space() statistics
+  // compute_generations_free_space() statistics
 
   inline void update_avg_major_pause() {
     _avg_major_pause->set_value(
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -34,6 +34,10 @@
 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "gc_implementation/shared/markSweep.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
@@ -108,8 +112,12 @@
   }
 
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
   GCCause::Cause gc_cause = heap->gc_cause();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+
+  _gc_timer->register_gc_start(os::elapsed_counter());
+  _gc_tracer->report_gc_start(gc_cause, _gc_timer->gc_start());
+
   PSAdaptiveSizePolicy* size_policy = heap->size_policy();
 
   // The scope of casr should end after code that can change
@@ -131,6 +139,7 @@
   AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
 
   heap->print_heap_before_gc();
+  heap->trace_heap_before_gc(_gc_tracer);
 
   // Fill in TLABs
   heap->accumulate_statistics_all_tlabs();
@@ -147,7 +156,7 @@
     old_gen->verify_object_start_array();
   }
 
-  heap->pre_full_gc_dump();
+  heap->pre_full_gc_dump(_gc_timer);
 
   // Filled in below to track the state of the young gen after the collection.
   bool eden_empty;
@@ -159,7 +168,7 @@
 
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -290,13 +299,13 @@
         // Used for diagnostics
         size_policy->clear_generation_free_space_flags();
 
-        size_policy->compute_generation_free_space(young_live,
-                                                   eden_live,
-                                                   old_live,
-                                                   cur_eden,
-                                                   max_old_gen_size,
-                                                   max_eden_size,
-                                                   true /* full gc*/);
+        size_policy->compute_generations_free_space(young_live,
+                                                    eden_live,
+                                                    old_live,
+                                                    cur_eden,
+                                                    max_old_gen_size,
+                                                    max_eden_size,
+                                                    true /* full gc*/);
 
         size_policy->check_gc_overhead_limit(young_live,
                                              eden_live,
@@ -374,13 +383,18 @@
   NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
 
   heap->print_heap_after_gc();
+  heap->trace_heap_after_gc(_gc_tracer);
 
-  heap->post_full_gc_dump();
+  heap->post_full_gc_dump(_gc_timer);
 
 #ifdef TRACESPINNING
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
+  _gc_timer->register_gc_end(os::elapsed_counter());
+
+  _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
+
   return true;
 }
 
@@ -498,7 +512,7 @@
 
 void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  TraceTime tm("phase 1", PrintGCDetails && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer);
   trace(" 1");
 
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
@@ -531,8 +545,10 @@
   // Process reference objects found during marking
   {
     ref_processor()->setup_policy(clear_all_softrefs);
-    ref_processor()->process_discovered_references(
-      is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
+    const ReferenceProcessorStats& stats =
+      ref_processor()->process_discovered_references(
+        is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer);
+    gc_tracer()->report_gc_reference_stats(stats);
   }
 
   // This is the point where the entire marking should have completed.
@@ -552,11 +568,12 @@
 
   // Clean up unreferenced symbols in symbol table.
   SymbolTable::unlink();
+  _gc_tracer->report_object_count_after_gc(is_alive_closure());
 }
 
 
 void PSMarkSweep::mark_sweep_phase2() {
-  TraceTime tm("phase 2", PrintGCDetails && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer);
   trace("2");
 
   // Now all live objects are marked, compute the new object addresses.
@@ -586,7 +603,7 @@
 
 void PSMarkSweep::mark_sweep_phase3() {
   // Adjust the pointers to reflect the new locations
-  TraceTime tm("phase 3", PrintGCDetails && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer);
   trace("3");
 
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
@@ -629,7 +646,7 @@
 
 void PSMarkSweep::mark_sweep_phase4() {
   EventMark m("4 compact heap");
-  TraceTime tm("phase 4", PrintGCDetails && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer);
   trace("4");
 
   // All pointers are now adjusted, move objects accordingly
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -39,6 +39,10 @@
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "gc_interface/gcCause.hpp"
 #include "memory/gcLocker.inline.hpp"
@@ -59,13 +63,25 @@
 #include <math.h>
 
 // All sizes are in HeapWords.
-const size_t ParallelCompactData::Log2RegionSize  = 9; // 512 words
+const size_t ParallelCompactData::Log2RegionSize  = 16; // 64K words
 const size_t ParallelCompactData::RegionSize      = (size_t)1 << Log2RegionSize;
 const size_t ParallelCompactData::RegionSizeBytes =
   RegionSize << LogHeapWordSize;
 const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1;
 const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1;
-const size_t ParallelCompactData::RegionAddrMask  = ~RegionAddrOffsetMask;
+const size_t ParallelCompactData::RegionAddrMask       = ~RegionAddrOffsetMask;
+
+const size_t ParallelCompactData::Log2BlockSize   = 7; // 128 words
+const size_t ParallelCompactData::BlockSize       = (size_t)1 << Log2BlockSize;
+const size_t ParallelCompactData::BlockSizeBytes  =
+  BlockSize << LogHeapWordSize;
+const size_t ParallelCompactData::BlockSizeOffsetMask = BlockSize - 1;
+const size_t ParallelCompactData::BlockAddrOffsetMask = BlockSizeBytes - 1;
+const size_t ParallelCompactData::BlockAddrMask       = ~BlockAddrOffsetMask;
+
+const size_t ParallelCompactData::BlocksPerRegion = RegionSize / BlockSize;
+const size_t ParallelCompactData::Log2BlocksPerRegion =
+  Log2RegionSize - Log2BlockSize;
 
 const ParallelCompactData::RegionData::region_sz_t
 ParallelCompactData::RegionData::dc_shift = 27;
@@ -359,6 +375,10 @@
   _reserved_byte_size = 0;
   _region_data = 0;
   _region_count = 0;
+
+  _block_vspace = 0;
+  _block_data = 0;
+  _block_count = 0;
 }
 
 bool ParallelCompactData::initialize(MemRegion covered_region)
@@ -372,8 +392,7 @@
   assert((region_size & RegionSizeOffsetMask) == 0,
          "region size not a multiple of RegionSize");
 
-  bool result = initialize_region_data(region_size);
-
+  bool result = initialize_region_data(region_size) && initialize_block_data();
   return result;
 }
 
@@ -418,17 +437,36 @@
   return false;
 }
 
+bool ParallelCompactData::initialize_block_data()
+{
+  assert(_region_count != 0, "region data must be initialized first");
+  const size_t count = _region_count << Log2BlocksPerRegion;
+  _block_vspace = create_vspace(count, sizeof(BlockData));
+  if (_block_vspace != 0) {
+    _block_data = (BlockData*)_block_vspace->reserved_low_addr();
+    _block_count = count;
+    return true;
+  }
+  return false;
+}
+
 void ParallelCompactData::clear()
 {
   memset(_region_data, 0, _region_vspace->committed_size());
+  memset(_block_data, 0, _block_vspace->committed_size());
 }
 
 void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) {
   assert(beg_region <= _region_count, "beg_region out of range");
   assert(end_region <= _region_count, "end_region out of range");
+  assert(RegionSize % BlockSize == 0, "RegionSize not a multiple of BlockSize");
 
   const size_t region_cnt = end_region - beg_region;
   memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData));
+
+  const size_t beg_block = beg_region * BlocksPerRegion;
+  const size_t block_cnt = region_cnt * BlocksPerRegion;
+  memset(_block_data + beg_block, 0, block_cnt * sizeof(BlockData));
 }
 
 HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const
@@ -707,49 +745,48 @@
 
 HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
   assert(addr != NULL, "Should detect NULL oop earlier");
-  assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap");
-#ifdef ASSERT
-  if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) {
-    gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr);
-  }
-#endif
-  assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked");
+  assert(PSParallelCompact::gc_heap()->is_in(addr), "not in heap");
+  assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");
 
   // Region covering the object.
-  size_t region_index = addr_to_region_idx(addr);
-  const RegionData* const region_ptr = region(region_index);
-  HeapWord* const region_addr = region_align_down(addr);
-
-  assert(addr < region_addr + RegionSize, "Region does not cover object");
-  assert(addr_to_region_ptr(region_addr) == region_ptr, "sanity check");
-
+  RegionData* const region_ptr = addr_to_region_ptr(addr);
   HeapWord* result = region_ptr->destination();
 
-  // If all the data in the region is live, then the new location of the object
-  // can be calculated from the destination of the region plus the offset of the
-  // object in the region.
+  // If the entire Region is live, the new location is region->destination + the
+  // offset of the object within in the Region.
+
+  // Run some performance tests to determine if this special case pays off.  It
+  // is worth it for pointers into the dense prefix.  If the optimization to
+  // avoid pointer updates in regions that only point to the dense prefix is
+  // ever implemented, this should be revisited.
   if (region_ptr->data_size() == RegionSize) {
-    result += pointer_delta(addr, region_addr);
-    DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result);)
+    result += region_offset(addr);
     return result;
   }
 
-  // The new location of the object is
-  //    region destination +
-  //    size of the partial object extending onto the region +
-  //    sizes of the live objects in the Region that are to the left of addr
-  const size_t partial_obj_size = region_ptr->partial_obj_size();
-  HeapWord* const search_start = region_addr + partial_obj_size;
+  // Otherwise, the new location is region->destination + block offset + the
+  // number of live words in the Block that are (a) to the left of addr and (b)
+  // due to objects that start in the Block.
+
+  // Fill in the block table if necessary.  This is unsynchronized, so multiple
+  // threads may fill the block table for a region (harmless, since it is
+  // idempotent).
+  if (!region_ptr->blocks_filled()) {
+    PSParallelCompact::fill_blocks(addr_to_region_idx(addr));
+    region_ptr->set_blocks_filled();
+  }
+
+  HeapWord* const search_start = block_align_down(addr);
+  const size_t block_offset = addr_to_block_ptr(addr)->offset();
 
   const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
-  size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
-
-  result += partial_obj_size + live_to_left;
-  DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result);)
+  const size_t live = bitmap->live_words_in_range(search_start, oop(addr));
+  result += block_offset + live;
+  DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result));
   return result;
 }
 
-#ifdef  ASSERT
+#ifdef ASSERT
 void ParallelCompactData::verify_clear(const PSVirtualSpace* vspace)
 {
   const size_t* const beg = (const size_t*)vspace->committed_low_addr();
@@ -762,16 +799,12 @@
 void ParallelCompactData::verify_clear()
 {
   verify_clear(_region_vspace);
+  verify_clear(_block_vspace);
 }
 #endif  // #ifdef ASSERT
 
-#ifdef NOT_PRODUCT
-ParallelCompactData::RegionData* debug_region(size_t region_index) {
-  ParallelCompactData& sd = PSParallelCompact::summary_data();
-  return sd.region(region_index);
-}
-#endif
-
+STWGCTimer          PSParallelCompact::_gc_timer;
+ParallelOldTracer   PSParallelCompact::_gc_tracer;
 elapsedTimer        PSParallelCompact::_accumulated_time;
 unsigned int        PSParallelCompact::_total_invocations = 0;
 unsigned int        PSParallelCompact::_maximum_compaction_gc_num = 0;
@@ -945,7 +978,7 @@
   // at each young gen gc.  Do the update unconditionally (even though a
   // promotion failure does not swap spaces) because an unknown number of minor
   // collections will have swapped the spaces an unknown number of times.
-  TraceTime tm("pre compact", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer);
   ParallelScavengeHeap* heap = gc_heap();
   _space_info[from_space_id].set_space(heap->young_gen()->from_space());
   _space_info[to_space_id].set_space(heap->young_gen()->to_space());
@@ -962,6 +995,7 @@
   _total_invocations++;
 
   heap->print_heap_before_gc();
+  heap->trace_heap_before_gc(&_gc_tracer);
 
   // Fill in TLABs
   heap->accumulate_statistics_all_tlabs();
@@ -987,7 +1021,7 @@
 
 void PSParallelCompact::post_compact()
 {
-  TraceTime tm("post compact", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("post compact", print_phases(), true, &_gc_timer);
 
   for (unsigned int id = old_space_id; id < last_space_id; ++id) {
     // Clear the marking bitmap, summary data and split info.
@@ -1813,7 +1847,7 @@
 void PSParallelCompact::summary_phase(ParCompactionManager* cm,
                                       bool maximum_compaction)
 {
-  TraceTime tm("summary phase", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer);
   // trace("2");
 
 #ifdef  ASSERT
@@ -1961,11 +1995,6 @@
                                       maximum_heap_compaction);
 }
 
-bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) {
-  size_t addr_region_index = addr_to_region_idx(addr);
-  return region_index == addr_region_index;
-}
-
 // This method contains no policy. You should probably
 // be calling invoke() instead.
 bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
@@ -1976,11 +2005,15 @@
     return false;
   }
 
+  ParallelScavengeHeap* heap = gc_heap();
+
+  _gc_timer.register_gc_start(os::elapsed_counter());
+  _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
+
   TimeStamp marking_start;
   TimeStamp compaction_start;
   TimeStamp collection_exit;
 
-  ParallelScavengeHeap* heap = gc_heap();
   GCCause::Cause gc_cause = heap->gc_cause();
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
@@ -1996,7 +2029,7 @@
     heap->record_gen_tops_before_GC();
   }
 
-  heap->pre_full_gc_dump();
+  heap->pre_full_gc_dump(&_gc_timer);
 
   _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
 
@@ -2023,7 +2056,7 @@
 
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -2043,7 +2076,7 @@
     bool marked_for_unloading = false;
 
     marking_start.update();
-    marking_phase(vmthread_cm, maximum_heap_compaction);
+    marking_phase(vmthread_cm, maximum_heap_compaction, &_gc_tracer);
 
     bool max_on_system_gc = UseMaximumCompactionOnSystemGC
       && gc_cause == GCCause::_java_lang_system_gc;
@@ -2101,13 +2134,13 @@
         // Used for diagnostics
         size_policy->clear_generation_free_space_flags();
 
-        size_policy->compute_generation_free_space(young_live,
-                                                   eden_live,
-                                                   old_live,
-                                                   cur_eden,
-                                                   max_old_gen_size,
-                                                   max_eden_size,
-                                                   true /* full gc*/);
+        size_policy->compute_generations_free_space(young_live,
+                                                    eden_live,
+                                                    old_live,
+                                                    cur_eden,
+                                                    max_old_gen_size,
+                                                    max_eden_size,
+                                                    true /* full gc*/);
 
         size_policy->check_gc_overhead_limit(young_live,
                                              eden_live,
@@ -2196,6 +2229,8 @@
   collection_exit.update();
 
   heap->print_heap_after_gc();
+  heap->trace_heap_after_gc(&_gc_tracer);
+
   if (PrintGCTaskTimeStamps) {
     gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " "
                            INT64_FORMAT,
@@ -2204,12 +2239,17 @@
     gc_task_manager()->print_task_time_stamps();
   }
 
-  heap->post_full_gc_dump();
+  heap->post_full_gc_dump(&_gc_timer);
 
 #ifdef TRACESPINNING
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
+  _gc_timer.register_gc_end(os::elapsed_counter());
+
+  _gc_tracer.report_dense_prefix(dense_prefix(old_space_id));
+  _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions());
+
   return true;
 }
 
@@ -2308,9 +2348,10 @@
 }
 
 void PSParallelCompact::marking_phase(ParCompactionManager* cm,
-                                      bool maximum_heap_compaction) {
+                                      bool maximum_heap_compaction,
+                                      ParallelOldTracer *gc_tracer) {
   // Recursively traverse all live objects and mark them
-  TraceTime tm("marking phase", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer);
 
   ParallelScavengeHeap* heap = gc_heap();
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
@@ -2325,7 +2366,8 @@
   ClassLoaderDataGraph::clear_claimed_marks();
 
   {
-    TraceTime tm_m("par mark", print_phases(), true, gclog_or_tty);
+    GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer);
+
     ParallelScavengeHeap::ParStrongRootsScope psrs;
 
     GCTaskQueue* q = GCTaskQueue::create();
@@ -2338,6 +2380,7 @@
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
+    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::class_loader_data));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
 
@@ -2352,19 +2395,24 @@
 
   // Process reference objects found during marking
   {
-    TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty);
+    GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer);
+
+    ReferenceProcessorStats stats;
     if (ref_processor()->processing_is_mt()) {
       RefProcTaskExecutor task_executor;
-      ref_processor()->process_discovered_references(
+      stats = ref_processor()->process_discovered_references(
         is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
-        &task_executor);
+        &task_executor, &_gc_timer);
     } else {
-      ref_processor()->process_discovered_references(
-        is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL);
+      stats = ref_processor()->process_discovered_references(
+        is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL,
+        &_gc_timer);
     }
+
+    gc_tracer->report_gc_reference_stats(stats);
   }
 
-  TraceTime tm_c("class unloading", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer);
 
   // This is the point where the entire marking should have completed.
   assert(cm->marking_stacks_empty(), "Marking should have completed");
@@ -2383,6 +2431,7 @@
 
   // Clean up unreferenced symbols in symbol table.
   SymbolTable::unlink();
+  _gc_tracer.report_object_count_after_gc(is_alive_closure());
 }
 
 void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) {
@@ -2423,7 +2472,7 @@
 
 void PSParallelCompact::adjust_roots() {
   // Adjust the pointers to reflect the new locations
-  TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer);
 
   // Need new claim bits when tracing through and adjusting pointers.
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -2459,7 +2508,7 @@
 void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
                                                       uint parallel_gc_threads)
 {
-  TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer);
 
   // Find the threads that are active
   unsigned int which = 0;
@@ -2533,7 +2582,7 @@
 
 void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
                                                     uint parallel_gc_threads) {
-  TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer);
 
   ParallelCompactData& sd = PSParallelCompact::summary_data();
 
@@ -2615,7 +2664,7 @@
                                      GCTaskQueue* q,
                                      ParallelTaskTerminator* terminator_ptr,
                                      uint parallel_gc_threads) {
-  TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("steal task setup", print_phases(), true, &_gc_timer);
 
   // Once a thread has drained it's stack, it should try to steal regions from
   // other threads.
@@ -2626,9 +2675,44 @@
   }
 }
 
+#ifdef ASSERT
+// Write a histogram of the number of times the block table was filled for a
+// region.
+void PSParallelCompact::write_block_fill_histogram(outputStream* const out)
+{
+  if (!TraceParallelOldGCCompactionPhase) return;
+
+  typedef ParallelCompactData::RegionData rd_t;
+  ParallelCompactData& sd = summary_data();
+
+  for (unsigned int id = old_space_id; id < last_space_id; ++id) {
+    MutableSpace* const spc = _space_info[id].space();
+    if (spc->bottom() != spc->top()) {
+      const rd_t* const beg = sd.addr_to_region_ptr(spc->bottom());
+      HeapWord* const top_aligned_up = sd.region_align_up(spc->top());
+      const rd_t* const end = sd.addr_to_region_ptr(top_aligned_up);
+
+      size_t histo[5] = { 0, 0, 0, 0, 0 };
+      const size_t histo_len = sizeof(histo) / sizeof(size_t);
+      const size_t region_cnt = pointer_delta(end, beg, sizeof(rd_t));
+
+      for (const rd_t* cur = beg; cur < end; ++cur) {
+        ++histo[MIN2(cur->blocks_filled_count(), histo_len - 1)];
+      }
+      out->print("%u %-4s" SIZE_FORMAT_W(5), id, space_names[id], region_cnt);
+      for (size_t i = 0; i < histo_len; ++i) {
+        out->print(" " SIZE_FORMAT_W(5) " %5.1f%%",
+                   histo[i], 100.0 * histo[i] / region_cnt);
+      }
+      out->cr();
+    }
+  }
+}
+#endif // #ifdef ASSERT
+
 void PSParallelCompact::compact() {
   // trace("5");
-  TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty);
+  GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer);
 
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
@@ -2645,7 +2729,7 @@
   enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
 
   {
-    TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty);
+    GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer);
 
     gc_task_manager()->execute_and_wait(q);
 
@@ -2659,12 +2743,14 @@
 
   {
     // Update the deferred objects, if any.  Any compaction manager can be used.
-    TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty);
+    GCTraceTime tm_du("deferred updates", print_phases(), true, &_gc_timer);
     ParCompactionManager* cm = ParCompactionManager::manager_array(0);
     for (unsigned int id = old_space_id; id < last_space_id; ++id) {
       update_deferred_objects(cm, SpaceId(id));
     }
   }
+
+  DEBUG_ONLY(write_block_fill_histogram(gclog_or_tty));
 }
 
 #ifdef  ASSERT
@@ -3129,6 +3215,57 @@
   } while (true);
 }
 
+void PSParallelCompact::fill_blocks(size_t region_idx)
+{
+  // Fill in the block table elements for the specified region.  Each block
+  // table element holds the number of live words in the region that are to the
+  // left of the first object that starts in the block.  Thus only blocks in
+  // which an object starts need to be filled.
+  //
+  // The algorithm scans the section of the bitmap that corresponds to the
+  // region, keeping a running total of the live words.  When an object start is
+  // found, if it's the first to start in the block that contains it, the
+  // current total is written to the block table element.
+  const size_t Log2BlockSize = ParallelCompactData::Log2BlockSize;
+  const size_t Log2RegionSize = ParallelCompactData::Log2RegionSize;
+  const size_t RegionSize = ParallelCompactData::RegionSize;
+
+  ParallelCompactData& sd = summary_data();
+  const size_t partial_obj_size = sd.region(region_idx)->partial_obj_size();
+  if (partial_obj_size >= RegionSize) {
+    return; // No objects start in this region.
+  }
+
+  // Ensure the first loop iteration decides that the block has changed.
+  size_t cur_block = sd.block_count();
+
+  const ParMarkBitMap* const bitmap = mark_bitmap();
+
+  const size_t Log2BitsPerBlock = Log2BlockSize - LogMinObjAlignment;
+  assert((size_t)1 << Log2BitsPerBlock ==
+         bitmap->words_to_bits(ParallelCompactData::BlockSize), "sanity");
+
+  size_t beg_bit = bitmap->words_to_bits(region_idx << Log2RegionSize);
+  const size_t range_end = beg_bit + bitmap->words_to_bits(RegionSize);
+  size_t live_bits = bitmap->words_to_bits(partial_obj_size);
+  beg_bit = bitmap->find_obj_beg(beg_bit + live_bits, range_end);
+  while (beg_bit < range_end) {
+    const size_t new_block = beg_bit >> Log2BitsPerBlock;
+    if (new_block != cur_block) {
+      cur_block = new_block;
+      sd.block(cur_block)->set_offset(bitmap->bits_to_words(live_bits));
+    }
+
+    const size_t end_bit = bitmap->find_obj_end(beg_bit, range_end);
+    if (end_bit < range_end - 1) {
+      live_bits += end_bit - beg_bit + 1;
+      beg_bit = bitmap->find_obj_beg(end_bit + 1, range_end);
+    } else {
+      return;
+    }
+  }
+}
+
 void
 PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) {
   const MutableSpace* sp = space(space_id);
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -46,6 +46,8 @@
 class PreGCValues;
 class MoveAndUpdateClosure;
 class RefProcTaskExecutor;
+class ParallelOldTracer;
+class STWGCTimer;
 
 // The SplitInfo class holds the information needed to 'split' a source region
 // so that the live data can be copied to two destination *spaces*.  Normally,
@@ -220,6 +222,17 @@
   // Mask for the bits in a pointer to get the address of the start of a region.
   static const size_t RegionAddrMask;
 
+  static const size_t Log2BlockSize;
+  static const size_t BlockSize;
+  static const size_t BlockSizeBytes;
+
+  static const size_t BlockSizeOffsetMask;
+  static const size_t BlockAddrOffsetMask;
+  static const size_t BlockAddrMask;
+
+  static const size_t BlocksPerRegion;
+  static const size_t Log2BlocksPerRegion;
+
   class RegionData
   {
   public:
@@ -272,6 +285,12 @@
     inline uint destination_count() const;
     inline uint destination_count_raw() const;
 
+    // Whether the block table for this region has been filled.
+    inline bool blocks_filled() const;
+
+    // Number of times the block table was filled.
+    DEBUG_ONLY(inline size_t blocks_filled_count() const;)
+
     // The location of the java heap data that corresponds to this region.
     inline HeapWord* data_location() const;
 
@@ -296,6 +315,7 @@
     void set_partial_obj_size(size_t words)    {
       _partial_obj_size = (region_sz_t) words;
     }
+    inline void set_blocks_filled();
 
     inline void set_destination_count(uint count);
     inline void set_live_obj_size(size_t words);
@@ -328,7 +348,11 @@
     HeapWord*            _partial_obj_addr;
     region_sz_t          _partial_obj_size;
     region_sz_t volatile _dc_and_los;
+    bool                 _blocks_filled;
+
 #ifdef ASSERT
+    size_t               _blocks_filled_count;   // Number of block table fills.
+
     // These enable optimizations that are only partially implemented.  Use
     // debug builds to prevent the code fragments from breaking.
     HeapWord*            _data_location;
@@ -337,11 +361,26 @@
 
 #ifdef ASSERT
    public:
-    uint            _pushed;   // 0 until region is pushed onto a worker's stack
+    uint                 _pushed;   // 0 until region is pushed onto a stack
    private:
 #endif
   };
 
+  // "Blocks" allow shorter sections of the bitmap to be searched.  Each Block
+  // holds an offset, which is the amount of live data in the Region to the left
+  // of the first live object that starts in the Block.
+  class BlockData
+  {
+  public:
+    typedef unsigned short int blk_ofs_t;
+
+    blk_ofs_t offset() const    { return _offset; }
+    void set_offset(size_t val) { _offset = (blk_ofs_t)val; }
+
+  private:
+    blk_ofs_t _offset;
+  };
+
 public:
   ParallelCompactData();
   bool initialize(MemRegion covered_region);
@@ -353,8 +392,9 @@
   inline RegionData* region(size_t region_idx) const;
   inline size_t     region(const RegionData* const region_ptr) const;
 
-  // Returns true if the given address is contained within the region
-  bool region_contains(size_t region_index, HeapWord* addr);
+  size_t block_count() const { return _block_count; }
+  inline BlockData* block(size_t block_idx) const;
+  inline size_t     block(const BlockData* block_ptr) const;
 
   void add_obj(HeapWord* addr, size_t len);
   void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); }
@@ -394,11 +434,24 @@
   inline HeapWord*  region_align_up(HeapWord* addr) const;
   inline bool       is_region_aligned(HeapWord* addr) const;
 
+  // Analogous to region_offset() for blocks.
+  size_t     block_offset(const HeapWord* addr) const;
+  size_t     addr_to_block_idx(const HeapWord* addr) const;
+  size_t     addr_to_block_idx(const oop obj) const {
+    return addr_to_block_idx((HeapWord*) obj);
+  }
+  inline BlockData* addr_to_block_ptr(const HeapWord* addr) const;
+  inline HeapWord*  block_to_addr(size_t block) const;
+  inline size_t     region_to_block_idx(size_t region) const;
+
+  inline HeapWord*  block_align_down(HeapWord* addr) const;
+  inline HeapWord*  block_align_up(HeapWord* addr) const;
+  inline bool       is_block_aligned(HeapWord* addr) const;
+
   // Return the address one past the end of the partial object.
   HeapWord* partial_obj_end(size_t region_idx) const;
 
-  // Return the new location of the object p after the
-  // the compaction.
+  // Return the location of the object after compaction.
   HeapWord* calc_new_pointer(HeapWord* addr);
 
   HeapWord* calc_new_pointer(oop p) {
@@ -411,6 +464,7 @@
 #endif  // #ifdef ASSERT
 
 private:
+  bool initialize_block_data();
   bool initialize_region_data(size_t region_size);
   PSVirtualSpace* create_vspace(size_t count, size_t element_size);
 
@@ -424,6 +478,10 @@
   size_t          _reserved_byte_size;
   RegionData*     _region_data;
   size_t          _region_count;
+
+  PSVirtualSpace* _block_vspace;
+  BlockData*      _block_data;
+  size_t          _block_count;
 };
 
 inline uint
@@ -438,6 +496,28 @@
   return destination_count_raw() >> dc_shift;
 }
 
+inline bool
+ParallelCompactData::RegionData::blocks_filled() const
+{
+  return _blocks_filled;
+}
+
+#ifdef ASSERT
+inline size_t
+ParallelCompactData::RegionData::blocks_filled_count() const
+{
+  return _blocks_filled_count;
+}
+#endif // #ifdef ASSERT
+
+inline void
+ParallelCompactData::RegionData::set_blocks_filled()
+{
+  _blocks_filled = true;
+  // Debug builds count the number of times the table was filled.
+  DEBUG_ONLY(Atomic::inc_ptr(&_blocks_filled_count));
+}
+
 inline void
 ParallelCompactData::RegionData::set_destination_count(uint count)
 {
@@ -532,6 +612,12 @@
   return pointer_delta(region_ptr, _region_data, sizeof(RegionData));
 }
 
+inline ParallelCompactData::BlockData*
+ParallelCompactData::block(size_t n) const {
+  assert(n < block_count(), "bad arg");
+  return _block_data + n;
+}
+
 inline size_t
 ParallelCompactData::region_offset(const HeapWord* addr) const
 {
@@ -598,6 +684,63 @@
   return region_offset(addr) == 0;
 }
 
+inline size_t
+ParallelCompactData::block_offset(const HeapWord* addr) const
+{
+  assert(addr >= _region_start, "bad addr");
+  assert(addr <= _region_end, "bad addr");
+  return (size_t(addr) & BlockAddrOffsetMask) >> LogHeapWordSize;
+}
+
+inline size_t
+ParallelCompactData::addr_to_block_idx(const HeapWord* addr) const
+{
+  assert(addr >= _region_start, "bad addr");
+  assert(addr <= _region_end, "bad addr");
+  return pointer_delta(addr, _region_start) >> Log2BlockSize;
+}
+
+inline ParallelCompactData::BlockData*
+ParallelCompactData::addr_to_block_ptr(const HeapWord* addr) const
+{
+  return block(addr_to_block_idx(addr));
+}
+
+inline HeapWord*
+ParallelCompactData::block_to_addr(size_t block) const
+{
+  assert(block < _block_count, "block out of range");
+  return _region_start + (block << Log2BlockSize);
+}
+
+inline size_t
+ParallelCompactData::region_to_block_idx(size_t region) const
+{
+  return region << Log2BlocksPerRegion;
+}
+
+inline HeapWord*
+ParallelCompactData::block_align_down(HeapWord* addr) const
+{
+  assert(addr >= _region_start, "bad addr");
+  assert(addr < _region_end + RegionSize, "bad addr");
+  return (HeapWord*)(size_t(addr) & BlockAddrMask);
+}
+
+inline HeapWord*
+ParallelCompactData::block_align_up(HeapWord* addr) const
+{
+  assert(addr >= _region_start, "bad addr");
+  assert(addr <= _region_end, "bad addr");
+  return block_align_down(addr + BlockSizeOffsetMask);
+}
+
+inline bool
+ParallelCompactData::is_block_aligned(HeapWord* addr) const
+{
+  return block_offset(addr) == 0;
+}
+
 // Abstract closure for use with ParMarkBitMap::iterate(), which will invoke the
 // do_addr() method.
 //
@@ -775,6 +918,7 @@
   // Convenient access to type names.
   typedef ParMarkBitMap::idx_t idx_t;
   typedef ParallelCompactData::RegionData RegionData;
+  typedef ParallelCompactData::BlockData BlockData;
 
   typedef enum {
     old_space_id, eden_space_id,
@@ -830,6 +974,8 @@
   friend class RefProcTaskProxy;
 
  private:
+  static STWGCTimer           _gc_timer;
+  static ParallelOldTracer    _gc_tracer;
   static elapsedTimer         _accumulated_time;
   static unsigned int         _total_invocations;
   static unsigned int         _maximum_compaction_gc_num;
@@ -873,7 +1019,8 @@
 
   // Mark live objects
   static void marking_phase(ParCompactionManager* cm,
-                            bool maximum_heap_compaction);
+                            bool maximum_heap_compaction,
+                            ParallelOldTracer *gc_tracer);
 
   template <class T>
   static inline void follow_root(ParCompactionManager* cm, T* p);
@@ -962,6 +1109,8 @@
   // Adjust addresses in roots.  Does not adjust addresses in heap.
   static void adjust_roots();
 
+  DEBUG_ONLY(static void write_block_fill_histogram(outputStream* const out);)
+
   // Move objects to new locations.
   static void compact_perm(ParCompactionManager* cm);
   static void compact();
@@ -1128,6 +1277,9 @@
     fill_region(cm, region);
   }
 
+  // Fill in the block table for the specified region.
+  static void fill_blocks(size_t region_idx);
+
   // Update the deferred objects in the space.
   static void update_deferred_objects(ParCompactionManager* cm, SpaceId id);
 
@@ -1137,6 +1289,8 @@
   // Reference Processing
   static ReferenceProcessor* const ref_processor() { return _ref_processor; }
 
+  static STWGCTimer* gc_timer() { return &_gc_timer; }
+
   // Return the SpaceId for the given address.
   static SpaceId space_id(HeapWord* addr);
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/mutableSpace.hpp"
 #include "memory/memRegion.hpp"
 #include "oops/oop.inline.hpp"
@@ -49,7 +50,7 @@
   guarantee(_manager_array != NULL, "Could not initialize promotion manager");
 
   _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads);
-  guarantee(_stack_array_depth != NULL, "Cound not initialize promotion manager");
+  guarantee(_stack_array_depth != NULL, "Could not initialize promotion manager");
 
   // Create and register the PSPromotionManager(s) for the worker threads.
   for(uint i=0; i<ParallelGCThreads; i++) {
@@ -86,13 +87,20 @@
   }
 }
 
-void PSPromotionManager::post_scavenge() {
+bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) {
+  bool promotion_failure_occurred = false;
+
   TASKQUEUE_STATS_ONLY(if (PrintGCDetails && ParallelGCVerbose) print_stats());
   for (uint i = 0; i < ParallelGCThreads + 1; i++) {
     PSPromotionManager* manager = manager_array(i);
     assert(manager->claimed_stack_depth()->is_empty(), "should be empty");
+    if (manager->_promotion_failed_info.has_failed()) {
+      gc_tracer.report_promotion_failed(manager->_promotion_failed_info);
+      promotion_failure_occurred = true;
+    }
     manager->flush_labs();
   }
+  return promotion_failure_occurred;
 }
 
 #if TASKQUEUE_STATS
@@ -187,6 +195,8 @@
   _old_lab.initialize(MemRegion(lab_base, (size_t)0));
   _old_gen_is_full = false;
 
+  _promotion_failed_info.reset();
+
   TASKQUEUE_STATS_ONLY(reset_stats());
 }
 
@@ -305,6 +315,8 @@
     // We won any races, we "own" this object.
     assert(obj == obj->forwardee(), "Sanity");
 
+    _promotion_failed_info.register_copy_failure(obj->size());
+
     obj->push_contents(this);
 
     // Save the mark if needed
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_HPP
 
 #include "gc_implementation/parallelScavenge/psPromotionLAB.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/taskqueue.hpp"
 
@@ -33,7 +35,7 @@
 // psPromotionManager is used by a single thread to manage object survival
 // during a scavenge. The promotion manager contains thread local data only.
 //
-// NOTE! Be carefull when allocating the stacks on cheap. If you are going
+// NOTE! Be careful when allocating the stacks on cheap. If you are going
 // to use a promotion manager in more than one thread, the stacks MUST be
 // on cheap. This can lead to memory leaks, though, as they are not auto
 // deallocated.
@@ -85,6 +87,8 @@
   uint                                _array_chunk_size;
   uint                                _min_array_size_for_chunking;
 
+  PromotionFailedInfo                 _promotion_failed_info;
+
   // Accessors
   static PSOldGen* old_gen()         { return _old_gen; }
   static MutableSpace* young_space() { return _young_space; }
@@ -149,7 +153,7 @@
   static void initialize();
 
   static void pre_scavenge();
-  static void post_scavenge();
+  static bool post_scavenge(YoungGCTracer& gc_tracer);
 
   static PSPromotionManager* gc_thread_promotion_manager(int index);
   static PSPromotionManager* vm_thread_promotion_manager();
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
     if (o->is_forwarded()) {
       o = o->forwardee();
       // Card mark
-      if (PSScavenge::is_obj_in_young((HeapWord*) o)) {
+      if (PSScavenge::is_obj_in_young(o)) {
         PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
       }
       oopDesc::encode_store_heap_oop_not_null(p, o);
@@ -153,7 +153,7 @@
 
         // This is the promotion failed test, and code handling.
         // The code belongs here for two reasons. It is slightly
-        // different thatn the code below, and cannot share the
+        // different than the code below, and cannot share the
         // CAS testing code. Keeping the code here also minimizes
         // the impact on the common case fast path code.
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -34,6 +34,10 @@
 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
 #include "gc_implementation/parallelScavenge/psTasks.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "gc_interface/gcCause.hpp"
@@ -61,17 +65,19 @@
 bool                       PSScavenge::_survivor_overflow = false;
 uint                       PSScavenge::_tenuring_threshold = 0;
 HeapWord*                  PSScavenge::_young_generation_boundary = NULL;
+uintptr_t                  PSScavenge::_young_generation_boundary_compressed = 0;
 elapsedTimer               PSScavenge::_accumulated_time;
+STWGCTimer                 PSScavenge::_gc_timer;
+ParallelScavengeTracer     PSScavenge::_gc_tracer;
 Stack<markOop, mtGC>       PSScavenge::_preserved_mark_stack;
 Stack<oop, mtGC>           PSScavenge::_preserved_oop_stack;
 CollectorCounters*         PSScavenge::_counters = NULL;
-bool                       PSScavenge::_promotion_failed = false;
 
 // Define before use
 class PSIsAliveClosure: public BoolObjectClosure {
 public:
   bool do_object_b(oop p) {
-    return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded();
+    return (!PSScavenge::is_obj_in_young(p)) || p->is_forwarded();
   }
 };
 
@@ -258,6 +264,8 @@
   assert(_preserved_mark_stack.is_empty(), "should be empty");
   assert(_preserved_oop_stack.is_empty(), "should be empty");
 
+  _gc_timer.register_gc_start(os::elapsed_counter());
+
   TimeStamp scavenge_entry;
   TimeStamp scavenge_midpoint;
   TimeStamp scavenge_exit;
@@ -277,11 +285,14 @@
     return false;
   }
 
+  _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
+
   bool promotion_failure_occurred = false;
 
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
   PSAdaptiveSizePolicy* size_policy = heap->size_policy();
+
   heap->increment_total_collections();
 
   AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
@@ -298,12 +309,12 @@
   }
 
   heap->print_heap_before_gc();
+  heap->trace_heap_before_gc(&_gc_tracer);
 
   assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity");
   assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity");
 
   size_t prev_used = heap->used();
-  assert(promotion_failed() == false, "Sanity");
 
   // Fill in TLABs
   heap->accumulate_statistics_all_tlabs();
@@ -320,7 +331,7 @@
 
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+    GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
 
@@ -386,7 +397,7 @@
     // We'll use the promotion manager again later.
     PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
     {
-      // TraceTime("Roots");
+      GCTraceTime tm("Scavenge", false, false, &_gc_timer);
       ParallelScavengeHeap::ParStrongRootsScope psrs;
 
       GCTaskQueue* q = GCTaskQueue::create();
@@ -408,6 +419,7 @@
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
+      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
 
@@ -427,38 +439,41 @@
 
     // Process reference objects discovered during scavenge
     {
+      GCTraceTime tm("References", false, false, &_gc_timer);
+
       reference_processor()->setup_policy(false); // not always_clear
       reference_processor()->set_active_mt_degree(active_workers);
       PSKeepAliveClosure keep_alive(promotion_manager);
       PSEvacuateFollowersClosure evac_followers(promotion_manager);
+      ReferenceProcessorStats stats;
       if (reference_processor()->processing_is_mt()) {
         PSRefProcTaskExecutor task_executor;
-        reference_processor()->process_discovered_references(
-          &_is_alive_closure, &keep_alive, &evac_followers, &task_executor);
+        stats = reference_processor()->process_discovered_references(
+          &_is_alive_closure, &keep_alive, &evac_followers, &task_executor,
+          &_gc_timer);
       } else {
-        reference_processor()->process_discovered_references(
-          &_is_alive_closure, &keep_alive, &evac_followers, NULL);
+        stats = reference_processor()->process_discovered_references(
+          &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer);
+      }
+
+      _gc_tracer.report_gc_reference_stats(stats);
+
+      // Enqueue reference objects discovered during scavenge.
+      if (reference_processor()->processing_is_mt()) {
+        PSRefProcTaskExecutor task_executor;
+        reference_processor()->enqueue_discovered_references(&task_executor);
+      } else {
+        reference_processor()->enqueue_discovered_references(NULL);
       }
     }
 
-    // Enqueue reference objects discovered during scavenge.
-    if (reference_processor()->processing_is_mt()) {
-      PSRefProcTaskExecutor task_executor;
-      reference_processor()->enqueue_discovered_references(&task_executor);
-    } else {
-      reference_processor()->enqueue_discovered_references(NULL);
-    }
-
-      // Unlink any dead interned Strings
-      StringTable::unlink(&_is_alive_closure);
-      // Process the remaining live ones
-      PSScavengeRootsClosure root_closure(promotion_manager);
-      StringTable::oops_do(&root_closure);
+    GCTraceTime tm("StringTable", false, false, &_gc_timer);
+    // Unlink any dead interned Strings and process the remaining live ones.
+    PSScavengeRootsClosure root_closure(promotion_manager);
+    StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
 
     // Finally, flush the promotion_manager's labs, and deallocate its stacks.
-    PSPromotionManager::post_scavenge();
-
-    promotion_failure_occurred = promotion_failed();
+    promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer);
     if (promotion_failure_occurred) {
       clean_up_failed_promotion();
       if (PrintGC) {
@@ -473,8 +488,6 @@
 
     if (!promotion_failure_occurred) {
       // Swap the survivor spaces.
-
-
       young_gen->eden_space()->clear(SpaceDecorator::Mangle);
       young_gen->from_space()->clear(SpaceDecorator::Mangle);
       young_gen->swap_spaces();
@@ -612,7 +625,11 @@
 
     NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
 
-    CodeCache::prune_scavenge_root_nmethods();
+    {
+      GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer);
+
+      CodeCache::prune_scavenge_root_nmethods();
+    }
 
     // Re-verify object start arrays
     if (VerifyObjectStartArray &&
@@ -652,6 +669,8 @@
   }
 
   heap->print_heap_after_gc();
+  heap->trace_heap_after_gc(&_gc_tracer);
+  _gc_tracer.report_tenuring_threshold(tenuring_threshold());
 
   if (ZapUnusedHeapArea) {
     young_gen->eden_space()->check_mangled_unused_area_complete();
@@ -672,6 +691,11 @@
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
+
+  _gc_timer.register_gc_end(os::elapsed_counter());
+
+  _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions());
+
   return !promotion_failure_occurred;
 }
 
@@ -681,7 +705,6 @@
 void PSScavenge::clean_up_failed_promotion() {
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-  assert(promotion_failed(), "Sanity");
 
   PSYoungGen* young_gen = heap->young_gen();
 
@@ -706,7 +729,6 @@
     // Clear the preserved mark and oop stack caches.
     _preserved_mark_stack.clear(true);
     _preserved_oop_stack.clear(true);
-    _promotion_failed = false;
   }
 
   // Reset the PromotionFailureALot counters.
@@ -717,11 +739,10 @@
 // fails. Some markOops will need preservation, some will not. Note
 // that the entire eden is traversed after a failed promotion, with
 // all forwarded headers replaced by the default markOop. This means
-// it is not neccessary to preserve most markOops.
+// it is not necessary to preserve most markOops.
 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) {
-  _promotion_failed = true;
   if (obj_mark->must_be_preserved_for_promotion_failure(obj)) {
-    // Should use per-worker private stakcs hetre rather than
+    // Should use per-worker private stacks here rather than
     // locking a common pair of stacks.
     ThreadCritical tc;
     _preserved_oop_stack.push(obj);
@@ -816,7 +837,7 @@
   // Set boundary between young_gen and old_gen
   assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
          "old above young");
-  _young_generation_boundary = young_gen->eden_space()->bottom();
+  set_young_generation_boundary(young_gen->eden_space()->bottom());
 
   // Initialize ref handling object for scavenging.
   MemRegion mr = young_gen->reserved();
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
 #include "gc_implementation/parallelScavenge/psVirtualspace.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
 #include "memory/allocation.hpp"
 #include "oops/oop.hpp"
 #include "utilities/stack.hpp"
@@ -37,8 +38,10 @@
 class OopStack;
 class ReferenceProcessor;
 class ParallelScavengeHeap;
+class ParallelScavengeTracer;
 class PSIsAliveClosure;
 class PSRefProcTaskExecutor;
+class STWGCTimer;
 
 class PSScavenge: AllStatic {
   friend class PSIsAliveClosure;
@@ -62,19 +65,23 @@
 
  protected:
   // Flags/counters
-  static ReferenceProcessor* _ref_processor;        // Reference processor for scavenging.
-  static PSIsAliveClosure    _is_alive_closure;     // Closure used for reference processing
-  static CardTableExtension* _card_table;           // We cache the card table for fast access.
-  static bool                _survivor_overflow;    // Overflow this collection
-  static uint                _tenuring_threshold;   // tenuring threshold for next scavenge
-  static elapsedTimer        _accumulated_time;     // total time spent on scavenge
-  static HeapWord*           _young_generation_boundary; // The lowest address possible for the young_gen.
-                                                         // This is used to decide if an oop should be scavenged,
-                                                         // cards should be marked, etc.
+  static ReferenceProcessor*  _ref_processor;        // Reference processor for scavenging.
+  static PSIsAliveClosure     _is_alive_closure;     // Closure used for reference processing
+  static CardTableExtension*  _card_table;           // We cache the card table for fast access.
+  static bool                 _survivor_overflow;    // Overflow this collection
+  static uint                 _tenuring_threshold;   // tenuring threshold for next scavenge
+  static elapsedTimer         _accumulated_time;     // total time spent on scavenge
+  static STWGCTimer           _gc_timer;             // GC time book keeper
+  static ParallelScavengeTracer _gc_tracer;          // GC tracing
+  // The lowest address possible for the young_gen.
+  // This is used to decide if an oop should be scavenged,
+  // cards should be marked, etc.
+  static HeapWord*            _young_generation_boundary;
+  // Used to optimize compressed oops young gen boundary checking.
+  static uintptr_t            _young_generation_boundary_compressed;
   static Stack<markOop, mtGC> _preserved_mark_stack; // List of marks to be restored after failed promotion
   static Stack<oop, mtGC>     _preserved_oop_stack;  // List of oops that need their mark restored.
-  static CollectorCounters*      _counters;          // collector performance counters
-  static bool                    _promotion_failed;
+  static CollectorCounters*   _counters;             // collector performance counters
 
   static void clean_up_failed_promotion();
 
@@ -90,7 +97,6 @@
   // Accessors
   static uint             tenuring_threshold()  { return _tenuring_threshold; }
   static elapsedTimer*    accumulated_time()    { return &_accumulated_time; }
-  static bool             promotion_failed()    { return _promotion_failed; }
   static int              consecutive_skipped_scavenges()
     { return _consecutive_skipped_scavenges; }
 
@@ -112,6 +118,9 @@
   // boundary moves, _young_generation_boundary must be reset
   static void set_young_generation_boundary(HeapWord* v) {
     _young_generation_boundary = v;
+    if (UseCompressedOops) {
+      _young_generation_boundary_compressed = (uintptr_t)oopDesc::encode_heap_oop((oop)v);
+    }
   }
 
   // Called by parallelScavengeHeap to init the tenuring threshold
@@ -140,11 +149,19 @@
   static void copy_and_push_safe_barrier_from_klass(PSPromotionManager* pm, oop* p);
 
   // Is an object in the young generation
-  // This assumes that the HeapWord argument is in the heap,
+  // This assumes that the 'o' is in the heap,
   // so it only checks one side of the complete predicate.
+
+  inline static bool is_obj_in_young(oop o) {
+    return (HeapWord*)o >= _young_generation_boundary;
+  }
+
+  inline static bool is_obj_in_young(narrowOop o) {
+    return (uintptr_t)o >= _young_generation_boundary_compressed;
+  }
+
   inline static bool is_obj_in_young(HeapWord* o) {
-    const bool result = (o >= _young_generation_boundary);
-    return result;
+    return o >= _young_generation_boundary;
   }
 };
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -39,9 +39,7 @@
 
 template <class T> inline bool PSScavenge::should_scavenge(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
-  if (oopDesc::is_null(heap_oop)) return false;
-  oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-  return PSScavenge::is_obj_in_young((HeapWord*)obj);
+  return PSScavenge::is_obj_in_young(heap_oop);
 }
 
 template <class T>
@@ -94,7 +92,7 @@
   // or from metadata.
   if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
       Universe::heap()->is_in_reserved(p)) {
-    if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
+    if (PSScavenge::is_obj_in_young(new_obj)) {
       card_table()->inline_write_ref_field_gc(p, new_obj);
     }
   }
@@ -147,7 +145,7 @@
       }
       oopDesc::encode_store_heap_oop_not_null(p, new_obj);
 
-      if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
+      if (PSScavenge::is_obj_in_young(new_obj)) {
         do_klass_barrier();
       }
     }
--- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -79,14 +79,15 @@
       break;
 
     case system_dictionary:
-      {
       SystemDictionary::oops_do(&roots_closure);
+      break;
 
-        // Move this to another root_type?
-        PSScavengeKlassClosure klass_closure(pm);
-        ClassLoaderDataGraph::oops_do(&roots_closure, &klass_closure, false);
-      }
-      break;
+    case class_loader_data:
+    {
+      PSScavengeKlassClosure klass_closure(pm);
+      ClassLoaderDataGraph::oops_do(&roots_closure, &klass_closure, false);
+    }
+    break;
 
     case management:
       Management::oops_do(&roots_closure);
--- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -59,9 +59,10 @@
     object_synchronizer   = 4,
     flat_profiler         = 5,
     system_dictionary     = 6,
-    management            = 7,
-    jvmti                 = 8,
-    code_cache            = 9
+    class_loader_data     = 7,
+    management            = 8,
+    jvmti                 = 9,
+    code_cache            = 10
   };
  private:
   RootType _root_type;
--- a/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -467,7 +467,7 @@
       (free_in_old_gen < (size_t) mem_free_old_limit &&
        free_in_eden < (size_t) mem_free_eden_limit))) {
     gclog_or_tty->print_cr(
-          "PSAdaptiveSizePolicy::compute_generation_free_space limits:"
+          "PSAdaptiveSizePolicy::check_gc_overhead_limit:"
           " promo_limit: " SIZE_FORMAT
           " max_eden_size: " SIZE_FORMAT
           " total_free_limit: " SIZE_FORMAT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/copyFailedInfo.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_COPYFAILEDINFO_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_COPYFAILEDINFO_HPP
+
+#include "runtime/thread.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class CopyFailedInfo : public CHeapObj<mtGC> {
+  size_t    _first_size;
+  size_t    _smallest_size;
+  size_t    _total_size;
+  uint      _count;
+
+ public:
+  CopyFailedInfo() : _first_size(0), _smallest_size(0), _total_size(0), _count(0) {}
+
+  virtual void register_copy_failure(size_t size) {
+    if (_first_size == 0) {
+      _first_size = size;
+      _smallest_size = size;
+    } else if (size < _smallest_size) {
+      _smallest_size = size;
+    }
+    _total_size += size;
+    _count++;
+  }
+
+  virtual void reset() {
+    _first_size = 0;
+    _smallest_size = 0;
+    _total_size = 0;
+    _count = 0;
+  }
+
+  bool has_failed() const { return _count != 0; }
+  size_t first_size() const { return _first_size; }
+  size_t smallest_size() const { return _smallest_size; }
+  size_t total_size() const { return _total_size; }
+  uint failed_count() const { return _count; }
+};
+
+class PromotionFailedInfo : public CopyFailedInfo {
+  OSThread* _thread;
+
+ public:
+  PromotionFailedInfo() : CopyFailedInfo(), _thread(NULL) {}
+
+  void register_copy_failure(size_t size) {
+    CopyFailedInfo::register_copy_failure(size);
+    if (_thread == NULL) {
+      _thread = Thread::current()->osthread();
+    } else {
+      assert(_thread == Thread::current()->osthread(), "The PromotionFailedInfo should be thread local.");
+    }
+  }
+
+  void reset() {
+    CopyFailedInfo::reset();
+    _thread = NULL;
+  }
+
+  OSThread* thread() const { return _thread; }
+};
+
+class EvacuationFailedInfo : public CopyFailedInfo {};
+
+#endif /* SHARE_VM_GC_IMPLEMENTATION_SHARED_COPYFAILEDINFO_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
+
+#include "memory/allocation.hpp"
+
+class VirtualSpaceSummary : public StackObj {
+  HeapWord* _start;
+  HeapWord* _committed_end;
+  HeapWord* _reserved_end;
+public:
+  VirtualSpaceSummary() :
+      _start(NULL), _committed_end(NULL), _reserved_end(NULL) { }
+  VirtualSpaceSummary(HeapWord* start, HeapWord* committed_end, HeapWord* reserved_end) :
+      _start(start), _committed_end(committed_end), _reserved_end(reserved_end) { }
+
+  HeapWord* start() const { return _start; }
+  HeapWord* committed_end() const { return _committed_end; }
+  HeapWord* reserved_end() const { return _reserved_end; }
+  size_t committed_size() const { return (uintptr_t)_committed_end - (uintptr_t)_start;  }
+  size_t reserved_size() const { return (uintptr_t)_reserved_end - (uintptr_t)_start; }
+};
+
+class SpaceSummary : public StackObj {
+  HeapWord* _start;
+  HeapWord* _end;
+  size_t    _used;
+public:
+  SpaceSummary() :
+      _start(NULL), _end(NULL), _used(0) { }
+  SpaceSummary(HeapWord* start, HeapWord* end, size_t used) :
+      _start(start), _end(end), _used(used) { }
+
+  HeapWord* start() const { return _start; }
+  HeapWord* end() const { return _end; }
+  size_t used() const { return _used; }
+  size_t size() const { return (uintptr_t)_end - (uintptr_t)_start; }
+};
+
+class MetaspaceSizes : public StackObj {
+  size_t _capacity;
+  size_t _used;
+  size_t _reserved;
+
+ public:
+  MetaspaceSizes() : _capacity(0), _used(0), _reserved(0) {}
+  MetaspaceSizes(size_t capacity, size_t used, size_t reserved) :
+    _capacity(capacity), _used(used), _reserved(reserved) {}
+
+  size_t capacity() const { return _capacity; }
+  size_t used() const { return _used; }
+  size_t reserved() const { return _reserved; }
+};
+
+class GCHeapSummary;
+class PSHeapSummary;
+
+class GCHeapSummaryVisitor {
+ public:
+  virtual void visit(const GCHeapSummary* heap_summary) const = 0;
+  virtual void visit(const PSHeapSummary* heap_summary) const {}
+};
+
+class GCHeapSummary : public StackObj {
+  VirtualSpaceSummary _heap;
+  size_t _used;
+
+ public:
+   GCHeapSummary() :
+       _heap(), _used(0) { }
+   GCHeapSummary(VirtualSpaceSummary& heap_space, size_t used) :
+       _heap(heap_space), _used(used) { }
+
+  const VirtualSpaceSummary& heap() const { return _heap; }
+  size_t used() const { return _used; }
+
+   virtual void accept(GCHeapSummaryVisitor* visitor) const {
+     visitor->visit(this);
+   }
+};
+
+class PSHeapSummary : public GCHeapSummary {
+  VirtualSpaceSummary  _old;
+  SpaceSummary         _old_space;
+  VirtualSpaceSummary  _young;
+  SpaceSummary         _eden;
+  SpaceSummary         _from;
+  SpaceSummary         _to;
+ public:
+   PSHeapSummary(VirtualSpaceSummary& heap_space, size_t heap_used, VirtualSpaceSummary old, SpaceSummary old_space, VirtualSpaceSummary young, SpaceSummary eden, SpaceSummary from, SpaceSummary to) :
+       GCHeapSummary(heap_space, heap_used), _old(old), _old_space(old_space), _young(young), _eden(eden), _from(from), _to(to) { }
+   const VirtualSpaceSummary& old() const { return _old; }
+   const SpaceSummary& old_space() const { return _old_space; }
+   const VirtualSpaceSummary& young() const { return _young; }
+   const SpaceSummary& eden() const { return _eden; }
+   const SpaceSummary& from() const { return _from; }
+   const SpaceSummary& to() const { return _to; }
+
+   virtual void accept(GCHeapSummaryVisitor* visitor) const {
+     visitor->visit(this);
+   }
+};
+
+class MetaspaceSummary : public StackObj {
+  MetaspaceSizes _meta_space;
+  MetaspaceSizes _data_space;
+  MetaspaceSizes _class_space;
+
+ public:
+  MetaspaceSummary() : _meta_space(), _data_space(), _class_space() {}
+  MetaspaceSummary(const MetaspaceSizes& meta_space, const MetaspaceSizes& data_space, const MetaspaceSizes& class_space) :
+       _meta_space(meta_space), _data_space(data_space), _class_space(class_space) { }
+
+  const MetaspaceSizes& meta_space() const { return _meta_space; }
+  const MetaspaceSizes& data_space() const { return _data_space; }
+  const MetaspaceSizes& class_space() const { return _class_space; }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTimer.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "utilities/growableArray.hpp"
+
+void GCTimer::register_gc_start(jlong time) {
+  _time_partitions.clear();
+  _gc_start = time;
+}
+
+void GCTimer::register_gc_end(jlong time) {
+  assert(!_time_partitions.has_active_phases(),
+      "We should have ended all started phases, before ending the GC");
+
+  _gc_end = time;
+}
+
+void GCTimer::register_gc_pause_start(const char* name, jlong time) {
+  _time_partitions.report_gc_phase_start(name, time);
+}
+
+void GCTimer::register_gc_pause_end(jlong time) {
+  _time_partitions.report_gc_phase_end(time);
+}
+
+void GCTimer::register_gc_phase_start(const char* name, jlong time) {
+  _time_partitions.report_gc_phase_start(name, time);
+}
+
+void GCTimer::register_gc_phase_end(jlong time) {
+  _time_partitions.report_gc_phase_end(time);
+}
+
+
+void STWGCTimer::register_gc_start(jlong time) {
+  GCTimer::register_gc_start(time);
+  register_gc_pause_start("GC Pause", time);
+}
+
+void STWGCTimer::register_gc_end(jlong time) {
+  register_gc_pause_end(time);
+  GCTimer::register_gc_end(time);
+}
+
+void ConcurrentGCTimer::register_gc_pause_start(const char* name, jlong time) {
+  GCTimer::register_gc_pause_start(name, time);
+}
+
+void ConcurrentGCTimer::register_gc_pause_end(jlong time) {
+  GCTimer::register_gc_pause_end(time);
+}
+
+void PhasesStack::clear() {
+  _next_phase_level = 0;
+}
+
+void PhasesStack::push(int phase_index) {
+  assert(_next_phase_level < PHASE_LEVELS, "Overflow");
+
+  _phase_indices[_next_phase_level] = phase_index;
+
+  _next_phase_level++;
+}
+
+int PhasesStack::pop() {
+  assert(_next_phase_level > 0, "Underflow");
+
+  _next_phase_level--;
+
+  return _phase_indices[_next_phase_level];
+}
+
+int PhasesStack::count() const {
+  return _next_phase_level;
+}
+
+
+TimePartitions::TimePartitions() {
+  _phases = new (ResourceObj::C_HEAP, mtGC) GrowableArray<PausePhase>(INITIAL_CAPACITY, true, mtGC);
+  clear();
+}
+
+TimePartitions::~TimePartitions() {
+  delete _phases;
+  _phases = NULL;
+}
+
+void TimePartitions::clear() {
+  _phases->clear();
+  _active_phases.clear();
+  _sum_of_pauses = 0;
+  _longest_pause = 0;
+}
+
+void TimePartitions::report_gc_phase_start(const char* name, jlong time) {
+  assert(_phases->length() <= 1000, "Too many recored phases?");
+
+  int level = _active_phases.count();
+
+  PausePhase phase;
+  phase.set_level(level);
+  phase.set_name(name);
+  phase.set_start(time);
+
+  int index = _phases->append(phase);
+
+  _active_phases.push(index);
+}
+
+void TimePartitions::update_statistics(GCPhase* phase) {
+  // FIXME: This should only be done for pause phases
+  if (phase->level() == 0) {
+    jlong pause = phase->end() - phase->start();
+    _sum_of_pauses += pause;
+    _longest_pause = MAX2(pause, _longest_pause);
+  }
+}
+
+void TimePartitions::report_gc_phase_end(jlong time) {
+  int phase_index = _active_phases.pop();
+  GCPhase* phase = _phases->adr_at(phase_index);
+  phase->set_end(time);
+  update_statistics(phase);
+}
+
+int TimePartitions::num_phases() const {
+  return _phases->length();
+}
+
+GCPhase* TimePartitions::phase_at(int index) const {
+  assert(index >= 0, "Out of bounds");
+  assert(index < _phases->length(), "Out of bounds");
+
+  return _phases->adr_at(index);
+}
+
+jlong TimePartitions::sum_of_pauses() {
+  return _sum_of_pauses;
+}
+
+jlong TimePartitions::longest_pause() {
+  return _longest_pause;
+}
+
+bool TimePartitions::has_active_phases() {
+  return _active_phases.count() > 0;
+}
+
+bool TimePartitionPhasesIterator::has_next() {
+  return _next < _time_partitions->num_phases();
+}
+
+GCPhase* TimePartitionPhasesIterator::next() {
+  assert(has_next(), "Must have phases left");
+  return _time_partitions->phase_at(_next++);
+}
+
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+class TimePartitionPhasesIteratorTest {
+ public:
+  static void all() {
+    one_pause();
+    two_pauses();
+    one_sub_pause_phase();
+    many_sub_pause_phases();
+    many_sub_pause_phases2();
+    max_nested_pause_phases();
+  }
+
+  static void validate_pause_phase(GCPhase* phase, int level, const char* name, jlong start, jlong end) {
+    assert(phase->level() == level, "Incorrect level");
+    assert(strcmp(phase->name(), name) == 0, "Incorrect name");
+    assert(phase->start() == start, "Incorrect start");
+    assert(phase->end() == end, "Incorrect end");
+  }
+
+  static void one_pause() {
+    TimePartitions time_partitions;
+    time_partitions.report_gc_phase_start("PausePhase", 2);
+    time_partitions.report_gc_phase_end(8);
+
+    TimePartitionPhasesIterator iter(&time_partitions);
+
+    validate_pause_phase(iter.next(), 0, "PausePhase", 2, 8);
+    assert(time_partitions.sum_of_pauses() == 8-2, "Incorrect");
+    assert(time_partitions.longest_pause() == 8-2, "Incorrect");
+
+    assert(!iter.has_next(), "Too many elements");
+  }
+
+  static void two_pauses() {
+    TimePartitions time_partitions;
+    time_partitions.report_gc_phase_start("PausePhase1", 2);
+    time_partitions.report_gc_phase_end(3);
+    time_partitions.report_gc_phase_start("PausePhase2", 4);
+    time_partitions.report_gc_phase_end(6);
+
+    TimePartitionPhasesIterator iter(&time_partitions);
+
+    validate_pause_phase(iter.next(), 0, "PausePhase1", 2, 3);
+    validate_pause_phase(iter.next(), 0, "PausePhase2", 4, 6);
+
+    assert(time_partitions.sum_of_pauses() == 3, "Incorrect");
+    assert(time_partitions.longest_pause() == 2, "Incorrect");
+
+    assert(!iter.has_next(), "Too many elements");
+  }
+
+  static void one_sub_pause_phase() {
+    TimePartitions time_partitions;
+    time_partitions.report_gc_phase_start("PausePhase", 2);
+    time_partitions.report_gc_phase_start("SubPhase", 3);
+    time_partitions.report_gc_phase_end(4);
+    time_partitions.report_gc_phase_end(5);
+
+    TimePartitionPhasesIterator iter(&time_partitions);
+
+    validate_pause_phase(iter.next(), 0, "PausePhase", 2, 5);
+    validate_pause_phase(iter.next(), 1, "SubPhase", 3, 4);
+
+    assert(time_partitions.sum_of_pauses() == 3, "Incorrect");
+    assert(time_partitions.longest_pause() == 3, "Incorrect");
+
+    assert(!iter.has_next(), "Too many elements");
+  }
+
+  static void max_nested_pause_phases() {
+    TimePartitions time_partitions;
+    time_partitions.report_gc_phase_start("PausePhase", 2);
+    time_partitions.report_gc_phase_start("SubPhase1", 3);
+    time_partitions.report_gc_phase_start("SubPhase2", 4);
+    time_partitions.report_gc_phase_start("SubPhase3", 5);
+    time_partitions.report_gc_phase_end(6);
+    time_partitions.report_gc_phase_end(7);
+    time_partitions.report_gc_phase_end(8);
+    time_partitions.report_gc_phase_end(9);
+
+    TimePartitionPhasesIterator iter(&time_partitions);
+
+    validate_pause_phase(iter.next(), 0, "PausePhase", 2, 9);
+    validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 8);
+    validate_pause_phase(iter.next(), 2, "SubPhase2", 4, 7);
+    validate_pause_phase(iter.next(), 3, "SubPhase3", 5, 6);
+
+    assert(time_partitions.sum_of_pauses() == 7, "Incorrect");
+    assert(time_partitions.longest_pause() == 7, "Incorrect");
+
+    assert(!iter.has_next(), "Too many elements");
+  }
+
+  static void many_sub_pause_phases() {
+    TimePartitions time_partitions;
+    time_partitions.report_gc_phase_start("PausePhase", 2);
+
+    time_partitions.report_gc_phase_start("SubPhase1", 3);
+    time_partitions.report_gc_phase_end(4);
+    time_partitions.report_gc_phase_start("SubPhase2", 5);
+    time_partitions.report_gc_phase_end(6);
+    time_partitions.report_gc_phase_start("SubPhase3", 7);
+    time_partitions.report_gc_phase_end(8);
+    time_partitions.report_gc_phase_start("SubPhase4", 9);
+    time_partitions.report_gc_phase_end(10);
+
+    time_partitions.report_gc_phase_end(11);
+
+    TimePartitionPhasesIterator iter(&time_partitions);
+
+    validate_pause_phase(iter.next(), 0, "PausePhase", 2, 11);
+    validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 4);
+    validate_pause_phase(iter.next(), 1, "SubPhase2", 5, 6);
+    validate_pause_phase(iter.next(), 1, "SubPhase3", 7, 8);
+    validate_pause_phase(iter.next(), 1, "SubPhase4", 9, 10);
+
+    assert(time_partitions.sum_of_pauses() == 9, "Incorrect");
+    assert(time_partitions.longest_pause() == 9, "Incorrect");
+
+    assert(!iter.has_next(), "Too many elements");
+  }
+
+  static void many_sub_pause_phases2() {
+    TimePartitions time_partitions;
+    time_partitions.report_gc_phase_start("PausePhase", 2);
+
+    time_partitions.report_gc_phase_start("SubPhase1", 3);
+    time_partitions.report_gc_phase_start("SubPhase11", 4);
+    time_partitions.report_gc_phase_end(5);
+    time_partitions.report_gc_phase_start("SubPhase12", 6);
+    time_partitions.report_gc_phase_end(7);
+    time_partitions.report_gc_phase_end(8);
+    time_partitions.report_gc_phase_start("SubPhase2", 9);
+    time_partitions.report_gc_phase_start("SubPhase21", 10);
+    time_partitions.report_gc_phase_end(11);
+    time_partitions.report_gc_phase_start("SubPhase22", 12);
+    time_partitions.report_gc_phase_end(13);
+    time_partitions.report_gc_phase_end(14);
+    time_partitions.report_gc_phase_start("SubPhase3", 15);
+    time_partitions.report_gc_phase_end(16);
+
+    time_partitions.report_gc_phase_end(17);
+
+    TimePartitionPhasesIterator iter(&time_partitions);
+
+    validate_pause_phase(iter.next(), 0, "PausePhase", 2, 17);
+    validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 8);
+    validate_pause_phase(iter.next(), 2, "SubPhase11", 4, 5);
+    validate_pause_phase(iter.next(), 2, "SubPhase12", 6, 7);
+    validate_pause_phase(iter.next(), 1, "SubPhase2", 9, 14);
+    validate_pause_phase(iter.next(), 2, "SubPhase21", 10, 11);
+    validate_pause_phase(iter.next(), 2, "SubPhase22", 12, 13);
+    validate_pause_phase(iter.next(), 1, "SubPhase3", 15, 16);
+
+    assert(time_partitions.sum_of_pauses() == 15, "Incorrect");
+    assert(time_partitions.longest_pause() == 15, "Incorrect");
+
+    assert(!iter.has_next(), "Too many elements");
+  }
+};
+
+class GCTimerTest {
+public:
+  static void all() {
+    gc_start();
+    gc_end();
+  }
+
+  static void gc_start() {
+    GCTimer gc_timer;
+    gc_timer.register_gc_start(1);
+
+    assert(gc_timer.gc_start() == 1, "Incorrect");
+  }
+
+  static void gc_end() {
+    GCTimer gc_timer;
+    gc_timer.register_gc_start(1);
+    gc_timer.register_gc_end(2);
+
+    assert(gc_timer.gc_end() == 2, "Incorrect");
+  }
+};
+
+void GCTimerAllTest::all() {
+  GCTimerTest::all();
+  TimePartitionPhasesIteratorTest::all();
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTimer.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP
+
+#include "memory/allocation.hpp"
+#include "prims/jni_md.h"
+#include "utilities/macros.hpp"
+
+class ConcurrentPhase;
+class GCPhase;
+class PausePhase;
+
+template <class E> class GrowableArray;
+
+class PhaseVisitor {
+ public:
+  virtual void visit(GCPhase* phase) = 0;
+  virtual void visit(PausePhase* phase) { visit((GCPhase*)phase); }
+  virtual void visit(ConcurrentPhase* phase) { visit((GCPhase*)phase); }
+};
+
+class GCPhase {
+  const char* _name;
+  int _level;
+  jlong _start;
+  jlong _end;
+
+ public:
+  void set_name(const char* name) { _name = name; }
+  const char* name() { return _name; }
+
+  int level() { return _level; }
+  void set_level(int level) { _level = level; }
+
+  jlong start() { return _start; }
+  void set_start(jlong time) { _start = time; }
+
+  jlong end() { return _end; }
+  void set_end(jlong time) { _end = time; }
+
+  virtual void accept(PhaseVisitor* visitor) = 0;
+};
+
+class PausePhase : public GCPhase {
+ public:
+  void accept(PhaseVisitor* visitor) {
+    visitor->visit(this);
+  }
+};
+
+class ConcurrentPhase : public GCPhase {
+  void accept(PhaseVisitor* visitor) {
+    visitor->visit(this);
+  }
+};
+
+class PhasesStack {
+ public:
+  // FIXME: Temporary set to 5 (used to be 4), since Reference processing needs it.
+  static const int PHASE_LEVELS = 5;
+
+ private:
+  int _phase_indices[PHASE_LEVELS];
+  int _next_phase_level;
+
+ public:
+  PhasesStack() { clear(); }
+  void clear();
+
+  void push(int phase_index);
+  int pop();
+  int count() const;
+};
+
+class TimePartitions {
+  static const int INITIAL_CAPACITY = 10;
+
+  // Currently we only support pause phases.
+  GrowableArray<PausePhase>* _phases;
+  PhasesStack _active_phases;
+
+  jlong _sum_of_pauses;
+  jlong _longest_pause;
+
+ public:
+  TimePartitions();
+  ~TimePartitions();
+  void clear();
+
+  void report_gc_phase_start(const char* name, jlong time);
+  void report_gc_phase_end(jlong time);
+
+  int num_phases() const;
+  GCPhase* phase_at(int index) const;
+
+  jlong sum_of_pauses();
+  jlong longest_pause();
+
+  bool has_active_phases();
+ private:
+  void update_statistics(GCPhase* phase);
+};
+
+class PhasesIterator {
+ public:
+  virtual bool has_next() = 0;
+  virtual GCPhase* next() = 0;
+};
+
+class GCTimer : public ResourceObj {
+  NOT_PRODUCT(friend class GCTimerTest;)
+ protected:
+  jlong _gc_start;
+  jlong _gc_end;
+  TimePartitions _time_partitions;
+
+ public:
+  virtual void register_gc_start(jlong time);
+  virtual void register_gc_end(jlong time);
+
+  void register_gc_phase_start(const char* name, jlong time);
+  void register_gc_phase_end(jlong time);
+
+  jlong gc_start() { return _gc_start; }
+  jlong gc_end() { return _gc_end; }
+
+  TimePartitions* time_partitions() { return &_time_partitions; }
+
+  long longest_pause();
+  long sum_of_pauses();
+
+ protected:
+  void register_gc_pause_start(const char* name, jlong time);
+  void register_gc_pause_end(jlong time);
+};
+
+class STWGCTimer : public GCTimer {
+ public:
+  virtual void register_gc_start(jlong time);
+  virtual void register_gc_end(jlong time);
+};
+
+class ConcurrentGCTimer : public GCTimer {
+ public:
+  void register_gc_pause_start(const char* name, jlong time);
+  void register_gc_pause_end(jlong time);
+};
+
+class TimePartitionPhasesIterator {
+  TimePartitions* _time_partitions;
+  int _next;
+
+ public:
+  TimePartitionPhasesIterator(TimePartitions* time_partitions) : _time_partitions(time_partitions), _next(0) { }
+
+  virtual bool has_next();
+  virtual GCPhase* next();
+};
+
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+class GCTimerAllTest {
+ public:
+  static void all();
+};
+
+#endif
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "memory/heapInspection.hpp"
+#include "memory/referenceProcessorStats.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/evacuationInfo.hpp"
+#endif
+
+#define assert_unset_gc_id() assert(_shared_gc_info.id() == SharedGCInfo::UNSET_GCID, "GC already started?")
+#define assert_set_gc_id() assert(_shared_gc_info.id() != SharedGCInfo::UNSET_GCID, "GC not started?")
+
+static jlong GCTracer_next_gc_id = 0;
+static GCId create_new_gc_id() {
+  return GCTracer_next_gc_id++;
+}
+
+void GCTracer::report_gc_start_impl(GCCause::Cause cause, jlong timestamp) {
+  assert_unset_gc_id();
+
+  GCId gc_id = create_new_gc_id();
+  _shared_gc_info.set_id(gc_id);
+  _shared_gc_info.set_cause(cause);
+  _shared_gc_info.set_start_timestamp(timestamp);
+}
+
+void GCTracer::report_gc_start(GCCause::Cause cause, jlong timestamp) {
+  assert_unset_gc_id();
+
+  report_gc_start_impl(cause, timestamp);
+}
+
+bool GCTracer::has_reported_gc_start() const {
+  return _shared_gc_info.id() != SharedGCInfo::UNSET_GCID;
+}
+
+void GCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+  assert_set_gc_id();
+
+  _shared_gc_info.set_sum_of_pauses(time_partitions->sum_of_pauses());
+  _shared_gc_info.set_longest_pause(time_partitions->longest_pause());
+  _shared_gc_info.set_end_timestamp(timestamp);
+
+  send_phase_events(time_partitions);
+  send_garbage_collection_event();
+}
+
+void GCTracer::report_gc_end(jlong timestamp, TimePartitions* time_partitions) {
+  assert_set_gc_id();
+
+  report_gc_end_impl(timestamp, time_partitions);
+
+  _shared_gc_info.set_id(SharedGCInfo::UNSET_GCID);
+}
+
+void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) const {
+  assert_set_gc_id();
+
+  send_reference_stats_event(REF_SOFT, rps.soft_count());
+  send_reference_stats_event(REF_WEAK, rps.weak_count());
+  send_reference_stats_event(REF_FINAL, rps.final_count());
+  send_reference_stats_event(REF_PHANTOM, rps.phantom_count());
+}
+
+#if INCLUDE_SERVICES
+void ObjectCountEventSenderClosure::do_cinfo(KlassInfoEntry* entry) {
+  if (should_send_event(entry)) {
+    send_event(entry);
+  }
+}
+
+void ObjectCountEventSenderClosure::send_event(KlassInfoEntry* entry) {
+  _gc_tracer->send_object_count_after_gc_event(entry->klass(), entry->count(),
+                                               entry->words() * BytesPerWord);
+}
+
+bool ObjectCountEventSenderClosure::should_send_event(KlassInfoEntry* entry) const {
+  double percentage_of_heap = ((double) entry->words()) / _total_size_in_words;
+  return percentage_of_heap > _size_threshold_percentage;
+}
+
+void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) {
+  assert_set_gc_id();
+
+  if (should_send_object_count_after_gc_event()) {
+    ResourceMark rm;
+
+    KlassInfoTable cit(false);
+    if (!cit.allocation_failed()) {
+      HeapInspection hi(false, false, false, NULL);
+      hi.populate_table(&cit, is_alive_cl);
+
+      ObjectCountEventSenderClosure event_sender(this, cit.size_of_instances_in_words());
+      cit.iterate(&event_sender);
+    }
+  }
+}
+#endif
+
+void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const {
+  assert_set_gc_id();
+
+  send_gc_heap_summary_event(when, heap_summary);
+  send_meta_space_summary_event(when, meta_space_summary);
+}
+
+void YoungGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+  assert_set_gc_id();
+  assert(_tenuring_threshold != UNSET_TENURING_THRESHOLD, "Tenuring threshold has not been reported");
+
+  GCTracer::report_gc_end_impl(timestamp, time_partitions);
+  send_young_gc_event();
+
+  _tenuring_threshold = UNSET_TENURING_THRESHOLD;
+}
+
+void YoungGCTracer::report_promotion_failed(const PromotionFailedInfo& pf_info) {
+  assert_set_gc_id();
+
+  send_promotion_failed_event(pf_info);
+}
+
+void YoungGCTracer::report_tenuring_threshold(const uint tenuring_threshold) {
+  _tenuring_threshold = tenuring_threshold;
+}
+
+void OldGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+  assert_set_gc_id();
+
+  GCTracer::report_gc_end_impl(timestamp, time_partitions);
+  send_old_gc_event();
+}
+
+void ParallelOldTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+  assert_set_gc_id();
+
+  OldGCTracer::report_gc_end_impl(timestamp, time_partitions);
+  send_parallel_old_event();
+}
+
+void ParallelOldTracer::report_dense_prefix(void* dense_prefix) {
+  assert_set_gc_id();
+
+  _parallel_old_gc_info.report_dense_prefix(dense_prefix);
+}
+
+void OldGCTracer::report_concurrent_mode_failure() {
+  assert_set_gc_id();
+
+  send_concurrent_mode_failure_event();
+}
+
+#if INCLUDE_ALL_GCS
+void G1NewTracer::report_yc_type(G1YCType type) {
+  assert_set_gc_id();
+
+  _g1_young_gc_info.set_type(type);
+}
+
+void G1NewTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+  assert_set_gc_id();
+
+  YoungGCTracer::report_gc_end_impl(timestamp, time_partitions);
+  send_g1_young_gc_event();
+}
+
+void G1NewTracer::report_evacuation_info(EvacuationInfo* info) {
+  assert_set_gc_id();
+
+  send_evacuation_info_event(info);
+}
+
+void G1NewTracer::report_evacuation_failed(EvacuationFailedInfo& ef_info) {
+  assert_set_gc_id();
+
+  send_evacuation_failed_event(ef_info);
+  ef_info.reset();
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACE_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACE_HPP
+
+#include "gc_interface/gcCause.hpp"
+#include "gc_interface/gcName.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "memory/allocation.hpp"
+#include "memory/klassInfoClosure.hpp"
+#include "memory/referenceType.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/g1YCTypes.hpp"
+#endif
+#include "utilities/macros.hpp"
+
+typedef uint GCId;
+
+class EvacuationInfo;
+class GCHeapSummary;
+class MetaspaceSummary;
+class PSHeapSummary;
+class ReferenceProcessorStats;
+class TimePartitions;
+class BoolObjectClosure;
+
+class SharedGCInfo VALUE_OBJ_CLASS_SPEC {
+  static const jlong UNSET_TIMESTAMP = -1;
+
+ public:
+  static const GCId UNSET_GCID = (GCId)-1;
+
+ private:
+  GCId _id;
+  GCName _name;
+  GCCause::Cause _cause;
+  jlong _start_timestamp;
+  jlong _end_timestamp;
+  jlong _sum_of_pauses;
+  jlong _longest_pause;
+
+ public:
+  SharedGCInfo(GCName name) : _id(UNSET_GCID), _name(name), _cause(GCCause::_last_gc_cause),
+      _start_timestamp(UNSET_TIMESTAMP), _end_timestamp(UNSET_TIMESTAMP), _sum_of_pauses(0), _longest_pause(0) {}
+
+  void set_id(GCId id) { _id = id; }
+  GCId id() const { return _id; }
+
+  void set_start_timestamp(jlong timestamp) { _start_timestamp = timestamp; }
+  jlong start_timestamp() const { return _start_timestamp; }
+
+  void set_end_timestamp(jlong timestamp) { _end_timestamp = timestamp; }
+  jlong end_timestamp() const { return _end_timestamp; }
+
+  void set_name(GCName name) { _name = name; }
+  GCName name() const { return _name; }
+
+  void set_cause(GCCause::Cause cause) { _cause = cause; }
+  GCCause::Cause cause() const { return _cause; }
+
+  void set_sum_of_pauses(jlong duration) { _sum_of_pauses = duration; }
+  jlong sum_of_pauses() const { return _sum_of_pauses; }
+
+  void set_longest_pause(jlong duration) { _longest_pause = duration; }
+  jlong longest_pause() const { return _longest_pause; }
+};
+
+class ParallelOldGCInfo VALUE_OBJ_CLASS_SPEC {
+  void* _dense_prefix;
+ public:
+  ParallelOldGCInfo() : _dense_prefix(NULL) {}
+  void report_dense_prefix(void* addr) {
+    _dense_prefix = addr;
+  }
+  void* dense_prefix() const { return _dense_prefix; }
+};
+
+#if INCLUDE_ALL_GCS
+
+class G1YoungGCInfo VALUE_OBJ_CLASS_SPEC {
+  G1YCType _type;
+ public:
+  G1YoungGCInfo() : _type(G1YCTypeEndSentinel) {}
+  void set_type(G1YCType type) {
+    _type = type;
+  }
+  G1YCType type() const { return _type; }
+};
+
+#endif // INCLUDE_ALL_GCS
+
+class GCTracer : public ResourceObj {
+  friend class ObjectCountEventSenderClosure;
+ protected:
+  SharedGCInfo _shared_gc_info;
+
+ public:
+  void report_gc_start(GCCause::Cause cause, jlong timestamp);
+  void report_gc_end(jlong timestamp, TimePartitions* time_partitions);
+  void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const;
+  void report_gc_reference_stats(const ReferenceProcessorStats& rp) const;
+  void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN;
+
+  bool has_reported_gc_start() const;
+
+ protected:
+  GCTracer(GCName name) : _shared_gc_info(name) {}
+  virtual void report_gc_start_impl(GCCause::Cause cause, jlong timestamp);
+  virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ private:
+  void send_garbage_collection_event() const;
+  void send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const;
+  void send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const;
+  void send_reference_stats_event(ReferenceType type, size_t count) const;
+  void send_phase_events(TimePartitions* time_partitions) const;
+  void send_object_count_after_gc_event(Klass* klass, jlong count, julong total_size) const NOT_SERVICES_RETURN;
+  bool should_send_object_count_after_gc_event() const;
+};
+
+class ObjectCountEventSenderClosure : public KlassInfoClosure {
+  GCTracer* _gc_tracer;
+  const double _size_threshold_percentage;
+  const size_t _total_size_in_words;
+ public:
+  ObjectCountEventSenderClosure(GCTracer* gc_tracer, size_t total_size_in_words) :
+    _gc_tracer(gc_tracer),
+    _size_threshold_percentage(ObjectCountCutOffPercent / 100),
+    _total_size_in_words(total_size_in_words)
+  {}
+  virtual void do_cinfo(KlassInfoEntry* entry);
+ protected:
+  virtual void send_event(KlassInfoEntry* entry);
+ private:
+  bool should_send_event(KlassInfoEntry* entry) const;
+};
+
+class YoungGCTracer : public GCTracer {
+  static const uint UNSET_TENURING_THRESHOLD = (uint) -1;
+
+  uint _tenuring_threshold;
+
+ protected:
+  YoungGCTracer(GCName name) : GCTracer(name), _tenuring_threshold(UNSET_TENURING_THRESHOLD) {}
+  virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ public:
+  void report_promotion_failed(const PromotionFailedInfo& pf_info);
+  void report_tenuring_threshold(const uint tenuring_threshold);
+
+ private:
+  void send_young_gc_event() const;
+  void send_promotion_failed_event(const PromotionFailedInfo& pf_info) const;
+};
+
+class OldGCTracer : public GCTracer {
+ protected:
+  OldGCTracer(GCName name) : GCTracer(name) {}
+  virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ public:
+  void report_concurrent_mode_failure();
+
+ private:
+  void send_old_gc_event() const;
+  void send_concurrent_mode_failure_event();
+};
+
+class ParallelOldTracer : public OldGCTracer {
+  ParallelOldGCInfo _parallel_old_gc_info;
+
+ public:
+  ParallelOldTracer() : OldGCTracer(ParallelOld) {}
+  void report_dense_prefix(void* dense_prefix);
+
+ protected:
+  void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ private:
+  void send_parallel_old_event() const;
+};
+
+class SerialOldTracer : public OldGCTracer {
+ public:
+  SerialOldTracer() : OldGCTracer(SerialOld) {}
+};
+
+class ParallelScavengeTracer : public YoungGCTracer {
+ public:
+  ParallelScavengeTracer() : YoungGCTracer(ParallelScavenge) {}
+};
+
+class DefNewTracer : public YoungGCTracer {
+ public:
+  DefNewTracer() : YoungGCTracer(DefNew) {}
+};
+
+class ParNewTracer : public YoungGCTracer {
+ public:
+  ParNewTracer() : YoungGCTracer(ParNew) {}
+};
+
+#if INCLUDE_ALL_GCS
+class G1NewTracer : public YoungGCTracer {
+  G1YoungGCInfo _g1_young_gc_info;
+
+ public:
+  G1NewTracer() : YoungGCTracer(G1New) {}
+
+  void report_yc_type(G1YCType type);
+  void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+  void report_evacuation_info(EvacuationInfo* info);
+  void report_evacuation_failed(EvacuationFailedInfo& ef_info);
+
+ private:
+  void send_g1_young_gc_event();
+  void send_evacuation_info_event(EvacuationInfo* info);
+  void send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const;
+};
+#endif
+
+class CMSTracer : public OldGCTracer {
+ public:
+  CMSTracer() : OldGCTracer(ConcurrentMarkSweep) {}
+};
+
+class G1OldTracer : public OldGCTracer {
+ public:
+  G1OldTracer() : OldGCTracer(G1Old) {}
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceBackend.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/evacuationInfo.hpp"
+#include "gc_implementation/g1/g1YCTypes.hpp"
+#endif
+
+// All GC dependencies against the trace framework is contained within this file.
+
+typedef uintptr_t TraceAddress;
+
+void GCTracer::send_garbage_collection_event() const {
+  EventGCGarbageCollection event(UNTIMED);
+  if (event.should_commit()) {
+    event.set_gcId(_shared_gc_info.id());
+    event.set_name(_shared_gc_info.name());
+    event.set_cause((u2) _shared_gc_info.cause());
+    event.set_sumOfPauses(_shared_gc_info.sum_of_pauses());
+    event.set_longestPause(_shared_gc_info.longest_pause());
+    event.set_starttime(_shared_gc_info.start_timestamp());
+    event.set_endtime(_shared_gc_info.end_timestamp());
+    event.commit();
+  }
+}
+
+void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const {
+  EventGCReferenceStatistics e;
+  if (e.should_commit()) {
+      e.set_gcId(_shared_gc_info.id());
+      e.set_type((u1)type);
+      e.set_count(count);
+      e.commit();
+  }
+}
+
+void ParallelOldTracer::send_parallel_old_event() const {
+  EventGCParallelOld e(UNTIMED);
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_densePrefix((TraceAddress)_parallel_old_gc_info.dense_prefix());
+    e.set_starttime(_shared_gc_info.start_timestamp());
+    e.set_endtime(_shared_gc_info.end_timestamp());
+    e.commit();
+  }
+}
+
+void YoungGCTracer::send_young_gc_event() const {
+  EventGCYoungGarbageCollection e(UNTIMED);
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_tenuringThreshold(_tenuring_threshold);
+    e.set_starttime(_shared_gc_info.start_timestamp());
+    e.set_endtime(_shared_gc_info.end_timestamp());
+    e.commit();
+  }
+}
+
+void OldGCTracer::send_old_gc_event() const {
+  EventGCOldGarbageCollection e(UNTIMED);
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_starttime(_shared_gc_info.start_timestamp());
+    e.set_endtime(_shared_gc_info.end_timestamp());
+    e.commit();
+  }
+}
+
+static TraceStructCopyFailed to_trace_struct(const CopyFailedInfo& cf_info) {
+  TraceStructCopyFailed failed_info;
+  failed_info.set_objectCount(cf_info.failed_count());
+  failed_info.set_firstSize(cf_info.first_size());
+  failed_info.set_smallestSize(cf_info.smallest_size());
+  failed_info.set_totalSize(cf_info.total_size());
+  return failed_info;
+}
+
+void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const {
+  EventPromotionFailed e;
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_data(to_trace_struct(pf_info));
+    e.set_thread(pf_info.thread()->thread_id());
+    e.commit();
+  }
+}
+
+// Common to CMS and G1
+void OldGCTracer::send_concurrent_mode_failure_event() {
+  EventConcurrentModeFailure e;
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.commit();
+  }
+}
+
+#if INCLUDE_SERVICES
+void GCTracer::send_object_count_after_gc_event(Klass* klass, jlong count, julong total_size) const {
+  EventObjectCountAfterGC e;
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_class(klass);
+    e.set_count(count);
+    e.set_totalSize(total_size);
+    e.commit();
+  }
+}
+#endif
+
+bool GCTracer::should_send_object_count_after_gc_event() const {
+#if INCLUDE_TRACE
+  return Tracing::is_event_enabled(EventObjectCountAfterGC::eventId);
+#else
+  return false;
+#endif
+}
+
+#if INCLUDE_ALL_GCS
+void G1NewTracer::send_g1_young_gc_event() {
+  EventGCG1GarbageCollection e(UNTIMED);
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_type(_g1_young_gc_info.type());
+    e.set_starttime(_shared_gc_info.start_timestamp());
+    e.set_endtime(_shared_gc_info.end_timestamp());
+    e.commit();
+  }
+}
+
+void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
+  EventEvacuationInfo e;
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_cSetRegions(info->collectionset_regions());
+    e.set_cSetUsedBefore(info->collectionset_used_before());
+    e.set_cSetUsedAfter(info->collectionset_used_after());
+    e.set_allocationRegions(info->allocation_regions());
+    e.set_allocRegionsUsedBefore(info->alloc_regions_used_before());
+    e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied());
+    e.set_bytesCopied(info->bytes_copied());
+    e.set_regionsFreed(info->regions_freed());
+    e.commit();
+  }
+}
+
+void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const {
+  EventEvacuationFailed e;
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_data(to_trace_struct(ef_info));
+    e.commit();
+  }
+}
+#endif
+
+static TraceStructVirtualSpace to_trace_struct(const VirtualSpaceSummary& summary) {
+  TraceStructVirtualSpace space;
+  space.set_start((TraceAddress)summary.start());
+  space.set_committedEnd((TraceAddress)summary.committed_end());
+  space.set_committedSize(summary.committed_size());
+  space.set_reservedEnd((TraceAddress)summary.reserved_end());
+  space.set_reservedSize(summary.reserved_size());
+  return space;
+}
+
+static TraceStructObjectSpace to_trace_struct(const SpaceSummary& summary) {
+  TraceStructObjectSpace space;
+  space.set_start((TraceAddress)summary.start());
+  space.set_end((TraceAddress)summary.end());
+  space.set_used(summary.used());
+  space.set_size(summary.size());
+  return space;
+}
+
+class GCHeapSummaryEventSender : public GCHeapSummaryVisitor {
+  GCId _id;
+  GCWhen::Type _when;
+ public:
+  GCHeapSummaryEventSender(GCId id, GCWhen::Type when) : _id(id), _when(when) {}
+
+  void visit(const GCHeapSummary* heap_summary) const {
+    const VirtualSpaceSummary& heap_space = heap_summary->heap();
+
+    EventGCHeapSummary e;
+    if (e.should_commit()) {
+      e.set_gcId(_id);
+      e.set_when((u1)_when);
+      e.set_heapSpace(to_trace_struct(heap_space));
+      e.set_heapUsed(heap_summary->used());
+      e.commit();
+    }
+  }
+
+  void visit(const PSHeapSummary* ps_heap_summary) const {
+    visit((GCHeapSummary*)ps_heap_summary);
+
+    const VirtualSpaceSummary& old_summary = ps_heap_summary->old();
+    const SpaceSummary& old_space = ps_heap_summary->old_space();
+    const VirtualSpaceSummary& young_summary = ps_heap_summary->young();
+    const SpaceSummary& eden_space = ps_heap_summary->eden();
+    const SpaceSummary& from_space = ps_heap_summary->from();
+    const SpaceSummary& to_space = ps_heap_summary->to();
+
+    EventPSHeapSummary e;
+    if (e.should_commit()) {
+      e.set_gcId(_id);
+      e.set_when((u1)_when);
+
+      e.set_oldSpace(to_trace_struct(ps_heap_summary->old()));
+      e.set_oldObjectSpace(to_trace_struct(ps_heap_summary->old_space()));
+      e.set_youngSpace(to_trace_struct(ps_heap_summary->young()));
+      e.set_edenSpace(to_trace_struct(ps_heap_summary->eden()));
+      e.set_fromSpace(to_trace_struct(ps_heap_summary->from()));
+      e.set_toSpace(to_trace_struct(ps_heap_summary->to()));
+      e.commit();
+    }
+  }
+};
+
+void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
+  GCHeapSummaryEventSender visitor(_shared_gc_info.id(), when);
+  heap_summary.accept(&visitor);
+}
+
+static TraceStructMetaspaceSizes to_trace_struct(const MetaspaceSizes& sizes) {
+  TraceStructMetaspaceSizes meta_sizes;
+
+  meta_sizes.set_capacity(sizes.capacity());
+  meta_sizes.set_used(sizes.used());
+  meta_sizes.set_reserved(sizes.reserved());
+
+  return meta_sizes;
+}
+
+void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const {
+  EventMetaspaceSummary e;
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_when((u1) when);
+    e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
+    e.set_dataSpace(to_trace_struct(meta_space_summary.data_space()));
+    e.set_classSpace(to_trace_struct(meta_space_summary.class_space()));
+    e.commit();
+  }
+}
+
+class PhaseSender : public PhaseVisitor {
+  GCId _gc_id;
+ public:
+  PhaseSender(GCId gc_id) : _gc_id(gc_id) {}
+
+  template<typename T>
+  void send_phase(PausePhase* pause) {
+    T event(UNTIMED);
+    if (event.should_commit()) {
+      event.set_gcId(_gc_id);
+      event.set_name(pause->name());
+      event.set_starttime(pause->start());
+      event.set_endtime(pause->end());
+      event.commit();
+    }
+  }
+
+  void visit(GCPhase* pause) { ShouldNotReachHere(); }
+  void visit(ConcurrentPhase* pause) { Unimplemented(); }
+  void visit(PausePhase* pause) {
+    assert(PhasesStack::PHASE_LEVELS == 5, "Need more event types");
+
+    switch (pause->level()) {
+      case 0: send_phase<EventGCPhasePause>(pause); break;
+      case 1: send_phase<EventGCPhasePauseLevel1>(pause); break;
+      case 2: send_phase<EventGCPhasePauseLevel2>(pause); break;
+      case 3: send_phase<EventGCPhasePauseLevel3>(pause); break;
+      default: /* Ignore sending this phase */ break;
+    }
+  }
+
+#undef send_phase
+};
+
+void GCTracer::send_phase_events(TimePartitions* time_partitions) const {
+  PhaseSender phase_reporter(_shared_gc_info.id());
+
+  TimePartitionPhasesIterator iter(time_partitions);
+  while (iter.has_next()) {
+    GCPhase* phase = iter.next();
+    phase->accept(&phase_reporter);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTraceTime.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/timer.hpp"
+#include "utilities/ostream.hpp"
+
+
+GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) :
+    _title(title), _doit(doit), _print_cr(print_cr), _timer(timer) {
+  if (_doit || _timer != NULL) {
+    _start_counter = os::elapsed_counter();
+  }
+
+  if (_timer != NULL) {
+    assert(SafepointSynchronize::is_at_safepoint(), "Tracing currently only supported at safepoints");
+    assert(Thread::current()->is_VM_thread(), "Tracing currently only supported from the VM thread");
+
+    _timer->register_gc_phase_start(title, _start_counter);
+  }
+
+  if (_doit) {
+    if (PrintGCTimeStamps) {
+      gclog_or_tty->stamp();
+      gclog_or_tty->print(": ");
+    }
+    gclog_or_tty->print("[%s", title);
+    gclog_or_tty->flush();
+  }
+}
+
+GCTraceTime::~GCTraceTime() {
+  jlong stop_counter = 0;
+
+  if (_doit || _timer != NULL) {
+    stop_counter = os::elapsed_counter();
+  }
+
+  if (_timer != NULL) {
+    _timer->register_gc_phase_end(stop_counter);
+  }
+
+  if (_doit) {
+    double seconds = TimeHelper::counter_to_seconds(stop_counter - _start_counter);
+    if (_print_cr) {
+      gclog_or_tty->print_cr(", %3.7f secs]", seconds);
+    } else {
+      gclog_or_tty->print(", %3.7f secs]", seconds);
+    }
+    gclog_or_tty->flush();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTraceTime.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
+
+#include "prims/jni_md.h"
+
+class GCTimer;
+
+class GCTraceTime {
+  const char* _title;
+  bool _doit;
+  bool _print_cr;
+  GCTimer* _timer;
+  jlong _start_counter;
+
+ public:
+  GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer);
+  ~GCTraceTime();
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/gcWhen.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCWHEN_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCWHEN_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+class GCWhen : AllStatic {
+ public:
+  enum Type {
+    BeforeGC,
+    AfterGC,
+    GCWhenEndSentinel
+  };
+
+  static const char* to_string(GCWhen::Type when) {
+    switch (when) {
+    case BeforeGC: return "Before GC";
+    case AfterGC:  return "After GC";
+    default: ShouldNotReachHere(); return NULL;
+    }
+  }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCWHEN_HPP
--- a/src/share/vm/gc_implementation/shared/markSweep.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/shared/markSweep.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -24,6 +24,8 @@
 
 #include "precompiled.hpp"
 #include "compiler/compileBroker.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "oops/methodData.hpp"
@@ -41,6 +43,8 @@
 size_t                  MarkSweep::_preserved_count_max = 0;
 PreservedMark*          MarkSweep::_preserved_marks = NULL;
 ReferenceProcessor*     MarkSweep::_ref_processor   = NULL;
+STWGCTimer*             MarkSweep::_gc_timer        = NULL;
+SerialOldTracer*        MarkSweep::_gc_tracer       = NULL;
 
 MarkSweep::FollowRootClosure  MarkSweep::follow_root_closure;
 CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true);
@@ -173,7 +177,10 @@
 void MarkSweep::KeepAliveClosure::do_oop(oop* p)       { MarkSweep::KeepAliveClosure::do_oop_work(p); }
 void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
 
-void marksweep_init() { /* empty */ }
+void marksweep_init() {
+  MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
+  MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
+}
 
 #ifndef PRODUCT
 
--- a/src/share/vm/gc_implementation/shared/markSweep.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/shared/markSweep.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,8 @@
 
 class ReferenceProcessor;
 class DataLayout;
+class SerialOldTracer;
+class STWGCTimer;
 
 // MarkSweep takes care of global mark-compact garbage collection for a
 // GenCollectedHeap using a four-phase pointer forwarding algorithm.  All
@@ -128,6 +130,9 @@
   // Reference processing (used in ...follow_contents)
   static ReferenceProcessor*             _ref_processor;
 
+  static STWGCTimer*                     _gc_timer;
+  static SerialOldTracer*                _gc_tracer;
+
   // Non public closures
   static KeepAliveClosure keep_alive;
 
@@ -151,6 +156,9 @@
   // Reference Processing
   static ReferenceProcessor* const ref_processor() { return _ref_processor; }
 
+  static STWGCTimer* gc_timer() { return _gc_timer; }
+  static SerialOldTracer* gc_tracer() { return _gc_tracer; }
+
   // Call backs for marking
   static void mark_object(oop obj);
   // Mark pointer and follow contents.  Empty marking stack afterwards.
--- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -158,7 +158,7 @@
   // Fills in the unallocated portion of the buffer with a garbage object.
   // If "end_of_gc" is TRUE, is after the last use in the GC.  IF "retain"
   // is true, attempt to re-use the unused portion in the next GC.
-  void retire(bool end_of_gc, bool retain);
+  virtual void retire(bool end_of_gc, bool retain);
 
   void print() PRODUCT_RETURN;
 };
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -145,32 +145,37 @@
   return false;
 }
 
+bool VM_GC_HeapInspection::collect() {
+  if (GC_locker::is_active()) {
+    return false;
+  }
+  Universe::heap()->collect_as_vm_thread(GCCause::_heap_inspection);
+  return true;
+}
+
 void VM_GC_HeapInspection::doit() {
   HandleMark hm;
-  CollectedHeap* ch = Universe::heap();
-  ch->ensure_parsability(false); // must happen, even if collection does
-                                 // not happen (e.g. due to GC_locker)
+  Universe::heap()->ensure_parsability(false); // must happen, even if collection does
+                                               // not happen (e.g. due to GC_locker)
+                                               // or _full_gc being false
   if (_full_gc) {
-    // The collection attempt below would be skipped anyway if
-    // the gc locker is held. The following dump may then be a tad
-    // misleading to someone expecting only live objects to show
-    // up in the dump (see CR 6944195). Just issue a suitable warning
-    // in that case and do not attempt to do a collection.
-    // The latter is a subtle point, because even a failed attempt
-    // to GC will, in fact, induce one in the future, which we
-    // probably want to avoid in this case because the GC that we may
-    // be about to attempt holds value for us only
-    // if it happens now and not if it happens in the eventual
-    // future.
-    if (GC_locker::is_active()) {
+    if (!collect()) {
+      // The collection attempt was skipped because the gc locker is held.
+      // The following dump may then be a tad misleading to someone expecting
+      // only live objects to show up in the dump (see CR 6944195). Just issue
+      // a suitable warning in that case and do not attempt to do a collection.
+      // The latter is a subtle point, because even a failed attempt
+      // to GC will, in fact, induce one in the future, which we
+      // probably want to avoid in this case because the GC that we may
+      // be about to attempt holds value for us only
+      // if it happens now and not if it happens in the eventual
+      // future.
       warning("GC locker is held; pre-dump GC was skipped");
-    } else {
-      ch->collect_as_vm_thread(GCCause::_heap_inspection);
     }
   }
   HeapInspection inspect(_csv_format, _print_help, _print_class_stats,
                          _columns);
-  inspect.heap_inspection(_out, _need_prologue /* need_prologue */);
+  inspect.heap_inspection(_out);
 }
 
 
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -129,21 +129,18 @@
  private:
   outputStream* _out;
   bool _full_gc;
-  bool _need_prologue;
   bool _csv_format; // "comma separated values" format for spreadsheet.
   bool _print_help;
   bool _print_class_stats;
   const char* _columns;
  public:
-  VM_GC_HeapInspection(outputStream* out, bool request_full_gc,
-                       bool need_prologue) :
+  VM_GC_HeapInspection(outputStream* out, bool request_full_gc) :
     VM_GC_Operation(0 /* total collections,      dummy, ignored */,
                     GCCause::_heap_inspection /* GC Cause */,
                     0 /* total full collections, dummy, ignored */,
                     request_full_gc) {
     _out = out;
     _full_gc = request_full_gc;
-    _need_prologue = need_prologue;
     _csv_format = false;
     _print_help = false;
     _print_class_stats = false;
@@ -159,6 +156,8 @@
   void set_print_help(bool value) {_print_help = value;}
   void set_print_class_stats(bool value) {_print_class_stats = value;}
   void set_columns(const char* value) {_columns = value;}
+ protected:
+  bool collect();
 };
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_interface/allocTracer.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_interface/allocTracer.hpp"
+#include "trace/tracing.hpp"
+#include "runtime/handles.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+void AllocTracer::send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size) {
+  EventAllocObjectOutsideTLAB event;
+  if (event.should_commit()) {
+    event.set_class(klass());
+    event.set_allocationSize(alloc_size);
+    event.commit();
+  }
+}
+
+void AllocTracer::send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size) {
+  EventAllocObjectInNewTLAB event;
+  if (event.should_commit()) {
+    event.set_class(klass());
+    event.set_allocationSize(alloc_size);
+    event.set_tlabSize(tlab_size);
+    event.commit();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_interface/allocTracer.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
+#define SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/handles.hpp"
+
+class AllocTracer : AllStatic {
+  public:
+    static void send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size);
+    static void send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size);
+};
+
+#endif /* SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP */
--- a/src/share/vm/gc_interface/collectedHeap.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_interface/collectedHeap.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,15 @@
 
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_implementation/shared/vmGCOperations.hpp"
+#include "gc_interface/allocTracer.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/metaspace.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "runtime/init.hpp"
@@ -65,11 +71,71 @@
   }
 }
 
+VirtualSpaceSummary CollectedHeap::create_heap_space_summary() {
+  size_t capacity_in_words = capacity() / HeapWordSize;
+
+  return VirtualSpaceSummary(
+    reserved_region().start(), reserved_region().start() + capacity_in_words, reserved_region().end());
+}
+
+GCHeapSummary CollectedHeap::create_heap_summary() {
+  VirtualSpaceSummary heap_space = create_heap_space_summary();
+  return GCHeapSummary(heap_space, used());
+}
+
+MetaspaceSummary CollectedHeap::create_metaspace_summary() {
+  const MetaspaceSizes meta_space(
+      0, /*MetaspaceAux::capacity_in_bytes(),*/
+      0, /*MetaspaceAux::used_in_bytes(),*/
+      MetaspaceAux::reserved_in_bytes());
+  const MetaspaceSizes data_space(
+      0, /*MetaspaceAux::capacity_in_bytes(Metaspace::NonClassType),*/
+      0, /*MetaspaceAux::used_in_bytes(Metaspace::NonClassType),*/
+      MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType));
+  const MetaspaceSizes class_space(
+      0, /*MetaspaceAux::capacity_in_bytes(Metaspace::ClassType),*/
+      0, /*MetaspaceAux::used_in_bytes(Metaspace::ClassType),*/
+      MetaspaceAux::reserved_in_bytes(Metaspace::ClassType));
+
+  return MetaspaceSummary(meta_space, data_space, class_space);
+}
+
+void CollectedHeap::print_heap_before_gc() {
+  if (PrintHeapAtGC) {
+    Universe::print_heap_before_gc();
+  }
+  if (_gc_heap_log != NULL) {
+    _gc_heap_log->log_heap_before();
+  }
+}
+
+void CollectedHeap::print_heap_after_gc() {
+  if (PrintHeapAtGC) {
+    Universe::print_heap_after_gc();
+  }
+  if (_gc_heap_log != NULL) {
+    _gc_heap_log->log_heap_after();
+  }
+}
+
+void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
+  const GCHeapSummary& heap_summary = create_heap_summary();
+  const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
+  gc_tracer->report_gc_heap_summary(when, heap_summary, metaspace_summary);
+}
+
+void CollectedHeap::trace_heap_before_gc(GCTracer* gc_tracer) {
+  trace_heap(GCWhen::BeforeGC, gc_tracer);
+}
+
+void CollectedHeap::trace_heap_after_gc(GCTracer* gc_tracer) {
+  trace_heap(GCWhen::AfterGC, gc_tracer);
+}
+
 // Memory state functions.
 
 
 CollectedHeap::CollectedHeap() : _n_par_threads(0)
-
 {
   const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));
   const size_t elements_per_word = HeapWordSize / sizeof(jint);
@@ -185,7 +251,7 @@
 }
 #endif
 
-HeapWord* CollectedHeap::allocate_from_tlab_slow(Thread* thread, size_t size) {
+HeapWord* CollectedHeap::allocate_from_tlab_slow(KlassHandle klass, Thread* thread, size_t size) {
 
   // Retain tlab and allocate object in shared space if
   // the amount free in the tlab is too large to discard.
@@ -209,6 +275,9 @@
   if (obj == NULL) {
     return NULL;
   }
+
+  AllocTracer::send_allocation_in_new_tlab_event(klass, new_tlab_size * HeapWordSize, size * HeapWordSize);
+
   if (ZeroTLAB) {
     // ..and clear it.
     Copy::zero_to_words(obj, new_tlab_size);
@@ -458,28 +527,28 @@
   }
 }
 
-void CollectedHeap::pre_full_gc_dump() {
+void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
   if (HeapDumpBeforeFullGC) {
-    TraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer);
     // We are doing a "major" collection and a heap dump before
     // major collection has been requested.
     HeapDumper::dump_heap();
   }
   if (PrintClassHistogramBeforeFullGC) {
-    TraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, gclog_or_tty);
-    VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */, false /* ! prologue */);
+    GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer);
+    VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
     inspector.doit();
   }
 }
 
-void CollectedHeap::post_full_gc_dump() {
+void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
   if (HeapDumpAfterFullGC) {
-    TraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer);
     HeapDumper::dump_heap();
   }
   if (PrintClassHistogramAfterFullGC) {
-    TraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, gclog_or_tty);
-    VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */, false /* ! prologue */);
+    GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer);
+    VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
     inspector.doit();
   }
 }
@@ -490,7 +559,7 @@
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj;
     assert(ScavengeRootsInCode > 0, "must be");
-    obj = common_mem_allocate_init(size, CHECK_NULL);
+    obj = common_mem_allocate_init(real_klass, size, CHECK_NULL);
   post_allocation_setup_common(klass, obj);
   assert(Universe::is_bootstrapping() ||
          !((oop)obj)->is_array(), "must not be an array");
--- a/src/share/vm/gc_interface/collectedHeap.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_interface/collectedHeap.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_HPP
 
 #include "gc_interface/gcCause.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
 #include "memory/allocation.hpp"
 #include "memory/barrierSet.hpp"
 #include "runtime/handles.hpp"
@@ -38,11 +39,16 @@
 // class defines the functions that a heap must implement, and contains
 // infrastructure common to all heaps.
 
+class AdaptiveSizePolicy;
 class BarrierSet;
+class CollectorPolicy;
+class GCHeapSummary;
+class GCTimer;
+class GCTracer;
+class MetaspaceSummary;
+class Thread;
 class ThreadClosure;
-class AdaptiveSizePolicy;
-class Thread;
-class CollectorPolicy;
+class VirtualSpaceSummary;
 
 class GCMessage : public FormatBuffer<1024> {
  public:
@@ -128,16 +134,16 @@
   virtual void resize_all_tlabs();
 
   // Allocate from the current thread's TLAB, with broken-out slow path.
-  inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
-  static HeapWord* allocate_from_tlab_slow(Thread* thread, size_t size);
+  inline static HeapWord* allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size);
+  static HeapWord* allocate_from_tlab_slow(KlassHandle klass, Thread* thread, size_t size);
 
   // Allocate an uninitialized block of the given size, or returns NULL if
   // this is impossible.
-  inline static HeapWord* common_mem_allocate_noinit(size_t size, TRAPS);
+  inline static HeapWord* common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS);
 
   // Like allocate_init, but the block returned by a successful allocation
   // is guaranteed initialized to zeros.
-  inline static HeapWord* common_mem_allocate_init(size_t size, TRAPS);
+  inline static HeapWord* common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS);
 
   // Helper functions for (VM) allocation.
   inline static void post_allocation_setup_common(KlassHandle klass, HeapWord* obj);
@@ -166,6 +172,8 @@
   // Fill with a single object (either an int array or a java.lang.Object).
   static inline void fill_with_object_impl(HeapWord* start, size_t words, bool zap = true);
 
+  virtual void trace_heap(GCWhen::Type when, GCTracer* tracer);
+
   // Verification functions
   virtual void check_for_bad_heap_word_value(HeapWord* addr, size_t size)
     PRODUCT_RETURN;
@@ -202,8 +210,6 @@
   MemRegion reserved_region() const { return _reserved; }
   address base() const { return (address)reserved_region().start(); }
 
-  // Future cleanup here. The following functions should specify bytes or
-  // heapwords as part of their signature.
   virtual size_t capacity() const = 0;
   virtual size_t used() const = 0;
 
@@ -550,8 +556,13 @@
   virtual void prepare_for_verify() = 0;
 
   // Generate any dumps preceding or following a full gc
-  void pre_full_gc_dump();
-  void post_full_gc_dump();
+  void pre_full_gc_dump(GCTimer* timer);
+  void post_full_gc_dump(GCTimer* timer);
+
+  VirtualSpaceSummary create_heap_space_summary();
+  GCHeapSummary create_heap_summary();
+
+  MetaspaceSummary create_metaspace_summary();
 
   // Print heap information on the given outputStream.
   virtual void print_on(outputStream* st) const = 0;
@@ -560,7 +571,7 @@
     print_on(tty);
   }
   // Print more detailed heap information on the given
-  // outputStream. The default behaviour is to call print_on(). It is
+  // outputStream. The default behavior is to call print_on(). It is
   // up to each subclass to override it and add any additional output
   // it needs.
   virtual void print_extended_on(outputStream* st) const {
@@ -589,23 +600,11 @@
   // Default implementation does nothing.
   virtual void print_tracing_info() const = 0;
 
-  // If PrintHeapAtGC is set call the appropriate routi
-  void print_heap_before_gc() {
-    if (PrintHeapAtGC) {
-      Universe::print_heap_before_gc();
-    }
-    if (_gc_heap_log != NULL) {
-      _gc_heap_log->log_heap_before();
-    }
-  }
-  void print_heap_after_gc() {
-    if (PrintHeapAtGC) {
-      Universe::print_heap_after_gc();
-    }
-    if (_gc_heap_log != NULL) {
-      _gc_heap_log->log_heap_after();
-    }
-  }
+  void print_heap_before_gc();
+  void print_heap_after_gc();
+
+  void trace_heap_before_gc(GCTracer* gc_tracer);
+  void trace_heap_after_gc(GCTracer* gc_tracer);
 
   // Heap verification
   virtual void verify(bool silent, VerifyOption option) = 0;
@@ -619,7 +618,7 @@
   inline bool promotion_should_fail();
 
   // Reset the PromotionFailureALot counters.  Should be called at the end of a
-  // GC in which promotion failure ocurred.
+  // GC in which promotion failure occurred.
   inline void reset_promotion_should_fail(volatile size_t* count);
   inline void reset_promotion_should_fail();
 #endif  // #ifndef PRODUCT
--- a/src/share/vm/gc_interface/collectedHeap.inline.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
 #define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
 
+#include "gc_interface/allocTracer.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "memory/threadLocalAllocBuffer.inline.hpp"
 #include "memory/universe.hpp"
@@ -107,7 +108,7 @@
   post_allocation_notify(klass, (oop)obj);
 }
 
-HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) {
+HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS) {
 
   // Clear unhandled oops for memory allocation.  Memory allocation might
   // not take out a lock if from tlab, so clear here.
@@ -120,7 +121,7 @@
 
   HeapWord* result = NULL;
   if (UseTLAB) {
-    result = CollectedHeap::allocate_from_tlab(THREAD, size);
+    result = allocate_from_tlab(klass, THREAD, size);
     if (result != NULL) {
       assert(!HAS_PENDING_EXCEPTION,
              "Unexpected exception, will result in uninitialized storage");
@@ -136,6 +137,9 @@
     assert(!HAS_PENDING_EXCEPTION,
            "Unexpected exception, will result in uninitialized storage");
     THREAD->incr_allocated_bytes(size * HeapWordSize);
+
+    AllocTracer::send_allocation_outside_tlab_event(klass, size * HeapWordSize);
+
     return result;
   }
 
@@ -165,13 +169,13 @@
   }
 }
 
-HeapWord* CollectedHeap::common_mem_allocate_init(size_t size, TRAPS) {
-  HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
+HeapWord* CollectedHeap::common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS) {
+  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
   init_obj(obj, size);
   return obj;
 }
 
-HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) {
+HeapWord* CollectedHeap::allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size) {
   assert(UseTLAB, "should use UseTLAB");
 
   HeapWord* obj = thread->tlab().allocate(size);
@@ -179,7 +183,7 @@
     return obj;
   }
   // Otherwise...
-  return allocate_from_tlab_slow(thread, size);
+  return allocate_from_tlab_slow(klass, thread, size);
 }
 
 void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
@@ -194,7 +198,7 @@
   debug_only(check_for_valid_allocation_state());
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
-  HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
+  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
   post_allocation_setup_obj(klass, obj);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
@@ -207,7 +211,7 @@
   debug_only(check_for_valid_allocation_state());
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
-  HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
+  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
   post_allocation_setup_array(klass, obj, length);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
@@ -220,7 +224,7 @@
   debug_only(check_for_valid_allocation_state());
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
-  HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
+  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
   ((oop)obj)->set_klass_gap(0);
   post_allocation_setup_array(klass, obj, length);
 #ifndef PRODUCT
--- a/src/share/vm/gc_interface/gcCause.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_interface/gcCause.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -72,6 +72,9 @@
     case _cms_final_remark:
       return "CMS Final Remark";
 
+    case _cms_concurrent_mark:
+      return "CMS Concurrent Mark";
+
     case _old_generation_expanded_on_last_scavenge:
       return "Old Generation Expanded On Last Scavenge";
 
--- a/src/share/vm/gc_interface/gcCause.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/gc_interface/gcCause.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -60,6 +60,7 @@
     _cms_generation_full,
     _cms_initial_mark,
     _cms_final_remark,
+    _cms_concurrent_mark,
 
     _old_generation_expanded_on_last_scavenge,
     _old_generation_too_full_to_scavenge,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_interface/gcName.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_INTERFACE_GCNAME_HPP
+#define SHARE_VM_GC_INTERFACE_GCNAME_HPP
+
+#include "utilities/debug.hpp"
+
+enum GCName {
+  ParallelOld,
+  SerialOld,
+  PSMarkSweep,
+  ParallelScavenge,
+  DefNew,
+  ParNew,
+  G1New,
+  ConcurrentMarkSweep,
+  G1Old,
+  GCNameEndSentinel
+};
+
+class GCNameHelper {
+ public:
+  static const char* to_string(GCName name) {
+    switch(name) {
+      case ParallelOld: return "ParallelOld";
+      case SerialOld: return "SerialOld";
+      case PSMarkSweep: return "PSMarkSweep";
+      case ParallelScavenge: return "ParallelScavenge";
+      case DefNew: return "DefNew";
+      case ParNew: return "ParNew";
+      case G1New: return "G1New";
+      case ConcurrentMarkSweep: return "ConcurrentMarkSweep";
+      case G1Old: return "G1Old";
+      default: ShouldNotReachHere(); return NULL;
+    }
+  }
+};
+
+#endif // SHARE_VM_GC_INTERFACE_GCNAME_HPP
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -468,7 +468,25 @@
 
 #ifdef ASSERT
   if (istate->_msg != initialize) {
-    assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
+    // We have a problem here if we are running with a pre-hsx24 JDK (for example during bootstrap)
+    // because in that case, EnableInvokeDynamic is true by default but will be later switched off
+    // if java_lang_invoke_MethodHandle::compute_offsets() detects that the JDK only has the classes
+    // for the old JSR292 implementation.
+    // This leads to a situation where 'istate->_stack_limit' always accounts for
+    // methodOopDesc::extra_stack_entries() because it is computed in
+    // CppInterpreterGenerator::generate_compute_interpreter_state() which was generated while
+    // EnableInvokeDynamic was still true. On the other hand, istate->_method->max_stack() doesn't
+    // account for extra_stack_entries() anymore because at the time when it is called
+    // EnableInvokeDynamic was already set to false.
+    // So we have a second version of the assertion which handles the case where EnableInvokeDynamic was
+    // switched off because of the wrong classes.
+    if (EnableInvokeDynamic || FLAG_IS_CMDLINE(EnableInvokeDynamic)) {
+      assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
+    } else {
+      const int extra_stack_entries = Method::extra_stack_entries_for_indy;
+      assert(labs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + extra_stack_entries
+                                                                                               + 1), "bad stack limit");
+    }
 #ifndef SHARK
     IA32_ONLY(assert(istate->_stack_limit == istate->_thread->last_Java_sp() + 1, "wrong"));
 #endif // !SHARK
--- a/src/share/vm/memory/allocation.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/allocation.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -60,10 +60,11 @@
 void  _ValueObj::operator delete [](void* p)    { ShouldNotCallThis(); }
 
 void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
-                                size_t word_size, bool read_only, TRAPS) {
+                                 size_t word_size, bool read_only,
+                                 MetaspaceObj::Type type, TRAPS) {
   // Klass has it's own operator new
   return Metaspace::allocate(loader_data, word_size, read_only,
-                             Metaspace::NonClassType, CHECK_NULL);
+                             type, CHECK_NULL);
 }
 
 bool MetaspaceObj::is_shared() const {
--- a/src/share/vm/memory/allocation.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/allocation.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -157,7 +157,8 @@
   mtJavaHeap          = 0x0C00,  // Java heap
   mtClassShared       = 0x0D00,  // class data sharing
   mtTest              = 0x0E00,  // Test type for verifying NMT
-  mt_number_of_types  = 0x000E,  // number of memory types (mtDontTrack
+  mtTracing           = 0x0F00,  // memory used for Tracing
+  mt_number_of_types  = 0x000F,  // number of memory types (mtDontTrack
                                  // is not included as validate type)
   mtDontTrack         = 0x0F00,  // memory we do not or cannot track
   mt_masks            = 0x7F00,
@@ -268,8 +269,55 @@
   bool is_shared() const;
   void print_address_on(outputStream* st) const;  // nonvirtual address printing
 
+#define METASPACE_OBJ_TYPES_DO(f) \
+  f(Unknown) \
+  f(Class) \
+  f(Symbol) \
+  f(TypeArrayU1) \
+  f(TypeArrayU2) \
+  f(TypeArrayU4) \
+  f(TypeArrayU8) \
+  f(TypeArrayOther) \
+  f(Method) \
+  f(ConstMethod) \
+  f(MethodData) \
+  f(ConstantPool) \
+  f(ConstantPoolCache) \
+  f(Annotation) \
+  f(MethodCounters)
+
+#define METASPACE_OBJ_TYPE_DECLARE(name) name ## Type,
+#define METASPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
+
+  enum Type {
+    // Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
+    METASPACE_OBJ_TYPES_DO(METASPACE_OBJ_TYPE_DECLARE)
+    _number_of_types
+  };
+
+  static const char * type_name(Type type) {
+    switch(type) {
+    METASPACE_OBJ_TYPES_DO(METASPACE_OBJ_TYPE_NAME_CASE)
+    default:
+      ShouldNotReachHere();
+      return NULL;
+    }
+  }
+
+  static MetaspaceObj::Type array_type(size_t elem_size) {
+    switch (elem_size) {
+    case 1: return TypeArrayU1Type;
+    case 2: return TypeArrayU2Type;
+    case 4: return TypeArrayU4Type;
+    case 8: return TypeArrayU8Type;
+    default:
+      return TypeArrayOtherType;
+    }
+  }
+
   void* operator new(size_t size, ClassLoaderData* loader_data,
-                     size_t word_size, bool read_only, Thread* thread);
+                     size_t word_size, bool read_only,
+                     Type type, Thread* thread);
                      // can't use TRAPS from this header file.
   void operator delete(void* p) { ShouldNotCallThis(); }
 };
--- a/src/share/vm/memory/defNewGeneration.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/defNewGeneration.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,10 @@
 #include "precompiled.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
 #include "gc_implementation/shared/gcPolicyCounters.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "memory/defNewGeneration.inline.hpp"
 #include "memory/gcLocker.inline.hpp"
@@ -223,6 +227,8 @@
   _next_gen = NULL;
   _tenuring_threshold = MaxTenuringThreshold;
   _pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize;
+
+  _gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
 }
 
 void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size,
@@ -558,12 +564,18 @@
                                size_t size,
                                bool   is_tlab) {
   assert(full || size > 0, "otherwise we don't want to collect");
+
   GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+  _gc_timer->register_gc_start(os::elapsed_counter());
+  DefNewTracer gc_tracer;
+  gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
+
   _next_gen = gch->next_gen(this);
   assert(_next_gen != NULL,
     "This must be the youngest gen, and not the only gen");
 
-  // If the next generation is too full to accomodate promotion
+  // If the next generation is too full to accommodate promotion
   // from this generation, pass on collection; let the next generation
   // do it.
   if (!collection_attempt_is_safe()) {
@@ -577,10 +589,12 @@
 
   init_assuming_no_promotion_failure();
 
-  TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
+  GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
   // Capture heap used before collection (for printing).
   size_t gch_prev_used = gch->used();
 
+  gch->trace_heap_before_gc(&gc_tracer);
+
   SpecializationStats::clear();
 
   // These can be shared for all code paths
@@ -631,9 +645,12 @@
   FastKeepAliveClosure keep_alive(this, &scan_weak_ref);
   ReferenceProcessor* rp = ref_processor();
   rp->setup_policy(clear_all_soft_refs);
+  const ReferenceProcessorStats& stats =
   rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers,
-                                    NULL);
-  if (!promotion_failed()) {
+                                    NULL, _gc_timer);
+  gc_tracer.report_gc_reference_stats(stats);
+
+  if (!_promotion_failed) {
     // Swap the survivor spaces.
     eden()->clear(SpaceDecorator::Mangle);
     from()->clear(SpaceDecorator::Mangle);
@@ -680,6 +697,7 @@
 
     // Inform the next generation that a promotion failure occurred.
     _next_gen->promotion_failure_occurred();
+    gc_tracer.report_promotion_failed(_promotion_failed_info);
 
     // Reset the PromotionFailureALot counters.
     NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
@@ -689,11 +707,18 @@
   to()->set_concurrent_iteration_safe_limit(to()->top());
   SpecializationStats::print();
 
-  // We need to use a monotonically non-deccreasing time in ms
+  // We need to use a monotonically non-decreasing time in ms
   // or we will see time-warp warnings and os::javaTimeMillis()
   // does not guarantee monotonicity.
   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   update_time_of_last_gc(now);
+
+  gch->trace_heap_after_gc(&gc_tracer);
+  gc_tracer.report_tenuring_threshold(tenuring_threshold());
+
+  _gc_timer->register_gc_end(os::elapsed_counter());
+
+  gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
 }
 
 class RemoveForwardPointerClosure: public ObjectClosure {
@@ -705,6 +730,7 @@
 
 void DefNewGeneration::init_assuming_no_promotion_failure() {
   _promotion_failed = false;
+  _promotion_failed_info.reset();
   from()->set_next_compaction_space(NULL);
 }
 
@@ -726,7 +752,7 @@
 }
 
 void DefNewGeneration::preserve_mark(oop obj, markOop m) {
-  assert(promotion_failed() && m->must_be_preserved_for_promotion_failure(obj),
+  assert(_promotion_failed && m->must_be_preserved_for_promotion_failure(obj),
          "Oversaving!");
   _objs_with_preserved_marks.push(obj);
   _preserved_marks_of_objs.push(m);
@@ -744,6 +770,7 @@
                         old->size());
   }
   _promotion_failed = true;
+  _promotion_failed_info.register_copy_failure(old->size());
   preserve_mark_if_necessary(old, old->mark());
   // forward to self
   old->forward_to(old);
@@ -962,6 +989,10 @@
   from()->set_top_for_allocations();
 }
 
+void DefNewGeneration::ref_processor_init() {
+  Generation::ref_processor_init();
+}
+
 
 void DefNewGeneration::update_counters() {
   if (UsePerfData) {
--- a/src/share/vm/memory/defNewGeneration.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/defNewGeneration.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,14 @@
 #include "gc_implementation/shared/ageTable.hpp"
 #include "gc_implementation/shared/cSpaceCounters.hpp"
 #include "gc_implementation/shared/generationCounters.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "memory/generation.inline.hpp"
 #include "utilities/stack.hpp"
 
 class EdenSpace;
 class ContiguousSpace;
 class ScanClosure;
+class STWGCTimer;
 
 // DefNewGeneration is a young generation containing eden, from- and
 // to-space.
@@ -46,15 +48,17 @@
   uint        _tenuring_threshold;   // Tenuring threshold for next collection.
   ageTable    _age_table;
   // Size of object to pretenure in words; command line provides bytes
-  size_t        _pretenure_size_threshold_words;
+  size_t      _pretenure_size_threshold_words;
 
   ageTable*   age_table() { return &_age_table; }
+
   // Initialize state to optimistically assume no promotion failure will
   // happen.
   void   init_assuming_no_promotion_failure();
   // True iff a promotion has failed in the current collection.
   bool   _promotion_failed;
   bool   promotion_failed() { return _promotion_failed; }
+  PromotionFailedInfo _promotion_failed_info;
 
   // Handling promotion failure.  A young generation collection
   // can fail if a live object cannot be copied out of its
@@ -132,6 +136,8 @@
   ContiguousSpace* _from_space;
   ContiguousSpace* _to_space;
 
+  STWGCTimer* _gc_timer;
+
   enum SomeProtectedConstants {
     // Generations are GenGrain-aligned and have size that are multiples of
     // GenGrain.
@@ -203,6 +209,8 @@
   DefNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level,
                    const char* policy="Copy");
 
+  virtual void ref_processor_init();
+
   virtual Generation::Name kind() { return Generation::DefNew; }
 
   // Accessing spaces
--- a/src/share/vm/memory/genCollectedHeap.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/genCollectedHeap.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/icBuffer.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/vmGCOperations.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/filemap.hpp"
@@ -388,7 +389,7 @@
     const char* gc_cause_prefix = complete ? "Full GC" : "GC";
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, gclog_or_tty);
+    GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL);
 
     gc_prologue(complete);
     increment_total_collections(complete);
@@ -417,10 +418,11 @@
             // The full_collections increment was missed above.
             increment_total_full_collections();
           }
-          pre_full_gc_dump();    // do any pre full gc dumps
+          pre_full_gc_dump(NULL);    // do any pre full gc dumps
         }
         // Timer for individual generations. Last argument is false: no CR
-        TraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, gclog_or_tty);
+        // FIXME: We should try to start the timing earlier to cover more of the GC pause
+        GCTraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, NULL);
         TraceCollectorStats tcs(_gens[i]->counters());
         TraceMemoryManagerStats tmms(_gens[i]->kind(),gc_cause());
 
@@ -534,7 +536,8 @@
     complete = complete || (max_level_collected == n_gens() - 1);
 
     if (complete) { // We did a "major" collection
-      post_full_gc_dump();   // do any post full gc dumps
+      // FIXME: See comment at pre_full_gc_dump call
+      post_full_gc_dump(NULL);   // do any post full gc dumps
     }
 
     if (PrintGCDetails) {
--- a/src/share/vm/memory/genMarkSweep.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/genMarkSweep.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,10 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/genMarkSweep.hpp"
@@ -65,7 +69,9 @@
   _ref_processor = rp;
   rp->setup_policy(clear_all_softrefs);
 
-  TraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
+  GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
+
+  gch->trace_heap_before_gc(_gc_tracer);
 
   // When collecting the permanent generation Method*s may be moving,
   // so we either have to flush all bcp data or convert it into bci.
@@ -155,6 +161,8 @@
   // does not guarantee monotonicity.
   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   gch->update_time_of_last_gc(now);
+
+  gch->trace_heap_after_gc(_gc_tracer);
 }
 
 void GenMarkSweep::allocate_stacks() {
@@ -192,7 +200,7 @@
 void GenMarkSweep::mark_sweep_phase1(int level,
                                   bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer);
   trace(" 1");
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
@@ -219,8 +227,10 @@
   // Process reference objects found during marking
   {
     ref_processor()->setup_policy(clear_all_softrefs);
-    ref_processor()->process_discovered_references(
-      &is_alive, &keep_alive, &follow_stack_closure, NULL);
+    const ReferenceProcessorStats& stats =
+      ref_processor()->process_discovered_references(
+        &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer);
+    gc_tracer()->report_gc_reference_stats(stats);
   }
 
   // This is the point where the entire marking should have completed.
@@ -240,6 +250,8 @@
 
   // Clean up unreferenced symbols in symbol table.
   SymbolTable::unlink();
+
+  gc_tracer()->report_object_count_after_gc(&is_alive);
 }
 
 
@@ -259,7 +271,7 @@
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer);
   trace("2");
 
   gch->prepare_for_compaction();
@@ -276,7 +288,7 @@
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   // Adjust the pointers to reflect the new locations
-  TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer);
   trace("3");
 
   // Need new claim bits for the pointer adjustment tracing.
@@ -331,7 +343,7 @@
   // to use a higher index (saved from phase2) when verifying perm_gen.
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty);
+  GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer);
   trace("4");
 
   GenCompactClosure blk;
--- a/src/share/vm/memory/generation.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/generation.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,8 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/allocation.inline.hpp"
@@ -624,12 +626,26 @@
                                            bool   clear_all_soft_refs,
                                            size_t size,
                                            bool   is_tlab) {
+  GenCollectedHeap* gch = GenCollectedHeap::heap();
+
   SpecializationStats::clear();
   // Temporarily expand the span of our ref processor, so
   // refs discovery is over the entire heap, not just this generation
   ReferenceProcessorSpanMutator
-    x(ref_processor(), GenCollectedHeap::heap()->reserved_region());
+    x(ref_processor(), gch->reserved_region());
+
+  STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
+  gc_timer->register_gc_start(os::elapsed_counter());
+
+  SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
+  gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
+
   GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs);
+
+  gc_timer->register_gc_end(os::elapsed_counter());
+
+  gc_tracer->report_gc_end(os::elapsed_counter(), gc_timer->time_partitions());
+
   SpecializationStats::print();
 }
 
--- a/src/share/vm/memory/heapInspection.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/heapInspection.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -95,7 +95,7 @@
     }
     elt = elt->next();
   }
-  elt = new KlassInfoEntry(k, list());
+  elt = new (std::nothrow) KlassInfoEntry(k, list());
   // We may be out of space to allocate the new entry.
   if (elt != NULL) {
     set_list(elt);
@@ -127,13 +127,15 @@
   _table->lookup(k);
 }
 
-KlassInfoTable::KlassInfoTable(int size, HeapWord* ref,
-                               bool need_class_stats) {
+KlassInfoTable::KlassInfoTable(bool need_class_stats) {
+  _size_of_instances_in_words = 0;
   _size = 0;
-  _ref = ref;
-  _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);
+  _ref = (HeapWord*) Universe::boolArrayKlassObj();
+  _buckets =
+    (KlassInfoBucket*)  AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets,
+                                            mtInternal, 0, AllocFailStrategy::RETURN_NULL);
   if (_buckets != NULL) {
-    _size = size;
+    _size = _num_buckets;
     for (int index = 0; index < _size; index++) {
       _buckets[index].initialize();
     }
@@ -179,6 +181,7 @@
   if (elt != NULL) {
     elt->set_count(elt->count() + 1);
     elt->set_words(elt->words() + obj->size());
+    _size_of_instances_in_words += obj->size();
     return true;
   } else {
     return false;
@@ -192,14 +195,18 @@
   }
 }
 
+size_t KlassInfoTable::size_of_instances_in_words() const {
+  return _size_of_instances_in_words;
+}
+
 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
   return (*e1)->compare(*e1,*e2);
 }
 
-KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) :
+KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title) :
   _cit(cit),
   _title(title) {
-  _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
+  _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(_histo_initial_size, true);
 }
 
 KlassInfoHisto::~KlassInfoHisto() {
@@ -444,25 +451,37 @@
  private:
   KlassInfoTable* _cit;
   size_t _missed_count;
+  BoolObjectClosure* _filter;
  public:
-  RecordInstanceClosure(KlassInfoTable* cit) :
-    _cit(cit), _missed_count(0) {}
+  RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
+    _cit(cit), _missed_count(0), _filter(filter) {}
 
   void do_object(oop obj) {
-    if (!_cit->record_instance(obj)) {
-      _missed_count++;
+    if (should_visit(obj)) {
+      if (!_cit->record_instance(obj)) {
+        _missed_count++;
+      }
     }
   }
 
   size_t missed_count() { return _missed_count; }
+
+ private:
+  bool should_visit(oop obj) {
+    return _filter == NULL || _filter->do_object_b(obj);
+  }
 };
 
-void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
+size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter) {
   ResourceMark rm;
-  // Get some random number for ref (the hash key)
-  HeapWord* ref = (HeapWord*) Universe::boolArrayKlassObj();
-  CollectedHeap* heap = Universe::heap();
-  bool is_shared_heap = false;
+
+  RecordInstanceClosure ric(cit, filter);
+  Universe::heap()->object_iterate(&ric);
+  return ric.missed_count();
+}
+
+void HeapInspection::heap_inspection(outputStream* st) {
+  ResourceMark rm;
 
   if (_print_help) {
     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
@@ -482,39 +501,30 @@
     return;
   }
 
-  // Collect klass instance info
-  KlassInfoTable cit(KlassInfoTable::cit_size, ref, _print_class_stats);
+  KlassInfoTable cit(_print_class_stats);
   if (!cit.allocation_failed()) {
-    // Iterate over objects in the heap
-    RecordInstanceClosure ric(&cit);
-    Universe::heap()->object_iterate(&ric);
-
-    // Report if certain classes are not counted because of
-    // running out of C-heap for the histogram.
-    size_t missed_count = ric.missed_count();
+    size_t missed_count = populate_table(&cit);
     if (missed_count != 0) {
       st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
                    " total instances in data below",
                    missed_count);
     }
+
     // Sort and print klass instance info
     const char *title = "\n"
               " num     #instances         #bytes  class name\n"
               "----------------------------------------------";
-    KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size);
+    KlassInfoHisto histo(&cit, title);
     HistoClosure hc(&histo);
+
     cit.iterate(&hc);
+
     histo.sort();
     histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
   } else {
     st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
   }
   st->flush();
-
-  if (need_prologue && is_shared_heap) {
-    SharedHeap* sh = (SharedHeap*)heap;
-    sh->gc_epilogue(false /* !full */); // release all acquired locks, etc.
-  }
 }
 
 class FindInstanceClosure : public ObjectClosure {
--- a/src/share/vm/memory/heapInspection.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/heapInspection.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -26,6 +26,7 @@
 #define SHARE_VM_MEMORY_HEAPINSPECTION_HPP
 
 #include "memory/allocation.inline.hpp"
+#include "memory/klassInfoClosure.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/annotations.hpp"
 #include "utilities/macros.hpp"
@@ -203,12 +204,6 @@
   const char* name() const;
 };
 
-class KlassInfoClosure: public StackObj {
- public:
-  // Called for each KlassInfoEntry.
-  virtual void do_cinfo(KlassInfoEntry* cie) = 0;
-};
-
 class KlassInfoBucket: public CHeapObj<mtInternal> {
  private:
   KlassInfoEntry* _list;
@@ -224,6 +219,8 @@
 class KlassInfoTable: public StackObj {
  private:
   int _size;
+  static const int _num_buckets = 20011;
+  size_t _size_of_instances_in_words;
 
   // An aligned reference address (typically the least
   // address in the perm gen) used for hashing klass
@@ -242,21 +239,19 @@
   };
 
  public:
-  // Table size
-  enum {
-    cit_size = 20011
-  };
-  KlassInfoTable(int size, HeapWord* ref, bool need_class_stats);
+  KlassInfoTable(bool need_class_stats);
   ~KlassInfoTable();
   bool record_instance(const oop obj);
   void iterate(KlassInfoClosure* cic);
   bool allocation_failed() { return _buckets == NULL; }
+  size_t size_of_instances_in_words() const;
 
   friend class KlassInfoHisto;
 };
 
 class KlassInfoHisto : public StackObj {
  private:
+  static const int _histo_initial_size = 1000;
   KlassInfoTable *_cit;
   GrowableArray<KlassInfoEntry*>* _elements;
   GrowableArray<KlassInfoEntry*>* elements() const { return _elements; }
@@ -334,11 +329,7 @@
   }
 
  public:
-  enum {
-    histo_initial_size = 1000
-  };
-  KlassInfoHisto(KlassInfoTable* cit, const char* title,
-             int estimatedCount);
+  KlassInfoHisto(KlassInfoTable* cit, const char* title);
   ~KlassInfoHisto();
   void add(KlassInfoEntry* cie);
   void print_histo_on(outputStream* st, bool print_class_stats, bool csv_format, const char *columns);
@@ -347,6 +338,11 @@
 
 #endif // INCLUDE_SERVICES
 
+// These declarations are needed since teh declaration of KlassInfoTable and
+// KlassInfoClosure are guarded by #if INLCUDE_SERVICES
+class KlassInfoTable;
+class KlassInfoClosure;
+
 class HeapInspection : public StackObj {
   bool _csv_format; // "comma separated values" format for spreadsheet.
   bool _print_help;
@@ -357,8 +353,11 @@
                  bool print_class_stats, const char *columns) :
       _csv_format(csv_format), _print_help(print_help),
       _print_class_stats(print_class_stats), _columns(columns) {}
-  void heap_inspection(outputStream* st, bool need_prologue) NOT_SERVICES_RETURN;
+  void heap_inspection(outputStream* st) NOT_SERVICES_RETURN;
+  size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL) NOT_SERVICES_RETURN;
   static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN;
+ private:
+  void iterate_over_heap(KlassInfoTable* cit, BoolObjectClosure* filter = NULL);
 };
 
 #endif // SHARE_VM_MEMORY_HEAPINSPECTION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/memory/klassInfoClosure.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
+#define SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
+
+class KlassInfoEntry;
+
+class KlassInfoClosure : public StackObj {
+ public:
+  // Called for each KlassInfoEntry.
+  virtual void do_cinfo(KlassInfoEntry* cie) = 0;
+};
+
+#endif // SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
--- a/src/share/vm/memory/metaspace.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/metaspace.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -713,6 +713,23 @@
 #ifdef ASSERT
   void verify_allocated_blocks_words();
 #endif
+
+  size_t get_raw_word_size(size_t word_size) {
+    // If only the dictionary is going to be used (i.e., no
+    // indexed free list), then there is a minimum size requirement.
+    // MinChunkSize is a placeholder for the real minimum size JJJ
+    size_t byte_size = word_size * BytesPerWord;
+
+    size_t byte_size_with_overhead = byte_size + Metablock::overhead();
+
+    size_t raw_bytes_size = MAX2(byte_size_with_overhead,
+                                 Metablock::min_block_byte_size());
+    raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
+    size_t raw_word_size = raw_bytes_size / BytesPerWord;
+    assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
+
+    return raw_word_size;
+  }
 };
 
 uint const SpaceManager::_small_chunk_limit = 4;
@@ -2320,19 +2337,7 @@
 MetaWord* SpaceManager::allocate(size_t word_size) {
   MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
 
-  // If only the dictionary is going to be used (i.e., no
-  // indexed free list), then there is a minimum size requirement.
-  // MinChunkSize is a placeholder for the real minimum size JJJ
-  size_t byte_size = word_size * BytesPerWord;
-
-  size_t byte_size_with_overhead = byte_size + Metablock::overhead();
-
-  size_t raw_bytes_size = MAX2(byte_size_with_overhead,
-                               Metablock::min_block_byte_size());
-  raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
-  size_t raw_word_size = raw_bytes_size / BytesPerWord;
-  assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
-
+  size_t raw_word_size = get_raw_word_size(word_size);
   BlockFreelist* fl =  block_freelists();
   MetaWord* p = NULL;
   // Allocation from the dictionary is expensive in the sense that
@@ -2896,6 +2901,9 @@
   if (class_chunk != NULL) {
     class_vsm()->add_chunk(class_chunk, true);
   }
+
+  _alloc_record_head = NULL;
+  _alloc_record_tail = NULL;
 }
 
 size_t Metaspace::align_word_size_up(size_t word_size) {
@@ -3000,12 +3008,14 @@
 }
 
 Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
-                              bool read_only, MetadataType mdtype, TRAPS) {
+                              bool read_only, MetaspaceObj::Type type, TRAPS) {
   if (HAS_PENDING_EXCEPTION) {
     assert(false, "Should not allocate with exception pending");
     return NULL;  // caller does a CHECK_NULL too
   }
 
+  MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
+
   // SSS: Should we align the allocations and make sure the sizes are aligned.
   MetaWord* result = NULL;
 
@@ -3015,13 +3025,13 @@
   // with the SymbolTable_lock.  Dumping is single threaded for now.  We'll have
   // to revisit this for application class data sharing.
   if (DumpSharedSpaces) {
-    if (read_only) {
-      result = loader_data->ro_metaspace()->allocate(word_size, NonClassType);
-    } else {
-      result = loader_data->rw_metaspace()->allocate(word_size, NonClassType);
-    }
+    assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity");
+    Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace();
+    result = space->allocate(word_size, NonClassType);
     if (result == NULL) {
       report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
+    } else {
+      space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
     }
     return Metablock::initialize(result, word_size);
   }
@@ -3056,6 +3066,38 @@
   return Metablock::initialize(result, word_size);
 }
 
+void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
+  assert(DumpSharedSpaces, "sanity");
+
+  AllocRecord *rec = new AllocRecord((address)ptr, type, (int)word_size * HeapWordSize);
+  if (_alloc_record_head == NULL) {
+    _alloc_record_head = _alloc_record_tail = rec;
+  } else {
+    _alloc_record_tail->_next = rec;
+    _alloc_record_tail = rec;
+  }
+}
+
+void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
+  assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces");
+
+  address last_addr = (address)bottom();
+
+  for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
+    address ptr = rec->_ptr;
+    if (last_addr < ptr) {
+      closure->doit(last_addr, MetaspaceObj::UnknownType, ptr - last_addr);
+    }
+    closure->doit(ptr, rec->_type, rec->_byte_size);
+    last_addr = ptr + rec->_byte_size;
+  }
+
+  address top = ((address)bottom()) + used_bytes_slow(Metaspace::NonClassType);
+  if (last_addr < top) {
+    closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr);
+  }
+}
+
 void Metaspace::purge() {
   MutexLockerEx cl(SpaceManager::expand_lock(),
                    Mutex::_no_safepoint_check_flag);
--- a/src/share/vm/memory/metaspace.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/metaspace.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,6 +127,23 @@
   static VirtualSpaceList* space_list()       { return _space_list; }
   static VirtualSpaceList* class_space_list() { return _class_space_list; }
 
+  // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
+  // maintain a single list for now.
+  void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
+
+  class AllocRecord : public CHeapObj<mtClass> {
+  public:
+    AllocRecord(address ptr, MetaspaceObj::Type type, int byte_size)
+      : _next(NULL), _ptr(ptr), _type(type), _byte_size(byte_size) {}
+    AllocRecord *_next;
+    address _ptr;
+    MetaspaceObj::Type _type;
+    int _byte_size;
+  };
+
+  AllocRecord * _alloc_record_head;
+  AllocRecord * _alloc_record_tail;
+
  public:
 
   Metaspace(Mutex* lock, MetaspaceType type);
@@ -148,8 +165,8 @@
   size_t used_bytes_slow(MetadataType mdtype) const;
   size_t capacity_bytes_slow(MetadataType mdtype) const;
 
-  static Metablock* allocate(ClassLoaderData* loader_data, size_t size,
-                            bool read_only, MetadataType mdtype, TRAPS);
+  static Metablock* allocate(ClassLoaderData* loader_data, size_t word_size,
+                             bool read_only, MetaspaceObj::Type type, TRAPS);
   void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
 
   MetaWord* expand_and_allocate(size_t size,
@@ -166,10 +183,20 @@
   void print_on(outputStream* st) const;
   // Debugging support
   void verify();
+
+  class AllocRecordClosure :  public StackObj {
+  public:
+    virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0;
+  };
+
+  void iterate(AllocRecordClosure *closure);
 };
 
 class MetaspaceAux : AllStatic {
+  static size_t free_chunks_total(Metaspace::MetadataType mdtype);
+  static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
 
+ public:
   // Statistics for class space and data space in metaspace.
 
   // These methods iterate over the classloader data graph
@@ -181,10 +208,6 @@
   // Iterates over the virtual space list.
   static size_t reserved_in_bytes(Metaspace::MetadataType mdtype);
 
-  static size_t free_chunks_total(Metaspace::MetadataType mdtype);
-  static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
-
- public:
   // Running sum of space in all Metachunks that has been
   // allocated to a Metaspace.  This is used instead of
   // iterating over all the classloaders. One for each
--- a/src/share/vm/memory/metaspaceShared.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/metaspaceShared.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -243,6 +243,147 @@
   bool reading() const { return false; }
 };
 
+// This is for dumping detailed statistics for the allocations
+// in the shared spaces.
+class DumpAllocClosure : public Metaspace::AllocRecordClosure {
+public:
+
+  // Here's poor man's enum inheritance
+#define SHAREDSPACE_OBJ_TYPES_DO(f) \
+  METASPACE_OBJ_TYPES_DO(f) \
+  f(SymbolHashentry) \
+  f(SymbolBuckets) \
+  f(Other)
+
+#define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type,
+#define SHAREDSPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
+
+  enum Type {
+    // Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
+    SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_DECLARE)
+    _number_of_types
+  };
+
+  static const char * type_name(Type type) {
+    switch(type) {
+    SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_NAME_CASE)
+    default:
+      ShouldNotReachHere();
+      return NULL;
+    }
+  }
+
+public:
+  enum {
+    RO = 0,
+    RW = 1
+  };
+
+  int _counts[2][_number_of_types];
+  int _bytes [2][_number_of_types];
+  int _which;
+
+  DumpAllocClosure() {
+    memset(_counts, 0, sizeof(_counts));
+    memset(_bytes,  0, sizeof(_bytes));
+  };
+
+  void iterate_metaspace(Metaspace* space, int which) {
+    assert(which == RO || which == RW, "sanity");
+    _which = which;
+    space->iterate(this);
+  }
+
+  virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) {
+    assert(int(type) >= 0 && type < MetaspaceObj::_number_of_types, "sanity");
+    _counts[_which][type] ++;
+    _bytes [_which][type] += byte_size;
+  }
+
+  void dump_stats(int ro_all, int rw_all, int md_all, int mc_all);
+};
+
+void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all) {
+  rw_all += (md_all + mc_all); // md and mc are all mapped Read/Write
+  int other_bytes = md_all + mc_all;
+
+  // Calculate size of data that was not allocated by Metaspace::allocate()
+  int symbol_count = _counts[RO][MetaspaceObj::SymbolType];
+  int symhash_bytes = symbol_count * sizeof (HashtableEntry<Symbol*, mtSymbol>);
+  int symbuck_count = SymbolTable::the_table()->table_size();
+  int symbuck_bytes = symbuck_count * sizeof(HashtableBucket<mtSymbol>);
+
+  _counts[RW][SymbolHashentryType] = symbol_count;
+  _bytes [RW][SymbolHashentryType] = symhash_bytes;
+  other_bytes -= symhash_bytes;
+
+  _counts[RW][SymbolBucketsType] = symbuck_count;
+  _bytes [RW][SymbolBucketsType] = symbuck_bytes;
+  other_bytes -= symbuck_bytes;
+
+  // TODO: count things like dictionary, vtable, etc
+  _bytes[RW][OtherType] =  other_bytes;
+
+  // prevent divide-by-zero
+  if (ro_all < 1) {
+    ro_all = 1;
+  }
+  if (rw_all < 1) {
+    rw_all = 1;
+  }
+
+  int all_ro_count = 0;
+  int all_ro_bytes = 0;
+  int all_rw_count = 0;
+  int all_rw_bytes = 0;
+
+  const char *fmt = "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f";
+  const char *sep = "--------------------+---------------------------+---------------------------+--------------------------";
+  const char *hdr = "                        ro_cnt   ro_bytes     % |   rw_cnt   rw_bytes     % |  all_cnt  all_bytes     %";
+
+  tty->print_cr("Detailed metadata info (rw includes md and mc):");
+  tty->print_cr(hdr);
+  tty->print_cr(sep);
+  for (int type = 0; type < int(_number_of_types); type ++) {
+    const char *name = type_name((Type)type);
+    int ro_count = _counts[RO][type];
+    int ro_bytes = _bytes [RO][type];
+    int rw_count = _counts[RW][type];
+    int rw_bytes = _bytes [RW][type];
+    int count = ro_count + rw_count;
+    int bytes = ro_bytes + rw_bytes;
+
+    double ro_perc = 100.0 * double(ro_bytes) / double(ro_all);
+    double rw_perc = 100.0 * double(rw_bytes) / double(rw_all);
+    double perc    = 100.0 * double(bytes)    / double(ro_all + rw_all);
+
+    tty->print_cr(fmt, name,
+                  ro_count, ro_bytes, ro_perc,
+                  rw_count, rw_bytes, rw_perc,
+                  count, bytes, perc);
+
+    all_ro_count += ro_count;
+    all_ro_bytes += ro_bytes;
+    all_rw_count += rw_count;
+    all_rw_bytes += rw_bytes;
+  }
+
+  int all_count = all_ro_count + all_rw_count;
+  int all_bytes = all_ro_bytes + all_rw_bytes;
+
+  double all_ro_perc = 100.0 * double(all_ro_bytes) / double(ro_all);
+  double all_rw_perc = 100.0 * double(all_rw_bytes) / double(rw_all);
+  double all_perc    = 100.0 * double(all_bytes)    / double(ro_all + rw_all);
+
+  tty->print_cr(sep);
+  tty->print_cr(fmt, "Total",
+                all_ro_count, all_ro_bytes, all_ro_perc,
+                all_rw_count, all_rw_bytes, all_rw_perc,
+                all_count, all_bytes, all_perc);
+
+  assert(all_ro_bytes == ro_all, "everything should have been counted");
+  assert(all_rw_bytes == rw_all, "everything should have been counted");
+}
 
 // Populate the shared space.
 
@@ -454,6 +595,14 @@
   mapinfo->close();
 
   memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
+
+  if (PrintSharedSpaces) {
+    DumpAllocClosure dac;
+    dac.iterate_metaspace(_loader_data->ro_metaspace(), DumpAllocClosure::RO);
+    dac.iterate_metaspace(_loader_data->rw_metaspace(), DumpAllocClosure::RW);
+
+    dac.dump_stats(int(ro_bytes), int(rw_bytes), int(md_bytes), int(mc_bytes));
+  }
 }
 
 static void link_shared_classes(Klass* obj, TRAPS) {
--- a/src/share/vm/memory/oopFactory.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/oopFactory.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "memory/referenceType.hpp"
 #include "memory/universe.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.hpp"
--- a/src/share/vm/memory/referenceProcessor.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/referenceProcessor.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 #include "precompiled.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/referencePolicy.hpp"
@@ -180,11 +182,20 @@
   // past clock value.
 }
 
-void ReferenceProcessor::process_discovered_references(
+size_t ReferenceProcessor::total_count(DiscoveredList lists[]) {
+  size_t total = 0;
+  for (uint i = 0; i < _max_num_q; ++i) {
+    total += lists[i].length();
+  }
+  return total;
+}
+
+ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
   BoolObjectClosure*           is_alive,
   OopClosure*                  keep_alive,
   VoidClosure*                 complete_gc,
-  AbstractRefProcTaskExecutor* task_executor) {
+  AbstractRefProcTaskExecutor* task_executor,
+  GCTimer*                     gc_timer) {
   NOT_PRODUCT(verify_ok_to_handle_reflists());
 
   assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
@@ -202,34 +213,43 @@
   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
 
   bool trace_time = PrintGCDetails && PrintReferenceGC;
+
   // Soft references
+  size_t soft_count = 0;
   {
-    TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);
-    process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
-                               is_alive, keep_alive, complete_gc, task_executor);
+    GCTraceTime tt("SoftReference", trace_time, false, gc_timer);
+    soft_count =
+      process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
+                                 is_alive, keep_alive, complete_gc, task_executor);
   }
 
   update_soft_ref_master_clock();
 
   // Weak references
+  size_t weak_count = 0;
   {
-    TraceTime tt("WeakReference", trace_time, false, gclog_or_tty);
-    process_discovered_reflist(_discoveredWeakRefs, NULL, true,
-                               is_alive, keep_alive, complete_gc, task_executor);
+    GCTraceTime tt("WeakReference", trace_time, false, gc_timer);
+    weak_count =
+      process_discovered_reflist(_discoveredWeakRefs, NULL, true,
+                                 is_alive, keep_alive, complete_gc, task_executor);
   }
 
   // Final references
+  size_t final_count = 0;
   {
-    TraceTime tt("FinalReference", trace_time, false, gclog_or_tty);
-    process_discovered_reflist(_discoveredFinalRefs, NULL, false,
-                               is_alive, keep_alive, complete_gc, task_executor);
+    GCTraceTime tt("FinalReference", trace_time, false, gc_timer);
+    final_count =
+      process_discovered_reflist(_discoveredFinalRefs, NULL, false,
+                                 is_alive, keep_alive, complete_gc, task_executor);
   }
 
   // Phantom references
+  size_t phantom_count = 0;
   {
-    TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty);
-    process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
-                               is_alive, keep_alive, complete_gc, task_executor);
+    GCTraceTime tt("PhantomReference", trace_time, false, gc_timer);
+    phantom_count =
+      process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
+                                 is_alive, keep_alive, complete_gc, task_executor);
   }
 
   // Weak global JNI references. It would make more sense (semantically) to
@@ -238,12 +258,14 @@
   // thus use JNI weak references to circumvent the phantom references and
   // resurrect a "post-mortem" object.
   {
-    TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty);
+    GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
     if (task_executor != NULL) {
       task_executor->set_single_threaded_mode();
     }
     process_phaseJNI(is_alive, keep_alive, complete_gc);
   }
+
+  return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count);
 }
 
 #ifndef PRODUCT
@@ -878,7 +900,7 @@
   balance_queues(_discoveredPhantomRefs);
 }
 
-void
+size_t
 ReferenceProcessor::process_discovered_reflist(
   DiscoveredList               refs_lists[],
   ReferencePolicy*             policy,
@@ -901,12 +923,11 @@
       must_balance) {
     balance_queues(refs_lists);
   }
+
+  size_t total_list_count = total_count(refs_lists);
+
   if (PrintReferenceGC && PrintGCDetails) {
-    size_t total = 0;
-    for (uint i = 0; i < _max_num_q; ++i) {
-      total += refs_lists[i].length();
-    }
-    gclog_or_tty->print(", %u refs", total);
+    gclog_or_tty->print(", %u refs", total_list_count);
   }
 
   // Phase 1 (soft refs only):
@@ -951,6 +972,8 @@
                      is_alive, keep_alive, complete_gc);
     }
   }
+
+  return total_list_count;
 }
 
 void ReferenceProcessor::clean_up_discovered_references() {
@@ -1266,14 +1289,15 @@
   BoolObjectClosure* is_alive,
   OopClosure* keep_alive,
   VoidClosure* complete_gc,
-  YieldClosure* yield) {
+  YieldClosure* yield,
+  GCTimer* gc_timer) {
 
   NOT_PRODUCT(verify_ok_to_handle_reflists());
 
   // Soft references
   {
-    TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
-              false, gclog_or_tty);
+    GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1285,8 +1309,8 @@
 
   // Weak references
   {
-    TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
-              false, gclog_or_tty);
+    GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1298,8 +1322,8 @@
 
   // Final references
   {
-    TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
-              false, gclog_or_tty);
+    GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1311,8 +1335,8 @@
 
   // Phantom references
   {
-    TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
-              false, gclog_or_tty);
+    GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
--- a/src/share/vm/memory/referenceProcessor.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/referenceProcessor.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,12 @@
 #define SHARE_VM_MEMORY_REFERENCEPROCESSOR_HPP
 
 #include "memory/referencePolicy.hpp"
+#include "memory/referenceProcessorStats.hpp"
+#include "memory/referenceType.hpp"
 #include "oops/instanceRefKlass.hpp"
 
+class GCTimer;
+
 // ReferenceProcessor class encapsulates the per-"collector" processing
 // of java.lang.Reference objects for GC. The interface is useful for supporting
 // a generational abstraction, in particular when there are multiple
@@ -204,6 +208,10 @@
 };
 
 class ReferenceProcessor : public CHeapObj<mtGC> {
+
+ private:
+  size_t total_count(DiscoveredList lists[]);
+
  protected:
   // Compatibility with pre-4965777 JDK's
   static bool _pending_list_uses_discovered_field;
@@ -282,13 +290,13 @@
   }
 
   // Process references with a certain reachability level.
-  void process_discovered_reflist(DiscoveredList               refs_lists[],
-                                  ReferencePolicy*             policy,
-                                  bool                         clear_referent,
-                                  BoolObjectClosure*           is_alive,
-                                  OopClosure*                  keep_alive,
-                                  VoidClosure*                 complete_gc,
-                                  AbstractRefProcTaskExecutor* task_executor);
+  size_t process_discovered_reflist(DiscoveredList               refs_lists[],
+                                    ReferencePolicy*             policy,
+                                    bool                         clear_referent,
+                                    BoolObjectClosure*           is_alive,
+                                    OopClosure*                  keep_alive,
+                                    VoidClosure*                 complete_gc,
+                                    AbstractRefProcTaskExecutor* task_executor);
 
   void process_phaseJNI(BoolObjectClosure* is_alive,
                         OopClosure*        keep_alive,
@@ -349,7 +357,8 @@
   void preclean_discovered_references(BoolObjectClosure* is_alive,
                                       OopClosure*        keep_alive,
                                       VoidClosure*       complete_gc,
-                                      YieldClosure*      yield);
+                                      YieldClosure*      yield,
+                                      GCTimer*           gc_timer);
 
   // Delete entries in the discovered lists that have
   // either a null referent or are not active. Such
@@ -500,12 +509,13 @@
   bool discover_reference(oop obj, ReferenceType rt);
 
   // Process references found during GC (called by the garbage collector)
-  void process_discovered_references(BoolObjectClosure*           is_alive,
-                                     OopClosure*                  keep_alive,
-                                     VoidClosure*                 complete_gc,
-                                     AbstractRefProcTaskExecutor* task_executor);
+  ReferenceProcessorStats
+  process_discovered_references(BoolObjectClosure*           is_alive,
+                                OopClosure*                  keep_alive,
+                                VoidClosure*                 complete_gc,
+                                AbstractRefProcTaskExecutor* task_executor,
+                                GCTimer *gc_timer);
 
- public:
   // Enqueue references at end of GC (called by the garbage collector)
   bool enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/memory/referenceProcessorStats.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_REFERENCEPROCESSORSTATS_HPP
+#define SHARE_VM_MEMORY_REFERENCEPROCESSORSTATS_HPP
+
+#include "utilities/globalDefinitions.hpp"
+
+class ReferenceProcessor;
+
+// ReferenceProcessorStats contains statistics about how many references that
+// have been traversed when processing references during garbage collection.
+class ReferenceProcessorStats {
+  size_t _soft_count;
+  size_t _weak_count;
+  size_t _final_count;
+  size_t _phantom_count;
+
+ public:
+  ReferenceProcessorStats() :
+    _soft_count(0),
+    _weak_count(0),
+    _final_count(0),
+    _phantom_count(0) {}
+
+  ReferenceProcessorStats(size_t soft_count,
+                          size_t weak_count,
+                          size_t final_count,
+                          size_t phantom_count) :
+    _soft_count(soft_count),
+    _weak_count(weak_count),
+    _final_count(final_count),
+    _phantom_count(phantom_count)
+  {}
+
+  size_t soft_count() const {
+    return _soft_count;
+  }
+
+  size_t weak_count() const {
+    return _weak_count;
+  }
+
+  size_t final_count() const {
+    return _final_count;
+  }
+
+  size_t phantom_count() const {
+    return _phantom_count;
+  }
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/memory/referenceType.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_MEMORY_REFRERENCETYPE_HPP
+#define SHARE_VM_MEMORY_REFRERENCETYPE_HPP
+
+#include "utilities/debug.hpp"
+
+// ReferenceType is used to distinguish between java/lang/ref/Reference subclasses
+
+enum ReferenceType {
+  REF_NONE,      // Regular class
+  REF_OTHER,     // Subclass of java/lang/ref/Reference, but not subclass of one of the classes below
+  REF_SOFT,      // Subclass of java/lang/ref/SoftReference
+  REF_WEAK,      // Subclass of java/lang/ref/WeakReference
+  REF_FINAL,     // Subclass of java/lang/ref/FinalReference
+  REF_PHANTOM    // Subclass of java/lang/ref/PhantomReference
+};
+
+#endif // SHARE_VM_MEMORY_REFRERENCETYPE_HPP
--- a/src/share/vm/memory/sharedHeap.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/sharedHeap.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -45,6 +45,7 @@
   SH_PS_FlatProfiler_oops_do,
   SH_PS_Management_oops_do,
   SH_PS_SystemDictionary_oops_do,
+  SH_PS_ClassLoaderDataGraph_oops_do,
   SH_PS_jvmti_oops_do,
   SH_PS_StringTable_oops_do,
   SH_PS_CodeCache_oops_do,
@@ -173,15 +174,21 @@
   if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
     if (so & SO_AllClasses) {
       SystemDictionary::oops_do(roots);
-      ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
     } else if (so & SO_SystemClasses) {
       SystemDictionary::always_strong_oops_do(roots);
-      ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
     } else {
       fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
     }
   }
 
+  if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) {
+    if (so & SO_AllClasses) {
+      ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
+    } else if (so & SO_SystemClasses) {
+      ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
+    }
+  }
+
   if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
     if (so & SO_Strings) {
       StringTable::oops_do(roots);
--- a/src/share/vm/memory/universe.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/universe.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -228,11 +228,8 @@
 
 void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
   if (size < alignment || size % alignment != 0) {
-    ResourceMark rm;
-    stringStream st;
-    st.print("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment);
-    char* error = st.as_string();
-    vm_exit_during_initialization(error);
+    vm_exit_during_initialization(
+      err_msg("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment));
   }
 }
 
@@ -822,12 +819,14 @@
       // keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
       Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
       if (verbose) {
-        tty->print(", Compressed Oops with base: "PTR_FORMAT, Universe::narrow_oop_base());
+        tty->print(", %s: "PTR_FORMAT,
+            narrow_oop_mode_to_string(HeapBasedNarrowOop),
+            Universe::narrow_oop_base());
       }
     } else {
       Universe::set_narrow_oop_base(0);
       if (verbose) {
-        tty->print(", zero based Compressed Oops");
+        tty->print(", %s", narrow_oop_mode_to_string(ZeroBasedNarrowOop));
       }
 #ifdef _WIN64
       if (!Universe::narrow_oop_use_implicit_null_checks()) {
@@ -842,7 +841,7 @@
       } else {
         Universe::set_narrow_oop_shift(0);
         if (verbose) {
-          tty->print(", 32-bits Oops");
+          tty->print(", %s", narrow_oop_mode_to_string(UnscaledNarrowOop));
         }
       }
     }
@@ -916,7 +915,7 @@
   }
 
   if (!total_rs.is_reserved()) {
-    vm_exit_during_initialization(err_msg("Could not reserve enough space for object heap %d bytes", total_reserved));
+    vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K));
     return total_rs;
   }
 
@@ -949,6 +948,33 @@
 }
 
 
+const char* Universe::narrow_oop_mode_to_string(Universe::NARROW_OOP_MODE mode) {
+  switch (mode) {
+    case UnscaledNarrowOop:
+      return "32-bits Oops";
+    case ZeroBasedNarrowOop:
+      return "zero based Compressed Oops";
+    case HeapBasedNarrowOop:
+      return "Compressed Oops with base";
+  }
+
+  ShouldNotReachHere();
+  return "";
+}
+
+
+Universe::NARROW_OOP_MODE Universe::narrow_oop_mode() {
+  if (narrow_oop_base() != 0) {
+    return HeapBasedNarrowOop;
+  }
+
+  if (narrow_oop_shift() != 0) {
+    return ZeroBasedNarrowOop;
+  }
+
+  return UnscaledNarrowOop;
+}
+
 
 void universe2_init() {
   EXCEPTION_MARK;
--- a/src/share/vm/memory/universe.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/memory/universe.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -253,19 +253,6 @@
     return m;
   }
 
-  // Narrow Oop encoding mode:
-  // 0 - Use 32-bits oops without encoding when
-  //     NarrowOopHeapBaseMin + heap_size < 4Gb
-  // 1 - Use zero based compressed oops with encoding when
-  //     NarrowOopHeapBaseMin + heap_size < 32Gb
-  // 2 - Use compressed oops with heap base + encoding.
-  enum NARROW_OOP_MODE {
-    UnscaledNarrowOop  = 0,
-    ZeroBasedNarrowOop = 1,
-    HeapBasedNarrowOop = 2
-  };
-  static char*    preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode);
-  static char*    preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode);
   static void     set_narrow_oop_base(address base) {
     assert(UseCompressedOops, "no compressed oops?");
     _narrow_oop._base    = base;
@@ -380,6 +367,21 @@
   static CollectedHeap* heap() { return _collectedHeap; }
 
   // For UseCompressedOops
+  // Narrow Oop encoding mode:
+  // 0 - Use 32-bits oops without encoding when
+  //     NarrowOopHeapBaseMin + heap_size < 4Gb
+  // 1 - Use zero based compressed oops with encoding when
+  //     NarrowOopHeapBaseMin + heap_size < 32Gb
+  // 2 - Use compressed oops with heap base + encoding.
+  enum NARROW_OOP_MODE {
+    UnscaledNarrowOop  = 0,
+    ZeroBasedNarrowOop = 1,
+    HeapBasedNarrowOop = 2
+  };
+  static NARROW_OOP_MODE narrow_oop_mode();
+  static const char* narrow_oop_mode_to_string(NARROW_OOP_MODE mode);
+  static char*    preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode);
+  static char*    preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode);
   static address  narrow_oop_base()                       { return  _narrow_oop._base; }
   static bool  is_narrow_oop_base(void* addr)             { return (narrow_oop_base() == (address)addr); }
   static int      narrow_oop_shift()                      { return  _narrow_oop._shift; }
--- a/src/share/vm/oops/annotations.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/annotations.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -33,7 +33,7 @@
 
 // Allocate annotations in metadata area
 Annotations* Annotations::allocate(ClassLoaderData* loader_data, TRAPS) {
-  return new (loader_data, size(), true, THREAD) Annotations();
+  return new (loader_data, size(), true, MetaspaceObj::AnnotationType, THREAD) Annotations();
 }
 
 // helper
--- a/src/share/vm/oops/arrayKlass.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/arrayKlass.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -94,7 +94,7 @@
   ResourceMark rm(THREAD);
   k->initialize_supers(super_klass(), CHECK);
   k->vtable()->initialize_vtable(false, CHECK);
-  java_lang_Class::create_mirror(k, CHECK);
+  java_lang_Class::create_mirror(k, Handle(NULL), CHECK);
 }
 
 GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots) {
--- a/src/share/vm/oops/constMethod.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/constMethod.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -40,7 +40,7 @@
                                    MethodType method_type,
                                    TRAPS) {
   int size = ConstMethod::size(byte_code_size, sizes);
-  return new (loader_data, size, true, THREAD) ConstMethod(
+  return new (loader_data, size, true, MetaspaceObj::ConstMethodType, THREAD) ConstMethod(
       byte_code_size, sizes, method_type, size);
 }
 
--- a/src/share/vm/oops/constantPool.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/constantPool.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -55,7 +55,7 @@
   // the resolved_references array, which is recreated at startup time.
   // But that could be moved to InstanceKlass (although a pain to access from
   // assembly code).  Maybe it could be moved to the cpCache which is RW.
-  return new (loader_data, size, false, THREAD) ConstantPool(tags);
+  return new (loader_data, size, false, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
 }
 
 ConstantPool::ConstantPool(Array<u1>* tags) {
@@ -1063,9 +1063,10 @@
     int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
     int i1 = invoke_dynamic_bootstrap_specifier_index(index1);
     int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2);
-    bool match = compare_entry_to(k1, cp2, k2, CHECK_false) &&
-                 compare_operand_to(i1, cp2, i2, CHECK_false);
-    return match;
+    // separate statements and variables because CHECK_false is used
+    bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false);
+    bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false);
+    return (match_entry && match_operand);
   } break;
 
   case JVM_CONSTANT_String:
--- a/src/share/vm/oops/cpCache.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/cpCache.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -542,7 +542,8 @@
                                      const intStack& invokedynamic_map, TRAPS) {
   int size = ConstantPoolCache::size(length);
 
-  return new (loader_data, size, false, THREAD) ConstantPoolCache(length, index_map, invokedynamic_map);
+  return new (loader_data, size, false, MetaspaceObj::ConstantPoolCacheType, THREAD)
+    ConstantPoolCache(length, index_map, invokedynamic_map);
 }
 
 void ConstantPoolCache::initialize(const intArray& inverse_index_map,
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -268,8 +268,6 @@
   set_fields(NULL, 0);
   set_constants(NULL);
   set_class_loader_data(NULL);
-  set_protection_domain(NULL);
-  set_signers(NULL);
   set_source_file_name(NULL);
   set_source_debug_extension(NULL, 0);
   set_array_name(NULL);
@@ -279,7 +277,6 @@
   set_is_marked_dependent(false);
   set_init_state(InstanceKlass::allocated);
   set_init_thread(NULL);
-  set_init_lock(NULL);
   set_reference_type(rt);
   set_oop_map_cache(NULL);
   set_jni_ids(NULL);
@@ -408,12 +405,6 @@
   }
   set_inner_classes(NULL);
 
-  // Null out Java heap objects, although these won't be walked to keep
-  // alive once this InstanceKlass is deallocated.
-  set_protection_domain(NULL);
-  set_signers(NULL);
-  set_init_lock(NULL);
-
   // We should deallocate the Annotations instance
   MetadataFactory::free_metadata(loader_data, annotations());
   set_annotations(NULL);
@@ -451,6 +442,24 @@
   }
 }
 
+// JVMTI spec thinks there are signers and protection domain in the
+// instanceKlass.  These accessors pretend these fields are there.
+// The hprof specification also thinks these fields are in InstanceKlass.
+oop InstanceKlass::protection_domain() const {
+  // return the protection_domain from the mirror
+  return java_lang_Class::protection_domain(java_mirror());
+}
+
+// To remove these from requires an incompatible change and CCC request.
+objArrayOop InstanceKlass::signers() const {
+  // return the signers from the mirror
+  return java_lang_Class::signers(java_mirror());
+}
+
+volatile oop InstanceKlass::init_lock() const {
+  // return the init lock from the mirror
+  return java_lang_Class::init_lock(java_mirror());
+}
 
 void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) {
   EXCEPTION_MARK;
@@ -1883,16 +1892,6 @@
 
 // Garbage collection
 
-void InstanceKlass::oops_do(OopClosure* cl) {
-  Klass::oops_do(cl);
-
-  cl->do_oop(adr_protection_domain());
-  cl->do_oop(adr_signers());
-  cl->do_oop(adr_init_lock());
-
-  // Don't walk the arrays since they are walked from the ClassLoaderData objects.
-}
-
 #ifdef ASSERT
 template <class T> void assert_is_in(T *p) {
   T heap_oop = oopDesc::load_heap_oop(p);
@@ -2241,9 +2240,6 @@
     m->remove_unshareable_info();
   }
 
-  // Need to reinstate when reading back the class.
-  set_init_lock(NULL);
-
   // do array classes also.
   array_klasses_do(remove_unshareable_in_class);
 }
@@ -2275,13 +2271,6 @@
     ik->itable()->initialize_itable(false, CHECK);
   }
 
-  // Allocate a simple java object for a lock.
-  // This needs to be a java object because during class initialization
-  // it can be held across a java call.
-  typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
-  Handle h(THREAD, (oop)r);
-  ik->set_init_lock(h());
-
   // restore constant pool resolved references
   ik->constants()->restore_unshareable_info(CHECK);
 
@@ -2331,10 +2320,15 @@
     FreeHeap(jmeths);
   }
 
-  MemberNameTable* mnt = member_names();
-  if (mnt != NULL) {
-    delete mnt;
-    set_member_names(NULL);
+  // Deallocate MemberNameTable
+  {
+    Mutex* lock_or_null = SafepointSynchronize::is_at_safepoint() ? NULL : MemberNameTable_lock;
+    MutexLockerEx ml(lock_or_null, Mutex::_no_safepoint_check_flag);
+    MemberNameTable* mnt = member_names();
+    if (mnt != NULL) {
+      delete mnt;
+      set_member_names(NULL);
+    }
   }
 
   int* indices = methods_cached_itable_indices_acquire();
@@ -2765,15 +2759,28 @@
   return NULL;
 }
 
-void InstanceKlass::add_member_name(Handle mem_name) {
+void InstanceKlass::add_member_name(int index, Handle mem_name) {
   jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
   MutexLocker ml(MemberNameTable_lock);
+  assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
   DEBUG_ONLY(No_Safepoint_Verifier nsv);
 
   if (_member_names == NULL) {
-    _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable();
+    _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count());
   }
-  _member_names->add_member_name(mem_name_wref);
+  _member_names->add_member_name(index, mem_name_wref);
+}
+
+oop InstanceKlass::get_member_name(int index) {
+  MutexLocker ml(MemberNameTable_lock);
+  assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
+  DEBUG_ONLY(No_Safepoint_Verifier nsv);
+
+  if (_member_names == NULL) {
+    return NULL;
+  }
+  oop mem_name =_member_names->get_member_name(index);
+  return mem_name;
 }
 
 // -----------------------------------------------------------------------------------------------------
@@ -2836,10 +2843,7 @@
     class_loader_data()->print_value_on(st);
     st->cr();
   }
-  st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
   st->print(BULLET"host class:        "); host_klass()->print_value_on_maybe_null(st); st->cr();
-  st->print(BULLET"signers:           "); signers()->print_value_on(st);               st->cr();
-  st->print(BULLET"init_lock:         "); ((oop)_init_lock)->print_value_on(st);       st->cr();
   if (source_file_name() != NULL) {
     st->print(BULLET"source file:       ");
     source_file_name()->print_value_on(st);
@@ -3040,7 +3044,6 @@
   n += (sz->_method_ordering_bytes       = sz->count_array(method_ordering()));
   n += (sz->_local_interfaces_bytes      = sz->count_array(local_interfaces()));
   n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
-  n += (sz->_signers_bytes               = sz->count_array(signers()));
   n += (sz->_fields_bytes                = sz->count_array(fields()));
   n += (sz->_inner_classes_bytes         = sz->count_array(inner_classes()));
   sz->_ro_bytes += n;
@@ -3206,17 +3209,11 @@
     guarantee(constants()->is_metadata(), "should be in metaspace");
     guarantee(constants()->is_constantPool(), "should be constant pool");
   }
-  if (protection_domain() != NULL) {
-    guarantee(protection_domain()->is_oop(), "should be oop");
-  }
   const Klass* host = host_klass();
   if (host != NULL) {
     guarantee(host->is_metadata(), "should be in metaspace");
     guarantee(host->is_klass(), "should be klass");
   }
-  if (signers() != NULL) {
-    guarantee(signers()->is_objArray(), "should be obj array");
-  }
 }
 
 void InstanceKlass::oop_verify_on(oop obj, outputStream* st) {
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/instanceKlass.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -26,6 +26,7 @@
 #define SHARE_VM_OOPS_INSTANCEKLASS_HPP
 
 #include "classfile/classLoaderData.hpp"
+#include "memory/referenceType.hpp"
 #include "oops/annotations.hpp"
 #include "oops/constMethod.hpp"
 #include "oops/fieldInfo.hpp"
@@ -37,6 +38,7 @@
 #include "utilities/accessFlags.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/macros.hpp"
+#include "trace/traceMacros.hpp"
 
 // An InstanceKlass is the VM level representation of a Java class.
 // It contains all information needed for at class at execution runtime.
@@ -58,8 +60,6 @@
 //    [fields                     ]
 //    [constants                  ]
 //    [class loader               ]
-//    [protection domain          ]
-//    [signers                    ]
 //    [source file name           ]
 //    [inner classes              ]
 //    [static field size          ]
@@ -180,16 +180,6 @@
   static volatile int _total_instanceKlass_count;
 
  protected:
-  // Protection domain.
-  oop             _protection_domain;
-  // Class signers.
-  objArrayOop     _signers;
-  // Lock for (1) initialization; (2) access to the ConstantPool of this class.
-  // Must be one per class and it has to be a VM internal object so java code
-  // cannot lock it (like the mirror).
-  // It has to be an object not a Mutex because it's held through java calls.
-  volatile oop    _init_lock;
-
   // Annotations for this class
   Annotations*    _annotations;
   // Array classes holding elements of this class.
@@ -527,8 +517,10 @@
   void set_constants(ConstantPool* c)    { _constants = c; }
 
   // protection domain
-  oop protection_domain()                  { return _protection_domain; }
-  void set_protection_domain(oop pd)       { klass_oop_store(&_protection_domain, pd); }
+  oop protection_domain() const;
+
+  // signers
+  objArrayOop signers() const;
 
   // host class
   Klass* host_klass() const              {
@@ -575,10 +567,6 @@
     }
   }
 
-  // signers
-  objArrayOop signers() const              { return _signers; }
-  void set_signers(objArrayOop s)          { klass_oop_store((oop*)&_signers, s); }
-
   // source file name
   Symbol* source_file_name() const         { return _source_file_name; }
   void set_source_file_name(Symbol* n);
@@ -912,8 +900,6 @@
   Method* method_at_itable(Klass* holder, int index, TRAPS);
 
   // Garbage collection
-  virtual void oops_do(OopClosure* cl);
-
   void oop_follow_contents(oop obj);
   int  oop_adjust_pointers(oop obj);
 
@@ -999,14 +985,12 @@
 
   // Lock during initialization
 public:
-  volatile oop init_lock() const     {return _init_lock; }
+  // Lock for (1) initialization; (2) access to the ConstantPool of this class.
+  // Must be one per class and it has to be a VM internal object so java code
+  // cannot lock it (like the mirror).
+  // It has to be an object not a Mutex because it's held through java calls.
+  volatile oop init_lock() const;
 private:
-  void set_init_lock(oop value) { klass_oop_store(&_init_lock, value); }
-
-  // Offsets for memory management
-  oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
-  oop* adr_signers() const           { return (oop*)&this->_signers;}
-  oop* adr_init_lock() const         { return (oop*)&this->_init_lock;}
 
   // Static methods that are used to implement member methods where an exposed this pointer
   // is needed due to possible GCs
@@ -1040,7 +1024,8 @@
   // JSR-292 support
   MemberNameTable* member_names() { return _member_names; }
   void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
-  void add_member_name(Handle member_name);
+  void add_member_name(int index, Handle member_name);
+  oop  get_member_name(int index);
 
 public:
   // JVMTI support
--- a/src/share/vm/oops/klass.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/klass.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -37,6 +37,7 @@
 #include "oops/klass.inline.hpp"
 #include "oops/oop.inline2.hpp"
 #include "runtime/atomic.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/stack.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_ALL_GCS
@@ -140,7 +141,7 @@
 
 void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) {
   return Metaspace::allocate(loader_data, word_size, /*read_only*/false,
-                             Metaspace::ClassType, CHECK_NULL);
+                             MetaspaceObj::ClassType, CHECK_NULL);
 }
 
 Klass::Klass() {
@@ -168,7 +169,7 @@
   set_next_sibling(NULL);
   set_next_link(NULL);
   set_alloc_count(0);
-  TRACE_SET_KLASS_TRACE_ID(this, 0);
+  TRACE_INIT_ID(this);
 
   set_prototype_header(markOopDesc::prototype());
   set_biased_lock_revocation_count(0);
@@ -511,8 +512,9 @@
   // (same order as class file parsing)
   loader_data->add_class(this);
 
-  // Recreate the class mirror
-  java_lang_Class::create_mirror(this, CHECK);
+  // Recreate the class mirror.  The protection_domain is always null for
+  // boot loader, for now.
+  java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
 }
 
 Klass* Klass::array_klass_or_null(int rank) {
--- a/src/share/vm/oops/klass.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/klass.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -445,7 +445,7 @@
   Klass* array_klass_or_null(int rank);
   Klass* array_klass_or_null();
 
-  virtual oop protection_domain()       { return NULL; }
+  virtual oop protection_domain() const = 0;
 
   oop class_loader() const;
 
--- a/src/share/vm/oops/method.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/method.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -74,7 +74,7 @@
 
   int size = Method::size(access_flags.is_native());
 
-  return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
+  return new (loader_data, size, false, MetaspaceObj::MethodType, THREAD) Method(cm, access_flags, size);
 }
 
 Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
--- a/src/share/vm/oops/method.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/method.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -671,13 +671,15 @@
                                                    Symbol* signature, //anything at all
                                                    TRAPS);
   static Klass* check_non_bcp_klass(Klass* klass);
-  // these operate only on invoke methods:
+
+  // How many extra stack entries for invokedynamic when it's enabled
+  static const int extra_stack_entries_for_jsr292 = 1;
+
+  // this operates only on invoke methods:
   // presize interpreter frames for extra interpreter stack entries, if needed
-  // method handles want to be able to push a few extra values (e.g., a bound receiver), and
-  // invokedynamic sometimes needs to push a bootstrap method, call site, and arglist,
-  // all without checking for a stack overflow
-  static int extra_stack_entries() { return EnableInvokeDynamic ? 2 : 0; }
-  static int extra_stack_words();  // = extra_stack_entries() * Interpreter::stackElementSize()
+  // Account for the extra appendix argument for invokehandle/invokedynamic
+  static int extra_stack_entries() { return EnableInvokeDynamic ? extra_stack_entries_for_jsr292 : 0; }
+  static int extra_stack_words();  // = extra_stack_entries() * Interpreter::stackElementSize
 
   // RedefineClasses() support:
   bool is_old() const                               { return access_flags().is_old(); }
--- a/src/share/vm/oops/methodCounters.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/methodCounters.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -26,7 +26,7 @@
 #include "runtime/thread.inline.hpp"
 
 MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) {
-  return new(loader_data, size(), false, THREAD) MethodCounters();
+  return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters();
 }
 
 void MethodCounters::clear_counters() {
--- a/src/share/vm/oops/methodData.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/methodData.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -388,7 +388,8 @@
 MethodData* MethodData::allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS) {
   int size = MethodData::compute_allocation_size_in_words(method);
 
-  return new (loader_data, size, false, THREAD) MethodData(method(), size, CHECK_NULL);
+  return new (loader_data, size, false, MetaspaceObj::MethodDataType, THREAD)
+    MethodData(method(), size, CHECK_NULL);
 }
 
 int MethodData::bytecode_cell_count(Bytecodes::Code code) {
--- a/src/share/vm/oops/objArrayKlass.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/objArrayKlass.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -75,7 +75,7 @@
   void  copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
 
   // Compute protection domain
-  oop protection_domain() { return bottom_klass()->protection_domain(); }
+  oop protection_domain() const { return bottom_klass()->protection_domain(); }
 
  private:
   // Either oop or narrowOop depending on UseCompressedOops.
--- a/src/share/vm/oops/symbol.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/symbol.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -55,7 +55,7 @@
   address res;
   int alloc_size = size(len)*HeapWordSize;
   res = (address) Metaspace::allocate(loader_data, size(len), true,
-                                      Metaspace::NonClassType, CHECK_NULL);
+                                      MetaspaceObj::SymbolType, CHECK_NULL);
   return res;
 }
 
--- a/src/share/vm/oops/typeArrayKlass.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/oops/typeArrayKlass.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -67,6 +67,8 @@
   typeArrayOop allocate(int length, TRAPS) { return allocate_common(length, true, THREAD); }
   oop multi_allocate(int rank, jint* sizes, TRAPS);
 
+  oop protection_domain() const { return NULL; }
+
   // Copying
   void  copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
 
--- a/src/share/vm/opto/compile.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/opto/compile.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,6 +63,7 @@
 #include "runtime/signature.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/timer.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/copy.hpp"
 #ifdef TARGET_ARCH_MODEL_x86_32
 # include "adfiles/ad_x86_32.hpp"
@@ -789,7 +790,7 @@
 
     if (failing())  return;
 
-    print_method("Before RemoveUseless", 3);
+    print_method(PHASE_BEFORE_REMOVEUSELESS, 3);
 
     // Remove clutter produced by parsing.
     if (!failing()) {
@@ -1804,9 +1805,9 @@
 
   {
     ResourceMark rm;
-    print_method("Before StringOpts", 3);
+    print_method(PHASE_BEFORE_STRINGOPTS, 3);
     PhaseStringOpts pso(initial_gvn(), for_igvn());
-    print_method("After StringOpts", 3);
+    print_method(PHASE_AFTER_STRINGOPTS, 3);
   }
 
   // now inline anything that we skipped the first time around
@@ -1961,7 +1962,7 @@
 
   NOT_PRODUCT( verify_graph_edges(); )
 
-  print_method("After Parsing");
+  print_method(PHASE_AFTER_PARSING);
 
  {
   // Iterative Global Value Numbering, including ideal transforms
@@ -1972,7 +1973,7 @@
     igvn.optimize();
   }
 
-  print_method("Iter GVN 1", 2);
+  print_method(PHASE_ITER_GVN1, 2);
 
   if (failing())  return;
 
@@ -1981,7 +1982,7 @@
     inline_incrementally(igvn);
   }
 
-  print_method("Incremental Inline", 2);
+  print_method(PHASE_INCREMENTAL_INLINE, 2);
 
   if (failing())  return;
 
@@ -1990,7 +1991,7 @@
     // Inline valueOf() methods now.
     inline_boxing_calls(igvn);
 
-    print_method("Incremental Boxing Inline", 2);
+    print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2);
 
     if (failing())  return;
   }
@@ -2005,7 +2006,7 @@
       // Cleanup graph (remove dead nodes).
       TracePhase t2("idealLoop", &_t_idealLoop, true);
       PhaseIdealLoop ideal_loop( igvn, false, true );
-      if (major_progress()) print_method("PhaseIdealLoop before EA", 2);
+      if (major_progress()) print_method(PHASE_PHASEIDEAL_BEFORE_EA, 2);
       if (failing())  return;
     }
     ConnectionGraph::do_analysis(this, &igvn);
@@ -2014,7 +2015,7 @@
 
     // Optimize out fields loads from scalar replaceable allocations.
     igvn.optimize();
-    print_method("Iter GVN after EA", 2);
+    print_method(PHASE_ITER_GVN_AFTER_EA, 2);
 
     if (failing())  return;
 
@@ -2025,7 +2026,7 @@
       igvn.set_delay_transform(false);
 
       igvn.optimize();
-      print_method("Iter GVN after eliminating allocations and locks", 2);
+      print_method(PHASE_ITER_GVN_AFTER_ELIMINATION, 2);
 
       if (failing())  return;
     }
@@ -2041,7 +2042,7 @@
       TracePhase t2("idealLoop", &_t_idealLoop, true);
       PhaseIdealLoop ideal_loop( igvn, true );
       loop_opts_cnt--;
-      if (major_progress()) print_method("PhaseIdealLoop 1", 2);
+      if (major_progress()) print_method(PHASE_PHASEIDEALLOOP1, 2);
       if (failing())  return;
     }
     // Loop opts pass if partial peeling occurred in previous pass
@@ -2049,7 +2050,7 @@
       TracePhase t3("idealLoop", &_t_idealLoop, true);
       PhaseIdealLoop ideal_loop( igvn, false );
       loop_opts_cnt--;
-      if (major_progress()) print_method("PhaseIdealLoop 2", 2);
+      if (major_progress()) print_method(PHASE_PHASEIDEALLOOP2, 2);
       if (failing())  return;
     }
     // Loop opts pass for loop-unrolling before CCP
@@ -2057,7 +2058,7 @@
       TracePhase t4("idealLoop", &_t_idealLoop, true);
       PhaseIdealLoop ideal_loop( igvn, false );
       loop_opts_cnt--;
-      if (major_progress()) print_method("PhaseIdealLoop 3", 2);
+      if (major_progress()) print_method(PHASE_PHASEIDEALLOOP3, 2);
     }
     if (!failing()) {
       // Verify that last round of loop opts produced a valid graph
@@ -2074,7 +2075,7 @@
     TracePhase t2("ccp", &_t_ccp, true);
     ccp.do_transform();
   }
-  print_method("PhaseCPP 1", 2);
+  print_method(PHASE_CPP1, 2);
 
   assert( true, "Break here to ccp.dump_old2new_map()");
 
@@ -2085,7 +2086,7 @@
     igvn.optimize();
   }
 
-  print_method("Iter GVN 2", 2);
+  print_method(PHASE_ITER_GVN2, 2);
 
   if (failing())  return;
 
@@ -2098,7 +2099,7 @@
       assert( cnt++ < 40, "infinite cycle in loop optimization" );
       PhaseIdealLoop ideal_loop( igvn, true);
       loop_opts_cnt--;
-      if (major_progress()) print_method("PhaseIdealLoop iterations", 2);
+      if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
       if (failing())  return;
     }
   }
@@ -2131,7 +2132,7 @@
     }
   }
 
-  print_method("Optimize finished", 2);
+  print_method(PHASE_OPTIMIZE_FINISHED, 2);
 }
 
 
@@ -2179,7 +2180,7 @@
     cfg.GlobalCodeMotion(m,unique(),proj_list);
     if (failing())  return;
 
-    print_method("Global code motion", 2);
+    print_method(PHASE_GLOBAL_CODE_MOTION, 2);
 
     NOT_PRODUCT( verify_graph_edges(); )
 
@@ -2232,7 +2233,7 @@
     Output();
   }
 
-  print_method("Final Code");
+  print_method(PHASE_FINAL_CODE);
 
   // He's dead, Jim.
   _cfg     = (PhaseCFG*)0xdeadbeef;
@@ -3319,8 +3320,16 @@
     // Record the first failure reason.
     _failure_reason = reason;
   }
+
+  EventCompilerFailure event;
+  if (event.should_commit()) {
+    event.set_compileID(Compile::compile_id());
+    event.set_failure(reason);
+    event.commit();
+  }
+
   if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
-    C->print_method(_failure_reason);
+    C->print_method(PHASE_FAILURE);
   }
   _root = NULL;  // flush the graph, too
 }
--- a/src/share/vm/opto/compile.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/opto/compile.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,10 +36,12 @@
 #include "libadt/vectset.hpp"
 #include "memory/resourceArea.hpp"
 #include "opto/idealGraphPrinter.hpp"
+#include "opto/phasetype.hpp"
 #include "opto/phase.hpp"
 #include "opto/regmask.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/vmThread.hpp"
+#include "trace/tracing.hpp"
 
 class Block;
 class Bundle;
@@ -322,6 +324,7 @@
   IdealGraphPrinter*    _printer;
 #endif
 
+
   // Node management
   uint                  _unique;                // Counter for unique Node indices
   VectorSet             _dead_node_list;        // Set of dead nodes
@@ -573,17 +576,43 @@
   bool              has_method_handle_invokes() const { return _has_method_handle_invokes;     }
   void          set_has_method_handle_invokes(bool z) {        _has_method_handle_invokes = z; }
 
+  jlong _latest_stage_start_counter;
+
   void begin_method() {
 #ifndef PRODUCT
     if (_printer) _printer->begin_method(this);
 #endif
+    C->_latest_stage_start_counter = os::elapsed_counter();
   }
-  void print_method(const char * name, int level = 1) {
+
+  void print_method(CompilerPhaseType cpt, int level = 1) {
+    EventCompilerPhase event(UNTIMED);
+    if (event.should_commit()) {
+      event.set_starttime(C->_latest_stage_start_counter);
+      event.set_endtime(os::elapsed_counter());
+      event.set_phase((u1) cpt);
+      event.set_compileID(C->_compile_id);
+      event.set_phaseLevel(level);
+      event.commit();
+    }
+
+
 #ifndef PRODUCT
-    if (_printer) _printer->print_method(this, name, level);
+    if (_printer) _printer->print_method(this, CompilerPhaseTypeHelper::to_string(cpt), level);
 #endif
+    C->_latest_stage_start_counter = os::elapsed_counter();
   }
-  void end_method() {
+
+  void end_method(int level = 1) {
+    EventCompilerPhase event(UNTIMED);
+    if (event.should_commit()) {
+      event.set_starttime(C->_latest_stage_start_counter);
+      event.set_endtime(os::elapsed_counter());
+      event.set_phase((u1) PHASE_END);
+      event.set_compileID(C->_compile_id);
+      event.set_phaseLevel(level);
+      event.commit();
+    }
 #ifndef PRODUCT
     if (_printer) _printer->end_method();
 #endif
--- a/src/share/vm/opto/escape.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/opto/escape.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -277,7 +277,7 @@
     // scalar replaceable objects.
     split_unique_types(alloc_worklist);
     if (C->failing())  return false;
-    C->print_method("After Escape Analysis", 2);
+    C->print_method(PHASE_AFTER_EA, 2);
 
 #ifdef ASSERT
   } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
@@ -2202,7 +2202,7 @@
     int opcode = uncast_base->Opcode();
     assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
            opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
-           (uncast_base->is_Mem() && uncast_base->bottom_type() == TypeRawPtr::NOTNULL) ||
+           (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
            (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
   }
   return base;
--- a/src/share/vm/opto/library_call.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/opto/library_call.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
 #include "opto/subnode.hpp"
 #include "prims/nativeLookup.hpp"
 #include "runtime/sharedRuntime.hpp"
+#include "trace/traceMacros.hpp"
 
 class LibraryIntrinsic : public InlineCallGenerator {
   // Extend the set of intrinsics known to the runtime:
--- a/src/share/vm/opto/loopnode.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/opto/loopnode.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -440,7 +440,7 @@
   // ---- SUCCESS!   Found A Trip-Counted Loop!  -----
   //
   assert(x->Opcode() == Op_Loop, "regular loops only");
-  C->print_method("Before CountedLoop", 3);
+  C->print_method(PHASE_BEFORE_CLOOPS, 3);
 
   Node *hook = new (C) Node(6);
 
@@ -791,7 +791,7 @@
   }
 #endif
 
-  C->print_method("After CountedLoop", 3);
+  C->print_method(PHASE_AFTER_CLOOPS, 3);
 
   return true;
 }
@@ -2164,7 +2164,7 @@
   // Split shared headers and insert loop landing pads.
   // Do not bother doing this on the Root loop of course.
   if( !_verify_me && !_verify_only && _ltree_root->_child ) {
-    C->print_method("Before beautify loops", 3);
+    C->print_method(PHASE_BEFORE_BEAUTIFY_LOOPS, 3);
     if( _ltree_root->_child->beautify_loops( this ) ) {
       // Re-build loop tree!
       _ltree_root->_child = NULL;
@@ -2178,7 +2178,7 @@
       // Reset loop nesting depth
       _ltree_root->set_nest( 0 );
 
-      C->print_method("After beautify loops", 3);
+      C->print_method(PHASE_AFTER_BEAUTIFY_LOOPS, 3);
     }
   }
 
--- a/src/share/vm/opto/matcher.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/opto/matcher.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -320,7 +320,7 @@
   find_shared( C->root() );
   find_shared( C->top() );
 
-  C->print_method("Before Matching");
+  C->print_method(PHASE_BEFORE_MATCHING);
 
   // Create new ideal node ConP #NULL even if it does exist in old space
   // to avoid false sharing if the corresponding mach node is not used.
@@ -1285,16 +1285,6 @@
     mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area;
   }
 
-  if (is_method_handle_invoke) {
-    // Kill some extra stack space in case method handles want to do
-    // a little in-place argument insertion.
-    // FIXME: Is this still necessary?
-    int regs_per_word  = NOT_LP64(1) LP64_ONLY(2); // %%% make a global const!
-    out_arg_limit_per_call += Method::extra_stack_entries() * regs_per_word;
-    // Do not update mcall->_argsize because (a) the extra space is not
-    // pushed as arguments and (b) _argsize is dead (not used anywhere).
-  }
-
   // Compute the max stack slot killed by any call.  These will not be
   // available for debug info, and will be used to adjust FIRST_STACK_mask
   // after all call sites have been visited.
@@ -1861,7 +1851,7 @@
 
   for( uint i=0; kid != NULL && i<2; kid = s->_kids[1], i++ ) {   // binary tree
     int newrule;
-    if( i == 0 )
+    if( i == 0)
       newrule = kid->_rule[_leftOp[rule]];
     else
       newrule = kid->_rule[_rightOp[rule]];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/opto/phasetype.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_OPTO_PHASETYPE_HPP
+#define SHARE_VM_OPTO_PHASETYPE_HPP
+
+enum CompilerPhaseType {
+  PHASE_BEFORE_STRINGOPTS,
+  PHASE_AFTER_STRINGOPTS,
+  PHASE_BEFORE_REMOVEUSELESS,
+  PHASE_AFTER_PARSING,
+  PHASE_ITER_GVN1,
+  PHASE_PHASEIDEAL_BEFORE_EA,
+  PHASE_ITER_GVN_AFTER_EA,
+  PHASE_ITER_GVN_AFTER_ELIMINATION,
+  PHASE_PHASEIDEALLOOP1,
+  PHASE_PHASEIDEALLOOP2,
+  PHASE_PHASEIDEALLOOP3,
+  PHASE_CPP1,
+  PHASE_ITER_GVN2,
+  PHASE_PHASEIDEALLOOP_ITERATIONS,
+  PHASE_OPTIMIZE_FINISHED,
+  PHASE_GLOBAL_CODE_MOTION,
+  PHASE_FINAL_CODE,
+  PHASE_AFTER_EA,
+  PHASE_BEFORE_CLOOPS,
+  PHASE_AFTER_CLOOPS,
+  PHASE_BEFORE_BEAUTIFY_LOOPS,
+  PHASE_AFTER_BEAUTIFY_LOOPS,
+  PHASE_BEFORE_MATCHING,
+  PHASE_INCREMENTAL_INLINE,
+  PHASE_INCREMENTAL_BOXING_INLINE,
+  PHASE_END,
+  PHASE_FAILURE,
+
+  PHASE_NUM_TYPES
+};
+
+class CompilerPhaseTypeHelper {
+  public:
+  static const char* to_string(CompilerPhaseType cpt) {
+    switch (cpt) {
+      case PHASE_BEFORE_STRINGOPTS:          return "Before StringOpts";
+      case PHASE_AFTER_STRINGOPTS:           return "After StringOpts";
+      case PHASE_BEFORE_REMOVEUSELESS:       return "Before RemoveUseless";
+      case PHASE_AFTER_PARSING:              return "After Parsing";
+      case PHASE_ITER_GVN1:                  return "Iter GVN 1";
+      case PHASE_PHASEIDEAL_BEFORE_EA:       return "PhaseIdealLoop before EA";
+      case PHASE_ITER_GVN_AFTER_EA:          return "Iter GVN after EA";
+      case PHASE_ITER_GVN_AFTER_ELIMINATION: return "Iter GVN after eliminating allocations and locks";
+      case PHASE_PHASEIDEALLOOP1:            return "PhaseIdealLoop 1";
+      case PHASE_PHASEIDEALLOOP2:            return "PhaseIdealLoop 2";
+      case PHASE_PHASEIDEALLOOP3:            return "PhaseIdealLoop 3";
+      case PHASE_CPP1:                       return "PhaseCPP 1";
+      case PHASE_ITER_GVN2:                  return "Iter GVN 2";
+      case PHASE_PHASEIDEALLOOP_ITERATIONS:  return "PhaseIdealLoop iterations";
+      case PHASE_OPTIMIZE_FINISHED:          return "Optimize finished";
+      case PHASE_GLOBAL_CODE_MOTION:         return "Global code motion";
+      case PHASE_FINAL_CODE:                 return "Final Code";
+      case PHASE_AFTER_EA:                   return "After Escape Analysis";
+      case PHASE_BEFORE_CLOOPS:              return "Before CountedLoop";
+      case PHASE_AFTER_CLOOPS:               return "After CountedLoop";
+      case PHASE_BEFORE_BEAUTIFY_LOOPS:      return "Before beautify loops";
+      case PHASE_AFTER_BEAUTIFY_LOOPS:       return "After beautify loops";
+      case PHASE_BEFORE_MATCHING:            return "Before Matching";
+      case PHASE_INCREMENTAL_INLINE:         return "Incremental Inline";
+      case PHASE_INCREMENTAL_BOXING_INLINE:  return "Incremental Boxing Inline";
+      case PHASE_END:                        return "End";
+      case PHASE_FAILURE:                    return "Failure";
+      default:
+        ShouldNotReachHere();
+        return NULL;
+    }
+  }
+};
+
+#endif //SHARE_VM_OPTO_PHASETYPE_HPP
--- a/src/share/vm/opto/reg_split.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/opto/reg_split.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -51,6 +51,15 @@
 
 static const char out_of_nodes[] = "out of nodes during split";
 
+static bool contains_no_live_range_input(const Node* def) {
+  for (uint i = 1; i < def->req(); ++i) {
+    if (def->in(i) != NULL && def->in_RegMask(i).is_NotEmpty()) {
+      return false;
+    }
+  }
+  return true;
+}
+
 //------------------------------get_spillcopy_wide-----------------------------
 // Get a SpillCopy node with wide-enough masks.  Use the 'wide-mask', the
 // wide ideal-register spill-mask if possible.  If the 'wide-mask' does
@@ -1312,7 +1321,7 @@
       Node *def = Reaches[pidx][slidx];
       assert( def, "must have reaching def" );
       // If input up/down sense and reg-pressure DISagree
-      if( def->rematerialize() ) {
+      if (def->rematerialize() && contains_no_live_range_input(def)) {
         // Place the rematerialized node above any MSCs created during
         // phi node splitting.  end_idx points at the insertion point
         // so look at the node before it.
--- a/src/share/vm/precompiled/precompiled.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/precompiled/precompiled.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -26,7 +26,6 @@
 // or if the user passes USE_PRECOMPILED_HEADER=0 to the makefiles.
 
 #ifndef DONT_USE_PRECOMPILED_HEADER
-
 # include "asm/assembler.hpp"
 # include "asm/assembler.inline.hpp"
 # include "asm/codeBuffer.hpp"
--- a/src/share/vm/prims/forte.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/forte.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -35,6 +35,19 @@
 #include "runtime/vframe.hpp"
 #include "runtime/vframeArray.hpp"
 
+// call frame copied from old .h file and renamed
+typedef struct {
+    jint lineno;                      // line number in the source file
+    jmethodID method_id;              // method executed in this frame
+} ASGCT_CallFrame;
+
+// call trace copied from old .h file and renamed
+typedef struct {
+    JNIEnv *env_id;                   // Env where trace was recorded
+    jint num_frames;                  // number of frames in this trace
+    ASGCT_CallFrame *frames;          // frames
+} ASGCT_CallTrace;
+
 // These name match the names reported by the forte quality kit
 enum {
   ticks_no_Java_frame         =  0,
@@ -50,6 +63,8 @@
   ticks_safepoint             = -10
 };
 
+#if INCLUDE_JVMTI
+
 //-------------------------------------------------------
 
 // Native interfaces for use by Forte tools.
@@ -360,20 +375,6 @@
 
 }
 
-
-// call frame copied from old .h file and renamed
-typedef struct {
-    jint lineno;                      // line number in the source file
-    jmethodID method_id;              // method executed in this frame
-} ASGCT_CallFrame;
-
-// call trace copied from old .h file and renamed
-typedef struct {
-    JNIEnv *env_id;                   // Env where trace was recorded
-    jint num_frames;                  // number of frames in this trace
-    ASGCT_CallFrame *frames;          // frames
-} ASGCT_CallTrace;
-
 static void forte_fill_call_trace_given_top(JavaThread* thd,
                                             ASGCT_CallTrace* trace,
                                             int depth,
@@ -634,3 +635,12 @@
     pointer_delta(end, start, sizeof(jbyte)), 0, NULL);
 #endif // !_WINDOWS && !IA64
 }
+
+#else // INCLUDE_JVMTI
+extern "C" {
+  JNIEXPORT
+  void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
+    trace->num_frames = ticks_no_class_load; // -1
+  }
+}
+#endif // INCLUDE_JVMTI
--- a/src/share/vm/prims/jni.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/jni.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -74,7 +74,6 @@
 #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"
@@ -5014,6 +5013,7 @@
 
 #ifndef PRODUCT
 
+#include "gc_implementation/shared/gcTimer.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
@@ -5031,6 +5031,7 @@
   if (ExecuteInternalVMTests) {
     tty->print_cr("Running internal VM tests");
     run_unit_test(GlobalDefinitions::test_globals());
+    run_unit_test(GCTimerAllTest::all());
     run_unit_test(arrayOopDesc::test_max_array_length());
     run_unit_test(CollectedHeap::test_is_in());
     run_unit_test(QuickSort::test_quick_sort());
@@ -5131,9 +5132,11 @@
        JvmtiExport::post_thread_start(thread);
     }
 
-    EVENT_BEGIN(TraceEventThreadStart, event);
-    EVENT_COMMIT(event,
-        EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+    EventThreadStart event;
+    if (event.should_commit()) {
+      event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+      event.commit();
+    }
 
     // Check if we should compile all classes on bootclasspath
     NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
@@ -5334,9 +5337,11 @@
     JvmtiExport::post_thread_start(thread);
   }
 
-  EVENT_BEGIN(TraceEventThreadStart, event);
-  EVENT_COMMIT(event,
-      EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+  EventThreadStart event;
+  if (event.should_commit()) {
+    event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+    event.commit();
+  }
 
   *(JNIEnv**)penv = thread->jni_environment();
 
--- a/src/share/vm/prims/jvm.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/jvm.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -59,6 +59,7 @@
 #include "services/attachListener.hpp"
 #include "services/management.hpp"
 #include "services/threadService.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/dtrace.hpp"
@@ -1072,11 +1073,7 @@
     return NULL;
   }
 
-  Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
-  objArrayOop signers = NULL;
-  if (k->oop_is_instance()) {
-    signers = InstanceKlass::cast(k)->signers();
-  }
+  objArrayOop signers = java_lang_Class::signers(JNIHandles::resolve_non_null(cls));
 
   // If there are no signers set in the class, or if the class
   // is an array, return NULL.
@@ -1102,7 +1099,7 @@
     // be called with an array.  Only the bootstrap loader creates arrays.
     Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
     if (k->oop_is_instance()) {
-      InstanceKlass::cast(k)->set_signers(objArrayOop(JNIHandles::resolve(signers)));
+      java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));
     }
   }
 JVM_END
@@ -1119,8 +1116,8 @@
     return NULL;
   }
 
-  Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
-  return (jobject) JNIHandles::make_local(env, k->protection_domain());
+  oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));
+  return (jobject) JNIHandles::make_local(env, pd);
 JVM_END
 
 
@@ -1139,7 +1136,7 @@
     if (k->oop_is_instance()) {
       oop pd = JNIHandles::resolve(protection_domain);
       assert(pd == NULL || pd->is_oop(), "just checking");
-      InstanceKlass::cast(k)->set_protection_domain(pd);
+      java_lang_Class::set_protection_domain(k->java_mirror(), pd);
     }
   }
 JVM_END
@@ -3003,6 +3000,8 @@
                              millis);
 #endif /* USDT2 */
 
+  EventThreadSleep event;
+
   if (millis == 0) {
     // When ConvertSleepToYield is on, this matches the classic VM implementation of
     // JVM_Sleep. Critical for similar threading behaviour (Win32)
@@ -3023,6 +3022,10 @@
       // An asynchronous exception (e.g., ThreadDeathException) could have been thrown on
       // us while we were sleeping. We do not overwrite those.
       if (!HAS_PENDING_EXCEPTION) {
+        if (event.should_commit()) {
+          event.set_time(millis);
+          event.commit();
+        }
 #ifndef USDT2
         HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);
 #else /* USDT2 */
@@ -3036,6 +3039,10 @@
     }
     thread->osthread()->set_state(old_state);
   }
+  if (event.should_commit()) {
+    event.set_time(millis);
+    event.commit();
+  }
 #ifndef USDT2
   HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);
 #else /* USDT2 */
--- a/src/share/vm/prims/jvmtiGen.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/jvmtiGen.java	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
 import org.xml.sax.SAXParseException;
 import org.w3c.dom.Document;
 import org.w3c.dom.DOMException;
-
 // For write operation
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
@@ -129,6 +128,7 @@
 
         factory.setNamespaceAware(true);
         factory.setValidating(true);
+        factory.setXIncludeAware(true);
 
         try {
             File datafile   = new File(inFileName);
--- a/src/share/vm/prims/jvmtiImpl.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/jvmtiImpl.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -360,19 +360,14 @@
   case CLEAR_BREAKPOINT:
     _breakpoints->clear_at_safepoint(*_bp);
     break;
-  case CLEAR_ALL_BREAKPOINT:
-    _breakpoints->clearall_at_safepoint();
-    break;
   default:
     assert(false, "Unknown operation");
   }
 }
 
 void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
-  // This operation keeps breakpoints alive
-  if (_breakpoints != NULL) {
-    _breakpoints->oops_do(f);
-  }
+  // The JvmtiBreakpoints in _breakpoints will be visited via
+  // JvmtiExport::oops_do.
   if (_bp != NULL) {
     _bp->oops_do(f);
   }
@@ -433,23 +428,13 @@
   }
 }
 
-void JvmtiBreakpoints::clearall_at_safepoint() {
-  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-
-  int len = _bps.length();
-  for (int i=0; i<len; i++) {
-    _bps.at(i).clear();
-  }
-  _bps.clear();
-}
-
 int JvmtiBreakpoints::length() { return _bps.length(); }
 
 int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) {
   if ( _bps.find(bp) != -1) {
      return JVMTI_ERROR_DUPLICATE;
   }
-  VM_ChangeBreakpoints set_breakpoint(this,VM_ChangeBreakpoints::SET_BREAKPOINT, &bp);
+  VM_ChangeBreakpoints set_breakpoint(VM_ChangeBreakpoints::SET_BREAKPOINT, &bp);
   VMThread::execute(&set_breakpoint);
   return JVMTI_ERROR_NONE;
 }
@@ -459,7 +444,7 @@
      return JVMTI_ERROR_NOT_FOUND;
   }
 
-  VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp);
+  VM_ChangeBreakpoints clear_breakpoint(VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp);
   VMThread::execute(&clear_breakpoint);
   return JVMTI_ERROR_NONE;
 }
@@ -490,11 +475,6 @@
   }
 }
 
-void JvmtiBreakpoints::clearall() {
-  VM_ChangeBreakpoints clearall_breakpoint(this,VM_ChangeBreakpoints::CLEAR_ALL_BREAKPOINT);
-  VMThread::execute(&clearall_breakpoint);
-}
-
 //
 // class JvmtiCurrentBreakpoints
 //
--- a/src/share/vm/prims/jvmtiImpl.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/jvmtiImpl.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -204,47 +204,6 @@
 
 ///////////////////////////////////////////////////////////////
 //
-// class VM_ChangeBreakpoints
-// Used by              : JvmtiBreakpoints
-// Used by JVMTI methods: none directly.
-// Note: A Helper class.
-//
-// VM_ChangeBreakpoints implements a VM_Operation for ALL modifications to the JvmtiBreakpoints class.
-//
-
-class VM_ChangeBreakpoints : public VM_Operation {
-private:
-  JvmtiBreakpoints* _breakpoints;
-  int               _operation;
-  JvmtiBreakpoint*  _bp;
-
-public:
-  enum { SET_BREAKPOINT=0, CLEAR_BREAKPOINT=1, CLEAR_ALL_BREAKPOINT=2 };
-
-  VM_ChangeBreakpoints(JvmtiBreakpoints* breakpoints, int operation) {
-    _breakpoints = breakpoints;
-    _bp = NULL;
-    _operation = operation;
-    assert(breakpoints != NULL, "breakpoints != NULL");
-    assert(operation == CLEAR_ALL_BREAKPOINT, "unknown breakpoint operation");
-  }
-  VM_ChangeBreakpoints(JvmtiBreakpoints* breakpoints, int operation, JvmtiBreakpoint *bp) {
-    _breakpoints = breakpoints;
-    _bp = bp;
-    _operation = operation;
-    assert(breakpoints != NULL, "breakpoints != NULL");
-    assert(bp != NULL, "bp != NULL");
-    assert(operation == SET_BREAKPOINT || operation == CLEAR_BREAKPOINT , "unknown breakpoint operation");
-  }
-
-  VMOp_Type type() const { return VMOp_ChangeBreakpoints; }
-  void doit();
-  void oops_do(OopClosure* f);
-};
-
-
-///////////////////////////////////////////////////////////////
-//
 // class JvmtiBreakpoints
 // Used by              : JvmtiCurrentBreakpoints
 // Used by JVMTI methods: none directly
@@ -271,7 +230,6 @@
   friend class VM_ChangeBreakpoints;
   void set_at_safepoint(JvmtiBreakpoint& bp);
   void clear_at_safepoint(JvmtiBreakpoint& bp);
-  void clearall_at_safepoint();
 
   static void do_element(GrowableElement *e);
 
@@ -286,7 +244,6 @@
   int  set(JvmtiBreakpoint& bp);
   int  clear(JvmtiBreakpoint& bp);
   void clearall_in_class_at_safepoint(Klass* klass);
-  void clearall();
   void gc_epilogue();
 };
 
@@ -344,6 +301,40 @@
     return false;
 }
 
+
+///////////////////////////////////////////////////////////////
+//
+// class VM_ChangeBreakpoints
+// Used by              : JvmtiBreakpoints
+// Used by JVMTI methods: none directly.
+// Note: A Helper class.
+//
+// VM_ChangeBreakpoints implements a VM_Operation for ALL modifications to the JvmtiBreakpoints class.
+//
+
+class VM_ChangeBreakpoints : public VM_Operation {
+private:
+  JvmtiBreakpoints* _breakpoints;
+  int               _operation;
+  JvmtiBreakpoint*  _bp;
+
+public:
+  enum { SET_BREAKPOINT=0, CLEAR_BREAKPOINT=1 };
+
+  VM_ChangeBreakpoints(int operation, JvmtiBreakpoint *bp) {
+    JvmtiBreakpoints& current_bps = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
+    _breakpoints = &current_bps;
+    _bp = bp;
+    _operation = operation;
+    assert(bp != NULL, "bp != NULL");
+  }
+
+  VMOp_Type type() const { return VMOp_ChangeBreakpoints; }
+  void doit();
+  void oops_do(OopClosure* f);
+};
+
+
 ///////////////////////////////////////////////////////////////
 // The get/set local operations must only be done by the VM thread
 // because the interpreter version needs to access oop maps, which can
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1349,12 +1349,11 @@
         CHECK_0);
     }
 
-    finalize_operands_merge(*merge_cp_p, THREAD);
-
     RC_TRACE_WITH_THREAD(0x00020000, THREAD,
       ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
       *merge_cp_length_p, scratch_i, _index_map_count));
   }
+  finalize_operands_merge(*merge_cp_p, THREAD);
 
   return true;
 } // end merge_constant_pools()
--- a/src/share/vm/prims/methodHandles.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/methodHandles.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -232,7 +232,8 @@
   // This is done eagerly, since it is readily available without
   // constructing any new objects.
   // TO DO: maybe intern mname_oop
-  m->method_holder()->add_member_name(mname);
+  m->method_holder()->add_member_name(m->method_idnum(), mname);
+
   return mname();
 }
 
@@ -301,7 +302,6 @@
   // Although the fieldDescriptor::_index would also identify the field,
   // we do not use it, because it is harder to decode.
   // TO DO: maybe intern mname_oop
-  InstanceKlass::cast(field_holder())->add_member_name(mname);
   return mname();
 }
 
@@ -943,7 +943,8 @@
 // MemberNameTable
 //
 
-MemberNameTable::MemberNameTable() : GrowableArray<jweak>(10, true) {
+MemberNameTable::MemberNameTable(int methods_cnt)
+                  : GrowableArray<jweak>(methods_cnt, true) {
   assert_locked_or_safepoint(MemberNameTable_lock);
 }
 
@@ -957,29 +958,18 @@
   }
 }
 
-// Return entry index if found, return -1 otherwise.
-int MemberNameTable::find_member_name(oop mem_name) {
+void MemberNameTable::add_member_name(int index, jweak mem_name_wref) {
   assert_locked_or_safepoint(MemberNameTable_lock);
-  int len = this->length();
-
-  for (int idx = 0; idx < len; idx++) {
-    jweak ref = this->at(idx);
-    oop entry = JNIHandles::resolve(ref);
-    if (entry == mem_name) {
-      return idx;
-    }
-  }
-  return -1;
+  this->at_put_grow(index, mem_name_wref);
 }
 
-void MemberNameTable::add_member_name(jweak mem_name_wref) {
+// Return a member name oop or NULL.
+oop MemberNameTable::get_member_name(int index) {
   assert_locked_or_safepoint(MemberNameTable_lock);
-  oop mem_name = JNIHandles::resolve(mem_name_wref);
 
-  // Each member name may appear just once: add only if not found
-  if (find_member_name(mem_name) == -1) {
-    this->append(mem_name_wref);
-  }
+  jweak ref = this->at(index);
+  oop mem_name = JNIHandles::resolve(ref);
+  return mem_name;
 }
 
 #if INCLUDE_JVMTI
--- a/src/share/vm/prims/methodHandles.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/methodHandles.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -219,7 +219,6 @@
   }
 };
 
-
 //------------------------------------------------------------------------------
 // MethodHandlesAdapterGenerator
 //
@@ -233,13 +232,13 @@
 //------------------------------------------------------------------------------
 // MemberNameTable
 //
+
 class MemberNameTable : public GrowableArray<jweak> {
  public:
-  MemberNameTable();
+  MemberNameTable(int methods_cnt);
   ~MemberNameTable();
-  void add_member_name(jweak mem_name_ref);
- private:
-  int find_member_name(oop mem_name);
+  void add_member_name(int index, jweak mem_name_ref);
+  oop  get_member_name(int index);
 
 #if INCLUDE_JVMTI
  public:
--- a/src/share/vm/prims/unsafe.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/unsafe.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
 #include "runtime/reflection.hpp"
 #include "runtime/synchronizer.hpp"
 #include "services/threadService.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/dtrace.hpp"
 
@@ -115,8 +116,6 @@
 
 inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) {
   jlong byte_offset = field_offset_to_byte_offset(field_offset);
-  // Don't allow unsafe to be used to read or write the header word of oops
-  assert(p == NULL || field_offset >= oopDesc::header_size(), "offset must be outside of header");
 #ifdef ASSERT
   if (p != NULL) {
     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
@@ -1206,6 +1205,7 @@
 
 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
   UnsafeWrapper("Unsafe_Park");
+  EventThreadPark event;
 #ifndef USDT2
   HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
 #else /* USDT2 */
@@ -1220,6 +1220,13 @@
   HOTSPOT_THREAD_PARK_END(
                           (uintptr_t) thread->parker());
 #endif /* USDT2 */
+  if (event.should_commit()) {
+    oop obj = thread->current_park_blocker();
+    event.set_klass(obj ? obj->klass() : NULL);
+    event.set_timeout(time);
+    event.set_address(obj ? (TYPE_ADDRESS) (uintptr_t) obj : 0);
+    event.commit();
+  }
 UNSAFE_END
 
 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
--- a/src/share/vm/prims/whitebox.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/prims/whitebox.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -37,6 +37,7 @@
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/macros.hpp"
+#include "utilities/exceptions.hpp"
 
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/g1/concurrentMark.hpp"
@@ -330,8 +331,18 @@
 WB_END
 
 
-WB_ENTRY(jlong, WB_ReserveMemory(JNIEnv* env, jobject o, jlong size))
-  return (jlong)os::reserve_memory(size, NULL, 0);
+WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
+  // static+volatile in order to force the read to happen
+  // (not be eliminated by the compiler)
+  static char c;
+  static volatile char* p;
+
+  p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
+  if (p == NULL) {
+    THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
+  }
+
+  c = *p;
 WB_END
 
 //Some convenience methods to deal with objects from java
@@ -437,7 +448,7 @@
   {CC"isInStringTable",   CC"(Ljava/lang/String;)Z",  (void*)&WB_IsInStringTable  },
   {CC"fullGC",   CC"()V",                             (void*)&WB_FullGC },
 
-  {CC"reserveMemory", CC"(J)J", (void*)&WB_ReserveMemory },
+  {CC"readReservedMemory", CC"()V",                   (void*)&WB_ReadReservedMemory },
 };
 
 #undef CC
--- a/src/share/vm/runtime/arguments.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -2217,6 +2217,13 @@
     status = false;
   }
 
+  if (ReservedCodeCacheSize < InitialCodeCacheSize) {
+    jio_fprintf(defaultStream::error_stream(),
+                "Invalid ReservedCodeCacheSize: %dK. Should be greater than InitialCodeCacheSize=%dK\n",
+                ReservedCodeCacheSize/K, InitialCodeCacheSize/K);
+    status = false;
+  }
+
   return status;
 }
 
@@ -2619,13 +2626,10 @@
     } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
                match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
       julong long_ReservedCodeCacheSize = 0;
-      ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize,
-                                            (size_t)InitialCodeCacheSize);
+      ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize, 1);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum code cache size: %s. Should be greater than InitialCodeCacheSize=%dK\n",
-                    option->optionString, InitialCodeCacheSize/K);
-        describe_range_error(errcode);
+                    "Invalid maximum code cache size: %s.\n", option->optionString);
         return JNI_EINVAL;
       }
       FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize);
--- a/src/share/vm/runtime/deoptimization.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/deoptimization.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -638,18 +638,22 @@
       // at an uncommon trap for an invoke (where the compiler
       // generates debug info before the invoke has executed)
       Bytecodes::Code cur_code = str.next();
-      if (cur_code == Bytecodes::_invokevirtual ||
-          cur_code == Bytecodes::_invokespecial ||
-          cur_code == Bytecodes::_invokestatic  ||
-          cur_code == Bytecodes::_invokeinterface) {
+      if (cur_code == Bytecodes::_invokevirtual   ||
+          cur_code == Bytecodes::_invokespecial   ||
+          cur_code == Bytecodes::_invokestatic    ||
+          cur_code == Bytecodes::_invokeinterface ||
+          cur_code == Bytecodes::_invokedynamic) {
         Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
         Symbol* signature = invoke.signature();
         ArgumentSizeComputer asc(signature);
         cur_invoke_parameter_size = asc.size();
-        if (cur_code != Bytecodes::_invokestatic) {
+        if (invoke.has_receiver()) {
           // Add in receiver
           ++cur_invoke_parameter_size;
         }
+        if (i != 0 && !invoke.is_invokedynamic() && MethodHandles::has_member_arg(invoke.klass(), invoke.name())) {
+          callee_size_of_parameters++;
+        }
       }
       if (str.bci() < max_bci) {
         Bytecodes::Code bc = str.next();
@@ -664,6 +668,7 @@
             case Bytecodes::_invokespecial:
             case Bytecodes::_invokestatic:
             case Bytecodes::_invokeinterface:
+            case Bytecodes::_invokedynamic:
             case Bytecodes::_athrow:
               break;
             default: {
--- a/src/share/vm/runtime/frame.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/frame.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1008,6 +1008,7 @@
   OopClosure*     _f;
   int             _offset;        // the current offset, incremented with each argument
   bool            _has_receiver;  // true if the callee has a receiver
+  bool            _has_appendix;  // true if the call has an appendix
   frame           _fr;
   RegisterMap*    _reg_map;
   int             _arg_size;
@@ -1027,19 +1028,20 @@
   }
 
  public:
-  CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr,  const RegisterMap* reg_map)
+  CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr,  const RegisterMap* reg_map)
     : SignatureInfo(signature) {
 
     // initialize CompiledArgumentOopFinder
     _f         = f;
     _offset    = 0;
     _has_receiver = has_receiver;
+    _has_appendix = has_appendix;
     _fr        = fr;
     _reg_map   = (RegisterMap*)reg_map;
-    _arg_size  = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
+    _arg_size  = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
 
     int arg_size;
-    _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size);
+    _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
     assert(arg_size == _arg_size, "wrong arg size");
   }
 
@@ -1049,12 +1051,16 @@
       _offset++;
     }
     iterate_parameters();
+    if (_has_appendix) {
+      handle_oop_offset();
+      _offset++;
+    }
   }
 };
 
-void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) {
+void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) {
   ResourceMark rm;
-  CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map);
+  CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
   finder.oops_do();
 }
 
--- a/src/share/vm/runtime/frame.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/frame.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -137,6 +137,7 @@
   bool is_interpreted_frame()    const;
   bool is_java_frame()           const;
   bool is_entry_frame()          const;             // Java frame called from C?
+  bool is_stub_frame()           const;
   bool is_ignored_frame()        const;
   bool is_native_frame()         const;
   bool is_runtime_frame()        const;
@@ -414,7 +415,7 @@
   oop* oopmapreg_to_location(VMReg reg, const RegisterMap* regmap) const;
 
   // Oops-do's
-  void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f);
+  void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f);
   void oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
 
  private:
--- a/src/share/vm/runtime/frame.inline.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/frame.inline.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,10 @@
   return StubRoutines::returns_to_call_stub(pc());
 }
 
+inline bool frame::is_stub_frame() const {
+  return StubRoutines::is_stub_code(pc()) || (_cb != NULL && _cb->is_adapter_blob());
+}
+
 inline bool frame::is_first_frame() const {
   return is_entry_frame() && entry_frame_is_first();
 }
--- a/src/share/vm/runtime/globals.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/globals.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -2310,6 +2310,10 @@
           "Print diagnostic message when GC is stalled"                     \
           "by JNI critical section")                                        \
                                                                             \
+  experimental(double, ObjectCountCutOffPercent, 0.5,                       \
+          "The percentage of the used heap that the instances of a class "  \
+          "must occupy for the class to generate a trace event.")           \
+                                                                            \
   /* GC log rotation setting */                                             \
                                                                             \
   product(bool, UseGCLogFileRotation, false,                                \
@@ -3688,7 +3692,13 @@
   experimental(uintx, ArrayAllocatorMallocLimit,                            \
           SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx),                        \
           "Allocation less than this value will be allocated "              \
-          "using malloc. Larger allocations will use mmap.")
+          "using malloc. Larger allocations will use mmap.")                \
+                                                                            \
+  product(bool, EnableTracing, false,                                       \
+          "Enable event-based tracing")                                     \
+  product(bool, UseLockedTracing, false,                                    \
+          "Use locked-tracing when doing event-based tracing")
+
 
 /*
  *  Macros for factoring of globals
--- a/src/share/vm/runtime/java.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/java.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,6 @@
 #include "services/memReporter.hpp"
 #include "services/memTracker.hpp"
 #include "trace/tracing.hpp"
-#include "trace/traceEventTypes.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/histogram.hpp"
@@ -528,9 +527,12 @@
     JvmtiExport::post_thread_end(thread);
   }
 
-  EVENT_BEGIN(TraceEventThreadEnd, event);
-  EVENT_COMMIT(event,
-      EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
+  EventThreadEnd event;
+  if (event.should_commit()) {
+      event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+      event.commit();
+  }
 
   // Always call even when there are not JVMTI environments yet, since environments
   // may be attached late and JVMTI must track phases of VM execution
--- a/src/share/vm/runtime/mutexLocker.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/mutexLocker.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -270,13 +270,12 @@
   def(MethodCompileQueue_lock      , Monitor, nonleaf+4,   true );
   def(Debug2_lock                  , Mutex  , nonleaf+4,   true );
   def(Debug3_lock                  , Mutex  , nonleaf+4,   true );
-  def(ProfileVM_lock               , Monitor, nonleaf+4,   false); // used for profiling of the VMThread
+  def(ProfileVM_lock               , Monitor, special,   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);
+  def(JfrMsg_lock                  , Monitor, leaf,        true);
+  def(JfrBuffer_lock               , Mutex,   nonleaf+1,   true);
+  def(JfrStream_lock               , Mutex,   nonleaf+2,   true);
   def(PeriodicTask_lock            , Monitor, nonleaf+5,   true);
 }
 
--- a/src/share/vm/runtime/objectMonitor.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/objectMonitor.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -36,7 +36,10 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
 #include "services/threadService.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/dtrace.hpp"
+#include "utilities/macros.hpp"
 #include "utilities/preserveException.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
@@ -371,6 +374,8 @@
   // Ensure the object-monitor relationship remains stable while there's contention.
   Atomic::inc_ptr(&_count);
 
+  EventJavaMonitorEnter event;
+
   { // Change java thread status to indicate blocked on monitor enter.
     JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this);
 
@@ -402,7 +407,7 @@
       //
           _recursions = 0 ;
       _succ = NULL ;
-      exit (Self) ;
+      exit (false, Self) ;
 
       jt->java_suspend_self();
     }
@@ -435,6 +440,14 @@
   if (JvmtiExport::should_post_monitor_contended_entered()) {
     JvmtiExport::post_monitor_contended_entered(jt, this);
   }
+
+  if (event.should_commit()) {
+    event.set_klass(((oop)this->object())->klass());
+    event.set_previousOwner((TYPE_JAVALANGTHREAD)_previous_owner_tid);
+    event.set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr()));
+    event.commit();
+  }
+
   if (ObjectMonitor::_sync_ContendedLockAttempts != NULL) {
      ObjectMonitor::_sync_ContendedLockAttempts->inc() ;
   }
@@ -917,7 +930,7 @@
 // Both impinge on OS scalability.  Given that, at most one thread parked on
 // a monitor will use a timer.
 
-void ATTR ObjectMonitor::exit(TRAPS) {
+void ATTR ObjectMonitor::exit(bool not_suspended, TRAPS) {
    Thread * Self = THREAD ;
    if (THREAD != _owner) {
      if (THREAD->is_lock_owned((address) _owner)) {
@@ -954,6 +967,14 @@
       _Responsible = NULL ;
    }
 
+#if INCLUDE_TRACE
+   // get the owner's thread id for the MonitorEnter event
+   // if it is enabled and the thread isn't suspended
+   if (not_suspended && Tracing::is_event_enabled(TraceJavaMonitorEnterEvent)) {
+     _previous_owner_tid = SharedRuntime::get_java_tid(Self);
+   }
+#endif
+
    for (;;) {
       assert (THREAD == _owner, "invariant") ;
 
@@ -1343,7 +1364,7 @@
    guarantee(Self == _owner, "complete_exit not owner");
    intptr_t save = _recursions; // record the old recursion count
    _recursions = 0;        // set the recursion level to be 0
-   exit (Self) ;           // exit the monitor
+   exit (true, Self) ;           // exit the monitor
    guarantee (_owner != Self, "invariant");
    return save;
 }
@@ -1397,6 +1418,20 @@
   for (v = *adr ; Atomic::cmpxchg (v + dx, adr, v) != v; v = *adr) ;
   return v ;
 }
+
+// helper method for posting a monitor wait event
+void ObjectMonitor::post_monitor_wait_event(EventJavaMonitorWait* event,
+                                                           jlong notifier_tid,
+                                                           jlong timeout,
+                                                           bool timedout) {
+  event->set_klass(((oop)this->object())->klass());
+  event->set_timeout((TYPE_ULONG)timeout);
+  event->set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr()));
+  event->set_notifier((TYPE_OSTHREAD)notifier_tid);
+  event->set_timedOut((TYPE_BOOLEAN)timedout);
+  event->commit();
+}
+
 // -----------------------------------------------------------------------------
 // Wait/Notify/NotifyAll
 //
@@ -1412,6 +1447,8 @@
    // Throw IMSX or IEX.
    CHECK_OWNER();
 
+   EventJavaMonitorWait event;
+
    // check for a pending interrupt
    if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
      // post monitor waited event.  Note that this is past-tense, we are done waiting.
@@ -1420,10 +1457,14 @@
         // wait was not timed out due to thread interrupt.
         JvmtiExport::post_monitor_waited(jt, this, false);
      }
+     if (event.should_commit()) {
+       post_monitor_wait_event(&event, 0, millis, false);
+     }
      TEVENT (Wait - Throw IEX) ;
      THROW(vmSymbols::java_lang_InterruptedException());
      return ;
    }
+
    TEVENT (Wait) ;
 
    assert (Self->_Stalled == 0, "invariant") ;
@@ -1455,7 +1496,7 @@
    intptr_t save = _recursions; // record the old recursion count
    _waiters++;                  // increment the number of waiters
    _recursions = 0;             // set the recursion level to be 1
-   exit (Self) ;                    // exit the monitor
+   exit (true, Self) ;                    // exit the monitor
    guarantee (_owner != Self, "invariant") ;
 
    // As soon as the ObjectMonitor's ownership is dropped in the exit()
@@ -1555,6 +1596,11 @@
      if (JvmtiExport::should_post_monitor_waited()) {
        JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);
      }
+
+     if (event.should_commit()) {
+       post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT);
+     }
+
      OrderAccess::fence() ;
 
      assert (Self->_Stalled != 0, "invariant") ;
@@ -1634,6 +1680,8 @@
         iterator->TState = ObjectWaiter::TS_ENTER ;
      }
      iterator->_notified = 1 ;
+     Thread * Self = THREAD;
+     iterator->_notifier_tid = Self->osthread()->thread_id();
 
      ObjectWaiter * List = _EntryList ;
      if (List != NULL) {
@@ -1758,6 +1806,8 @@
      guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ;
      guarantee (iterator->_notified == 0, "invariant") ;
      iterator->_notified = 1 ;
+     Thread * Self = THREAD;
+     iterator->_notifier_tid = Self->osthread()->thread_id();
      if (Policy != 4) {
         iterator->TState = ObjectWaiter::TS_ENTER ;
      }
--- a/src/share/vm/runtime/objectMonitor.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/objectMonitor.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
 #include "runtime/park.hpp"
 #include "runtime/perfData.hpp"
 
-
 // ObjectWaiter serves as a "proxy" or surrogate thread.
 // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
 // ParkEvent instead.  Beware, however, that the JVMTI code
@@ -43,6 +42,7 @@
   ObjectWaiter * volatile _next;
   ObjectWaiter * volatile _prev;
   Thread*       _thread;
+  jlong         _notifier_tid;
   ParkEvent *   _event;
   volatile int  _notified ;
   volatile TStates TState ;
@@ -55,6 +55,9 @@
   void wait_reenter_end(ObjectMonitor *mon);
 };
 
+// forward declaration to avoid include tracing.hpp
+class EventJavaMonitorWait;
+
 // WARNING:
 //   This is a very sensitive and fragile class. DO NOT make any
 // change unless you are fully aware of the underlying semantics.
@@ -151,6 +154,7 @@
     _SpinFreq     = 0 ;
     _SpinClock    = 0 ;
     OwnerIsThread = 0 ;
+    _previous_owner_tid = 0;
   }
 
   ~ObjectMonitor() {
@@ -192,7 +196,7 @@
 
   bool      try_enter (TRAPS) ;
   void      enter(TRAPS);
-  void      exit(TRAPS);
+  void      exit(bool not_suspended, TRAPS);
   void      wait(jlong millis, bool interruptable, TRAPS);
   void      notify(TRAPS);
   void      notifyAll(TRAPS);
@@ -218,6 +222,10 @@
   void      ctAsserts () ;
   void      ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ;
   bool      ExitSuspendEquivalent (JavaThread * Self) ;
+  void      post_monitor_wait_event(EventJavaMonitorWait * event,
+                                                   jlong notifier_tid,
+                                                   jlong timeout,
+                                                   bool timedout);
 
  private:
   friend class ObjectSynchronizer;
@@ -240,6 +248,7 @@
 
  protected:                         // protected for jvmtiRawMonitor
   void *  volatile _owner;          // pointer to owning thread OR BasicLock
+  volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
   volatile intptr_t  _recursions;   // recursion count, 0 for first entry
  private:
   int OwnerIsThread ;               // _owner is (Thread *) vs SP/BasicLock
--- a/src/share/vm/runtime/os.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/os.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -265,8 +265,7 @@
         VMThread::execute(&op1);
         Universe::print_heap_at_SIGBREAK();
         if (PrintClassHistogram) {
-          VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */,
-                                   true /* need_prologue */);
+          VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */);
           VMThread::execute(&op1);
         }
         if (JvmtiExport::should_post_data_dump()) {
@@ -1444,11 +1443,16 @@
   return (int) i;
 }
 
+void os::SuspendedThreadTask::run() {
+  assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this");
+  internal_do_task();
+  _done = true;
+}
+
 bool os::create_stack_guard_pages(char* addr, size_t bytes) {
   return os::pd_create_stack_guard_pages(addr, bytes);
 }
 
-
 char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
   char* result = pd_reserve_memory(bytes, addr, alignment_hint);
   if (result != NULL) {
@@ -1551,3 +1555,19 @@
   pd_realign_memory(addr, bytes, alignment_hint);
 }
 
+#ifndef TARGET_OS_FAMILY_windows
+/* try to switch state from state "from" to state "to"
+ * returns the state set after the method is complete
+ */
+os::SuspendResume::State os::SuspendResume::switch_state(os::SuspendResume::State from,
+                                                         os::SuspendResume::State to)
+{
+  os::SuspendResume::State result =
+    (os::SuspendResume::State) Atomic::cmpxchg((jint) to, (jint *) &_state, (jint) from);
+  if (result == from) {
+    // success
+    return to;
+  }
+  return result;
+}
+#endif
--- a/src/share/vm/runtime/os.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/os.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -781,6 +781,104 @@
   // ResumeThread call)
   static void pause();
 
+  class SuspendedThreadTaskContext {
+  public:
+    SuspendedThreadTaskContext(Thread* thread, void *ucontext) : _thread(thread), _ucontext(ucontext) {}
+    Thread* thread() const { return _thread; }
+    void* ucontext() const { return _ucontext; }
+  private:
+    Thread* _thread;
+    void* _ucontext;
+  };
+
+  class SuspendedThreadTask {
+  public:
+    SuspendedThreadTask(Thread* thread) : _thread(thread), _done(false) {}
+    virtual ~SuspendedThreadTask() {}
+    void run();
+    bool is_done() { return _done; }
+    virtual void do_task(const SuspendedThreadTaskContext& context) = 0;
+  protected:
+  private:
+    void internal_do_task();
+    Thread* _thread;
+    bool _done;
+  };
+
+#ifndef TARGET_OS_FAMILY_windows
+  // Suspend/resume support
+  // Protocol:
+  //
+  // a thread starts in SR_RUNNING
+  //
+  // SR_RUNNING can go to
+  //   * SR_SUSPEND_REQUEST when the WatcherThread wants to suspend it
+  // SR_SUSPEND_REQUEST can go to
+  //   * SR_RUNNING if WatcherThread decides it waited for SR_SUSPENDED too long (timeout)
+  //   * SR_SUSPENDED if the stopped thread receives the signal and switches state
+  // SR_SUSPENDED can go to
+  //   * SR_WAKEUP_REQUEST when the WatcherThread has done the work and wants to resume
+  // SR_WAKEUP_REQUEST can go to
+  //   * SR_RUNNING when the stopped thread receives the signal
+  //   * SR_WAKEUP_REQUEST on timeout (resend the signal and try again)
+  class SuspendResume {
+   public:
+    enum State {
+      SR_RUNNING,
+      SR_SUSPEND_REQUEST,
+      SR_SUSPENDED,
+      SR_WAKEUP_REQUEST
+    };
+
+  private:
+    volatile State _state;
+
+  private:
+    /* try to switch state from state "from" to state "to"
+     * returns the state set after the method is complete
+     */
+    State switch_state(State from, State to);
+
+  public:
+    SuspendResume() : _state(SR_RUNNING) { }
+
+    State state() const { return _state; }
+
+    State request_suspend() {
+      return switch_state(SR_RUNNING, SR_SUSPEND_REQUEST);
+    }
+
+    State cancel_suspend() {
+      return switch_state(SR_SUSPEND_REQUEST, SR_RUNNING);
+    }
+
+    State suspended() {
+      return switch_state(SR_SUSPEND_REQUEST, SR_SUSPENDED);
+    }
+
+    State request_wakeup() {
+      return switch_state(SR_SUSPENDED, SR_WAKEUP_REQUEST);
+    }
+
+    State running() {
+      return switch_state(SR_WAKEUP_REQUEST, SR_RUNNING);
+    }
+
+    bool is_running() const {
+      return _state == SR_RUNNING;
+    }
+
+    bool is_suspend_request() const {
+      return _state == SR_SUSPEND_REQUEST;
+    }
+
+    bool is_suspended() const {
+      return _state == SR_SUSPENDED;
+    }
+  };
+#endif
+
+
  protected:
   static long _rand_seed;                   // seed for random number generator
   static int _processor_count;              // number of processors
--- a/src/share/vm/runtime/perfData.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/perfData.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -323,6 +323,10 @@
   }
 }
 
+PerfData* PerfDataManager::find_by_name(const char* name) {
+  return _all->find_by_name(name);
+}
+
 PerfDataList* PerfDataManager::all() {
 
   MutexLocker ml(PerfDataManager_lock);
--- a/src/share/vm/runtime/perfData.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/perfData.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -693,6 +693,9 @@
     // the given name.
     static bool exists(const char* name) { return _all->contains(name); }
 
+    // method to search for a instrumentation object by name
+    static PerfData* find_by_name(const char* name);
+
     // method to map a CounterNS enumeration to a namespace string
     static const char* ns_to_string(CounterNS ns) {
       return _name_spaces[ns];
--- a/src/share/vm/runtime/reflection.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/reflection.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,6 @@
 #include "runtime/signature.hpp"
 #include "runtime/vframe.hpp"
 
-#define JAVA_1_5_VERSION                  49
-
 static void trace_class_resolution(Klass* to_class) {
   ResourceMark rm;
   int line_number = -1;
@@ -375,7 +373,7 @@
     }
   }
   klass = klass->array_klass(dim, CHECK_NULL);
-  oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD);
+  oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL);
   assert(obj->is_array(), "just checking");
   return arrayOop(obj);
 }
@@ -507,9 +505,11 @@
       under_host_klass(accessee_ik, accessor))
     return true;
 
-  if (RelaxAccessControlCheck ||
-      (accessor_ik->major_version() < JAVA_1_5_VERSION &&
-       accessee_ik->major_version() < JAVA_1_5_VERSION)) {
+  if ((RelaxAccessControlCheck &&
+        accessor_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION &&
+        accessee_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION) ||
+      (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION &&
+       accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) {
     return classloader_only &&
       Verifier::relax_verify_for(accessor_ik->class_loader()) &&
       accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
@@ -817,6 +817,10 @@
     typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
     java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
   }
+  if (java_lang_reflect_Constructor::has_type_annotations_field()) {
+    typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL);
+    java_lang_reflect_Constructor::set_type_annotations(ch(), an_oop);
+  }
   return ch();
 }
 
--- a/src/share/vm/runtime/sharedRuntime.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -2726,7 +2726,7 @@
   return regs.first();
 }
 
-VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, int* arg_size) {
+VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int* arg_size) {
   // This method is returning a data structure allocating as a
   // ResourceObject, so do not put any ResourceMarks in here.
   char *s = sig->as_C_string();
@@ -2770,6 +2770,11 @@
     default : ShouldNotReachHere();
     }
   }
+
+  if (has_appendix) {
+    sig_bt[cnt++] = T_OBJECT;
+  }
+
   assert( cnt < 256, "grow table size" );
 
   int comp_args_on_stack;
--- a/src/share/vm/runtime/sharedRuntime.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -410,7 +410,7 @@
 
   // Convert a sig into a calling convention register layout
   // and find interesting things about it.
-  static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, int *arg_size);
+  static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int *arg_size);
   static VMReg     name_for_receiver();
 
   // "Top of Stack" slots that may be unused by the calling convention but must
--- a/src/share/vm/runtime/stubRoutines.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/stubRoutines.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -226,6 +226,8 @@
   static void    initialize1();                            // must happen before universe::genesis
   static void    initialize2();                            // must happen after  universe::genesis
 
+  static bool is_stub_code(address addr)                   { return contains(addr); }
+
   static bool contains(address addr) {
     return
       (_code1 != NULL && _code1->blob_contains(addr)) ||
--- a/src/share/vm/runtime/sweeper.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/sweeper.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
 #include "runtime/os.hpp"
 #include "runtime/sweeper.hpp"
 #include "runtime/vm_operations.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/events.hpp"
 #include "utilities/xmlstream.hpp"
 
@@ -130,6 +131,9 @@
 long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
 nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
 int       NMethodSweeper::_seen = 0 ;        // No. of nmethods we have currently processed in current pass of CodeCache
+int       NMethodSweeper::_flushed_count = 0;   // Nof. nmethods flushed in current sweep
+int       NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep
+int       NMethodSweeper::_marked_count = 0;    // Nof. nmethods marked for reclaim in current sweep
 
 volatile int NMethodSweeper::_invocations = 0;   // No. of invocations left until we are completed with this pass
 volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
@@ -143,6 +147,15 @@
 int       NMethodSweeper::_dead_compile_ids = 0;
 long      NMethodSweeper::_last_flush_traversal_id = 0;
 
+int       NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache
+int       NMethodSweeper::_total_nof_methods_reclaimed = 0;
+jlong     NMethodSweeper::_total_time_sweeping = 0;
+jlong     NMethodSweeper::_total_time_this_sweep = 0;
+jlong     NMethodSweeper::_peak_sweep_time = 0;
+jlong     NMethodSweeper::_peak_sweep_fraction_time = 0;
+jlong     NMethodSweeper::_total_disconnect_time = 0;
+jlong     NMethodSweeper::_peak_disconnect_time = 0;
+
 class MarkActivationClosure: public CodeBlobClosure {
 public:
   virtual void do_code_blob(CodeBlob* cb) {
@@ -176,6 +189,8 @@
     _invocations = NmethodSweepFraction;
     _current     = CodeCache::first_nmethod();
     _traversals  += 1;
+    _total_time_this_sweep = 0;
+
     if (PrintMethodFlushing) {
       tty->print_cr("### Sweep: stack traversal %d", _traversals);
     }
@@ -229,12 +244,13 @@
 }
 
 void NMethodSweeper::sweep_code_cache() {
-#ifdef ASSERT
-  jlong sweep_start;
-  if (PrintMethodFlushing) {
-    sweep_start = os::javaTimeMillis();
-  }
-#endif
+
+  jlong sweep_start_counter = os::elapsed_counter();
+
+  _flushed_count   = 0;
+  _zombified_count = 0;
+  _marked_count    = 0;
+
   if (PrintMethodFlushing && Verbose) {
     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations);
   }
@@ -302,14 +318,34 @@
     }
   }
 
+  jlong sweep_end_counter = os::elapsed_counter();
+  jlong sweep_time = sweep_end_counter - sweep_start_counter;
+  _total_time_sweeping  += sweep_time;
+  _total_time_this_sweep += sweep_time;
+  _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
+  _total_nof_methods_reclaimed += _flushed_count;
+
+  EventSweepCodeCache event(UNTIMED);
+  if (event.should_commit()) {
+    event.set_starttime(sweep_start_counter);
+    event.set_endtime(sweep_end_counter);
+    event.set_sweepIndex(_traversals);
+    event.set_sweepFractionIndex(NmethodSweepFraction - _invocations + 1);
+    event.set_sweptCount(todo);
+    event.set_flushedCount(_flushed_count);
+    event.set_markedCount(_marked_count);
+    event.set_zombifiedCount(_zombified_count);
+    event.commit();
+  }
+
 #ifdef ASSERT
   if(PrintMethodFlushing) {
-    jlong sweep_end             = os::javaTimeMillis();
-    tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start);
+    tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, (jlong)sweep_time);
   }
 #endif
 
   if (_invocations == 1) {
+    _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
     log_sweep("finished");
   }
 
@@ -388,12 +424,14 @@
         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
       }
       release_nmethod(nm);
+      _flushed_count++;
     } else {
       if (PrintMethodFlushing && Verbose) {
         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
       }
       nm->mark_for_reclamation();
       _resweep = true;
+      _marked_count++;
       SWEEP(nm);
     }
   } else if (nm->is_not_entrant()) {
@@ -405,6 +443,7 @@
       }
       nm->make_zombie();
       _resweep = true;
+      _zombified_count++;
       SWEEP(nm);
     } else {
       // Still alive, clean up its inline caches
@@ -420,13 +459,16 @@
     // Unloaded code, just make it a zombie
     if (PrintMethodFlushing && Verbose)
       tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
+
     if (nm->is_osr_method()) {
       SWEEP(nm);
       // No inline caches will ever point to osr methods, so we can just remove it
       release_nmethod(nm);
+      _flushed_count++;
     } else {
       nm->make_zombie();
       _resweep = true;
+      _zombified_count++;
       SWEEP(nm);
     }
   } else {
@@ -484,7 +526,7 @@
   // If there was a race in detecting full code cache, only run
   // one vm op for it or keep the compiler shut off
 
-  debug_only(jlong start = os::javaTimeMillis();)
+  jlong disconnect_start_counter = os::elapsed_counter();
 
   // Traverse the code cache trying to dump the oldest nmethods
   int curr_max_comp_id = CompileBroker::get_compilation_id();
@@ -541,13 +583,28 @@
     _last_full_flush_time = os::javaTimeMillis();
   }
 
+  jlong disconnect_end_counter = os::elapsed_counter();
+  jlong disconnect_time = disconnect_end_counter - disconnect_start_counter;
+  _total_disconnect_time += disconnect_time;
+  _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time);
+
+  EventCleanCodeCache event(UNTIMED);
+  if (event.should_commit()) {
+    event.set_starttime(disconnect_start_counter);
+    event.set_endtime(disconnect_end_counter);
+    event.set_disconnectedCount(disconnected);
+    event.set_madeNonEntrantCount(made_not_entrant);
+    event.commit();
+  }
+  _number_of_flushes++;
+
   // After two more traversals the sweeper will get rid of unrestored nmethods
   _last_flush_traversal_id = _traversals;
   _resweep = true;
 #ifdef ASSERT
-  jlong end = os::javaTimeMillis();
+
   if(PrintMethodFlushing && Verbose) {
-    tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start);
+    tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time);
   }
 #endif
 }
--- a/src/share/vm/runtime/sweeper.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/sweeper.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,12 @@
 //
 
 class NMethodSweeper : public AllStatic {
-  static long      _traversals;   // Stack traversal count
-  static nmethod*  _current;      // Current nmethod
-  static int       _seen;         // Nof. nmethod we have currently processed in current pass of CodeCache
+  static long      _traversals;      // Stack scan count, also sweep ID.
+  static nmethod*  _current;         // Current nmethod
+  static int       _seen;            // Nof. nmethod we have currently processed in current pass of CodeCache
+  static int       _flushed_count;   // Nof. nmethods flushed in current sweep
+  static int       _zombified_count; // Nof. nmethods made zombie in current sweep
+  static int       _marked_count;    // Nof. nmethods marked for reclaim in current sweep
 
   static volatile int  _invocations;   // No. of invocations left until we are completed with this pass
   static volatile int  _sweep_started; // Flag to control conc sweeper
@@ -53,6 +56,16 @@
   static int       _highest_marked;   // highest compile id dumped at last emergency unloading
   static int       _dead_compile_ids; // number of compile ids that where not in the cache last flush
 
+  // Stat counters
+  static int       _number_of_flushes;            // Total of full traversals caused by full cache
+  static int       _total_nof_methods_reclaimed;  // Accumulated nof methods flushed
+  static jlong     _total_time_sweeping;          // Accumulated time sweeping
+  static jlong     _total_time_this_sweep;        // Total time this sweep
+  static jlong     _peak_sweep_time;              // Peak time for a full sweep
+  static jlong     _peak_sweep_fraction_time;     // Peak time sweeping one fraction
+  static jlong     _total_disconnect_time;        // Total time cleaning code mem
+  static jlong     _peak_disconnect_time;         // Peak time cleaning code mem
+
   static void process_nmethod(nmethod *nm);
   static void release_nmethod(nmethod* nm);
 
@@ -60,7 +73,14 @@
   static bool sweep_in_progress();
 
  public:
-  static long traversal_count() { return _traversals; }
+  static long traversal_count()              { return _traversals; }
+  static int  number_of_flushes()            { return _number_of_flushes; }
+  static int  total_nof_methods_reclaimed()  { return _total_nof_methods_reclaimed; }
+  static jlong total_time_sweeping()         { return _total_time_sweeping; }
+  static jlong peak_sweep_time()             { return _peak_sweep_time; }
+  static jlong peak_sweep_fraction_time()    { return _peak_sweep_fraction_time; }
+  static jlong total_disconnect_time()       { return _total_disconnect_time; }
+  static jlong peak_disconnect_time()        { return _peak_disconnect_time; }
 
 #ifdef ASSERT
   // Keep track of sweeper activity in the ring buffer
--- a/src/share/vm/runtime/synchronizer.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/synchronizer.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -213,7 +213,7 @@
      }
   }
 
-  ObjectSynchronizer::inflate(THREAD, object)->exit (THREAD) ;
+  ObjectSynchronizer::inflate(THREAD, object)->exit (true, THREAD) ;
 }
 
 // -----------------------------------------------------------------------------
@@ -343,7 +343,7 @@
   // If this thread has locked the object, exit the monitor.  Note:  can't use
   // monitor->check(CHECK); must exit even if an exception is pending.
   if (monitor->check(THREAD)) {
-     monitor->exit(THREAD);
+     monitor->exit(true, THREAD);
   }
 }
 
--- a/src/share/vm/runtime/task.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/task.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,9 +114,11 @@
   disenroll();
 }
 
+/* enroll could be called from a JavaThread, so we have to check for
+ * safepoint when taking the lock to avoid deadlocking */
 void PeriodicTask::enroll() {
   MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
-                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+                     NULL : PeriodicTask_lock);
 
   if (_num_tasks == PeriodicTask::max_tasks) {
     fatal("Overflow in PeriodicTask table");
@@ -131,9 +133,11 @@
   }
 }
 
+/* disenroll could be called from a JavaThread, so we have to check for
+ * safepoint when taking the lock to avoid deadlocking */
 void PeriodicTask::disenroll() {
   MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
-                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+                     NULL : PeriodicTask_lock);
 
   int index;
   for(index = 0; index < _num_tasks && _tasks[index] != this; index++)
--- a/src/share/vm/runtime/thread.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/thread.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -77,7 +77,8 @@
 #include "services/management.hpp"
 #include "services/memTracker.hpp"
 #include "services/threadService.hpp"
-#include "trace/traceEventTypes.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
@@ -238,7 +239,6 @@
   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;
@@ -1659,9 +1659,11 @@
     JvmtiExport::post_thread_start(this);
   }
 
-  EVENT_BEGIN(TraceEventThreadStart, event);
-  EVENT_COMMIT(event,
-     EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));
+  EventThreadStart event;
+  if (event.should_commit()) {
+     event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj()));
+     event.commit();
+  }
 
   // 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
@@ -1791,9 +1793,11 @@
 
     // 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())));
+    EventThreadEnd event;
+    if (event.should_commit()) {
+        event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj()));
+        event.commit();
+    }
 
     // Call after last event on thread
     EVENT_THREAD_EXIT(this);
@@ -3648,8 +3652,8 @@
   // Notify JVMTI agents that VM initialization is complete - nop if no agents.
   JvmtiExport::post_vm_initialized();
 
-  if (!TRACE_START()) {
-    vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
+  if (TRACE_START() != JNI_OK) {
+    vm_exit_during_initialization("Failed to start tracing backend.");
   }
 
   if (CleanChunkPoolAsync) {
--- a/src/share/vm/runtime/thread.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/thread.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -47,7 +47,8 @@
 #include "services/memRecorder.hpp"
 #endif // INCLUDE_NMT
 
-#include "trace/tracing.hpp"
+#include "trace/traceBackend.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/top.hpp"
 #if INCLUDE_ALL_GCS
@@ -258,7 +259,7 @@
   jlong _allocated_bytes;                       // Cumulative number of bytes allocated on
                                                 // the Java heap
 
-  TRACE_BUFFER _trace_buffer;                   // Thread-local buffer for tracing
+  TRACE_DATA _trace_data;                       // Thread-local data for tracing
 
   int   _vm_operation_started_count;            // VM_Operation support
   int   _vm_operation_completed_count;          // VM_Operation support
@@ -449,8 +450,7 @@
     return allocated_bytes;
   }
 
-  TRACE_BUFFER trace_buffer()              { return _trace_buffer; }
-  void set_trace_buffer(TRACE_BUFFER buf)  { _trace_buffer = buf; }
+  TRACE_DATA* trace_data()              { return &_trace_data; }
 
   // VM operation support
   int vm_operation_ticket()                      { return ++_vm_operation_started_count; }
@@ -638,9 +638,6 @@
   jint _hashStateZ ;
   void * _schedctl ;
 
-  intptr_t _ScratchA, _ScratchB ;              // Scratch locations for fast-path sync code
-  static ByteSize ScratchA_offset()            { return byte_offset_of(Thread, _ScratchA ); }
-  static ByteSize ScratchB_offset()            { return byte_offset_of(Thread, _ScratchB ); }
 
   volatile jint rng [4] ;                      // RNG for spin loop
 
--- a/src/share/vm/runtime/timer.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/timer.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,11 @@
 # include "os_bsd.inline.hpp"
 #endif
 
+double TimeHelper::counter_to_seconds(jlong counter) {
+  double count = (double) counter;
+  double freq  = (double) os::elapsed_frequency();
+  return counter/freq;
+}
 
 void elapsedTimer::add(elapsedTimer t) {
   _counter += t._counter;
@@ -59,9 +64,7 @@
 }
 
 double elapsedTimer::seconds() const {
-  double count = (double) _counter;
-  double freq  = (double) os::elapsed_frequency();
-  return count/freq;
+ return TimeHelper::counter_to_seconds(_counter);
 }
 
 jlong elapsedTimer::milliseconds() const {
@@ -90,9 +93,7 @@
 double TimeStamp::seconds() const {
   assert(is_updated(), "must not be clear");
   jlong new_count = os::elapsed_counter();
-  double count = (double) new_count - _counter;
-  double freq  = (double) os::elapsed_frequency();
-  return count/freq;
+  return TimeHelper::counter_to_seconds(new_count - _counter);
 }
 
 jlong TimeStamp::milliseconds() const {
@@ -110,19 +111,15 @@
 }
 
 TraceTime::TraceTime(const char* title,
-                     bool doit,
-                     bool print_cr,
-                     outputStream* logfile) {
+                     bool doit) {
   _active   = doit;
   _verbose  = true;
-  _print_cr = print_cr;
-  _logfile = (logfile != NULL) ? logfile : tty;
 
   if (_active) {
     _accum = NULL;
-    _logfile->stamp(PrintGCTimeStamps);
-    _logfile->print("[%s", title);
-    _logfile->flush();
+    tty->stamp(PrintGCTimeStamps);
+    tty->print("[%s", title);
+    tty->flush();
     _t.start();
   }
 }
@@ -130,17 +127,14 @@
 TraceTime::TraceTime(const char* title,
                      elapsedTimer* accumulator,
                      bool doit,
-                     bool verbose,
-                     outputStream* logfile) {
+                     bool verbose) {
   _active = doit;
   _verbose = verbose;
-  _print_cr = true;
-  _logfile = (logfile != NULL) ? logfile : tty;
   if (_active) {
     if (_verbose) {
-      _logfile->stamp(PrintGCTimeStamps);
-      _logfile->print("[%s", title);
-      _logfile->flush();
+      tty->stamp(PrintGCTimeStamps);
+      tty->print("[%s", title);
+      tty->flush();
     }
     _accum = accumulator;
     _t.start();
@@ -152,12 +146,8 @@
     _t.stop();
     if (_accum!=NULL) _accum->add(_t);
     if (_verbose) {
-      if (_print_cr) {
-        _logfile->print_cr(", %3.7f secs]", _t.seconds());
-      } else {
-        _logfile->print(", %3.7f secs]", _t.seconds());
-      }
-      _logfile->flush();
+      tty->print_cr(", %3.7f secs]", _t.seconds());
+      tty->flush();
     }
   }
 }
--- a/src/share/vm/runtime/timer.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/timer.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,21 +82,16 @@
  private:
   bool          _active;    // do timing
   bool          _verbose;   // report every timing
-  bool          _print_cr;  // add a CR to the end of the timer report
   elapsedTimer  _t;         // timer
   elapsedTimer* _accum;     // accumulator
-  outputStream* _logfile;   // output log file
  public:
-  // Constuctors
+  // Constructors
   TraceTime(const char* title,
-            bool doit = true,
-            bool print_cr = true,
-            outputStream *logfile = NULL);
+            bool doit = true);
   TraceTime(const char* title,
             elapsedTimer* accumulator,
             bool doit = true,
-            bool verbose = false,
-            outputStream *logfile = NULL );
+            bool verbose = false);
   ~TraceTime();
 
   // Accessors
@@ -125,4 +120,9 @@
   ~TraceCPUTime();
 };
 
+class TimeHelper {
+ public:
+  static double counter_to_seconds(jlong counter);
+};
+
 #endif // SHARE_VM_RUNTIME_TIMER_HPP
--- a/src/share/vm/runtime/vmStructs.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -60,6 +60,7 @@
 #include "memory/generationSpec.hpp"
 #include "memory/heap.hpp"
 #include "memory/metablock.hpp"
+#include "memory/referenceType.hpp"
 #include "memory/space.hpp"
 #include "memory/tenuredGeneration.hpp"
 #include "memory/universe.hpp"
@@ -295,10 +296,8 @@
   nonstatic_field(InstanceKlass,               _transitive_interfaces,                        Array<Klass*>*)                        \
   nonstatic_field(InstanceKlass,               _fields,                                       Array<u2>*)                            \
   nonstatic_field(InstanceKlass,               _java_fields_count,                            u2)                                    \
-  nonstatic_field(InstanceKlass,               _constants,                                    ConstantPool*)                  \
+  nonstatic_field(InstanceKlass,               _constants,                                    ConstantPool*)                         \
   nonstatic_field(InstanceKlass,               _class_loader_data,                            ClassLoaderData*)                      \
-  nonstatic_field(InstanceKlass,               _protection_domain,                            oop)                                   \
-  nonstatic_field(InstanceKlass,               _signers,                                      objArrayOop)                           \
   nonstatic_field(InstanceKlass,               _source_file_name,                             Symbol*)                               \
   nonstatic_field(InstanceKlass,               _source_debug_extension,                       char*)                                 \
   nonstatic_field(InstanceKlass,               _inner_classes,                               Array<jushort>*)                       \
--- a/src/share/vm/runtime/vmThread.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/vmThread.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -35,6 +35,7 @@
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
 #include "services/runtimeService.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/xmlstream.hpp"
@@ -365,7 +366,23 @@
                      (char *) op->name(), strlen(op->name()),
                      op->evaluation_mode());
 #endif /* USDT2 */
+
+    EventExecuteVMOperation event;
+
     op->evaluate();
+
+    if (event.should_commit()) {
+      bool is_concurrent = op->evaluate_concurrently();
+      event.set_operation(op->type());
+      event.set_safepoint(op->evaluate_at_safepoint());
+      event.set_blocking(!is_concurrent);
+      // Only write caller thread information for non-concurrent vm operations.
+      // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
+      // This is because the caller thread could have exited already.
+      event.set_caller(is_concurrent ? 0 : op->calling_thread()->osthread()->thread_id());
+      event.commit();
+    }
+
 #ifndef USDT2
     HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
                      op->evaluation_mode());
@@ -601,7 +618,7 @@
     {
       VMOperationQueue_lock->lock_without_safepoint_check();
       bool ok = _vm_queue->add(op);
-      op->set_timestamp(os::javaTimeMillis());
+    op->set_timestamp(os::javaTimeMillis());
       VMOperationQueue_lock->notify();
       VMOperationQueue_lock->unlock();
       // VM_Operation got skipped
--- a/src/share/vm/runtime/vm_operations.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/vm_operations.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 #include "runtime/thread.inline.hpp"
 #include "runtime/vm_operations.hpp"
 #include "services/threadService.hpp"
+#include "trace/tracing.hpp"
 
 #define VM_OP_NAME_INITIALIZE(name) #name,
 
@@ -62,19 +63,21 @@
   }
 }
 
+const char* VM_Operation::mode_to_string(Mode mode) {
+  switch(mode) {
+    case _safepoint      : return "safepoint";
+    case _no_safepoint   : return "no safepoint";
+    case _concurrent     : return "concurrent";
+    case _async_safepoint: return "async safepoint";
+    default              : return "unknown";
+  }
+}
 // Called by fatal error handler.
 void VM_Operation::print_on_error(outputStream* st) const {
   st->print("VM_Operation (" PTR_FORMAT "): ", this);
   st->print("%s", name());
 
-  const char* mode;
-  switch(evaluation_mode()) {
-    case _safepoint      : mode = "safepoint";       break;
-    case _no_safepoint   : mode = "no safepoint";    break;
-    case _concurrent     : mode = "concurrent";      break;
-    case _async_safepoint: mode = "async safepoint"; break;
-    default              : mode = "unknown";         break;
-  }
+  const char* mode = mode_to_string(evaluation_mode());
   st->print(", mode: %s", mode);
 
   if (calling_thread()) {
--- a/src/share/vm/runtime/vm_operations.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/runtime/vm_operations.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -178,6 +178,8 @@
            evaluation_mode() == _async_safepoint;
   }
 
+  static const char* mode_to_string(Mode mode);
+
   // Debugging
   void print_on_error(outputStream* st) const;
   const char* name() const { return _names[type()]; }
--- a/src/share/vm/services/attachListener.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/services/attachListener.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -227,7 +227,7 @@
     }
     live_objects_only = strcmp(arg0, "-live") == 0;
   }
-  VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */, true /* need_prologue */);
+  VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */);
   VMThread::execute(&heapop);
   return JNI_OK;
 }
--- a/src/share/vm/services/diagnosticArgument.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/services/diagnosticArgument.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "runtime/thread.hpp"
 #include "services/diagnosticArgument.hpp"
 
@@ -86,9 +87,18 @@
 
 template <> void DCmdArgument<jlong>::parse_value(const char* str,
                                                   size_t len, TRAPS) {
-    if (str == NULL || sscanf(str, JLONG_FORMAT, &_value) != 1) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-      "Integer parsing error in diagnostic command arguments\n");
+  int scanned = -1;
+  if (str == NULL
+      || sscanf(str, JLONG_FORMAT"%n", &_value, &scanned) != 1
+      || (size_t)scanned != len)
+  {
+    ResourceMark rm;
+
+    char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+    strncpy(buf, str, len);
+    buf[len] = '\0';
+    Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
+      "Integer parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
   }
 }
 
@@ -96,7 +106,7 @@
   if (has_default()) {
     this->parse_value(_default_string, strlen(_default_string), THREAD);
     if (HAS_PENDING_EXCEPTION) {
-      fatal("Default string must be parsable");
+      fatal("Default string must be parseable");
     }
   } else {
     set_value(0);
@@ -116,8 +126,13 @@
     } else if (len == strlen("false") && strncasecmp(str, "false", len) == 0) {
        set_value(false);
     } else {
-      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-        "Boolean parsing error in diagnostic command arguments");
+      ResourceMark rm;
+
+      char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+      strncpy(buf, str, len);
+      buf[len] = '\0';
+      Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
+        "Boolean parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
     }
   }
 }
@@ -168,7 +183,7 @@
                                                  size_t len, TRAPS) {
   if (str == NULL) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              "Integer parsing error nanotime value: syntax error");
+              "Integer parsing error nanotime value: syntax error, value is null");
   }
 
   int argc = sscanf(str, JLONG_FORMAT, &_value._time);
--- a/src/share/vm/services/diagnosticCommand.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/services/diagnosticCommand.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -320,8 +320,7 @@
 
 void ClassHistogramDCmd::execute(DCmdSource source, TRAPS) {
   VM_GC_HeapInspection heapop(output(),
-                              !_all.value() /* request full gc if false */,
-                              true /* need_prologue */);
+                              !_all.value() /* request full gc if false */);
   VMThread::execute(&heapop);
 }
 
@@ -361,8 +360,7 @@
   }
 
   VM_GC_HeapInspection heapop(output(),
-                              true, /* request_full_gc */
-                              true /* need_prologue */);
+                              true /* request_full_gc */);
   heapop.set_csv_format(_csv.value());
   heapop.set_print_help(_help.value());
   heapop.set_print_class_stats(true);
--- a/src/share/vm/services/memBaseline.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/services/memBaseline.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -41,6 +41,7 @@
   {mtOther,      "Other"},
   {mtSymbol,     "Symbol"},
   {mtNMT,        "Memory Tracking"},
+  {mtTracing,    "Tracing"},
   {mtChunk,      "Pooled Free Chunks"},
   {mtClassShared,"Shared spaces for classes"},
   {mtTest,       "Test"},
--- a/src/share/vm/services/memTracker.cpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/services/memTracker.cpp	Fri Jun 21 15:56:24 2013 -0700
@@ -34,6 +34,7 @@
 #include "services/memReporter.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/decoder.hpp"
+#include "utilities/defaultStream.hpp"
 #include "utilities/globalDefinitions.hpp"
 
 bool NMT_track_callsite = false;
@@ -77,7 +78,15 @@
   if (strcmp(option_line, "=summary") == 0) {
     _tracking_level = NMT_summary;
   } else if (strcmp(option_line, "=detail") == 0) {
-    _tracking_level = NMT_detail;
+    // detail relies on a stack-walking ability that may not
+    // be available depending on platform and/or compiler flags
+    if (PLATFORM_NMT_DETAIL_SUPPORTED) {
+      _tracking_level = NMT_detail;
+    } else {
+      jio_fprintf(defaultStream::error_stream(),
+        "NMT detail is not supported on this platform.  Using NMT summary instead.");
+      _tracking_level = NMT_summary;
+    }
   } else if (strcmp(option_line, "=off") != 0) {
     vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/noTraceBackend.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_TRACE_NOTRACEBACKEND_HPP
+#define SHARE_VM_TRACE_NOTRACEBACKEND_HPP
+
+#include "prims/jni.h"
+
+typedef jlong TracingTime;
+typedef jlong RelativeTracingTime;
+
+class NoTraceBackend {
+public:
+  static TracingTime time() {
+    return 0;
+  }
+};
+
+class TraceThreadData {
+public:
+    TraceThreadData() {}
+};
+
+typedef NoTraceBackend Tracing;
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/trace.dtd	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+  
+-->
+
+<!ELEMENT trace (xi:include, relation_decls, events*, xi:include, xi:include)>
+<!ELEMENT types (content_types, primary_types)>
+<!ELEMENT content_types (content_type|struct_type)*>
+<!ELEMENT content_type (value|structvalue|structarray|array)*>
+<!ELEMENT struct_type (value*)>
+<!ELEMENT primary_types (primary_type*)>
+<!ELEMENT primary_type EMPTY>
+<!ELEMENT relation_decls (relation_decl*)>
+<!ELEMENT relation_decl EMPTY>
+<!ELEMENT events (event|struct)*>
+<!ELEMENT event (value|structvalue)*>
+<!ELEMENT struct (value|structvalue)*>
+<!ELEMENT value EMPTY>
+<!ELEMENT structvalue EMPTY>
+<!ELEMENT structarray EMPTY>
+<!ELEMENT array EMPTY>
+<!ATTLIST content_type  id             CDATA #REQUIRED
+                        hr_name        CDATA #REQUIRED
+                        type           CDATA #REQUIRED
+                        jvm_type       CDATA #IMPLIED
+                        builtin_type   CDATA #IMPLIED>
+<!ATTLIST struct_type   id             CDATA #REQUIRED>
+<!ATTLIST structarray   type           CDATA #REQUIRED
+                        field          CDATA #REQUIRED
+                        label          CDATA #REQUIRED>
+<!ATTLIST primary_type  symbol         CDATA #REQUIRED
+                        datatype       CDATA #REQUIRED
+                        contenttype    CDATA #REQUIRED
+                        type           CDATA #REQUIRED
+                        sizeop         CDATA #REQUIRED>
+<!ATTLIST relation_decl id             CDATA #REQUIRED
+                        uri            CDATA #REQUIRED>
+<!ATTLIST event         id             CDATA #REQUIRED
+                        path           CDATA #REQUIRED
+                        label          CDATA #REQUIRED
+                        description    CDATA #IMPLIED
+                        has_thread     CDATA "false"
+                        ignore_check   CDATA "false"
+                        has_stacktrace CDATA "false"
+                        is_instant     CDATA "false"
+                        is_constant    CDATA "false"
+                        is_requestable CDATA "false">
+<!ATTLIST struct        id             CDATA #REQUIRED>
+<!ATTLIST value         type           CDATA #REQUIRED
+                        field          CDATA #REQUIRED
+                        label          CDATA #REQUIRED
+                        description    CDATA #IMPLIED
+                        relation       CDATA "NOT_AVAILABLE"
+                        transition     CDATA "NONE">
+<!ATTLIST array         type           CDATA #REQUIRED
+                        field          CDATA #REQUIRED
+                        label          CDATA #REQUIRED
+                        description    CDATA #IMPLIED>
+<!ATTLIST structarray   type           CDATA #REQUIRED
+                        field          CDATA #REQUIRED
+                        label          CDATA #REQUIRED
+                        description    CDATA #IMPLIED>
+<!ATTLIST structvalue   type           CDATA #REQUIRED
+                        field          CDATA #REQUIRED
+                        label          CDATA #REQUIRED
+                        description    CDATA #IMPLIED>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/trace.xml	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,367 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ 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.
+
+-->
+
+
+<!DOCTYPE trace SYSTEM "trace.dtd" [
+<!ENTITY % xinclude SYSTEM "xinclude.mod">
+%xinclude;
+]>
+
+<trace>
+  <xi:include href="tracetypes.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+  <relation_decls>
+    <relation_decl id="GC_ID" uri="vm/gc/id"/>
+    <relation_decl id="COMP_ID" uri="vm/compiler/id"/>
+    <relation_decl id="SWEEP_ID" uri="vm/code_sweeper/id"/>
+    <relation_decl id="JAVA_MONITOR_ADDRESS" uri="java/monitor/address"/>
+  </relation_decls>
+
+<!--
+
+Events in the JVM are by default timed (it's more common)
+Perhaps a little strange. Might change.
+
+EVENTS
+
+Declard with the 'event' tag.
+
+<value fields> can be one or more of
+   value            - a simple primitive or constant type value
+   structvalue      - value is a sub-struct. This type must be previously defined
+                      with 'struct'
+All these require you to declare type, field and label of the field. They also accept
+an optional description of the field. If the meaning of the field is not obvious
+from the label you should provide a description. If an event however is not actually
+meant for end-users, you should probably _not_ write descriptions at all, since you
+might just add more concepts the user has no notion of/interest in.
+
+Events should be modeled after what conceptual process you are expressing, _NOT_
+from whatever data structures you might use inside the JVM for expressing a process.
+
+
+STRUCT
+
+Declared with the 'struct' tag.
+
+Declares a structure type that can be used in other events.
+
+-->
+
+  <events>
+    <event id="ThreadStart" path="java/thread_start" label="Java Thread Start"
+           has_thread="true" is_instant="true">
+      <value type="JAVALANGTHREAD" field="javalangthread" label="Java Thread"/>
+    </event>
+
+    <event id="ThreadEnd" path="java/thread_end" label="Java Thread End"
+           has_thread="true" is_instant="true">
+      <value type="JAVALANGTHREAD" field="javalangthread" label="Java Thread"/>
+    </event>
+
+    <event id="ThreadSleep" path="java/thread_sleep" label="Java Thread Sleep"
+            has_thread="true" has_stacktrace="true" is_instant="false">
+      <value type="MILLIS" field="time" label="Sleep Time"/>
+    </event>
+
+    <event id="ThreadPark" path="java/thread_park" label="Java Thread Park"
+            has_thread="true" has_stacktrace="true" is_instant="false">
+      <value type="CLASS" field="klass" label="Class Parked On"/>
+      <value type="MILLIS" field="timeout" label="Park Timeout"/>
+      <value type="ADDRESS" field="address" label="Address of Object Parked" relation="JAVA_MONITOR_ADDRESS"/>
+    </event>
+
+    <event id="JavaMonitorEnter" path="java/monitor_enter" label="Java Monitor Blocked"
+            has_thread="true" has_stacktrace="true" is_instant="false">
+      <value type="CLASS" field="klass" label="Monitor Class"/>
+      <value type="JAVALANGTHREAD" field="previousOwner" label="Previous Monitor Owner"/>
+      <value type="ADDRESS" field="address" label="Monitor Address" relation="JAVA_MONITOR_ADDRESS"/>
+    </event>
+
+    <event id="JavaMonitorWait" path="java/monitor_wait" label="Java Monitor Wait" description="Waiting on a Java monitor"
+            has_thread="true" has_stacktrace="true" is_instant="false">
+      <value type="CLASS" field="klass" label="Monitor Class" description="Class of object waited on"/>
+      <value type="OSTHREAD" field="notifier" label="Notifier Thread" description="Notifying Thread"/>
+      <value type="MILLIS" field="timeout" label="Timeout" description="Maximum wait time"/>
+      <value type="BOOLEAN" field="timedOut" label="Timed Out" description="Wait has been timed out"/>
+      <value type="ADDRESS" field="address" label="Monitor Address" description="Address of object waited on" relation="JAVA_MONITOR_ADDRESS"/>
+    </event>
+
+    <event id="ClassLoad" path="vm/class/load" label="Class Load"
+            has_thread="true" has_stacktrace="true" is_instant="false">
+      <value type="CLASS" field="loadedClass" label="Loaded Class"/>
+      <value type="CLASS" field="definingClassLoader" label="Defining Class Loader"/>
+      <value type="CLASS" field="initiatingClassLoader" label="Initiating Class Loader"/>
+    </event>
+
+    <event id="ClassUnload" path="vm/class/unload" label="Class Unload"
+        has_thread="true" is_instant="true">
+      <value type="CLASS" field="unloadedClass" label="Unloaded Class"/>
+      <value type="CLASS" field="definingClassLoader" label="Defining Class Loader"/>
+    </event>
+
+    <struct id="VirtualSpace">
+      <value type="ADDRESS" field="start" label="Start Address" description="Start address of the virtual space" />
+      <value type="ADDRESS" field="committedEnd" label="Committed End Address" description="End address of the committed memory for the virtual space" />
+      <value type="BYTES64" field="committedSize" label="Committed Size" description="Size of the committed memory for the virtual space" />
+      <value type="ADDRESS" field="reservedEnd" label="Reserved End Address" description="End address of the reserved memory for the virtual space" />
+      <value type="BYTES64" field="reservedSize" label="Reserved Size" description="Size of the reserved memory for the virtual space" />
+    </struct>
+
+    <struct id="ObjectSpace">
+      <value type="ADDRESS" field="start" label="Start Address" description="Start address of the space" />
+      <value type="ADDRESS" field="end" label="End Address" description="End address of the space" />
+      <value type="BYTES64" field="used" label="Used" description="Bytes allocated by objects in the space" />
+      <value type="BYTES64" field="size" label="Size" description="Size of the space" />
+    </struct>
+
+    <event id="GCHeapSummary" path="vm/gc/heap/summary" label="Heap Summary" is_instant="true">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="GCWHEN" field="when" label="When" />
+      <structvalue type="VirtualSpace" field="heapSpace" label="Heap Space"/>
+      <value type="BYTES64" field="heapUsed" label="Heap Used" description="Bytes allocated by objects in the heap"/>
+    </event>
+
+    <struct id="MetaspaceSizes">
+      <value type="BYTES64" field="capacity" label="Capacity" description="Total available memory to allocate in" />
+      <value type="BYTES64" field="used" label="Used" description="Bytes allocated by objects in the space" />
+      <value type="BYTES64" field="reserved" label="Reserved" description="Reserved memory for this space" />
+    </struct>
+
+    <event id="MetaspaceSummary" path="vm/gc/heap/metaspace_summary" label="Metaspace Summary" is_instant="true">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="GCWHEN" field="when" label="When" />
+      <structvalue type="MetaspaceSizes" field="metaspace" label="Total"/>
+      <structvalue type="MetaspaceSizes" field="dataSpace" label="Data"/>
+      <structvalue type="MetaspaceSizes" field="classSpace" label="Class"/>
+    </event>
+
+    <event id="PSHeapSummary" path="vm/gc/heap/ps_summary" label="ParallelScavengeHeap Summary" is_instant="true">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="GCWHEN" field="when" label="When" />
+
+      <structvalue type="VirtualSpace" field="oldSpace" label="Old Space"/>
+      <structvalue type="ObjectSpace" field="oldObjectSpace" label="Old Object Space"/>
+
+      <structvalue type="VirtualSpace" field="youngSpace" label="Young Space"/>
+      <structvalue type="ObjectSpace" field="edenSpace" label="Eden Space"/>
+      <structvalue type="ObjectSpace" field="fromSpace" label="From Space"/>
+      <structvalue type="ObjectSpace" field="toSpace" label="To Space"/>
+    </event>
+
+    <event id="GCGarbageCollection" path="vm/gc/collector/garbage_collection" label="Garbage Collection"
+           description="Garbage collection performed by the JVM">
+      <value type="UINT" field="gcId"  label="GC ID" relation="GC_ID" />
+      <value type="GCNAME" field="name" label="Name" description="The name of the Garbage Collector" />
+      <value type="GCCAUSE" field="cause" label="Cause" description="The reason for triggering this Garbage Collection" />
+      <value type="RELATIVE_TICKS" field="sumOfPauses" label="Sum of Pauses" description="Sum of all the times in which Java execution was paused during the garbage collection" />
+      <value type="RELATIVE_TICKS" field="longestPause" label="Longest Pause" description="Longest individual pause during the garbage collection" />
+    </event>
+
+    <event id="GCParallelOld" path="vm/gc/collector/parold_garbage_collection" label="Parallel Old Garbage Collection"
+           description="Extra information specific to Parallel Old Garbage Collections">
+      <value type="UINT" field="gcId"  label="GC ID" relation="GC_ID" />
+      <value type="ADDRESS" field="densePrefix" label="Dense Prefix" description="The address of the dense prefix, used when compacting" />
+    </event>
+
+    <event id="GCYoungGarbageCollection" path="vm/gc/collector/young_garbage_collection" label="Young Garbage Collection"
+           description="Extra information specific to Young Garbage Collections">
+      <value type="UINT" field="gcId"  label="GC ID" relation="GC_ID" />
+      <value type="UINT" field="tenuringThreshold" label="Tenuring Threshold" />
+    </event>
+
+    <event id="GCOldGarbageCollection" path="vm/gc/collector/old_garbage_collection" label="Old Garbage Collection"
+           description="Extra information specific to Old Garbage Collections">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+    </event>
+
+    <event id="GCG1GarbageCollection" path="vm/gc/collector/g1_garbage_collection" label="G1 Garbage Collection"
+           description="Extra information specific to G1 Garbage Collections">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="G1YCTYPE" field="type" label="Type" />
+    </event>
+
+    <event id="EvacuationInfo" path="vm/gc/detailed/evacuation_info" label="Evacuation Info" is_instant="true">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="UINT" field="cSetRegions" label="Collection Set Regions"/>
+      <value type="BYTES64" field="cSetUsedBefore" label="Collection Set Before" description="Memory usage before GC in the collection set regions"/>
+      <value type="BYTES64" field="cSetUsedAfter" label="Collection Set After" description="Memory usage after GC in the collection set regions"/>
+      <value type="UINT" field="allocationRegions" label="Allocation Regions" description="Regions chosen as allocation regions during evacuation (includes survivors and old space regions)"/>
+      <value type="BYTES64" field="allocRegionsUsedBefore" label="Alloc Regions Before" description="Memory usage before GC in allocation regions"/>
+      <value type="BYTES64" field="allocRegionsUsedAfter" label="Alloc Regions After" description="Memory usage after GC in allocation regions"/>
+      <value type="BYTES64" field="bytesCopied" label="BytesCopied"/>
+      <value type="UINT" field="regionsFreed" label="Regions Freed"/>
+    </event>
+
+    <event id="GCReferenceStatistics" path="vm/gc/reference/statistics"
+           label="GC Reference Statistics" is_instant="true"
+           description="Total count of processed references during GC">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="REFERENCETYPE" field="type" label="Type" />
+      <value type="ULONG" field="count" label="Total Count" />
+    </event>
+
+    <struct id="CopyFailed">
+      <value type="ULONG" field="objectCount" label="Object Count"/>
+      <value type="BYTES64" field="firstSize" label="First Failed Object Size"/>
+      <value type="BYTES64" field="smallestSize" label="Smallest Failed Object Size"/>
+      <value type="BYTES64" field="totalSize" label="Total Object Size"/>
+    </struct>
+
+    <event id="ObjectCountAfterGC" path="vm/gc/detailed/object_count_after_gc" is_instant="true" label="Object Count after GC">
+      <value type="UINT" field="gcId"  label="GC ID" relation="GC_ID" />
+      <value type="CLASS" field="class" label="Class" />
+      <value type="LONG" field="count" label="Count" />
+      <value type="BYTES64" field="totalSize" label="Total Size" />
+    </event>
+
+    <event id="PromotionFailed" path="vm/gc/detailed/promotion_failed" label="Promotion Failed" is_instant="true"
+           description="Promotion of an object failed">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <structvalue type="CopyFailed" field="data" label="data"/>
+      <value type="OSTHREAD" field="thread" label="Running thread"/>
+    </event>
+
+    <event id="EvacuationFailed" path="vm/gc/detailed/evacuation_failed" label="Evacuation Failed" is_instant="true"
+           description="Evacuation of an object failed">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <structvalue type="CopyFailed" field="data" label="data"/>
+    </event>
+
+    <event id="ConcurrentModeFailure" path="vm/gc/detailed/concurrent_mode_failure" label="Concurrent Mode Failure"
+           is_instant="true" description="Concurrent Mode failed">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+    </event>
+
+    <event id="GCPhasePause" path="vm/gc/phases/pause" label="GC Phase Pause">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="UTF8" field="name" label="Name" />
+    </event>
+
+    <event id="GCPhasePauseLevel1" path="vm/gc/phases/pause_level_1" label="GC Phase Pause Level 1">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="UTF8" field="name" label="Name" />
+    </event>
+
+    <event id="GCPhasePauseLevel2" path="vm/gc/phases/pause_level_2" label="GC Phase Pause Level 2">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="UTF8" field="name" label="Name" />
+    </event>
+
+    <event id="GCPhasePauseLevel3" path="vm/gc/phases/pause_level_3" label="GC Phase Pause Level 3">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="UTF8" field="name" label="Name" />
+    </event>
+
+    <!-- Compiler events -->
+
+    <event id="Compilation" path="vm/compiler/compilation" label="Compilation"
+         has_thread="true" is_requestable="false" is_constant="false">
+      <value type="METHOD" field="method" label="Java Method"/>
+      <value type="UINT" field="compileID" label="Compilation ID" relation="COMP_ID"/>
+      <value type="USHORT" field="compileLevel" label="Compilation Level"/>
+      <value type="BOOLEAN" field="succeded" label="Succeeded"/>
+      <value type="BOOLEAN" field="isOsr" label="On Stack Replacement"/>
+      <value type="BYTES" field="codeSize" label="Compiled Code Size"/>
+      <value type="BYTES" field="inlinedBytes" label="Inlined Code Size"/>
+    </event>
+
+    <event id="CompilerPhase" path="vm/compiler/phase" label="Compiler Phase"
+            has_thread="true" is_requestable="false" is_constant="false">
+      <value type="COMPILERPHASETYPE" field="phase" label="Compile Phase"/>
+      <value type="UINT" field="compileID" label="Compilation ID" relation="COMP_ID"/>
+      <value type="USHORT" field="phaseLevel" label="Phase Level"/>
+    </event>
+
+    <event id="CompilerFailure" path="vm/compiler/failure" label="Compilation Failure"
+            has_thread="true" is_requestable="false" is_constant="false" is_instant="true">
+      <value type="UTF8" field="failure" label="Message"/>
+      <value type="UINT" field="compileID" label="Compilation ID" relation="COMP_ID"/>
+    </event>
+
+    <!-- Code sweeper events -->
+
+    <event id="SweepCodeCache" path="vm/code_sweeper/sweep" label="Sweep Code Cache"
+       has_thread="true" is_requestable="false" is_constant="false">
+      <value type="INTEGER" field="sweepIndex" label="Sweep Index" relation="SWEEP_ID"/>
+      <value type="USHORT" field="sweepFractionIndex" label="Fraction Index"/>
+      <value type="UINT" field="sweptCount" label="Methods Swept"/>
+      <value type="UINT" field="flushedCount" label="Methods Flushed"/>
+      <value type="UINT" field="markedCount" label="Methods Reclaim"/>
+      <value type="UINT" field="zombifiedCount" label="Methods Zombified"/>
+    </event>
+
+    <event id="CleanCodeCache" path="vm/code_sweeper/clean" label="Clean Code Cache"
+             description="Clean code cache from oldest methods"
+             has_thread="true" is_requestable="false" is_constant="false">
+      <value type="UINT" field="disconnectedCount" label="Methods Disconnected"/>
+      <value type="UINT" field="madeNonEntrantCount" label="Methods Made Non-Entrant"/>
+    </event>
+
+    <!-- Code cache events -->
+
+    <event id="CodeCacheFull" path="vm/code_cache/full" label="Code Cache Full"
+         has_thread="true" is_requestable="false" is_constant="false" is_instant="true">
+      <value type="ADDRESS" field="startAddress" label="Start Address"/>
+      <value type="ADDRESS" field="commitedTopAddress" label="Commited Top"/>
+      <value type="ADDRESS" field="reservedTopAddress" label="Reserved Top"/>
+      <value type="INTEGER" field="entryCount" label="Entries"/>
+      <value type="INTEGER" field="methodCount" label="Methods"/>
+      <value type="INTEGER" field="adaptorCount" label="Adaptors"/>
+      <value type="BYTES64" field="unallocatedCapacity" label="Unallocated"/>
+      <value type="INTEGER" field="fullCount" label="Full Count"/>
+    </event>
+
+    <event id="ExecuteVMOperation" path="vm/runtime/execute_vm_operation" label="VM Operation"
+        description="Execution of a VM Operation" has_thread="true">
+      <value type="VMOPERATIONTYPE" field="operation" label="Operation" />
+      <value type="BOOLEAN" field="safepoint" label="At Safepoint" description="If the operation occured at a safepoint."/>
+      <value type="BOOLEAN" field="blocking" label="Caller Blocked" description="If the calling thread was blocked until the operation was complete."/>
+      <value type="OSTHREAD" field="caller" label="Caller" transition="FROM" description="Thread requesting operation. If non-blocking, will be set to 0 indicating thread is unknown."/>
+    </event>
+
+    <!-- Allocation events -->
+    <event id="AllocObjectInNewTLAB" path="java/object_alloc_in_new_TLAB" label="Allocation in new TLAB"
+        description="Allocation in new Thread Local Allocation Buffer" has_thread="true" has_stacktrace="true" is_instant="true">
+      <value type="CLASS" field="class" label="Class" description="Class of allocated object"/>
+      <value type="BYTES64" field="allocationSize" label="Allocation Size"/>
+      <value type="BYTES64" field="tlabSize" label="TLAB Size"/>
+    </event>
+
+    <event id="AllocObjectOutsideTLAB" path="java/object_alloc_outside_TLAB" label="Allocation outside TLAB"
+        description="Allocation outside Thread Local Allocation Buffers" has_thread="true" has_stacktrace="true" is_instant="true">
+      <value type="CLASS" field="class" label="Class" description="Class of allocated object"/>
+      <value type="BYTES64" field="allocationSize" label="Allocation Size"/>
+    </event>
+  </events>
+
+  <xi:include href="../../../closed/share/vm/trace/traceeventtypes.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <xi:fallback/>
+  </xi:include>
+
+  <xi:include href="../../../closed/share/vm/trace/traceevents.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <xi:fallback/>
+  </xi:include>
+</trace>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceBackend.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_TRACEBACKEND_HPP
+#define SHARE_VM_TRACE_TRACEBACKEND_HPP
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
+#include "trace/traceTime.hpp"
+#include "tracefiles/traceEventIds.hpp"
+
+class TraceBackend {
+public:
+  static bool enabled(void) {
+    return EnableTracing;
+  }
+
+  static bool is_event_enabled(TraceEventId id) {
+    return enabled();
+  }
+
+  static TracingTime time() {
+    return os::elapsed_counter();
+  }
+
+  static TracingTime time_adjustment(jlong time) {
+    return time;
+  }
+
+  static void on_unloading_classes(void) {
+  }
+};
+
+class TraceThreadData {
+public:
+    TraceThreadData() {}
+};
+
+typedef TraceBackend Tracing;
+
+#else /* INCLUDE_TRACE */
+
+#include "trace/noTraceBackend.hpp"
+
+#endif /* INCLUDE_TRACE */
+#endif /* SHARE_VM_TRACE_TRACEBACKEND_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceDataTypes.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_TRACEDATATYPES_HPP
+#define SHARE_VM_TRACE_TRACEDATATYPES_HPP
+
+#include <stddef.h>
+
+#include "utilities/globalDefinitions.hpp"
+
+enum {
+  CONTENT_TYPE_NONE             = 0,
+  CONTENT_TYPE_BYTES            = 1,
+  CONTENT_TYPE_EPOCHMILLIS      = 2,
+  CONTENT_TYPE_MILLIS           = 3,
+  CONTENT_TYPE_NANOS            = 4,
+  CONTENT_TYPE_TICKS            = 5,
+  CONTENT_TYPE_ADDRESS          = 6,
+
+  CONTENT_TYPE_OSTHREAD,
+  CONTENT_TYPE_JAVALANGTHREAD,
+  CONTENT_TYPE_STACKTRACE,
+  CONTENT_TYPE_CLASS,
+  CONTENT_TYPE_PERCENTAGE,
+
+  JVM_CONTENT_TYPES_START       = 30,
+  JVM_CONTENT_TYPES_END         = 100
+};
+
+enum ReservedEvent {
+  EVENT_PRODUCERS,
+  EVENT_CHECKPOINT,
+  EVENT_BUFFERLOST,
+
+  NUM_RESERVED_EVENTS
+};
+
+typedef enum ReservedEvent ReservedEvent;
+
+typedef u8 classid;
+typedef u8 stacktraceid;
+typedef u8 methodid;
+typedef u8 fieldid;
+
+#endif // SHARE_VM_TRACE_TRACEDATATYPES_HPP
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceEvent.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_TRACEEVENT_HPP
+#define SHARE_VM_TRACE_TRACEEVENT_HPP
+
+enum EventStartTime {
+  UNTIMED,
+  TIMED
+};
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "trace/traceBackend.hpp"
+#include "trace/tracing.hpp"
+#include "tracefiles/traceEventIds.hpp"
+#include "tracefiles/traceTypes.hpp"
+
+template<typename T>
+class TraceEvent : public StackObj {
+ protected:
+  jlong _startTime;
+  jlong _endTime;
+
+ private:
+  bool _started;
+#ifdef ASSERT
+  bool _committed;
+  bool _cancelled;
+ protected:
+  bool _ignore_check;
+#endif
+
+ public:
+  TraceEvent(EventStartTime timing=TIMED) :
+    _startTime(0),
+    _endTime(0),
+    _started(false)
+#ifdef ASSERT
+    ,
+    _committed(false),
+    _cancelled(false),
+    _ignore_check(false)
+#endif
+  {
+    if (T::is_enabled()) {
+      _started = true;
+      if (timing == TIMED && !T::isInstant) {
+        static_cast<T *>(this)->set_starttime(Tracing::time());
+      }
+    }
+  }
+
+  static bool is_enabled() {
+    return Tracing::is_event_enabled(T::eventId);
+  }
+
+  bool should_commit() {
+    return _started;
+  }
+
+  void ignoreCheck() {
+    DEBUG_ONLY(_ignore_check = true);
+  }
+
+  void commit() {
+    if (!should_commit()) {
+        cancel();
+        return;
+    }
+    if (_endTime == 0) {
+      static_cast<T*>(this)->set_endtime(Tracing::time());
+    }
+    if (static_cast<T*>(this)->should_write()) {
+      static_cast<T*>(this)->writeEvent();
+    }
+    set_commited();
+  }
+
+  void set_starttime(jlong time) {
+    _startTime = time;
+  }
+
+  void set_endtime(jlong time) {
+    _endTime = time;
+  }
+
+  TraceEventId id() const {
+    return T::eventId;
+  }
+
+  bool is_instant() const {
+    return T::isInstant;
+  }
+
+  bool is_requestable() const {
+    return T::isRequestable;
+  }
+
+  bool has_thread() const {
+    return T::hasThread;
+  }
+
+  bool has_stacktrace() const {
+    return T::hasStackTrace;
+  }
+
+  void cancel() {
+    assert(!_committed && !_cancelled, "event was already committed/cancelled");
+    DEBUG_ONLY(_cancelled = true);
+  }
+
+  void set_commited() {
+    assert(!_committed, "event has already been committed");
+    DEBUG_ONLY(_committed = true);
+  }
+
+  ~TraceEvent() {
+    if (_started) {
+      assert(_ignore_check || _committed || _cancelled, "event was not committed/cancelled");
+    }
+  }
+};
+
+#endif /* INCLUDE_TRACE */
+
+#endif /* SHARE_VM_TRACE_TRACEEVENT_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceEventClasses.xsl	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ 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.
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
+<xsl:import href="xsl_util.xsl"/>
+
+<xsl:template match="/">
+  <xsl:call-template name="file-header"/>
+
+#ifndef TRACEFILES_TRACEEVENTCLASSES_HPP
+#define TRACEFILES_TRACEEVENTCLASSES_HPP
+
+// On purpose outside the INCLUDE_TRACE
+// Some parts of traceEvent.hpp are used outside of
+// INCLUDE_TRACE
+
+#include "memory/resourceArea.hpp"
+#include "tracefiles/traceTypes.hpp"
+#include "trace/traceEvent.hpp"
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+
+#include "trace/traceStream.hpp"
+#include "utilities/ostream.hpp"
+
+  <xsl:apply-templates select="trace/events/struct" mode="trace"/>
+  <xsl:apply-templates select="trace/events/event" mode="trace"/>
+
+#else
+
+class TraceEvent {
+public:
+  TraceEvent() {}
+  void set_starttime(jlong time) const {}
+  void set_endtime(jlong time) const {}
+  bool should_commit() const { return false; }
+  void commit() const {}
+};
+
+  <xsl:apply-templates select="trace/events/struct" mode="empty"/>
+  <xsl:apply-templates select="trace/events/event" mode="empty"/>
+
+#endif
+
+#endif
+</xsl:template>
+
+<xsl:template match="struct" mode="trace">
+struct TraceStruct<xsl:value-of select="@id"/>
+{
+private:
+<xsl:apply-templates select="value" mode="write-fields"/>
+public:
+<xsl:apply-templates select="value" mode="write-setters"/>
+
+  void writeStruct(TraceStream&amp; ts) {
+<xsl:apply-templates select="value" mode="write-data"/>
+  }
+};
+
+</xsl:template>
+
+<xsl:template match="struct" mode="empty">
+struct TraceStruct<xsl:value-of select="@id"/> 
+{
+public:
+<xsl:apply-templates select="value" mode="write-empty-setters"/>
+};
+</xsl:template>
+
+
+<xsl:template match="event" mode="empty">
+  <xsl:value-of select="concat('class Event', @id, ' : public TraceEvent')"/>
+{
+ public:
+<xsl:value-of select="concat('  Event', @id, '(bool ignore=true) {}')"/>
+<xsl:text>
+</xsl:text>
+
+<xsl:apply-templates select="value|structvalue|transition_value|relation" mode="write-empty-setters"/>
+};
+
+</xsl:template>
+
+
+<xsl:template match="event" mode="trace">
+  <xsl:value-of select="concat('class Event', @id, ' : public TraceEvent&lt;Event', @id, '&gt;')"/>
+{
+ public:
+  static const bool hasThread = <xsl:value-of select="@has_thread"/>;
+  static const bool hasStackTrace = <xsl:value-of select="@has_stacktrace"/>;
+  static const bool isInstant = <xsl:value-of select="@is_instant"/>;
+  static const bool isRequestable = <xsl:value-of select="@is_requestable"/>;
+  static const TraceEventId eventId = <xsl:value-of select="concat('Trace', @id, 'Event')"/>;
+
+ private:
+<xsl:apply-templates select="value|structvalue|transition_value|relation" mode="write-fields"/>
+
+  void writeEventContent(void) {
+    TraceStream ts(*tty);
+    ts.print("<xsl:value-of select="@label"/>: [");
+<xsl:apply-templates select="value|structvalue" mode="write-data"/>
+    ts.print("]\n");
+  }
+
+ public:
+<xsl:apply-templates select="value|structvalue|transition_value|relation" mode="write-setters"/>
+
+  bool should_write(void) {
+    return true;
+  }
+<xsl:text>
+
+</xsl:text>
+  <xsl:value-of select="concat('  Event', @id, '(EventStartTime timing=TIMED) : TraceEvent&lt;Event', @id, '&gt;(timing) {}', $newline)"/>
+  void writeEvent(void) {
+    ResourceMark rm;
+    if (UseLockedTracing) {
+      ttyLocker lock;
+      writeEventContent();
+    } else {
+      writeEventContent();
+    }
+  }
+};
+
+</xsl:template>
+
+<xsl:template match="value|transition_value|relation" mode="write-empty-setters">
+  <xsl:param name="cls"/>
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="wt" select="//primary_type[@symbol=$type]/@type"/>
+  <xsl:value-of select="concat('  void set_', @field, '(', $wt, ' value) { }')"/>
+  <xsl:if test="position() != last()">
+    <xsl:text>
+</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="structvalue" mode="write-empty-setters">
+  <xsl:param name="cls"/>
+  <xsl:value-of select="concat('  void set_', @field, '(const TraceStruct', @type, '&amp; value) { }')"/>
+  <xsl:if test="position() != last()">
+    <xsl:text>
+</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+
+<xsl:template match="value[@type='TICKS']" mode="write-setters">
+#if INCLUDE_TRACE
+  <xsl:value-of select="concat('void set_', @field, '(jlong time) { _', @field, ' = time; }')"/>
+#else
+  <xsl:value-of select="concat('void set_', @field, '(jlong ignore) {}')"/>
+#endif
+</xsl:template>
+
+<xsl:template match="value[@type='RELATIVE_TICKS']" mode="write-setters">
+#if INCLUDE_TRACE
+  <xsl:value-of select="concat('void set_', @field, '(jlong time) { _', @field, ' = time; }')"/>
+#else
+  <xsl:value-of select="concat('void set_', @field, '(jlong ignore) {}')"/>
+#endif
+</xsl:template>
+
+<xsl:template match="value" mode="write-fields">
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="wt" select="//primary_type[@symbol=$type]/@type"/>
+  <xsl:value-of select="concat('  ', $wt, ' _', @field, ';')"/>
+  <xsl:if test="position() != last()">
+    <xsl:text> 
+</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="structvalue" mode="write-fields">
+  <xsl:value-of select="concat('  TraceStruct', @type, ' _', @field, ';')"/>
+  <xsl:text>
+</xsl:text>
+</xsl:template>
+
+<xsl:template match="value|transition_value|relation" mode="write-setters">
+  <xsl:param name="cls"/>
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="wt" select="//primary_type[@symbol=$type]/@type"/>
+  <xsl:value-of select="concat('  void set_', @field, '(', $wt, ' value) { this->_', @field, ' = value; }')"/>
+  <xsl:if test="position() != last()">
+    <xsl:text>
+</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="structvalue" mode="write-setters">
+  <xsl:param name="cls"/>
+  <xsl:value-of select="concat('  void set_', @field, '(const TraceStruct', @type, '&amp; value) { this->_', @field, ' = value; }')"/>
+  <xsl:if test="position() != last()">
+    <xsl:text>
+</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="value" mode="write-data">
+  <xsl:variable name="type" select="@type"/>
+  <xsl:variable name="wt" select="//primary_type[@symbol=$type]/@writetype"/>
+  <xsl:value-of select="concat('    ts.print_val(&quot;', @label, '&quot;, _', @field, ');')"/>
+  <xsl:if test="position() != last()">
+    <xsl:text>
+    ts.print(", ");
+</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="structvalue" mode="write-data">
+  <xsl:value-of select="concat('    _', @field, '.writeStruct(ts);')"/>
+  <xsl:if test="position() != last()">
+    <xsl:text>
+    ts.print(", ");
+</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceEventIds.xsl	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ 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.
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
+<xsl:import href="xsl_util.xsl"/>
+
+<xsl:template match="/">
+  <xsl:call-template name="file-header"/>
+
+#ifndef TRACEFILES_JFREVENTIDS_HPP
+#define TRACEFILES_JFREVENTIDS_HPP
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "trace/traceDataTypes.hpp"
+
+/**
+ * Enum of the event types in the JVM
+ */
+enum TraceEventId {
+  _traceeventbase = (NUM_RESERVED_EVENTS-1), // Make sure we start at right index.
+  
+  // Events -> enum entry
+<xsl:for-each select="trace/events/event">
+  <xsl:value-of select="concat('  Trace', @id, 'Event,', $newline)"/>
+</xsl:for-each>
+  MaxTraceEventId
+};
+
+/**
+ * Struct types in the JVM
+ */
+enum TraceStructId {
+<xsl:for-each select="trace/types/content_types/*">
+  <xsl:value-of select="concat('  Trace', @id, 'Struct,', $newline)"/>
+</xsl:for-each>
+<xsl:for-each select="trace/events/*">
+  <xsl:value-of select="concat('  Trace', @id, 'Struct,', $newline)"/>
+</xsl:for-each>
+  MaxTraceStructId
+};
+
+typedef enum TraceEventId  TraceEventId;
+typedef enum TraceStructId TraceStructId;
+
+#endif
+#endif
+</xsl:template>
+
+</xsl:stylesheet>
--- a/src/share/vm/trace/traceEventTypes.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * 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
--- a/src/share/vm/trace/traceMacros.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/trace/traceMacros.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,22 +25,14 @@
 #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_DATA TraceThreadData
 
-#define TRACE_START() true
-#define TRACE_INITIALIZE() 0
+#define TRACE_START() JNI_OK
+#define TRACE_INITIALIZE() JNI_OK
 
-#define TRACE_SET_KLASS_TRACE_ID(x1, x2) do { } while (0)
 #define TRACE_DEFINE_KLASS_METHODS typedef int ___IGNORED_hs_trace_type1
 #define TRACE_DEFINE_KLASS_TRACE_ID typedef int ___IGNORED_hs_trace_type2
 #define TRACE_DEFINE_OFFSET typedef int ___IGNORED_hs_trace_type3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceStream.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_TRACESTREAM_HPP
+#define SHARE_VM_TRACE_TRACESTREAM_HPP
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "oops/klass.hpp"
+#include "oops/method.hpp"
+#include "oops/symbol.hpp"
+#include "utilities/ostream.hpp"
+
+class TraceStream : public StackObj {
+ private:
+  outputStream& _st;
+
+ public:
+  TraceStream(outputStream& stream): _st(stream) {}
+
+  void print_val(const char* label, u1 val) {
+    _st.print("%s = "UINT32_FORMAT, label, val);
+  }
+
+  void print_val(const char* label, u2 val) {
+    _st.print("%s = "UINT32_FORMAT, label, val);
+  }
+
+  void print_val(const char* label, s2 val) {
+    _st.print("%s = "INT32_FORMAT, label, val);
+  }
+
+  void print_val(const char* label, u4 val) {
+    _st.print("%s = "UINT32_FORMAT, label, val);
+  }
+
+  void print_val(const char* label, s4 val) {
+    _st.print("%s = "INT32_FORMAT, label, val);
+  }
+
+  void print_val(const char* label, u8 val) {
+    _st.print("%s = "UINT64_FORMAT, label, val);
+  }
+
+  void print_val(const char* label, s8 val) {
+    _st.print("%s = "INT64_FORMAT, label, val);
+  }
+
+  void print_val(const char* label, bool val) {
+    _st.print("%s = %s", label, val ? "true" : "false");
+  }
+
+  void print_val(const char* label, float val) {
+    _st.print("%s = %f", label, val);
+  }
+
+  void print_val(const char* label, double val) {
+    _st.print("%s = %f", label, val);
+  }
+
+  // Caller is machine generated code located in traceEventClasses.hpp
+  // Event<TraceId>::writeEvent() (pseudocode) contains the
+  // necessary ResourceMark for the resource allocations below.
+  // See traceEventClasses.xsl for details.
+  void print_val(const char* label, const Klass* const val) {
+    const char* description = "NULL";
+    if (val != NULL) {
+      Symbol* name = val->name();
+      if (name != NULL) {
+        description = name->as_C_string();
+      }
+    }
+    _st.print("%s = %s", label, description);
+  }
+
+  // Caller is machine generated code located in traceEventClasses.hpp
+  // Event<TraceId>::writeEvent() (pseudocode) contains the
+  // necessary ResourceMark for the resource allocations below.
+  // See traceEventClasses.xsl for details.
+  void print_val(const char* label, const Method* const val) {
+    const char* description = "NULL";
+    if (val != NULL) {
+      description = val->name_and_sig_as_C_string();
+    }
+    _st.print("%s = %s", label, description);
+  }
+
+  void print_val(const char* label, const char* val) {
+    _st.print("%s = '%s'", label, val);
+  }
+
+  void print(const char* val) {
+    _st.print(val);
+  }
+};
+
+#endif /* INCLUDE_TRACE */
+#endif /* SHARE_VM_TRACE_TRACESTREAM_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceTime.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_TRACETIME_HPP
+#define SHARE_VM_TRACE_TRACETIME_HPP
+
+#include "prims/jni.h"
+
+typedef jlong TracingTime;
+typedef jlong RelativeTracingTime;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/traceTypes.xsl	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ 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.
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
+<xsl:import href="xsl_util.xsl"/>
+
+<xsl:template match="/">
+  <xsl:call-template name="file-header"/>
+
+#ifndef TRACEFILES_JFRTYPES_HPP
+#define TRACEFILES_JFRTYPES_HPP
+
+#include "trace/traceDataTypes.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "oops/symbol.hpp"
+
+enum JVMContentType {
+  _not_a_content_type = (JVM_CONTENT_TYPES_START - 1),
+  
+<xsl:for-each select="trace/types/content_types/content_type[@jvm_type]">
+  <xsl:value-of select="concat('  CONTENT_TYPE_', @jvm_type, ',',  $newline)"/>
+</xsl:for-each>
+  NUM_JVM_CONTENT_TYPES
+};
+
+
+enum JVMEventRelations {
+  JVM_REL_NOT_AVAILABLE = 0,
+  
+<xsl:for-each select="trace/relation_decls/relation_decl">
+  <xsl:value-of select="concat('  JVM_REL_', @id, ',', $newline)"/>
+</xsl:for-each>
+  NUM_EVENT_RELATIONS
+};
+
+/**
+ * Create typedefs for the JRA types:
+ *   typedef s8 TYPE_LONG;
+ *   typedef s4 TYPE_INTEGER;
+ *   typedef const char * TYPE_STRING;
+ *   ...
+ */
+<xsl:for-each select="trace/types/primary_types/primary_type">
+typedef <xsl:value-of select="@type"/>  TYPE_<xsl:value-of select="@symbol"/>;
+</xsl:for-each>
+
+#endif // JFRFILES_JFRTYPES_HPP
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/tracetypes.xml	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,368 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ 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.
+-->
+
+<!DOCTYPE types SYSTEM "trace.dtd">
+
+<!--
+
+Content types (complex) should create constant pool data
+in the recording.
+Currently at least, there is _NO_ verification that whatever
+writer you have is actually writing correctly. So BE CAREFUL!
+
+Declared with the 'content_type' tag.
+
+<type> is the ID type, i.e the integer type that resolves this. Most often
+U4 or U8, but for example really small number constants, like GCTYPE uses U1.
+
+<content-type> is where it gets interesting. 'builtin_type' means we're
+defining how we resolve one of the trace built-in types (Class, Thread etc),
+jvm_type means defining a new one for our own use.
+
+Example: (GcMode)
+
+<content_type id="GCMode" hr_name="GC mode" type="U1" jvm_type="GCMODE">
+  <value type="UTF8" field="desc" description="Description"/>
+</content_type>
+
+This creates a content type CONTENT_TYPE_GCMODE
+The field type referencing it is u1 (U1), and the constant pool struct has one field, the name.
+
+Before we can use it we need also define a primary field data type:
+
+<primary_type symbol="GCMODE" datatype="U1" contenttype="NONE"
+              type="u8" sizeop="sizeof(u1)"/>
+
+Now we can use the content + data type in declaring event fields.
+Remember however, that for us to be able to resolve the value later we must also add
+creating the constant pool data in  VM_JFRCheckpoint::write_checkpoint
+
+   ...
+   //CGMODE
+   w->be_uint(CONTENT_TYPE_GCMODE);
+   w->be_uint(MM_GC_MODE_UNINITIALIZED);
+   for (i = 0; i < MM_GC_MODE_UNINITIALIZED; i++) {
+      w->uchar(i);
+      w->write_utf8(gcModeGetName(i));
+   }
+
+ -->
+
+ <types>
+  <content_types>
+    <content_type id="Thread" hr_name="Thread"
+                  type="U4" builtin_type="OSTHREAD">
+      <value type="UTF8" field="name" label="Thread name"/>
+    </content_type>
+
+    <content_type id="VMThread" hr_name="VM Thread"
+                  type="U8" jvm_type="VMTHREAD">
+      <value type="OSTHREAD" field="thread" label="VM Thread"/>
+    </content_type>
+
+    <!-- The first argument ("JavaThread") is misleading, it's really a
+         java.lang.Thread id (long), but Mission Control depends on the name
+         being "JavaThread" so it shouldn't be changed.
+    -->
+    <content_type id="JavaThread" hr_name="Java thread"
+                  type="U8" builtin_type="JAVALANGTHREAD">
+      <value type="OSTHREAD" field="thread" label="OS Thread ID"/>
+      <value type="BYTES64" field="allocInsideTla"
+             label="Allocated bytes inside TLAs"/>
+      <value type="BYTES64" field="allocOutsideTla"
+             label="Allocated bytes outside TLAs"/>
+      <value type="THREADGROUP" field="group" label="Java Thread Group"/>
+    </content_type>
+
+    <content_type id="ThreadGroup" hr_name="Thread group"
+                  type="U4" jvm_type="THREADGROUP">
+      <value type="THREADGROUP" field="parent" label="Parent"/>
+      <value type="UTF8" field="name" label="Name"/>
+    </content_type>
+
+    <content_type id="StackTrace" hr_name="Stacktrace"
+                  type="U8" builtin_type="STACKTRACE">
+      <value type="BOOLEAN" field="truncated" label="Truncated"/>
+      <structarray type="StackFrame" field="frames" label="Stack frames"/>
+    </content_type>
+
+    <content_type id="Class" hr_name="Java class"
+                  type="U8" builtin_type="CLASS">
+      <value type="CLASS" field="loaderClass" label="ClassLoader"/>
+      <value type="SYMBOL" field="name" label="Name"/>
+      <value type="SHORT" field="modifiers" label="Access modifiers"/>
+    </content_type>
+
+    <content_type id="Method" hr_name="Java method"
+                  type="U8" jvm_type="METHOD">
+      <value type="CLASS" field="class" label="Class"/>
+      <value type="SYMBOL" field="name" label="Name"/>
+      <value type="SYMBOL" field="signature" label="Signature"/>
+      <value type="SHORT" field="modifiers" label="Access modifiers"/>
+    </content_type>
+
+    <content_type id="UTFConstant" hr_name="UTF constant"
+                  type="U8" jvm_type="SYMBOL">
+      <value type="UTF8" field="utf8" label="UTF8 data"/>
+    </content_type>
+
+    <content_type id="ThreadState" hr_name="Java Thread State"
+                  type="U2" jvm_type="THREADSTATE">
+      <value type="UTF8" field="name" label="Name"/>
+    </content_type>
+
+    <content_type id="FrameType" hr_name="Frame type"
+                  type="U1" jvm_type="FRAMETYPE">
+      <value type="UTF8" field="desc" label="Description"/>
+    </content_type>
+
+    <struct_type id="StackFrame">
+      <value type="METHOD" field="method" label="Java Method"/>
+      <value type="INTEGER" field="line" label="Line number"/>
+      <value type="FRAMETYPE" field="type" label="Frame type"/>
+    </struct_type>
+
+    <content_type id="GCName" hr_name="GC Name"
+                  type="U1" jvm_type="GCNAME">
+      <value type="UTF8" field="name" label="name" />
+    </content_type>
+
+    <content_type id="GCCause" hr_name="GC Cause"
+                  type="U2" jvm_type="GCCAUSE">
+      <value type="UTF8" field="cause" label="cause" />
+    </content_type>
+
+    <content_type id="GCWhen" hr_name="GC When"
+                  type="U1" jvm_type="GCWHEN">
+      <value type="UTF8" field="when" label="when" />
+    </content_type>
+
+    <content_type id="G1YCType" hr_name="G1 YC Type"
+                  type="U1" jvm_type="G1YCTYPE">
+      <value type="UTF8" field="type" label="type" />
+    </content_type>
+
+    <content_type id="ReferenceType" hr_name="Reference Type"
+                  type="U1" jvm_type="REFERENCETYPE">
+      <value type="UTF8" field="type" label="type" />
+    </content_type>
+
+    <content_type id="NARROW_OOP_MODE" hr_name="Narrow Oop Mode"
+                  type="U1" jvm_type="NARROWOOPMODE">
+      <value type="UTF8" field="mode" label="mode" />
+    </content_type>
+
+    <content_type id="VMOperationType" hr_name="VM Operation Type"
+                  type="U2" jvm_type="VMOPERATIONTYPE">
+      <value type="UTF8" field="type" label="type" />
+    </content_type>
+
+    <content_type id="CompilerPhaseType" hr_name="Compiler Phase Type"
+                  type="U1" jvm_type="COMPILERPHASETYPE">
+      <value type="UTF8" field="phase" label="phase" />
+    </content_type>
+
+  </content_types>
+
+
+  <primary_types>
+    <!--
+      - primary_type takes these attributes:
+      -   symbol      INTEGER, LONG etc
+      -   datatype    The trace datatype, see enum DataType
+      -   contenttype Either resolved content type or the semantic meaning
+      -   type        The actual type as used in structures etc
+      -   sizeop      A function/macro that can be applied on a single
+      -               struct value of type "type" and yield the factual byte
+      -               size we need to write.  The % is replaced by the value
+      -->
+
+    <!-- SIGNED 64bit -->
+    <primary_type symbol="LONG" datatype="LONG" contenttype="NONE"
+                  type="s8" sizeop="sizeof(s8)"/>
+
+    <!-- UNSIGNED 64bit -->
+    <primary_type symbol="ULONG" datatype="U8" contenttype="NONE"
+                  type="u8" sizeop="sizeof(u8)"/>
+
+    <!-- SIGNED 32bit -->
+    <primary_type symbol="INTEGER" datatype="INT" contenttype="NONE"
+                  type="s4" sizeop="sizeof(s4)"/>
+
+    <!-- UNSIGNED 32bit -->
+    <primary_type symbol="UINT" datatype="U4" contenttype="NONE"
+                  type="unsigned" sizeop="sizeof(unsigned)"/>
+
+    <!-- UNSIGNED 16bit -->
+    <primary_type symbol="USHORT" datatype="U2" contenttype="NONE"
+                  type="u2" sizeop="sizeof(u2)"/>
+
+    <!--  SIGNED 16bit -->
+    <primary_type symbol="SHORT" datatype="SHORT" contenttype="NONE"
+                  type="s2" sizeop="sizeof(s2)"/>
+
+    <!--  SIGNED 8bit -->
+    <primary_type symbol="BYTE" datatype="BYTE" contenttype="NONE"
+                  type="s1" sizeop="sizeof(s1)"/>
+
+    <!--  UNSIGNED 8bit -->
+    <primary_type symbol="UBYTE" datatype="U1" contenttype="NONE"
+                  type="u1" sizeop="sizeof(u1)"/>
+
+    <!--  float 32bit -->
+    <primary_type symbol="FLOAT" datatype="FLOAT" contenttype="NONE"
+                  type="float" sizeop="sizeof(float)"/>
+
+    <!--  float 64bit -->
+    <primary_type symbol="DOUBLE" datatype="DOUBLE" contenttype="NONE"
+                  type="double" sizeop="sizeof(double)"/>
+
+    <!-- boolean type (1-byte) -->
+    <primary_type symbol="BOOLEAN" datatype="BOOLEAN" contenttype="NONE"
+                  type="bool" sizeop="1"/>
+
+    <!-- 32-bit unsigned integer, SEMANTIC value BYTES -->
+    <primary_type symbol="BYTES" datatype="U4" contenttype="BYTES"
+                  type="u4" sizeop="sizeof(u4)"/>
+
+    <primary_type symbol="IOBYTES" datatype="U4" contenttype="BYTES"
+                  type="u4" sizeop="sizeof(u4)"/>
+
+    <!-- 64-bit unsigned integer, SEMANTIC value BYTES -->
+    <primary_type symbol="BYTES64" datatype="U8" contenttype="BYTES"
+                  type="u8" sizeop="sizeof(u8)"/>
+
+    <!-- 64-bit unsigned integer, SEMANTIC value ABSOLUTE MILLISECONDS -->
+    <primary_type symbol="EPOCHMILLIS" datatype="LONG" contenttype="EPOCHMILLIS"
+                  type="s8" sizeop="sizeof(s8)"/>
+
+    <!-- 64-bit unsigned integer, SEMANTIC value RELATIVE MILLISECONDS -->
+    <primary_type symbol="MILLIS" datatype="LONG" contenttype="MILLIS"
+                  type="s8" sizeop="sizeof(s8)"/>
+
+    <!-- 64-bit unsigned integer, SEMANTIC value RELATIVE NANOSECONDS -->
+    <primary_type symbol="NANOS" datatype="LONG" contenttype="NANOS"
+                  type="s8" sizeop="sizeof(s8)"/>
+
+    <!-- 64-bit signed integer, SEMANTIC value ABSOLUTE TICKS -->
+    <primary_type symbol="TICKS" datatype="LONG" contenttype="TICKS"
+                  type="s8" sizeop="sizeof(s8)"/>
+
+    <!-- 64-bit signed integer, SEMANTIC value RELATIVE TICKS -->
+    <primary_type symbol="RELATIVE_TICKS" datatype="LONG" contenttype="TICKS"
+                  type="s8" sizeop="sizeof(s8)"/>
+
+    <!-- 64-bit unsigned integer, SEMANTIC value ADDRESS (mem loc) -->
+    <primary_type symbol="ADDRESS" datatype="U8" contenttype="ADDRESS"
+                  type="u8" sizeop="sizeof(u8)"/>
+
+    <!-- 32-bit float, SEMANTIC value PERCENTAGE (0.0-1.0) -->
+    <primary_type symbol="PERCENT" datatype="FLOAT" contenttype="PERCENTAGE"
+                  type="float" sizeop="sizeof(float)"/>
+
+    <!-- UTF-encoded string, max length 64k -->
+    <primary_type symbol="UTF8" datatype="UTF8" contenttype="NONE"
+                  type="const char *" sizeop="sizeof_utf(%)"/>
+
+    <!-- Symbol* constant. Note that this may currently ONLY be used by
+          classes, methods fields.  This restriction might be lifted. -->
+    <primary_type symbol="SYMBOL" datatype="U8" contenttype="SYMBOL"
+                  type="Symbol *" sizeop="sizeof(u8)"/>
+
+    <!-- A Klass *. The actual class is marked as "used" and will
+         eventually be written into the recording constant pool -->
+    <primary_type symbol="CLASS" datatype="U8" contenttype="CLASS"
+                  type="Klass *" sizeop="sizeof(u8)"/>
+
+    <!-- A Method *. The method is marked as "used" and will eventually be
+         written into the recording constant pool. -->
+    <primary_type symbol="METHOD" datatype="U8" contenttype="METHOD"
+                  type="Method *" sizeop="sizeof(u8)"/>
+
+    <!--  The type for stacktraces in the recording. Shoudl not be used by
+          events explicitly -->
+    <primary_type symbol="STACKTRACE" datatype="U8" contenttype="STACKTRACE"
+                  type="u8" sizeop="sizeof(u8)"/>
+
+    <!-- OS Thread ID -->
+    <primary_type symbol="OSTHREAD" datatype="U4" contenttype="OSTHREAD"
+                  type="u4" sizeop="sizeof(u4)"/>
+
+    <!-- VM Thread ID Note: changed from U2 to U8 for hotspot -->
+    <primary_type symbol="VMTHREAD" datatype="U8" contenttype="VMTHREAD"
+                  type="u8"  sizeop="sizeof(u8)"/>
+
+    <!-- Java Thread ID -->
+    <primary_type symbol="JAVALANGTHREAD" datatype="LONG"
+                  contenttype="JAVALANGTHREAD" type="s8"
+                  sizeop="sizeof(s8)"/>
+
+    <!-- Threadgroup THIS TYPE MAY NOT BE USED IN NORMAL EVENTS (ATM). Only
+          for thread constant pool // KK TODO: u8 should be ObjectP -->
+    <primary_type symbol="THREADGROUP" datatype="U4" contenttype="THREADGROUP"
+                  type="u8"
+                  sizeop="sizeof(u4)"/>
+
+    <!-- FRAMETYPE enum -->
+    <primary_type symbol="FRAMETYPE" datatype="U1" contenttype="FRAMETYPE"
+                  type="u1" sizeop="sizeof(u1)"/>
+
+    <!-- THREADSTATE enum -->
+    <primary_type symbol="THREADSTATE" datatype="U2" contenttype="THREADSTATE"
+                  type="u2" sizeop="sizeof(u2)"/>
+
+    <!-- GCName -->
+    <primary_type symbol="GCNAME" datatype="U1" contenttype="GCNAME"
+                  type="u1" sizeop="sizeof(u1)" />
+
+    <!-- GCCAUSE -->
+    <primary_type symbol="GCCAUSE" datatype="U2" contenttype="GCCAUSE"
+                  type="u2" sizeop="sizeof(u2)" />
+
+    <!-- GCWHEN -->
+    <primary_type symbol="GCWHEN" datatype="U1" contenttype="GCWHEN"
+                  type="u1" sizeop="sizeof(u1)" />
+
+    <!-- G1YCType -->
+    <primary_type symbol="G1YCTYPE" datatype="U1" contenttype="G1YCTYPE"
+                  type="u1" sizeop="sizeof(u1)" />
+
+    <!-- REFERENCETYPE -->
+    <primary_type symbol="REFERENCETYPE" datatype="U1"
+                  contenttype="REFERENCETYPE" type="u1" sizeop="sizeof(u1)" />
+
+    <!-- NARROWOOPMODE -->
+    <primary_type symbol="NARROWOOPMODE" datatype="U1"
+                  contenttype="NARROWOOPMODE" type="u1" sizeop="sizeof(u1)" />
+
+    <!-- COMPILERPHASETYPE -->
+    <primary_type symbol="COMPILERPHASETYPE" datatype="U1"
+                  contenttype="COMPILERPHASETYPE" type="u1" sizeop="sizeof(u1)" />
+
+    <!-- VMOPERATIONTYPE -->
+    <primary_type symbol="VMOPERATIONTYPE" datatype="U2" contenttype="VMOPERATIONTYPE"
+                  type="u2" sizeop="sizeof(u2)" />
+
+  </primary_types>
+</types>
--- a/src/share/vm/trace/tracing.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/trace/tracing.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_TRACE_TRACING_HPP
 #define SHARE_VM_TRACE_TRACING_HPP
 
-#include "trace/traceMacros.hpp"
+#include "tracefiles/traceEventClasses.hpp"
+#include "tracefiles/traceEventIds.hpp"
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/xinclude.mod	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ 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.
+  
+-->
+
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+  
+-->
+<!ELEMENT xi:include (xi:fallback?) >
+<!ATTLIST xi:include
+    xmlns:xi   CDATA       #FIXED    "http://www.w3.org/2001/XInclude"
+    href       CDATA       #IMPLIED
+    parse      (xml|text)  "xml"
+    xpointer   CDATA       #IMPLIED
+    encoding   CDATA       #IMPLIED 
+    accept     CDATA       #IMPLIED
+    accept-language CDATA  #IMPLIED >
+
+<!ELEMENT xi:fallback ANY>
+<!ATTLIST xi:fallback
+    xmlns:xi   CDATA   #FIXED   "http://www.w3.org/2001/XInclude" >
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/trace/xsl_util.xsl	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ 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.
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!-- utilities used when generating code -->
+
+<xsl:variable name="newline">
+  <xsl:text>&#xA;</xsl:text>
+</xsl:variable>
+
+<xsl:variable name="indent1">
+  <xsl:text>&#xA;  </xsl:text>
+</xsl:variable>
+
+<xsl:variable name="indent2">
+  <xsl:text>&#xA;    </xsl:text>
+</xsl:variable>
+
+<xsl:variable name="indent3">
+  <xsl:text>&#xA;      </xsl:text>
+</xsl:variable>
+
+<xsl:variable name="indent4">
+  <xsl:text>&#xA;        </xsl:text>
+</xsl:variable>
+
+<xsl:variable name="quote">
+  <xsl:text>"</xsl:text>
+</xsl:variable>
+
+<xsl:template name="file-header">
+  <xsl:text>/* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */</xsl:text>
+</xsl:template>
+
+<xsl:template name="string-replace-all">
+  <xsl:param name="text" />
+  <xsl:param name="replace" />
+  <xsl:param name="by" />
+  <xsl:choose>
+    <xsl:when test="contains($text, $replace)">
+      <xsl:value-of select="substring-before($text,$replace)" />
+      <xsl:value-of select="$by" />
+      <xsl:call-template name="string-replace-all">
+        <xsl:with-param name="text" select="substring-after($text,$replace)" />
+        <xsl:with-param name="replace" select="$replace" />
+        <xsl:with-param name="by" select="$by" />
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$text" />
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+</xsl:stylesheet>
--- a/src/share/vm/utilities/array.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/utilities/array.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -320,7 +320,7 @@
   void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) {
     size_t word_size = Array::size(length);
     return (void*) Metaspace::allocate(loader_data, word_size, read_only,
-                        Metaspace::NonClassType, CHECK_NULL);
+                                       MetaspaceObj::array_type(sizeof(T)), CHECK_NULL);
   }
 
   static size_t byte_sizeof(int length) { return sizeof(Array<T>) + MAX2(length - 1, 0) * sizeof(T); }
--- a/src/share/vm/utilities/globalDefinitions.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -380,6 +380,14 @@
 # include "globalDefinitions_ppc.hpp"
 #endif
 
+/*
+ * If a platform does not support NMT_detail
+ * the platform specific globalDefinitions (above)
+ * can set PLATFORM_NMT_DETAIL_SUPPORTED to false
+ */
+#ifndef PLATFORM_NMT_DETAIL_SUPPORTED
+#define PLATFORM_NMT_DETAIL_SUPPORTED true
+#endif
 
 // The byte alignment to be used by Arena::Amalloc.  See bugid 4169348.
 // Note: this value must be a power of 2
@@ -755,18 +763,6 @@
 TosState as_TosState(BasicType type);
 
 
-// ReferenceType is used to distinguish between java/lang/ref/Reference subclasses
-
-enum ReferenceType {
- REF_NONE,      // Regular class
- REF_OTHER,     // Subclass of java/lang/ref/Reference, but not subclass of one of the classes below
- REF_SOFT,      // Subclass of java/lang/ref/SoftReference
- REF_WEAK,      // Subclass of java/lang/ref/WeakReference
- REF_FINAL,     // Subclass of java/lang/ref/FinalReference
- REF_PHANTOM    // Subclass of java/lang/ref/PhantomReference
-};
-
-
 // JavaThreadState keeps track of which part of the code a thread is executing in. This
 // information is needed by the safepoint code.
 //
--- a/src/share/vm/utilities/macros.hpp	Thu Jun 20 16:30:44 2013 -0700
+++ b/src/share/vm/utilities/macros.hpp	Fri Jun 21 15:56:24 2013 -0700
@@ -160,6 +160,10 @@
 #define NOT_NMT_RETURN_(code) { return code; }
 #endif // INCLUDE_NMT
 
+#ifndef INCLUDE_TRACE
+#define INCLUDE_TRACE 1
+#endif // INCLUDE_TRACE
+
 // COMPILER1 variant
 #ifdef COMPILER1
 #ifdef COMPILER2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/8011771/Test8011771.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8011771
+ * @summary Array bound check elimination's in block motion doesn't always reset its data structures from one step to the other.
+ * @run main/othervm -XX:-BackgroundCompilation Test8011771
+ *
+ */
+
+public class Test8011771 {
+
+    static void m(int[] a, int[] b, int j) {
+        // Array bound check elimination inserts a predicate before
+        // the loop. We'll have the predicate fail, so the method is
+        // recompiled without optimistic optimizations
+        for (int i = 0; i < 10; i++) {
+            a[i] = i;
+        }
+
+        // The test itself
+        a[j] = 0;
+        a[j+5] = 0;
+        b[j+4] = 0; // this range check shouldn't be eliminated
+    }
+
+    static public void main(String[] args) {
+        int[] arr1 = new int[10], arr2 = new int[10];
+        // force compilation:
+        for (int i = 0; i < 5000; i++) {
+            m(arr1, arr2, 0);
+        }
+
+        try {
+            m(new int[1], null, 0); // force predicate failure
+        } catch(ArrayIndexOutOfBoundsException e) {}
+
+        // force compilation again (no optimistic opts):
+        for (int i = 0; i < 5000; i++) {
+            m(arr1, arr2, 0);
+        }
+
+        // Check that the range check  on the second array wasn't optimized out
+        boolean success = false;
+        try {
+            m(arr1, new int[1], 0);
+        } catch(ArrayIndexOutOfBoundsException e) {
+            success = true;
+        }
+        if (success) {
+            System.out.println("TEST PASSED");
+        } else {
+            throw new RuntimeException("TEST FAILED: erroneous bound check elimination");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/8013496/Test8013496.sh	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,55 @@
+#!/bin/sh
+# 
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+# 
+#
+# @test
+# @bug 8013496
+# @summary Test checks that the order in which ReversedCodeCacheSize and 
+#          InitialCodeCacheSize are passed to the VM is irrelevant.  
+# @run shell Test8013496.sh
+#
+#
+## some tests require path to find test source dir
+if [ "${TESTSRC}" = "" ]
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+set -x
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:ReservedCodeCacheSize=2m -XX:InitialCodeCacheSize=500K -version > 1.out 2>&1
+${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:InitialCodeCacheSize=500K -XX:ReservedCodeCacheSize=2m -version > 2.out 2>&1
+
+diff 1.out 2.out
+
+result=$?
+if [ $result -eq 0 ] ; then  
+  echo "Test Passed"
+  exit 0
+else
+  echo "Test Failed"
+  exit 1
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/8015436/Test8015436.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8015436
+ * @summary the IK _initial_method_idnum value must be adjusted if overpass methods are added
+ * @run main Test8015436
+ *
+ */
+
+/*
+ * The test checks that a MemberName for the defaultMethod() is cached in
+ * the class MemberNameTable without a crash in the VM fastdebug mode.
+ * The original issue was that the InstanceKlass _initial_method_idnum was
+ * not adjusted properly when the overpass methods are added to the class.
+ * The expected/correct behavior: The test does not crash nor throw any exceptions.
+ * All the invocations of the defaultMethod() must be completed successfully.
+ */
+
+import java.lang.invoke.*;
+
+interface InterfaceWithDefaultMethod {
+    public void someMethod();
+
+    default public void defaultMethod(String str){
+        System.out.println("defaultMethod() " + str);
+    }
+}
+
+public class Test8015436 implements InterfaceWithDefaultMethod {
+    @Override
+    public void someMethod() {
+        System.out.println("someMethod() invoked");
+    }
+
+    public static void main(String[] args) throws Throwable {
+        Test8015436 testObj = new Test8015436();
+        testObj.someMethod();
+        testObj.defaultMethod("invoked directly");
+
+        MethodHandles.Lookup lookup = MethodHandles.lookup();
+        MethodType   mt = MethodType.methodType(void.class, String.class);
+        MethodHandle mh = lookup.findVirtual(Test8015436.class, "defaultMethod", mt);
+        mh.invokeExact(testObj, "invoked via a MethodHandle");
+    }
+}
+
+/*
+ * A successful execution gives the output:
+ *   someMethod() invoked
+ *   defaultMethod() invoked directly
+ *   defaultMethod() invoked via a MethodHandle
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestSummarizeRSetStats.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestSummarizeRSetStats.java
+ * @bug 8013895
+ * @library /testlibrary
+ * @build TestSummarizeRSetStats
+ * @summary Verify output of -XX:+G1SummarizeRSetStats
+ * @run main TestSummarizeRSetStats
+ *
+ * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod.
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class RunSystemGCs {
+    // 4M size, both are directly allocated into the old gen
+    static Object[] largeObject1 = new Object[1024 * 1024];
+    static Object[] largeObject2 = new Object[1024 * 1024];
+
+    static int[] temp;
+
+    public static void main(String[] args) {
+        // create some cross-references between these objects
+        for (int i = 0; i < largeObject1.length; i++) {
+            largeObject1[i] = largeObject2;
+        }
+
+        for (int i = 0; i < largeObject2.length; i++) {
+            largeObject2[i] = largeObject1;
+        }
+
+        int numGCs = Integer.parseInt(args[0]);
+
+        if (numGCs > 0) {
+            // try to force a minor collection: the young gen is 4M, the
+            // amount of data allocated below is roughly that (4*1024*1024 +
+            // some header data)
+            for (int i = 0; i < 1024 ; i++) {
+                temp = new int[1024];
+            }
+        }
+
+        for (int i = 0; i < numGCs - 1; i++) {
+            System.gc();
+        }
+    }
+}
+
+public class TestSummarizeRSetStats {
+
+    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
+        ArrayList<String> finalargs = new ArrayList<String>();
+        String[] defaultArgs = new String[] {
+            "-XX:+UseG1GC",
+            "-Xmn4m",
+            "-Xmx20m",
+            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
+            "-XX:+PrintGC",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:G1HeapRegionSize=1M",
+        };
+
+        finalargs.addAll(Arrays.asList(defaultArgs));
+
+        if (additionalArgs != null) {
+            finalargs.addAll(Arrays.asList(additionalArgs));
+        }
+
+        finalargs.add(RunSystemGCs.class.getName());
+        finalargs.add(String.valueOf(numGCs));
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            finalargs.toArray(new String[0]));
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        output.shouldHaveExitValue(0);
+
+        String result = output.getStdout();
+        return result;
+    }
+
+    private static void expectStatistics(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
+        int actualTotal = result.split("Concurrent RS processed").length - 1;
+        int actualCumulative = result.split("Cumulative RS summary").length - 1;
+
+        if (expectedCumulative != actualCumulative) {
+            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
+        }
+
+        if (expectedPeriodic != (actualTotal - actualCumulative)) {
+            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        String result;
+
+        // no RSet statistics output
+        result = runTest(null, 0);
+        expectStatistics(result, 0, 0);
+
+        // no RSet statistics output
+        result = runTest(null, 2);
+        expectStatistics(result, 0, 0);
+
+        // no RSet statistics output
+        result = runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+        expectStatistics(result, 0, 0);
+
+        // single RSet statistics output at the end
+        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
+        expectStatistics(result, 1, 0);
+
+        // single RSet statistics output at the end
+        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
+        expectStatistics(result, 1, 0);
+
+        // single RSet statistics output
+        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
+        expectStatistics(result, 1, 0);
+
+        // two times RSet statistics output
+        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
+        expectStatistics(result, 1, 1);
+
+        // four times RSet statistics output
+        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+        expectStatistics(result, 1, 3);
+
+        // three times RSet statistics output
+        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
+        expectStatistics(result, 1, 2);
+
+        // single RSet statistics output
+        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
+        expectStatistics(result, 1, 1);
+    }
+}
+
--- a/test/runtime/8007320/ConstMethodTest.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/test/runtime/8007320/ConstMethodTest.java	Fri Jun 21 15:56:24 2013 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8007320
+ * @bug 8007320 8014709
  * @summary Test all optional fields in ConstMethod
  * @compile -g -parameters ConstMethodTest.java
  * @run main ConstMethodTest
@@ -74,6 +74,11 @@
 
 @MyAnnotation(name="someName", value = "Hello World")
 public class ConstMethodTest {
+    public @TypeAnno("constructor") ConstMethodTest() { }
+
+    public ConstMethodTest(int i) {
+        // needs a second unannotated constructor
+    }
 
     private static void check(boolean b) {
         if (!b)
@@ -139,10 +144,26 @@
         }
     }
 
+    private static void testConstructor() throws Exception {
+        for (Constructor c : ConstMethodTest.class.getDeclaredConstructors()) {
+            Annotation[] aa = c.getAnnotatedReturnType().getAnnotations();
+            if (c.getParameterTypes().length == 1) { // should be un-annotated
+                check(aa.length == 0);
+            } else if (c.getParameterTypes().length == 0) { //should be annotated
+                check(aa.length == 1);
+                check(((TypeAnno)aa[0]).value().equals("constructor"));
+            } else {
+                //should not happen
+                check(false);
+            }
+        }
+    }
+
     public static void main(java.lang.String[] unused) throws Throwable {
         // pass 5 so kitchenSinkFunc is instantiated with an int
         kitchenSinkFunc("parameter", "param2", 5);
         test1();
+        testConstructor();
     }
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Metaspace/FragmentMetaspace.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @library /runtime/testlibrary
+ * @build GeneratedClassLoader
+ * @run main/othervm/timeout=200 FragmentMetaspace
+ */
+
+import java.io.IOException;
+
+/**
+ * Test that tries to fragment the native memory used by class loaders.
+ * This test creates class loaders that load classes of increasing size for every
+ * iteration. By increasing the size of the class meta data needed for every iteration
+ * we stress the subsystem for allocating native memory for meta data.
+ */
+public class FragmentMetaspace {
+
+    public static void main(String... args) {
+        runGrowing(Long.valueOf(System.getProperty("time", "80000")));
+        // try to clean up and unload classes to decrease
+        // class verification time in debug vm
+        System.gc();
+    }
+
+    private static void runGrowing(long time) {
+        long startTime = System.currentTimeMillis();
+        for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
+            try {
+                GeneratedClassLoader gcl = new GeneratedClassLoader();
+
+                Class<?> c = gcl.getGeneratedClasses(i, 100)[0];
+                c.newInstance();
+                c = null;
+
+                gcl = null;
+            } catch (IOException|InstantiationException|IllegalAccessException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Metaspace/FragmentMetaspaceSimple.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @library /runtime/testlibrary
+ * @library classes
+ * @build test.Empty ClassUnloadCommon
+ * @run main/othervm/timeout=200 FragmentMetaspaceSimple
+ */
+
+import java.util.ArrayList;
+
+/**
+ * Test that tries to fragment the native memory used by class loaders.
+ * Keeps every other class loader alive in order to fragment the memory space
+ * used to store classes and meta data. Since the memory is probably allocated in
+ * chunks per class loader this will cause a lot of fragmentation if not handled
+ * properly since every other chunk will be unused.
+ */
+public class FragmentMetaspaceSimple {
+    public static void main(String... args) {
+        runSimple(Long.valueOf(System.getProperty("time", "80000")));
+        System.gc();
+    }
+
+    private static void runSimple(long time) {
+        long startTime = System.currentTimeMillis();
+        ArrayList<ClassLoader> cls = new ArrayList<>();
+        for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
+            ClassLoader ldr = ClassUnloadCommon.newClassLoader();
+            if (i % 1000 == 0) {
+                cls.clear();
+            }
+            // only keep every other class loader alive
+            if (i % 2 == 1) {
+                cls.add(ldr);
+            }
+            Class<?> c = null;
+            try {
+                c = ldr.loadClass("test.Empty");
+            } catch (ClassNotFoundException ex) {
+                throw new RuntimeException(ex);
+            }
+            c = null;
+        }
+        cls = null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Metaspace/classes/test/Empty.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test;
+
+public class Empty {
+public String toString() { return "nothing"; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/contended/HasNonStatic.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import sun.misc.Unsafe;
+import sun.misc.Contended;
+
+/*
+ * @test
+ * @bug     8015270
+ * @summary \@Contended: fix multiple issues in the layout code
+ *
+ * @run main/othervm -XX:-RestrictContended HasNonStatic
+ */
+public class HasNonStatic {
+
+    public static void main(String[] args) throws Exception {
+        R1 r1 = new R1();
+        R2 r2 = new R2();
+        R3 r3 = new R3();
+        R4 r4 = new R4();
+    }
+
+    public static class R1 {
+        @Contended
+        Object o;
+    }
+
+    @Contended
+    public static class R2 {
+        Object o;
+    }
+
+    @Contended
+    public static class R3 {
+    }
+
+    public static class R4 extends R3 {
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/contended/OopMaps.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import sun.misc.Unsafe;
+import sun.misc.Contended;
+
+/*
+ * @test
+ * @bug     8015270
+ * @bug     8015493
+ * @summary \@Contended: fix multiple issues in the layout code
+ *
+ * @run main/othervm -XX:-RestrictContended -XX:ContendedPaddingWidth=128 -Xmx128m OopMaps
+ */
+public class OopMaps {
+
+    public static final int COUNT = 10000;
+
+    public static void main(String[] args) throws Exception {
+        Object o01 = new Object();
+        Object o02 = new Object();
+        Object o03 = new Object();
+        Object o04 = new Object();
+        Object o05 = new Object();
+        Object o06 = new Object();
+        Object o07 = new Object();
+        Object o08 = new Object();
+        Object o09 = new Object();
+        Object o10 = new Object();
+        Object o11 = new Object();
+        Object o12 = new Object();
+        Object o13 = new Object();
+        Object o14 = new Object();
+
+        R1[] rs = new R1[COUNT];
+
+        for (int i = 0; i < COUNT; i++) {
+           R1 r1 = new R1();
+           r1.o01 = o01;
+           r1.o02 = o02;
+           r1.o03 = o03;
+           r1.o04 = o04;
+           r1.o05 = o05;
+           r1.o06 = o06;
+           r1.o07 = o07;
+           r1.o08 = o08;
+           r1.o09 = o09;
+           r1.o10 = o10;
+           r1.o11 = o11;
+           r1.o12 = o12;
+           r1.o13 = o13;
+           r1.o14 = o14;
+           r1.i1 = 1;
+           r1.i2 = 2;
+           r1.i3 = 3;
+           r1.i4 = 4;
+           rs[i] = r1;
+        }
+
+        System.gc();
+
+        for (int i = 0; i < COUNT; i++) {
+           R1 r1 = rs[i];
+           if (r1.o01 != o01) throw new Error("Test Error: o01");
+           if (r1.o02 != o02) throw new Error("Test Error: o02");
+           if (r1.o03 != o03) throw new Error("Test Error: o03");
+           if (r1.o04 != o04) throw new Error("Test Error: o04");
+           if (r1.o05 != o05) throw new Error("Test Error: o05");
+           if (r1.o06 != o06) throw new Error("Test Error: o06");
+           if (r1.o07 != o07) throw new Error("Test Error: o07");
+           if (r1.o08 != o08) throw new Error("Test Error: o08");
+           if (r1.o09 != o09) throw new Error("Test Error: o09");
+           if (r1.o10 != o10) throw new Error("Test Error: o10");
+           if (r1.o11 != o11) throw new Error("Test Error: o11");
+           if (r1.o12 != o12) throw new Error("Test Error: o12");
+           if (r1.o13 != o13) throw new Error("Test Error: o13");
+           if (r1.o14 != o14) throw new Error("Test Error: o14");
+           if (r1.i1 != 1)    throw new Error("Test Error: i1");
+           if (r1.i2 != 2)    throw new Error("Test Error: i2");
+           if (r1.i3 != 3)    throw new Error("Test Error: i3");
+           if (r1.i4 != 4)    throw new Error("Test Error: i4");
+        }
+    }
+
+    public static class R0 {
+        int i1;
+        int i2;
+
+        Object o01;
+        Object o02;
+
+        @Contended
+        Object o03;
+
+        @Contended
+        Object o04;
+
+        @Contended
+        Object o05;
+
+        @Contended
+        Object o06;
+
+        @Contended
+        Object o07;
+   }
+
+   public static class R1 extends R0 {
+        int i3;
+        int i4;
+
+        Object o08;
+        Object o09;
+
+        @Contended
+        Object o10;
+
+        @Contended
+        Object o11;
+
+        @Contended
+        Object o12;
+
+        @Contended
+        Object o13;
+
+        @Contended
+        Object o14;
+   }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/memory/MultiAllocateNullCheck.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test MultiAllocateNullCheck
+ * @bug 6726963
+ * @summary multi_allocate() call does not CHECK_NULL and causes crash in fastdebug bits
+ * @run main/othervm -Xmx32m MultiAllocateNullCheck
+ */
+
+import java.lang.reflect.Array;
+
+public class MultiAllocateNullCheck {
+      public static void main(String[] args) throws Exception {
+        Object x = null;
+        try
+        {
+            x = Array.newInstance(String.class, new int[]
+                {Integer.MAX_VALUE, Integer.MAX_VALUE});
+            System.out.println("Array was created");
+        } catch (OutOfMemoryError e) {
+            System.out.println("Out of memory occured, which is OK in this case");
+        }
+    }
+}
--- a/test/runtime/memory/ReserveMemory.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/test/runtime/memory/ReserveMemory.java	Fri Jun 21 15:56:24 2013 -0700
@@ -34,29 +34,20 @@
 
 import com.oracle.java.testlibrary.*;
 
-import java.lang.reflect.Field;
 import sun.hotspot.WhiteBox;
-import sun.misc.Unsafe;
 
 public class ReserveMemory {
-  private static Unsafe getUnsafe() throws Exception {
-    Field f = Unsafe.class.getDeclaredField("theUnsafe");
-    f.setAccessible(true);
-    return (Unsafe)f.get(null);
-  }
-
   private static boolean isWindows() {
     return System.getProperty("os.name").toLowerCase().startsWith("win");
   }
 
+  private static boolean isOsx() {
+    return System.getProperty("os.name").toLowerCase().startsWith("mac");
+  }
+
   public static void main(String args[]) throws Exception {
     if (args.length > 0) {
-      long address = WhiteBox.getWhiteBox().reserveMemory(4096);
-
-      System.out.println("Reserved memory at address: 0x" + Long.toHexString(address));
-      System.out.println("Will now read from the address, expecting a crash!");
-
-      int x = getUnsafe().getInt(address);
+      WhiteBox.getWhiteBox().readReservedMemory();
 
       throw new Exception("Read of reserved/uncommitted memory unexpectedly succeeded, expected crash!");
     }
@@ -71,6 +62,8 @@
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
     if (isWindows()) {
       output.shouldContain("EXCEPTION_ACCESS_VIOLATION");
+    } else if (isOsx()) {
+      output.shouldContain("SIGBUS");
     } else {
       output.shouldContain("SIGSEGV");
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/testlibrary/GeneratedClassLoader.java	Fri Jun 21 15:56:24 2013 -0700
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+
+/**
+ * A class loader that generates new classes.
+ * The generated classes are made by first emitting java sources with nested
+ * static classes, these are then compiled and the class files are read back.
+ * Some efforts are made to make the class instances unique and of not insignificant
+ * size.
+ */
+public class GeneratedClassLoader extends ClassLoader {
+    /**
+     * Holds a pair of class bytecodes and class name (for use with defineClass).
+     */
+    private static class GeneratedClass {
+        public byte[] bytes;
+        public String name;
+        public GeneratedClass(byte[] bytes, String name) {
+            this.bytes = bytes; this.name = name;
+        }
+    }
+
+    /**
+     * Used to uniquely name every class generated.
+     */
+    private static int count = 0;
+    /**
+     * Used to enable/disable keeping the class files and java sources for
+     * the generated classes.
+     */
+    private static boolean deleteFiles = Boolean.parseBoolean(
+        System.getProperty("GeneratedClassLoader.deleteFiles", "true"));
+
+    private static String bigstr =
+        "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+        + "In facilisis scelerisque vehicula. Donec congue nisi a "
+        + "leo posuere placerat lobortis felis ultrices. Pellentesque "
+        + "habitant morbi tristique senectus et netus et malesuada "
+        + "fames ac turpis egestas. Nam tristique velit at felis "
+        + "iaculis at tempor sem vestibulum. Sed adipiscing lectus "
+        + "non mi molestie sagittis. Morbi eu purus urna. Nam tempor "
+        + "tristique massa eget semper. Mauris cursus, nulla et ornare "
+        + "vehicula, leo dolor scelerisque metus, sit amet rutrum erat "
+        + "sapien quis dui. Nullam eleifend risus et velit accumsan sed "
+        + "suscipit felis pulvinar. Nullam faucibus suscipit gravida. "
+        + "Pellentesque habitant morbi tristique senectus et netus et "
+        + "malesuada fames ac turpis egestas. Nullam ut massa augue, "
+        + "nec viverra mauris.";
+
+    private static int getNextCount() {
+        return count++;
+    }
+
+    ////// end statics
+
+    private JavaCompiler javac;
+    private String nameBase;
+
+    public GeneratedClassLoader() {
+        javac = ToolProvider.getSystemJavaCompiler();
+        nameBase = "TestSimpleClass";
+    }
+
+    private long getBigValue(int which) {
+        // > 65536 is too large to encode in the bytecode
+        // so this will force us to emit a constant pool entry for this int
+        return (long)which + 65537;
+    }
+
+    private String getBigString(int which) {
+        return bigstr + which;
+    }
+
+    private String getClassName(int count) {
+        return nameBase + count;
+    }
+
+    private String generateSource(int count, int sizeFactor, int numClasses) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("public class ").append(getClassName(count)).append("{\n");
+        for (int j = 0; j < numClasses; ++j) {
+            sb.append("public static class ")
+              .append("Class")
+              .append(j)
+              .append("{\n");
+            for (int i = 0; i < sizeFactor; ++i) {
+                int value = i;
+                sb.append("private long field")
+                  .append(i).append(" = ")
+                  .append(getBigValue(value++))
+                  .append(";\n");
+                sb.append("public long method")
+                  .append(i)
+                  .append("() {\n");
+                sb.append("return ")
+                  .append(getBigValue(value++))
+                  .append(";");
+                sb.append("}\n");
+                sb.append("private String str").append(i)
+                  .append(" = \"")
+                  .append(getBigString(i))
+                  .append("\";");
+            }
+            sb.append("\n}");
+        }
+        sb.append("\n}");
+        return sb.toString();
+    }
+
+    private GeneratedClass[] getGeneratedClass(int sizeFactor, int numClasses) throws IOException {
+        int uniqueCount = getNextCount();
+        String src = generateSource(uniqueCount, sizeFactor, numClasses);
+        String className = getClassName(uniqueCount);
+        File file = new File(className + ".java");
+        try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
+            pw.append(src);
+            pw.flush();
+        }
+        int exitcode = javac.run(null, null, null, file.getCanonicalPath());
+        if (exitcode != 0) {
+            throw new RuntimeException("javac failure when compiling: " +
+                    file.getCanonicalPath());
+        } else {
+            if (deleteFiles) {
+                file.delete();
+            }
+        }
+        GeneratedClass[] gc = new GeneratedClass[numClasses];
+        for (int i = 0; i < numClasses; ++i) {
+            String name = className + "$" + "Class" + i;
+            File classFile = new File(name + ".class");
+            byte[] bytes;
+            try (DataInputStream dis = new DataInputStream(new FileInputStream(classFile))) {
+                bytes = new byte[dis.available()];
+                dis.readFully(bytes);
+            }
+            if (deleteFiles) {
+                classFile.delete();
+            }
+            gc[i] = new GeneratedClass(bytes, name);
+        }
+        if (deleteFiles) {
+            new File(className + ".class").delete();
+        }
+        return gc;
+    }
+
+    /**
+     * Generate a single class, compile it and load it.
+     * @param sizeFactor Fuzzy measure of how large the class should be.
+     * @return the Class instance.
+     * @throws IOException
+     */
+    public Class<?> generateClass(int sizeFactor) throws IOException {
+        return getGeneratedClasses(sizeFactor, 1)[0];
+    }
+
+    /**
+     * Generate several classes, compile and load them.
+     * @param sizeFactor Fuzzy measure of how large each class should be.
+     * @param numClasses The number of classes to create
+     * @return an array of the Class instances.
+     * @throws IOException
+     */
+    public Class<?>[] getGeneratedClasses(int sizeFactor, int numClasses) throws IOException {
+        GeneratedClass[] gc = getGeneratedClass(sizeFactor, numClasses);
+        Class<?>[] classes = new Class[numClasses];
+        for (int i = 0; i < numClasses; ++i) {
+            classes[i] = defineClass(gc[i].name, gc[i].bytes, 0 , gc[i].bytes.length);
+        }
+        return classes;
+    }
+}
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Thu Jun 20 16:30:44 2013 -0700
+++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Fri Jun 21 15:56:24 2013 -0700
@@ -115,7 +115,7 @@
   public native boolean isInStringTable(String str);
 
   // Memory
-  public native long reserveMemory(long size);
+  public native void readReservedMemory();
 
   // force Full GC
   public native void fullGC();