Merge
authorlana
Thu, 22 Oct 2015 11:13:08 -0700
changeset 33202 643e2fbeccc3
parent 33060 5e522d8ea16c (current diff)
parent 33201 0729c02cb845 (diff)
child 33231 a6d6dd711998
Merge
hotspot/test/compiler/TestMoveStoresOutOfLoopsStoreNoCtrl.java
hotspot/test/runtime/6888954/vmerrors.sh
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java	Thu Oct 22 11:13:08 2015 -0700
@@ -67,9 +67,6 @@
       }
     }
 
-    public void visitValueLocation(Address valueAddr) {
-    }
-
     public void visitNarrowOopLocation(Address narrowOopAddr) {
       addressVisitor.visitCompOopAddress(narrowOopAddr);
     }
@@ -216,9 +213,9 @@
       }
     }
 
-    // We want narow oop, value and oop oop_types
-    OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[]{
-        OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
+    // We want narow oop and oop oop_types
+    OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] {
+        OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
     };
 
     {
@@ -231,8 +228,6 @@
             // to detect in the debugging system
             // assert(Universe::is_heap_or_null(*loc), "found non oop pointer");
             visitor.visitOopLocation(loc);
-          } else if (omv.getType() == OopMapValue.OopTypes.VALUE_VALUE) {
-            visitor.visitValueLocation(loc);
           } else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) {
             visitor.visitNarrowOopLocation(loc);
           }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -49,7 +49,6 @@
   // Types of OopValues
   static int UNUSED_VALUE;
   static int OOP_VALUE;
-  static int VALUE_VALUE;
   static int NARROWOOP_VALUE;
   static int CALLEE_SAVED_VALUE;
   static int DERIVED_OOP_VALUE;
@@ -73,7 +72,6 @@
     REGISTER_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::register_mask_in_place").intValue();
     UNUSED_VALUE           = db.lookupIntConstant("OopMapValue::unused_value").intValue();
     OOP_VALUE              = db.lookupIntConstant("OopMapValue::oop_value").intValue();
-    VALUE_VALUE            = db.lookupIntConstant("OopMapValue::value_value").intValue();
     NARROWOOP_VALUE        = db.lookupIntConstant("OopMapValue::narrowoop_value").intValue();
     CALLEE_SAVED_VALUE     = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue();
     DERIVED_OOP_VALUE      = db.lookupIntConstant("OopMapValue::derived_oop_value").intValue();
@@ -82,7 +80,6 @@
   public static abstract class OopTypes {
     public static final OopTypes UNUSED_VALUE       = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE;       }};
     public static final OopTypes OOP_VALUE          = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE;          }};
-    public static final OopTypes VALUE_VALUE        = new OopTypes() { int getValue() { return OopMapValue.VALUE_VALUE;        }};
     public static final OopTypes NARROWOOP_VALUE    = new OopTypes() { int getValue() { return OopMapValue.NARROWOOP_VALUE;         }};
     public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }};
     public static final OopTypes DERIVED_OOP_VALUE  = new OopTypes() { int getValue() { return OopMapValue.DERIVED_OOP_VALUE;  }};
@@ -105,7 +102,6 @@
 
   // Querying
   public boolean isOop()         { return (getValue() & TYPE_MASK_IN_PLACE) == OOP_VALUE;          }
-  public boolean isValue()       { return (getValue() & TYPE_MASK_IN_PLACE) == VALUE_VALUE;        }
   public boolean isNarrowOop()   { return (getValue() & TYPE_MASK_IN_PLACE) == NARROWOOP_VALUE;    }
   public boolean isCalleeSaved() { return (getValue() & TYPE_MASK_IN_PLACE) == CALLEE_SAVED_VALUE; }
   public boolean isDerivedOop()  { return (getValue() & TYPE_MASK_IN_PLACE) == DERIVED_OOP_VALUE;  }
@@ -117,7 +113,6 @@
     int which = (getValue() & TYPE_MASK_IN_PLACE);
          if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE;
     else if (which == OOP_VALUE)    return OopTypes.OOP_VALUE;
-    else if (which == VALUE_VALUE)  return OopTypes.VALUE_VALUE;
     else if (which == NARROWOOP_VALUE)   return OopTypes.NARROWOOP_VALUE;
     else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE;
     else if (which == DERIVED_OOP_VALUE)  return OopTypes.DERIVED_OOP_VALUE;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java	Thu Oct 22 11:13:08 2015 -0700
@@ -31,6 +31,5 @@
 public interface OopMapVisitor {
   public void visitOopLocation(Address oopAddr);
   public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr);
-  public void visitValueLocation(Address valueAddr);
   public void visitNarrowOopLocation(Address narrowOopAddr);
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Thu Oct 22 11:13:08 2015 -0700
@@ -536,9 +536,6 @@
       }
     }
 
-    public void visitValueLocation(Address valueAddr) {
-    }
-
     public void visitNarrowOopLocation(Address compOopAddr) {
       addressVisitor.visitCompOopAddress(compOopAddr);
     }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Oct 22 11:13:08 2015 -0700
@@ -1220,9 +1220,6 @@
       oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
       buf.append(omvIterator.iterate(oms, "NarrowOops:", false));
 
-      oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
-      buf.append(omvIterator.iterate(oms, "Values:", false));
-
       oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
       buf.append(omvIterator.iterate(oms, "Callee saved:",  true));
 
--- a/hotspot/make/bsd/makefiles/compiler1.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/bsd/makefiles/compiler1.make	Thu Oct 22 11:13:08 2015 -0700
@@ -28,4 +28,7 @@
 
 VM_SUBDIR = client
 
+# We don't support the JVMCI in a client VM.
+INCLUDE_JVMCI := false
+
 CFLAGS += -DCOMPILER1
--- a/hotspot/make/bsd/makefiles/gcc.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/bsd/makefiles/gcc.make	Thu Oct 22 11:13:08 2015 -0700
@@ -149,6 +149,7 @@
     PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH)
     PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH)
     PCH_FLAG/unsafe.o = $(PCH_FLAG/NO_PCH)
+    PCH_FLAG/jvmciCompilerToVM.o = $(PCH_FLAG/NO_PCH)
 
   endif
 else # ($(USE_CLANG), true)
@@ -313,10 +314,11 @@
 
 # Work around some compiler bugs.
 ifeq ($(USE_CLANG), true)
-  # Clang <= 6.1
+  # Clang < 6 | <= 6.1 | <= 7.0
   ifeq ($(shell expr \
       $(CC_VER_MAJOR) \< 6 \| \
-      \( $(CC_VER_MAJOR) = 6 \& $(CC_VER_MINOR) \<= 1 \) \
+      \( $(CC_VER_MAJOR) = 6 \& $(CC_VER_MINOR) \<= 1 \) \| \
+      \( $(CC_VER_MAJOR) = 7 \& $(CC_VER_MINOR) \<= 0 \) \
     ), 1)
     OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
     OPT_CFLAGS/unsafe.o += -O1
--- a/hotspot/make/bsd/makefiles/jsig.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/bsd/makefiles/jsig.make	Thu Oct 22 11:13:08 2015 -0700
@@ -62,7 +62,7 @@
 $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
 	@echo $(LOG_INFO) Making signal interposition lib...
 	$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
-                         $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $<
+                         $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $<
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(OS_VENDOR), Darwin)
 	$(DSYMUTIL) $@
--- a/hotspot/make/bsd/makefiles/minimal1.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/bsd/makefiles/minimal1.make	Thu Oct 22 11:13:08 2015 -0700
@@ -38,6 +38,7 @@
 INCLUDE_NMT := false
 INCLUDE_TRACE := false
 INCLUDE_CDS := false
+INCLUDE_JVMCI := false
 
 CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
 CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/hotspot/make/excludeSrc.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/excludeSrc.make	Thu Oct 22 11:13:08 2015 -0700
@@ -106,6 +106,25 @@
 	 memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp
 endif
 
+ifneq (,$(findstring $(Platform_arch_model), x86_64, sparc))
+      # JVMCI is supported only on x86_64 and SPARC.
+else
+      INCLUDE_JVMCI := false
+endif
+
+ifeq ($(INCLUDE_JVMCI), false)
+      CXXFLAGS += -DINCLUDE_JVMCI=0
+      CFLAGS += -DINCLUDE_JVMCI=0
+
+      jvmci_dir := $(HS_COMMON_SRC)/share/vm/jvmci
+      jvmci_dir_alt := $(HS_ALT_SRC)/share/vm/jvmci
+      jvmci_exclude := $(notdir $(wildcard $(jvmci_dir)/*.cpp))	\
+			$(notdir $(wildcard $(jvmci_dir_alt)/*.cpp))
+      Src_Files_EXCLUDE += $(jvmci_exclude) \
+	jvmciCodeInstaller_aarch64.cpp jvmciCodeInstaller_ppc.cpp jvmciCodeInstaller_sparc.cpp \
+	jvmciCodeInstaller_x86.cpp
+endif
+
 -include $(HS_ALT_MAKE)/excludeSrc.make
 
 .PHONY: $(HS_ALT_MAKE)/excludeSrc.make
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/gensrc/Gensrc-jdk.vm.ci.gmk	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,122 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
+GENSRC_DIR := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.vm.ci
+SRC_DIR := $(HOTSPOT_TOPDIR)/src/jdk.vm.ci/share/classes
+
+################################################################################
+# Compile the annotation processor
+
+$(eval $(call SetupJavaCompilation, BUILD_JVMCI_OPTIONS, \
+    SETUP := GENERATE_OLDBYTECODE, \
+    SRC := $(SRC_DIR)/jdk.vm.ci.options/src \
+        $(SRC_DIR)/jdk.vm.ci.options.processor/src \
+        $(SRC_DIR)/jdk.vm.ci.inittimer/src, \
+    BIN := $(BUILDTOOLS_OUTPUTDIR)/jvmci_options, \
+    JAR := $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.options.jar, \
+))
+
+$(eval $(call SetupJavaCompilation, BUILD_JVMCI_SERVICE, \
+    SETUP := GENERATE_OLDBYTECODE, \
+    SRC := $(SRC_DIR)/jdk.vm.ci.service/src \
+        $(SRC_DIR)/jdk.vm.ci.service.processor/src, \
+    BIN := $(BUILDTOOLS_OUTPUTDIR)/jvmci_service, \
+    JAR := $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.service.jar, \
+))
+
+################################################################################
+
+PROC_SRC_SUBDIRS := \
+    jdk.vm.ci.compiler \
+    jdk.vm.ci.hotspot \
+    jdk.vm.ci.hotspot.amd64 \
+    jdk.vm.ci.hotspot.sparc \
+    #
+
+PROC_SRC_DIRS := $(patsubst %, $(SRC_DIR)/%/src, $(PROC_SRC_SUBDIRS))
+
+PROC_SRCS := $(filter %.java, $(call CacheFind, $(PROC_SRC_DIRS)))
+
+ALL_SRC_DIRS := $(wildcard $(SRC_DIR)/*/src)
+SOURCEPATH := $(call PathList, $(ALL_SRC_DIRS))
+PROCESSOR_PATH := $(call PathList, \
+    $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.options.jar \
+    $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.service.jar)
+
+$(GENSRC_DIR)/_gensrc_proc_done: $(PROC_SRCS) \
+    $(BUILD_JVMCI_OPTIONS) $(BUILD_JVMCI_SERVICE)
+	$(MKDIR) -p $(@D)
+	$(eval $(call ListPathsSafely,PROC_SRCS,$(@D)/_gensrc_proc_files))
+	$(JAVA_SMALL) $(NEW_JAVAC) \
+	    -XDignore.symbol.file \
+	    -sourcepath $(SOURCEPATH) \
+	    -implicit:none \
+	    -proc:only \
+	    -processorpath $(PROCESSOR_PATH) \
+	    -d $(GENSRC_DIR) \
+	    -s $(GENSRC_DIR) \
+	    @$(@D)/_gensrc_proc_files
+	$(TOUCH) $@
+
+TARGETS += $(GENSRC_DIR)/_gensrc_proc_done
+
+################################################################################
+
+$(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors: \
+    $(GENSRC_DIR)/_gensrc_proc_done
+	$(MKDIR) -p $(@D)
+	($(CD) $(GENSRC_DIR)/META-INF/jvmci.options && \
+	    $(RM) -f $@; \
+	    for i in $$(ls); do \
+	      echo $${i}_OptionDescriptors >> $@; \
+	    done)
+
+TARGETS += $(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors
+
+################################################################################
+
+$(GENSRC_DIR)/_providers_converted: $(GENSRC_DIR)/_gensrc_proc_done
+	$(MKDIR) -p $(GENSRC_DIR)/META-INF/services
+	($(CD) $(GENSRC_DIR)/META-INF/jvmci.providers && \
+	    for i in $$($(LS)); do \
+	      c=$$($(CAT) $$i | $(TR) -d '\n\r'); \
+	      $(ECHO) $$i >> $(GENSRC_DIR)/META-INF/services/$$c; \
+	    done)
+	$(TOUCH) $@
+
+TARGETS += $(GENSRC_DIR)/_providers_converted
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: default all
--- a/hotspot/make/linux/makefiles/compiler1.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/linux/makefiles/compiler1.make	Thu Oct 22 11:13:08 2015 -0700
@@ -28,4 +28,7 @@
 
 VM_SUBDIR = client
 
+# We don't support the JVMCI in a client VM.
+INCLUDE_JVMCI := false
+
 CFLAGS += -DCOMPILER1
--- a/hotspot/make/linux/makefiles/gcc.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make	Thu Oct 22 11:13:08 2015 -0700
@@ -213,12 +213,16 @@
   # 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"
+    # GCC < 4.3
     WARNING_FLAGS += -Wconversion
   endif  
   ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1"
+    # GCC >= 4.8
     # This flag is only known since GCC 4.3. Gcc 4.8 contains a fix so that with templates no
     # warnings are issued: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856
     WARNING_FLAGS += -Wtype-limits
+    # GCC < 4.8 don't accept this flag for C++.
+    WARNING_FLAGS += -Wno-format-zero-length
   endif
 endif
 
--- a/hotspot/make/linux/makefiles/minimal1.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/linux/makefiles/minimal1.make	Thu Oct 22 11:13:08 2015 -0700
@@ -38,6 +38,7 @@
 INCLUDE_NMT := false
 INCLUDE_TRACE := false
 INCLUDE_CDS := false
+INCLUDE_JVMCI := false
 
 CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
 CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/hotspot/make/solaris/makefiles/compiler1.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/solaris/makefiles/compiler1.make	Thu Oct 22 11:13:08 2015 -0700
@@ -28,4 +28,7 @@
 
 VM_SUBDIR = client
 
+# We don't support the JVMCI in a client VM.
+INCLUDE_JVMCI := false
+
 CFLAGS += -DCOMPILER1
--- a/hotspot/make/windows/build_vm_def.sh	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/windows/build_vm_def.sh	Thu Oct 22 11:13:08 2015 -0700
@@ -52,6 +52,7 @@
 CAT="$MKS_HOME/cat.exe"
 RM="$MKS_HOME/rm.exe"
 DUMPBIN="link.exe /dump"
+export VS_UNICODE_OUTPUT= 
 
 if [ "$1" = "-nosa" ]; then
     echo EXPORTS > vm.def
--- a/hotspot/make/windows/create_obj_files.sh	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/windows/create_obj_files.sh	Thu Oct 22 11:13:08 2015 -0700
@@ -111,6 +111,7 @@
 
 COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*"
 COMPILER1_SPECIFIC_FILES="c1_*"
+JVMCI_SPECIFIC_FILES="*jvmci* *JVMCI*"
 SHARK_SPECIFIC_FILES="shark"
 ZERO_SPECIFIC_FILES="zero"
 
@@ -119,11 +120,11 @@
 
 # Exclude per type.
 case "${TYPE}" in
-    "compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
+    "compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${JVMCI_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
     "compiler2") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
     "tiered")    Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
-    "zero")      Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
-    "shark")     Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES}" ;;
+    "zero")      Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${JVMCI_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
+    "shark")     Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${JVMCI_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES}" ;;
 esac
 
 # Special handling of arch model.
--- a/hotspot/make/windows/makefiles/compile.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/windows/makefiles/compile.make	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2015, 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,7 @@
 #   /nologo   Supress copyright message at every cl.exe startup
 #   /W3       Warning level 3
 #   /Zi       Include debugging information
+#   /d2Zi+    Extended debugging symbols for optimized code (/Zo in VS2013 Update 3 and later)
 #   /WX       Treat any warning error as a fatal error
 #   /MD       Use dynamic multi-threaded runtime (msvcrt.dll or msvc*NN.dll)
 #   /MTd      Use static multi-threaded runtime debug versions
@@ -57,7 +58,7 @@
 
 # Let's add debug information when Full Debug Symbols is enabled
 !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
-CXX_FLAGS=$(CXX_FLAGS) /Zi
+CXX_FLAGS=$(CXX_FLAGS) /Zi /d2Zi+
 !endif
 
 # Based on BUILDARCH we add some flags and select the default compiler name
--- a/hotspot/make/windows/makefiles/projectcreator.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/windows/makefiles/projectcreator.make	Thu Oct 22 11:13:08 2015 -0700
@@ -145,6 +145,10 @@
  -ignorePath_TARGET tiered \
  -ignorePath_TARGET c1_
 
+ProjectCreatorIDEOptionsIgnoreJVMCI=\
+ -ignorePath_TARGET src/share/vm/jvmci \
+ -ignorePath_TARGET vm/jvmci
+
 ProjectCreatorIDEOptionsIgnoreCompiler2=\
  -ignorePath_TARGET compiler2 \
  -ignorePath_TARGET tiered \
@@ -165,6 +169,8 @@
 ##################################################
 ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
  -define_compiler1 COMPILER1 \
+ -define_compiler1 INCLUDE_JVMCI=0 \
+$(ProjectCreatorIDEOptionsIgnoreJVMCI:TARGET=compiler1) \
 $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
 
 ##################################################
--- a/hotspot/make/windows/makefiles/vm.make	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/make/windows/makefiles/vm.make	Thu Oct 22 11:13:08 2015 -0700
@@ -40,7 +40,7 @@
 !endif
 
 !if "$(Variant)" == "compiler1"
-CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1"
+CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" /D INCLUDE_JVMCI=0
 !endif
 
 !if "$(Variant)" == "compiler2"
@@ -152,6 +152,7 @@
 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/jvmci
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/compiler
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/code
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/interpreter
@@ -163,6 +164,7 @@
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/gc/cms
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/gc/g1
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/asm
+VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/logging
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/memory
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/oops
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/prims
@@ -232,6 +234,9 @@
 {$(COMMONSRC)\share\vm\classfile}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+{$(COMMONSRC)\share\vm\jvmci}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
 {$(COMMONSRC)\share\vm\gc\parallel}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
@@ -250,6 +255,9 @@
 {$(COMMONSRC)\share\vm\asm}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+{$(COMMONSRC)\share\vm\logging}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
 {$(COMMONSRC)\share\vm\memory}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
@@ -330,6 +338,9 @@
 {$(ALTSRC)\share\vm\asm}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+{$(ALTSRC)\share\vm\logging}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
 {$(ALTSRC)\share\vm\memory}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Thu Oct 22 11:13:08 2015 -0700
@@ -1039,6 +1039,7 @@
   bool leading_membar(const MemBarNode *barrier);
 
   bool is_card_mark_membar(const MemBarNode *barrier);
+  bool is_CAS(int opcode);
 
   MemBarNode *leading_to_normal(MemBarNode *leading);
   MemBarNode *normal_to_leading(const MemBarNode *barrier);
@@ -1057,6 +1058,9 @@
   bool unnecessary_volatile(const Node *barrier);
   bool needs_releasing_store(const Node *store);
 
+  // predicate controlling translation of CompareAndSwapX
+  bool needs_acquiring_load_exclusive(const Node *load);
+
   // predicate controlling translation of StoreCM
   bool unnecessary_storestore(const Node *storecm);
 %}
@@ -1088,15 +1092,58 @@
   //   str<x>
   //   dmb ish
   //
+  // We can also use ldaxr and stlxr to implement compare and swap CAS
+  // sequences. These are normally translated to an instruction
+  // sequence like the following
+  //
+  //   dmb      ish
+  // retry:
+  //   ldxr<x>   rval raddr
+  //   cmp       rval rold
+  //   b.ne done
+  //   stlxr<x>  rval, rnew, rold
+  //   cbnz      rval retry
+  // done:
+  //   cset      r0, eq
+  //   dmb ishld
+  //
+  // Note that the exclusive store is already using an stlxr
+  // instruction. That is required to ensure visibility to other
+  // threads of the exclusive write (assuming it succeeds) before that
+  // of any subsequent writes.
+  //
+  // The following instruction sequence is an improvement on the above
+  //
+  // retry:
+  //   ldaxr<x>  rval raddr
+  //   cmp       rval rold
+  //   b.ne done
+  //   stlxr<x>  rval, rnew, rold
+  //   cbnz      rval retry
+  // done:
+  //   cset      r0, eq
+  //
+  // We don't need the leading dmb ish since the stlxr guarantees
+  // visibility of prior writes in the case that the swap is
+  // successful. Crucially we don't have to worry about the case where
+  // the swap is not successful since no valid program should be
+  // relying on visibility of prior changes by the attempting thread
+  // in the case where the CAS fails.
+  //
+  // Similarly, we don't need the trailing dmb ishld if we substitute
+  // an ldaxr instruction since that will provide all the guarantees we
+  // require regarding observation of changes made by other threads
+  // before any change to the CAS address observed by the load.
+  //
   // In order to generate the desired instruction sequence we need to
   // be able to identify specific 'signature' ideal graph node
   // sequences which i) occur as a translation of a volatile reads or
-  // writes and ii) do not occur through any other translation or
-  // graph transformation. We can then provide alternative aldc
-  // matching rules which translate these node sequences to the
-  // desired machine code sequences. Selection of the alternative
-  // rules can be implemented by predicates which identify the
-  // relevant node sequences.
+  // writes or CAS operations and ii) do not occur through any other
+  // translation or graph transformation. We can then provide
+  // alternative aldc matching rules which translate these node
+  // sequences to the desired machine code sequences. Selection of the
+  // alternative rules can be implemented by predicates which identify
+  // the relevant node sequences.
   //
   // The ideal graph generator translates a volatile read to the node
   // sequence
@@ -1163,6 +1210,15 @@
   // get if it is fed and feeds a cpuorder membar and if its feed
   // membar also feeds an acquiring load.
   //
+  // Finally an inlined (Unsafe) CAS operation is translated to the
+  // following ideal graph
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder
+  //   CompareAndSwapX {CardMark}-optional
+  //   MemBarCPUOrder
+  //   MemBarAcquire
+  //
   // So, where we can identify these volatile read and write
   // signatures we can choose to plant either of the above two code
   // sequences. For a volatile read we can simply plant a normal
@@ -1177,6 +1233,14 @@
   // and MemBarVolatile and instead plant a simple stlr<x>
   // instruction.
   //
+  // when we recognise a CAS signature we can choose to plant a dmb
+  // ish as a translation for the MemBarRelease, the conventional
+  // macro-instruction sequence for the CompareAndSwap node (which
+  // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire.
+  // Alternatively, we can elide generation of the dmb instructions
+  // and plant the alternative CompareAndSwap macro-instruction
+  // sequence (which uses ldaxr<x>).
+  // 
   // Of course, the above only applies when we see these signature
   // configurations. We still want to plant dmb instructions in any
   // other cases where we may see a MemBarAcquire, MemBarRelease or
@@ -1194,7 +1258,8 @@
   // relevant dmb instructions.
   //
 
-  // graph traversal helpers used for volatile put/get optimization
+  // graph traversal helpers used for volatile put/get and CAS
+  // optimization
 
   // 1) general purpose helpers
 
@@ -1220,16 +1285,19 @@
 	return NULL;
     }
 
-    if (!ctl || !mem || !ctl->is_Proj() || !mem->is_Proj())
+    if (!ctl || !mem || !ctl->is_Proj() || !mem->is_Proj()) {
       return NULL;
+    }
 
     membar = ctl->lookup(0);
 
-    if (!membar || !membar->is_MemBar())
+    if (!membar || !membar->is_MemBar()) {
       return NULL;
-
-    if (mem->lookup(0) != membar)
+    }
+
+    if (mem->lookup(0) != membar) {
       return NULL;
+    }
 
     return membar->as_MemBar();
   }
@@ -1259,8 +1327,9 @@
       }
     }
 
-    if (child == NULL)
+    if (child == NULL) {
       return NULL;
+    }
 
     for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
       x = mem->fast_out(i);
@@ -1283,15 +1352,18 @@
   {
     int opcode = barrier->Opcode();
     // if this is a release membar we are ok
-    if (opcode == Op_MemBarRelease)
+    if (opcode == Op_MemBarRelease) {
       return true;
+    }
     // if its a cpuorder membar . . .
-    if (opcode != Op_MemBarCPUOrder)
+    if (opcode != Op_MemBarCPUOrder) {
       return false;
+    }
     // then the parent has to be a release membar
     MemBarNode *parent = parent_membar(barrier);
-    if (!parent)
+    if (!parent) {
       return false;
+    }
     opcode = parent->Opcode();
     return opcode == Op_MemBarRelease;
   }
@@ -1314,11 +1386,13 @@
   
   bool is_card_mark_membar(const MemBarNode *barrier)
   {
-    if (!UseG1GC && !(UseConcMarkSweepGC && UseCondCardMark))
+    if (!UseG1GC && !(UseConcMarkSweepGC && UseCondCardMark)) {
       return false;
-
-    if (barrier->Opcode() != Op_MemBarVolatile)
+    }
+
+    if (barrier->Opcode() != Op_MemBarVolatile) {
       return false;
+    }
 
     ProjNode *mem = barrier->proj_out(TypeFunc::Memory);
 
@@ -1333,8 +1407,8 @@
   }
 
 
-  // 3) helper predicates to traverse volatile put graphs which may
-  // contain GC barrier subgraphs
+  // 3) helper predicates to traverse volatile put or CAS graphs which
+  // may contain GC barrier subgraphs
 
   // Preamble
   // --------
@@ -1404,8 +1478,7 @@
   // currently being unmarked in which case the volatile put graph
   // will look slightly different
   //
-  //   MemBarRelease
-  //   MemBarCPUOrder___________________________________________
+  //   MemBarRelease____________________________________________
   //         ||    \\               Ctl \     Ctl \     \\  Mem \
   //         ||    StoreN/P[mo_release] CastP2X   If   LoadB     |
   //         | \     /                              \            |
@@ -1419,7 +1492,7 @@
   // memory flow includes the following subgraph:
   //
   //   MemBarRelease
-  //   MemBarCPUOrder
+  //  {MemBarCPUOrder}
   //          |  \      . . .
   //          |  StoreX[mo_release]  . . .
   //          |   /
@@ -1431,8 +1504,48 @@
   // detected starting from any candidate MemBarRelease,
   // StoreX[mo_release] or MemBarVolatile.
   //
+  // A simple variation on this normal case occurs for an unsafe CAS
+  // operation. The basic graph for a non-object CAS is
+  //
+  //   MemBarRelease
+  //         ||
+  //   MemBarCPUOrder
+  //         ||     \\   . . .
+  //         ||     CompareAndSwapX
+  //         ||       |
+  //         ||     SCMemProj
+  //         | \     /
+  //         | MergeMem
+  //         | /
+  //   MemBarCPUOrder
+  //         ||
+  //   MemBarAcquire
+  //
+  // The same basic variations on this arrangement (mutatis mutandis)
+  // occur when a card mark is introduced. i.e. we se the same basic
+  // shape but the StoreP/N is replaced with CompareAndSawpP/N and the
+  // tail of the graph is a pair comprising a MemBarCPUOrder +
+  // MemBarAcquire.
+  //
+  // So, in the case of a CAS the normal graph has the variant form
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder
+  //          |   \      . . .
+  //          |  CompareAndSwapX  . . .
+  //          |    |
+  //          |   SCMemProj
+  //          |   /  . . .
+  //         MergeMem
+  //          |
+  //   MemBarCPUOrder
+  //   MemBarAcquire
+  //
+  // This graph can also easily be detected starting from any
+  // candidate MemBarRelease, CompareAndSwapX or MemBarAcquire.
+  //
   // the code below uses two helper predicates, leading_to_normal and
-  // normal_to_leading to identify this configuration, one validating
+  // normal_to_leading to identify these normal graphs, one validating
   // the layout starting from the top membar and searching down and
   // the other validating the layout starting from the lower membar
   // and searching up.
@@ -1450,7 +1563,9 @@
   // they are only inserted for object puts. This significantly
   // complicates the task of identifying whether a MemBarRelease,
   // StoreX[mo_release] or MemBarVolatile forms part of a volatile put
-  // when using these GC configurations (see below).
+  // when using these GC configurations (see below). It adds similar
+  // complexity to the task of identifying whether a MemBarRelease,
+  // CompareAndSwapX or MemBarAcquire forms part of a CAS.
   //
   // In both cases the post-write subtree includes an auxiliary
   // MemBarVolatile (StoreLoad barrier) separating the object put and
@@ -1489,7 +1604,8 @@
   // (LoadB) from the card. Ctl and Mem are fed to the If via an
   // intervening StoreLoad barrier (MemBarVolatile).
   //
-  // So, with CMS we may see a node graph which looks like this
+  // So, with CMS we may see a node graph for a volatile object store
+  // which looks like this
   //
   //   MemBarRelease
   //   MemBarCPUOrder_(leading)__________________
@@ -1524,6 +1640,55 @@
   // from the StoreCM into the trailing membar (n.b. the latter
   // proceeds via a Phi associated with the If region).
   //
+  // The graph for a CAS varies slightly, the obvious difference being
+  // that the StoreN/P node is replaced by a CompareAndSwapP/N node
+  // and the trailing MemBarVolatile by a MemBarCPUOrder +
+  // MemBarAcquire pair. The other important difference is that the
+  // CompareAndSwap node's SCMemProj is not merged into the card mark
+  // membar - it still feeds the trailing MergeMem. This also means
+  // that the card mark membar receives its Mem feed directly from the
+  // leading membar rather than via a MergeMem.
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder__(leading)_________________________
+  //       ||                       \\                 C \
+  //   MemBarVolatile (card mark)  CompareAndSwapN/P  CastP2X
+  //     C |  ||    M |              |
+  //       | LoadB    |       ______/|
+  //       |   |      |      /       |
+  //       | Cmp      |     /      SCMemProj
+  //       | /        |    /         |
+  //       If         |   /         /
+  //       | \        |  /         /
+  // IfFalse  IfTrue  | /         /
+  //       \     / \  |/ prec    /
+  //        \   / StoreCM       /
+  //         \ /      |        /
+  //        Region   . . .    /
+  //          | \            /
+  //          |  . . .  \   / Bot
+  //          |       MergeMem
+  //          |          |
+  //        MemBarCPUOrder
+  //        MemBarAcquire (trailing)
+  //
+  // This has a slightly different memory subgraph to the one seen
+  // previously but the core of it is the same as for the CAS normal
+  // sungraph
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder____
+  //      ||             \      . . .
+  //   MemBarVolatile  CompareAndSwapX  . . .
+  //      |  \            |
+  //        . . .   SCMemProj
+  //          |     /  . . .
+  //         MergeMem
+  //          |
+  //   MemBarCPUOrder
+  //   MemBarAcquire
+  //
+  //
   // G1 is quite a lot more complicated. The nodes inserted on behalf
   // of G1 may comprise: a pre-write graph which adds the old value to
   // the SATB queue; the releasing store itself; and, finally, a
@@ -1575,12 +1740,16 @@
   // n.b. the LoadB in this subgraph is not the card read -- it's a
   // read of the SATB queue active flag.
   //
+  // Once again the CAS graph is a minor variant on the above with the
+  // expected substitutions of CompareAndSawpX for StoreN/P and
+  // MemBarCPUOrder + MemBarAcquire for trailing MemBarVolatile.
+  //
   // The G1 post-write subtree is also optional, this time when the
   // new value being written is either null or can be identified as a
   // newly allocated (young gen) object with no intervening control
   // flow. The latter cannot happen but the former may, in which case
-  // the card mark membar is omitted and the memory feeds from the
-  // leading membar and the StoreN/P are merged direct into the
+  // the card mark membar is omitted and the memory feeds form the
+  // leading membar and the SToreN/P are merged direct into the
   // trailing membar as per the normal subgraph. So, the only special
   // case which arises is when the post-write subgraph is generated.
   //
@@ -1668,47 +1837,84 @@
   // value check has been elided the total number of Phis is 2
   // otherwise it is 3.
   //
+  // The CAS graph when using G1GC also includes a pre-write subgraph
+  // and an optional post-write subgraph. Teh sam evarioations are
+  // introduced as for CMS with conditional card marking i.e. the
+  // StoreP/N is swapped for a CompareAndSwapP/N, the tariling
+  // MemBarVolatile for a MemBarCPUOrder + MemBarAcquire pair and the
+  // Mem feed from the CompareAndSwapP/N includes a precedence
+  // dependency feed to the StoreCM and a feed via an SCMemProj to the
+  // trailing membar. So, as before the configuration includes the
+  // normal CAS graph as a subgraph of the memory flow.
+  //
   // So, the upshot is that in all cases the volatile put graph will
   // include a *normal* memory subgraph betwen the leading membar and
-  // its child membar. When that child is not a card mark membar then
-  // it marks the end of a volatile put subgraph. If the child is a
-  // card mark membar then the normal subgraph will form part of a
-  // volatile put subgraph if and only if the child feeds an
-  // AliasIdxBot Mem feed to a trailing barrier via a MergeMem. That
-  // feed is either direct (for CMS) or via 2 or 3 Phi nodes merging
-  // the leading barrier memory flow (for G1).
+  // its child membar, either a volatile put graph (including a
+  // releasing StoreX) or a CAS graph (including a CompareAndSwapX).
+  // When that child is not a card mark membar then it marks the end
+  // of the volatile put or CAS subgraph. If the child is a card mark
+  // membar then the normal subgraph will form part of a volatile put
+  // subgraph if and only if the child feeds an AliasIdxBot Mem feed
+  // to a trailing barrier via a MergeMem. That feed is either direct
+  // (for CMS) or via 2 or 3 Phi nodes merging the leading barrier
+  // memory flow (for G1).
   // 
   // The predicates controlling generation of instructions for store
   // and barrier nodes employ a few simple helper functions (described
-  // below) which identify the presence or absence of these subgraph
-  // configurations and provide a means of traversing from one node in
-  // the subgraph to another.
+  // below) which identify the presence or absence of all these
+  // subgraph configurations and provide a means of traversing from
+  // one node in the subgraph to another.
+
+  // is_CAS(int opcode)
+  //
+  // return true if opcode is one of the possible CompareAndSwapX
+  // values otherwise false.
+
+  bool is_CAS(int opcode)
+  {
+    return (opcode == Op_CompareAndSwapI ||
+	    opcode == Op_CompareAndSwapL ||
+	    opcode == Op_CompareAndSwapN ||
+	    opcode == Op_CompareAndSwapP);
+  }
 
   // leading_to_normal
   //
-  //graph traversal helper which detects the normal case Mem feed
-  // from a release membar (or, optionally, its cpuorder child) to a
-  // dependent volatile membar i.e. it ensures that the following Mem
-  // flow subgraph is present.
+  //graph traversal helper which detects the normal case Mem feed from
+  // a release membar (or, optionally, its cpuorder child) to a
+  // dependent volatile membar i.e. it ensures that one or other of
+  // the following Mem flow subgraph is present.
   //
   //   MemBarRelease
-  //   MemBarCPUOrder
+  //   MemBarCPUOrder {leading}
   //          |  \      . . .
   //          |  StoreN/P[mo_release]  . . .
   //          |   /
   //         MergeMem
   //          |
-  //   MemBarVolatile
-  //
-  // if the correct configuration is present returns the volatile
+  //   MemBarVolatile {trailing or card mark}
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
+  //      |       \      . . .
+  //      |     CompareAndSwapX  . . .
+  //               |
+  //     . . .    SCMemProj
+  //           \   |
+  //      |    MergeMem
+  //      |       /
+  //    MemBarCPUOrder
+  //    MemBarAcquire {trailing}
+  //
+  // if the correct configuration is present returns the trailing
   // membar otherwise NULL.
   //
   // the input membar is expected to be either a cpuorder membar or a
   // release membar. in the latter case it should not have a cpu membar
   // child.
   //
-  // the returned membar may be a card mark membar rather than a
-  // trailing membar.
+  // the returned value may be a card mark or trailing membar
+  //
 
   MemBarNode *leading_to_normal(MemBarNode *leading)
   {
@@ -1719,54 +1925,103 @@
     // check the mem flow
     ProjNode *mem = leading->proj_out(TypeFunc::Memory);
 
-    if (!mem)
+    if (!mem) {
       return NULL;
+    }
 
     Node *x = NULL;
     StoreNode * st = NULL;
+    LoadStoreNode *cas = NULL;
     MergeMemNode *mm = NULL;
 
     for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
       x = mem->fast_out(i);
       if (x->is_MergeMem()) {
-	if (mm != NULL)
+	if (mm != NULL) {
 	  return NULL;
+	}
 	// two merge mems is one too many
 	mm = x->as_MergeMem();
       } else if (x->is_Store() && x->as_Store()->is_release() && x->Opcode() != Op_StoreCM) {
-	// two releasing stores is one too many
-	if (st != NULL)
+	// two releasing stores/CAS nodes is one too many
+	if (st != NULL || cas != NULL) {
+	  return NULL;
+	}
+	st = x->as_Store();
+      } else if (is_CAS(x->Opcode())) {
+	if (st != NULL || cas != NULL) {
 	  return NULL;
-	st = x->as_Store();
+	}
+	cas = x->as_LoadStore();
+      }
+    }
+
+    // must have a store or a cas
+    if (!st && !cas) {
+      return NULL;
+    }
+
+    // must have a merge if we also have st
+    if (st && !mm) {
+      return NULL;
+    }
+
+    Node *y = NULL;
+    if (cas) {
+      // look for an SCMemProj
+      for (DUIterator_Fast imax, i = cas->fast_outs(imax); i < imax; i++) {
+	x = cas->fast_out(i);
+	if (x->is_Proj()) {
+	  y = x;
+	  break;
+	}
+      }
+      if (y == NULL) {
+	return NULL;
       }
-    }
-
-    if (!mm || !st)
-      return NULL;
-
-    bool found = false;
-    // ensure the store feeds the merge
-    for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
-      if (st->fast_out(i) == mm) {
-	found = true;
+      // the proj must feed a MergeMem
+      for (DUIterator_Fast imax, i = y->fast_outs(imax); i < imax; i++) {
+	x = y->fast_out(i);
+	if (x->is_MergeMem()) {
+	  mm = x->as_MergeMem();
+	  break;
+	}
+      }
+      if (mm == NULL)
+	return NULL;
+    } else {
+      // ensure the store feeds the existing mergemem;
+      for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
+	if (st->fast_out(i) == mm) {
+	  y = st;
+	  break;
+	}
+      }
+      if (y == NULL) {
+	return NULL;
+      }
+    }
+
+    MemBarNode *mbar = NULL;
+    // ensure the merge feeds to the expected type of membar
+    for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
+      x = mm->fast_out(i);
+      if (x->is_MemBar()) {
+	int opcode = x->Opcode();
+	if (opcode == Op_MemBarVolatile && st) {
+	  mbar = x->as_MemBar();
+	} else if (cas && opcode == Op_MemBarCPUOrder) {
+	  MemBarNode *y =  x->as_MemBar();
+	  y = child_membar(y);
+	  if (y != NULL && y->Opcode() == Op_MemBarAcquire) {
+	    mbar = y;
+	  }
+	}
 	break;
       }
     }
 
-    if (!found)
-      return NULL;
-
-    MemBarNode *mbvol = NULL;
-    // ensure the merge feeds a volatile membar
-    for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
-      x = mm->fast_out(i);
-      if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) {
-	mbvol = x->as_MemBar();
-	break;
-      }
-    }
-
-    return mbvol;
+    return mbar;
   }
 
   // normal_to_leading
@@ -1774,7 +2029,7 @@
   // graph traversal helper which detects the normal case Mem feed
   // from either a card mark or a trailing membar to a preceding
   // release membar (optionally its cpuorder child) i.e. it ensures
-  // that the following Mem flow subgraph is present.
+  // that one or other of the following Mem flow subgraphs is present.
   //
   //   MemBarRelease
   //   MemBarCPUOrder {leading}
@@ -1783,7 +2038,19 @@
   //          |   /
   //         MergeMem
   //          |
-  //   MemBarVolatile
+  //   MemBarVolatile {card mark or trailing}
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
+  //      |       \      . . .
+  //      |     CompareAndSwapX  . . .
+  //               |
+  //     . . .    SCMemProj
+  //           \   |
+  //      |    MergeMem
+  //      |        /
+  //    MemBarCPUOrder
+  //    MemBarAcquire {trailing}
   //
   // this predicate checks for the same flow as the previous predicate
   // but starting from the bottom rather than the top.
@@ -1797,51 +2064,116 @@
   MemBarNode *normal_to_leading(const MemBarNode *barrier)
   {
     // input must be a volatile membar
-    assert(barrier->Opcode() == Op_MemBarVolatile, "expecting a volatile membar");
+    assert((barrier->Opcode() == Op_MemBarVolatile ||
+	    barrier->Opcode() == Op_MemBarAcquire),
+	   "expecting a volatile or an acquire membar");
     Node *x;
+    bool is_cas = barrier->Opcode() == Op_MemBarAcquire;
+
+    // if we have an acquire membar then it must be fed via a CPUOrder
+    // membar
+
+    if (is_cas) {
+      // skip to parent barrier which must be a cpuorder
+      x = parent_membar(barrier);
+      if (x->Opcode() != Op_MemBarCPUOrder)
+	return NULL;
+    } else {
+      // start from the supplied barrier
+      x = (Node *)barrier;
+    }
 
     // the Mem feed to the membar should be a merge
-    x = barrier->in(TypeFunc::Memory);
+    x = x ->in(TypeFunc::Memory);
     if (!x->is_MergeMem())
       return NULL;
 
     MergeMemNode *mm = x->as_MergeMem();
 
-    // the AliasIdxBot slice should be another MemBar projection
-    x = mm->in(Compile::AliasIdxBot);
+    if (is_cas) {
+      // the merge should be fed from the CAS via an SCMemProj node
+      x = NULL;
+      for (uint idx = 1; idx < mm->req(); idx++) {
+	if (mm->in(idx)->Opcode() == Op_SCMemProj) {
+	  x = mm->in(idx);
+	  break;
+	}
+      }
+      if (x == NULL) {
+	return NULL;
+      }
+      // check for a CAS feeding this proj
+      x = x->in(0);
+      int opcode = x->Opcode();
+      if (!is_CAS(opcode)) {
+	return NULL;
+      }
+      // the CAS should get its mem feed from the leading membar
+      x = x->in(MemNode::Memory);
+    } else {
+      // the merge should get its Bottom mem feed from the leading membar
+      x = mm->in(Compile::AliasIdxBot);      
+    } 
+
     // ensure this is a non control projection
-    if (!x->is_Proj() || x->is_CFG())
+    if (!x->is_Proj() || x->is_CFG()) {
       return NULL;
+    }
     // if it is fed by a membar that's the one we want
     x = x->in(0);
 
-    if (!x->is_MemBar())
+    if (!x->is_MemBar()) {
       return NULL;
+    }
 
     MemBarNode *leading = x->as_MemBar();
     // reject invalid candidates
-    if (!leading_membar(leading))
+    if (!leading_membar(leading)) {
       return NULL;
-
-    // ok, we have a leading ReleaseMembar, now for the sanity clauses
-
-    // the leading membar must feed Mem to a releasing store
+    }
+
+    // ok, we have a leading membar, now for the sanity clauses
+
+    // the leading membar must feed Mem to a releasing store or CAS
     ProjNode *mem = leading->proj_out(TypeFunc::Memory);
     StoreNode *st = NULL;
+    LoadStoreNode *cas = NULL;
     for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
       x = mem->fast_out(i);
       if (x->is_Store() && x->as_Store()->is_release() && x->Opcode() != Op_StoreCM) {
+	// two stores or CASes is one too many
+	if (st != NULL || cas != NULL) {
+	  return NULL;
+	}
 	st = x->as_Store();
-	break;
+      } else if (is_CAS(x->Opcode())) {
+	if (st != NULL || cas != NULL) {
+	  return NULL;
+	}
+	cas = x->as_LoadStore();
       }
     }
-    if (st == NULL)
+
+    // we should not have both a store and a cas
+    if (st == NULL & cas == NULL) {
       return NULL;
-
-    // the releasing store has to feed the same merge
-    for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
-      if (st->fast_out(i) == mm)
-	return leading;
+    }
+
+    if (st == NULL) {
+      // nothing more to check
+      return leading;
+    } else {
+      // we should not have a store if we started from an acquire
+      if (is_cas) {
+	return NULL;
+      }
+
+      // the store should feed the merge we used to get here
+      for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
+	if (st->fast_out(i) == mm) {
+	  return leading;
+	}
+      }
     }
 
     return NULL;
@@ -1865,8 +2197,8 @@
   //  Bot |  / 
   //   MergeMem 
   //      |
-  //   MemBarVolatile (trailing)
-  //
+  //      |
+  //    MemBarVolatile {trailing}
   //
   // 2)
   //   MemBarRelease/CPUOrder (leading)
@@ -1884,7 +2216,8 @@
   //     Bot |   /
   //       MergeMem
   //         |
-  //   MemBarVolatile (trailing)
+  //    MemBarVolatile {trailing}
+  //
   //
   // 3)
   //   MemBarRelease/CPUOrder (leading)
@@ -1905,7 +2238,8 @@
   //     Bot |   /
   //       MergeMem
   //         |
-  //   MemBarVolatile (trailing)
+  //         |
+  //    MemBarVolatile {trailing}
   //
   // configuration 1 is only valid if UseConcMarkSweepGC &&
   // UseCondCardMark
@@ -1955,8 +2289,9 @@
 	    break;
 	  }
 	}
-	if (!phi)
+	if (!phi) {
 	  return NULL;
+	}
 	// look for another merge below this phi
 	feed = phi;
       } else {
@@ -1969,7 +2304,7 @@
     assert(mm->as_MergeMem()->in(Compile::AliasIdxBot) == feed, "expecting membar to feed AliasIdxBot slice to Merge");
 
     MemBarNode *trailing = NULL;
-    // be sure we have a volatile membar below the merge
+    // be sure we have a trailing membar the merge
     for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
       x = mm->fast_out(i);
       if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) {
@@ -1984,24 +2319,32 @@
   // trailing_to_card_mark
   //
   // graph traversal helper which detects extra, non-normal Mem feed
-  // from a trailing membar to a preceding card mark volatile membar
-  // i.e. it identifies whether one of the three possible extra GC
-  // post-write Mem flow subgraphs is present
+  // from a trailing volatile membar to a preceding card mark volatile
+  // membar i.e. it identifies whether one of the three possible extra
+  // GC post-write Mem flow subgraphs is present
   //
   // this predicate checks for the same flow as the previous predicate
   // but starting from the bottom rather than the top.
   //
-  // if the configurationis present returns the card mark membar
+  // if the configuration is present returns the card mark membar
   // otherwise NULL
+  //
+  // n.b. the supplied membar is expected to be a trailing
+  // MemBarVolatile i.e. the caller must ensure the input node has the
+  // correct opcode
 
   MemBarNode *trailing_to_card_mark(const MemBarNode *trailing)
   {
-    assert(!is_card_mark_membar(trailing), "not expecting a card mark membar");
-
+    assert(trailing->Opcode() == Op_MemBarVolatile,
+	   "expecting a volatile membar");
+    assert(!is_card_mark_membar(trailing),
+	   "not expecting a card mark membar");
+
+    // the Mem feed to the membar should be a merge
     Node *x = trailing->in(TypeFunc::Memory);
-    // the Mem feed to the membar should be a merge
-    if (!x->is_MergeMem())
+    if (!x->is_MergeMem()) {
       return NULL;
+    }
 
     MergeMemNode *mm = x->as_MergeMem();
 
@@ -2054,13 +2397,15 @@
     }
     // the proj has to come from the card mark membar
     x = x->in(0);
-    if (!x->is_MemBar())
+    if (!x->is_MemBar()) {
       return NULL;
+    }
 
     MemBarNode *card_mark_membar = x->as_MemBar();
 
-    if (!is_card_mark_membar(card_mark_membar))
+    if (!is_card_mark_membar(card_mark_membar)) {
       return NULL;
+    }
 
     return card_mark_membar;
   }
@@ -2068,7 +2413,7 @@
   // trailing_to_leading
   //
   // graph traversal helper which checks the Mem flow up the graph
-  // from a (non-card mark) volatile membar attempting to locate and
+  // from a (non-card mark) trailing membar attempting to locate and
   // return an associated leading membar. it first looks for a
   // subgraph in the normal configuration (relying on helper
   // normal_to_leading). failing that it then looks for one of the
@@ -2081,22 +2426,35 @@
   // if the configuration is valid returns the cpuorder member for
   // preference or when absent the release membar otherwise NULL.
   //
-  // n.b. the input membar is expected to be a volatile membar but
-  // must *not* be a card mark membar.
+  // n.b. the input membar is expected to be either a volatile or
+  // acquire membar but in the former case must *not* be a card mark
+  // membar.
 
   MemBarNode *trailing_to_leading(const MemBarNode *trailing)
   {
-    assert(!is_card_mark_membar(trailing), "not expecting a card mark membar");
+    assert((trailing->Opcode() == Op_MemBarAcquire ||
+	    trailing->Opcode() == Op_MemBarVolatile),
+	   "expecting an acquire or volatile membar");
+    assert((trailing->Opcode() != Op_MemBarVolatile ||
+	    !is_card_mark_membar(trailing)),
+	   "not expecting a card mark membar");
 
     MemBarNode *leading = normal_to_leading(trailing);
 
-    if (leading)
+    if (leading) {
       return leading;
+    }
+
+    // nothing more to do if this is an acquire
+    if (trailing->Opcode() == Op_MemBarAcquire) {
+      return NULL;
+    }
 
     MemBarNode *card_mark_membar = trailing_to_card_mark(trailing);
 
-    if (!card_mark_membar)
+    if (!card_mark_membar) {
       return NULL;
+    }
 
     return normal_to_leading(card_mark_membar);
   }
@@ -2105,10 +2463,12 @@
 
 bool unnecessary_acquire(const Node *barrier)
 {
-  // assert barrier->is_MemBar();
-  if (UseBarriersForVolatile)
+  assert(barrier->is_MemBar(), "expecting a membar");
+
+  if (UseBarriersForVolatile) {
     // we need to plant a dmb
     return false;
+  }
 
   // a volatile read derived from bytecode (or also from an inlined
   // SHA field read via LibraryCallKit::load_field_from_object)
@@ -2140,8 +2500,9 @@
     //
     // where * tags node we were passed
     // and |k means input k
-    if (x->is_DecodeNarrowPtr())
+    if (x->is_DecodeNarrowPtr()) {
       x = x->in(1);
+    }
 
     return (x->is_Load() && x->as_Load()->is_acquire());
   }
@@ -2167,8 +2528,9 @@
     return false;
   ctl = parent->proj_out(TypeFunc::Control);
   mem = parent->proj_out(TypeFunc::Memory);
-  if (!ctl || !mem)
+  if (!ctl || !mem) {
     return false;
+  }
   // ensure the proj nodes both feed a LoadX[mo_acquire]
   LoadNode *ld = NULL;
   for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) {
@@ -2180,38 +2542,46 @@
     }
   }
   // it must be an acquiring load
-  if (! ld || ! ld->is_acquire())
-    return false;
-  for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
-    x = mem->fast_out(i);
-    // if we see the same load we drop it and stop searching
-    if (x == ld) {
-      ld = NULL;
-      break;
-    }
-  }
-  // we must have dropped the load
-  if (ld)
-    return false;
-  // check for a child cpuorder membar
-  MemBarNode *child  = child_membar(barrier->as_MemBar());
-  if (!child || child->Opcode() != Op_MemBarCPUOrder)
-    return false;
-
-  return true;
+  if (ld && ld->is_acquire()) {
+
+    for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
+      x = mem->fast_out(i);
+      // if we see the same load we drop it and stop searching
+      if (x == ld) {
+	ld = NULL;
+	break;
+      }
+    }
+    // we must have dropped the load
+    if (ld == NULL) {
+      // check for a child cpuorder membar
+      MemBarNode *child  = child_membar(barrier->as_MemBar());
+      if (child && child->Opcode() == Op_MemBarCPUOrder)
+	return true;
+    }
+  }
+
+  // final option for unnecessary mebar is that it is a trailing node
+  // belonging to a CAS
+
+  MemBarNode *leading = trailing_to_leading(barrier->as_MemBar());
+
+  return leading != NULL;
 }
 
 bool needs_acquiring_load(const Node *n)
 {
-  // assert n->is_Load();
-  if (UseBarriersForVolatile)
+  assert(n->is_Load(), "expecting a load");
+  if (UseBarriersForVolatile) {
     // we use a normal load and a dmb
     return false;
+  }
 
   LoadNode *ld = n->as_Load();
 
-  if (!ld->is_acquire())
+  if (!ld->is_acquire()) {
     return false;
+  }
 
   // check if this load is feeding an acquire membar
   //
@@ -2261,20 +2631,23 @@
 
   membar = parent_membar(ld);
 
-  if (!membar || !membar->Opcode() == Op_MemBarCPUOrder)
+  if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) {
     return false;
+  }
 
   // ensure that there is a CPUOrder->Acquire->CPUOrder membar chain
 
   membar = child_membar(membar);
 
-  if (!membar || !membar->Opcode() == Op_MemBarAcquire)
+  if (!membar || !membar->Opcode() == Op_MemBarAcquire) {
     return false;
+  }
 
   membar = child_membar(membar);
   
-  if (!membar || !membar->Opcode() == Op_MemBarCPUOrder)
+  if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) {
     return false;
+  }
 
   return true;
 }
@@ -2285,9 +2658,10 @@
 	  n->Opcode() == Op_MemBarRelease),
 	 "expecting a release membar");
 
-  if (UseBarriersForVolatile)
+  if (UseBarriersForVolatile) {
     // we need to plant a dmb
     return false;
+  }
 
   // if there is a dependent CPUOrder barrier then use that as the
   // leading
@@ -2303,12 +2677,14 @@
   // must start with a normal feed
   MemBarNode *child_barrier = leading_to_normal(barrier);
 
-  if (!child_barrier)
+  if (!child_barrier) {
     return false;
-
-  if (!is_card_mark_membar(child_barrier))
+  }
+
+  if (!is_card_mark_membar(child_barrier)) {
     // this is the trailing membar and we are done
     return true;
+  }
 
   // must be sure this card mark feeds a trailing membar
   MemBarNode *trailing = card_mark_to_trailing(child_barrier);
@@ -2318,17 +2694,19 @@
 bool unnecessary_volatile(const Node *n)
 {
   // assert n->is_MemBar();
-  if (UseBarriersForVolatile)
+  if (UseBarriersForVolatile) {
     // we need to plant a dmb
     return false;
+  }
 
   MemBarNode *mbvol = n->as_MemBar();
 
   // first we check if this is part of a card mark. if so then we have
   // to generate a StoreLoad barrier
   
-  if (is_card_mark_membar(mbvol))
+  if (is_card_mark_membar(mbvol)) {
       return false;
+  }
 
   // ok, if it's not a card mark then we still need to check if it is
   // a trailing membar of a volatile put hgraph.
@@ -2341,29 +2719,33 @@
 bool needs_releasing_store(const Node *n)
 {
   // assert n->is_Store();
-  if (UseBarriersForVolatile)
+  if (UseBarriersForVolatile) {
     // we use a normal store and dmb combination
     return false;
+  }
 
   StoreNode *st = n->as_Store();
 
   // the store must be marked as releasing
-  if (!st->is_release())
+  if (!st->is_release()) {
     return false;
+  }
 
   // the store must be fed by a membar
 
   Node *x = st->lookup(StoreNode::Memory);
 
-  if (! x || !x->is_Proj())
+  if (! x || !x->is_Proj()) {
     return false;
+  }
 
   ProjNode *proj = x->as_Proj();
 
   x = proj->lookup(0);
 
-  if (!x || !x->is_MemBar())
+  if (!x || !x->is_MemBar()) {
     return false;
+  }
 
   MemBarNode *barrier = x->as_MemBar();
 
@@ -2372,24 +2754,76 @@
   // volatile put graph.
 
   // reject invalid candidates
-  if (!leading_membar(barrier))
+  if (!leading_membar(barrier)) {
     return false;
+  }
 
   // does this lead a normal subgraph?
   MemBarNode *mbvol = leading_to_normal(barrier);
 
-  if (!mbvol)
+  if (!mbvol) {
     return false;
+  }
 
   // all done unless this is a card mark
-  if (!is_card_mark_membar(mbvol))
+  if (!is_card_mark_membar(mbvol)) {
     return true;
+  }
   
   // we found a card mark -- just make sure we have a trailing barrier
 
   return (card_mark_to_trailing(mbvol) != NULL);
 }
 
+// predicate controlling translation of CAS
+//
+// returns true if CAS needs to use an acquiring load otherwise false
+
+bool needs_acquiring_load_exclusive(const Node *n)
+{
+  assert(is_CAS(n->Opcode()), "expecting a compare and swap");
+  if (UseBarriersForVolatile) {
+    return false;
+  }
+
+  // CAS nodes only ought to turn up in inlined unsafe CAS operations
+#ifdef ASSERT
+  LoadStoreNode *st = n->as_LoadStore();
+
+  // the store must be fed by a membar
+
+  Node *x = st->lookup(StoreNode::Memory);
+
+  assert (x && x->is_Proj(), "CAS not fed by memory proj!");
+
+  ProjNode *proj = x->as_Proj();
+
+  x = proj->lookup(0);
+
+  assert (x && x->is_MemBar(), "CAS not fed by membar!");
+
+  MemBarNode *barrier = x->as_MemBar();
+
+  // the barrier must be a cpuorder mmebar fed by a release membar
+
+  assert(barrier->Opcode() == Op_MemBarCPUOrder,
+	 "CAS not fed by cpuorder membar!");
+      
+  MemBarNode *b = parent_membar(barrier);
+  assert ((b != NULL && b->Opcode() == Op_MemBarRelease),
+	  "CAS not fed by cpuorder+release membar pair!");
+
+  // does this lead a normal subgraph?
+  MemBarNode *mbar = leading_to_normal(barrier);
+
+  assert(mbar != NULL, "CAS not embedded in normal graph!");
+
+  assert(mbar->Opcode() == Op_MemBarAcquire, "trailing membar should be an acquire");
+#endif // ASSERT
+  // so we can just return true here
+  return true;
+}
+
 // predicate controlling translation of StoreCM
 //
 // returns true if a StoreStore must precede the card write otherwise
@@ -2403,14 +2837,16 @@
   // and the associated card mark when we are using CMS without
   // conditional card marking
 
-  if (!UseConcMarkSweepGC || UseCondCardMark)
+  if (!UseConcMarkSweepGC || UseCondCardMark) {
     return true;
+  }
 
   // if we are implementing volatile puts using barriers then the
   // object put as an str so we must insert the dmb ishst
 
-  if (UseBarriersForVolatile)
+  if (UseBarriersForVolatile) {
     return false;
+  }
 
   // we can omit the dmb ishst if this StoreCM is part of a volatile
   // put because in thta case the put will be implemented by stlr
@@ -2422,19 +2858,22 @@
 
   Node *x = storecm->in(StoreNode::Memory);
 
-  if (!x->is_Proj())
+  if (!x->is_Proj()) {
     return false;
+  }
 
   x = x->in(0);
 
-  if (!x->is_MemBar())
+  if (!x->is_MemBar()) {
     return false;
+  }
 
   MemBarNode *leading = x->as_MemBar();
 
   // reject invalid candidates
-  if (!leading_membar(leading))
+  if (!leading_membar(leading)) {
     return false;
+  }
 
   // we can omit the StoreStore if it is the head of a normal subgraph
   return (leading_to_normal(leading) != NULL);
@@ -3024,6 +3463,10 @@
   return true;  // Per default match rules are supported.
 }
 
+const int Matcher::float_pressure(int default_pressure_threshold) {
+  return default_pressure_threshold;
+}
+
 int Matcher::regnum_to_fpu_offset(int regnum)
 {
   Unimplemented();
@@ -8365,9 +8808,13 @@
 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
 // can't match them
 
+// standard CompareAndSwapX when we are using barriers
+// these have higher priority than the rules selected by a predicate
+
 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
 
   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
+  ins_cost(2 * VOLATILE_REF_COST);
 
   effect(KILL cr);
 
@@ -8385,6 +8832,7 @@
 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
 
   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
+  ins_cost(2 * VOLATILE_REF_COST);
 
   effect(KILL cr);
 
@@ -8402,6 +8850,7 @@
 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
 
   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+  ins_cost(2 * VOLATILE_REF_COST);
 
   effect(KILL cr);
 
@@ -8419,6 +8868,7 @@
 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
 
   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
+  ins_cost(2 * VOLATILE_REF_COST);
 
   effect(KILL cr);
 
@@ -8433,6 +8883,84 @@
   ins_pipe(pipe_slow);
 %}
 
+// alternative CompareAndSwapX when we are eliding barriers
+
+instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
+
+  predicate(needs_acquiring_load_exclusive(n));
+  match(Set res (CompareAndSwapI mem (Binary oldval newval)));
+  ins_cost(VOLATILE_REF_COST);
+
+  effect(KILL cr);
+
+ format %{
+    "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
+    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
+ %}
+
+ ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
+            aarch64_enc_cset_eq(res));
+
+  ins_pipe(pipe_slow);
+%}
+
+instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
+
+  predicate(needs_acquiring_load_exclusive(n));
+  match(Set res (CompareAndSwapL mem (Binary oldval newval)));
+  ins_cost(VOLATILE_REF_COST);
+
+  effect(KILL cr);
+
+ format %{
+    "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
+    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
+ %}
+
+ ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
+            aarch64_enc_cset_eq(res));
+
+  ins_pipe(pipe_slow);
+%}
+
+instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+
+  predicate(needs_acquiring_load_exclusive(n));
+  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+  ins_cost(VOLATILE_REF_COST);
+
+  effect(KILL cr);
+
+ format %{
+    "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
+    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
+ %}
+
+ ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
+            aarch64_enc_cset_eq(res));
+
+  ins_pipe(pipe_slow);
+%}
+
+instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
+
+  predicate(needs_acquiring_load_exclusive(n));
+  match(Set res (CompareAndSwapN mem (Binary oldval newval)));
+  ins_cost(VOLATILE_REF_COST);
+
+  effect(KILL cr);
+
+ format %{
+    "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
+    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
+ %}
+
+ ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
+            aarch64_enc_cset_eq(res));
+
+  ins_pipe(pipe_slow);
+%}
+
 
 instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{
   match(Set prev (GetAndSetI mem newv));
@@ -13286,6 +13814,25 @@
   ins_pipe(pipe_cmp_branch);
 %}
 
+instruct cmpP_narrowOop_imm0_branch(cmpOp cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
+  match(If cmp (CmpP (DecodeN oop) zero));
+  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
+            || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
+  effect(USE labl);
+
+  ins_cost(BRANCH_COST);
+  format %{ "cb$cmp   $oop, $labl" %}
+  ins_encode %{
+    Label* L = $labl$$label;
+    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
+    if (cond == Assembler::EQ)
+      __ cbzw($oop$$Register, *L);
+    else
+      __ cbnzw($oop$$Register, *L);
+  %}
+  ins_pipe(pipe_cmp_branch);
+%}
+
 // Conditional Far Branch
 // Conditional Far Branch Unsigned
 // TODO: fixme
@@ -14662,6 +15209,102 @@
   ins_pipe(pipe_class_default);
 %}
 
+// --------------------------------- SQRT -------------------------------------
+
+instruct vsqrt2D(vecX dst, vecX src)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (SqrtVD src));
+  format %{ "fsqrt  $dst, $src\t# vector (2D)" %}
+  ins_encode %{
+    __ fsqrt(as_FloatRegister($dst$$reg), __ T2D,
+             as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// --------------------------------- ABS --------------------------------------
+
+instruct vabs2F(vecD dst, vecD src)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AbsVF src));
+  ins_cost(INSN_COST * 3);
+  format %{ "fabs  $dst,$src\t# vector (2S)" %}
+  ins_encode %{
+    __ fabs(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vabs4F(vecX dst, vecX src)
+%{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (AbsVF src));
+  ins_cost(INSN_COST * 3);
+  format %{ "fabs  $dst,$src\t# vector (4S)" %}
+  ins_encode %{
+    __ fabs(as_FloatRegister($dst$$reg), __ T4S,
+            as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vabs2D(vecX dst, vecX src)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AbsVD src));
+  ins_cost(INSN_COST * 3);
+  format %{ "fabs  $dst,$src\t# vector (2D)" %}
+  ins_encode %{
+    __ fabs(as_FloatRegister($dst$$reg), __ T2D,
+            as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// --------------------------------- NEG --------------------------------------
+
+instruct vneg2F(vecD dst, vecD src)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (NegVF src));
+  ins_cost(INSN_COST * 3);
+  format %{ "fneg  $dst,$src\t# vector (2S)" %}
+  ins_encode %{
+    __ fneg(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vneg4F(vecX dst, vecX src)
+%{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (NegVF src));
+  ins_cost(INSN_COST * 3);
+  format %{ "fneg  $dst,$src\t# vector (4S)" %}
+  ins_encode %{
+    __ fneg(as_FloatRegister($dst$$reg), __ T4S,
+            as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vneg2D(vecX dst, vecX src)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (NegVD src));
+  ins_cost(INSN_COST * 3);
+  format %{ "fneg  $dst,$src\t# vector (2D)" %}
+  ins_encode %{
+    __ fneg(as_FloatRegister($dst$$reg), __ T2D,
+            as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 // --------------------------------- AND --------------------------------------
 
 instruct vand8B(vecD dst, vecD src1, vecD src2)
--- a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -2311,6 +2311,12 @@
 
 #define MSG "invalid arrangement"
 
+#define ASSERTION (T == T2S || T == T4S || T == T2D)
+  INSN(fsqrt, 1, 0b11111);
+  INSN(fabs,  0, 0b01111);
+  INSN(fneg,  1, 0b01111);
+#undef ASSERTION
+
 #define ASSERTION (T == T8B || T == T16B || T == T4H || T == T8H || T == T2S || T == T4S)
   INSN(rev64, 0, 0b00000);
 #undef ASSERTION
--- a/hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -68,10 +68,11 @@
 
 // Peephole and CISC spilling both break the graph, and so makes the
 // scheduler sick.
-define_pd_global(bool, OptoPeephole,                 true);
+define_pd_global(bool, OptoPeephole,                 false);
 define_pd_global(bool, UseCISCSpill,                 true);
 define_pd_global(bool, OptoScheduling,               false);
 define_pd_global(bool, OptoBundling,                 false);
+define_pd_global(bool, OptoRegScheduling,            false);
 
 define_pd_global(intx, ReservedCodeCacheSize,        48*M);
 define_pd_global(intx, NonProfiledCodeHeapSize,      21*M);
--- a/hotspot/src/cpu/aarch64/vm/compiledIC_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/compiledIC_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -51,13 +51,15 @@
 // ----------------------------------------------------------------------------
 
 #define __ _masm.
-address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {
+address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
   // Stub is fixed up when the corresponding call is converted from
   // calling compiled code to calling interpreted code.
   // mov rmethod, 0
   // jmp -4 # to self
 
-  address mark = cbuf.insts_mark();  // Get mark within main instrs section.
+  if (mark == NULL) {
+    mark = cbuf.insts_mark();  // Get mark within main instrs section.
+  }
 
   // Note that the code buffer's insts_mark is always relative to insts.
   // That's why we must use the macroassembler to generate a stub.
--- a/hotspot/src/cpu/aarch64/vm/cppInterpreterGenerator_aarch64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/cppInterpreterGenerator_aarch64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,5 +30,6 @@
 
   void generate_more_monitors();
   void generate_deopt_handling();
+  void lock_method(void);
 
 #endif // CPU_AARCH64_VM_CPPINTERPRETERGENERATOR_AARCH64_HPP
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,6 +42,11 @@
 
 // Implementation of InterpreterMacroAssembler
 
+void InterpreterMacroAssembler::jump_to_entry(address entry) {
+  assert(entry, "Entry must have been generated by now");
+  b(entry);
+}
+
 #ifndef CC_INTERP
 
 void InterpreterMacroAssembler::check_and_handle_popframe(Register java_thread) {
@@ -1542,14 +1547,14 @@
     if (MethodData::profile_arguments()) {
       Label done;
       int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
-      add(mdp, mdp, off_to_args);
 
       for (int i = 0; i < TypeProfileArgsLimit; i++) {
         if (i > 0 || MethodData::profile_return()) {
           // If return value type is profiled we may have no argument to profile
-          ldr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
+          ldr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())));
           sub(tmp, tmp, i*TypeStackSlotEntries::per_arg_count());
           cmp(tmp, TypeStackSlotEntries::per_arg_count());
+          add(rscratch1, mdp, off_to_args);
           br(Assembler::LT, done);
         }
         ldr(tmp, Address(callee, Method::const_offset()));
@@ -1557,26 +1562,27 @@
         // stack offset o (zero based) from the start of the argument
         // list, for n arguments translates into offset n - o - 1 from
         // the end of the argument list
-        ldr(rscratch1, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
+        ldr(rscratch1, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))));
         sub(tmp, tmp, rscratch1);
         sub(tmp, tmp, 1);
         Address arg_addr = argument_address(tmp);
         ldr(tmp, arg_addr);
 
-        Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
+        Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i)));
         profile_obj_type(tmp, mdo_arg_addr);
 
         int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
-        add(mdp, mdp, to_add);
         off_to_args += to_add;
       }
 
       if (MethodData::profile_return()) {
-        ldr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
+        ldr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())));
         sub(tmp, tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
       }
 
+      add(rscratch1, mdp, off_to_args);
       bind(done);
+      mov(mdp, rscratch1);
 
       if (MethodData::profile_return()) {
         // We're right after the type profile for the last
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -66,6 +66,8 @@
 
   void load_earlyret_value(TosState state);
 
+  void jump_to_entry(address entry);
+
 #ifdef CC_INTERP
   void save_bcp()                                          { /*  not needed in c++ interpreter and harmless */ }
   void restore_bcp()                                       { /*  not needed in c++ interpreter and harmless */ }
--- a/hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,14 +41,13 @@
   address generate_native_entry(bool synchronized);
   address generate_abstract_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
-  address generate_jump_to_normal_entry(void);
-  address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
-  address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
+  address generate_accessor_entry(void) { return NULL; }
+  address generate_empty_entry(void) { return NULL; }
   void generate_transcendental_entry(AbstractInterpreter::MethodKind kind, int fpargs);
   address generate_Reference_get_entry();
   address generate_CRC32_update_entry();
   address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind);
-  void lock_method(void);
+  address generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
   void generate_stack_overflow_check(void);
 
   void generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue);
--- a/hotspot/src/cpu/aarch64/vm/interpreter_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/interpreter_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -236,17 +236,6 @@
   __ blrt(rscratch1, gpargs, fpargs, rtype);
 }
 
-// Jump into normal path for accessor and empty entry to jump to normal entry
-// The "fast" optimization don't update compilation count therefore can disable inlining
-// for these functions that should be inlined.
-address InterpreterGenerator::generate_jump_to_normal_entry(void) {
-  address entry_point = __ pc();
-
-  assert(Interpreter::entry_for_kind(Interpreter::zerolocals) != NULL, "should already be generated");
-  __ b(Interpreter::entry_for_kind(Interpreter::zerolocals));
-  return entry_point;
-}
-
 // Abstract method entry
 // Attempt to execute abstract method. Throw exception
 address InterpreterGenerator::generate_abstract_entry(void) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 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 "jvmci/jvmciCodeInstaller.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "vmreg_aarch64.inline.hpp"
+
+jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  Unimplemented();
+  return 0;
+}
+
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
+  Unimplemented();
+}
+
+// convert JVMCI register indices (as used in oop maps) to HotSpot registers
+VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg) {
+  return NULL;
+}
+
+bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) {
+  return false;
+}
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1709,6 +1709,20 @@
   return idivq_offset;
 }
 
+void MacroAssembler::membar(Membar_mask_bits order_constraint) {
+  address prev = pc() - NativeMembar::instruction_size;
+  if (prev == code()->last_membar()) {
+    NativeMembar *bar = NativeMembar_at(prev);
+    // We are merging two memory barrier instructions.  On AArch64 we
+    // can do this simply by ORing them together.
+    bar->set_kind(bar->get_kind() | order_constraint);
+    BLOCK_COMMENT("merged membar");
+  } else {
+    code()->set_last_membar(pc());
+    dmb(Assembler::barrier(order_constraint));
+  }
+}
+
 // MacroAssembler routines found actually to be needed
 
 void MacroAssembler::push(Register src)
@@ -2238,7 +2252,7 @@
     ttyLocker ttyl;
     ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n",
                     msg);
-    assert(false, err_msg("DEBUG MESSAGE: %s", msg));
+    assert(false, "DEBUG MESSAGE: %s", msg);
   }
 }
 
@@ -2286,18 +2300,30 @@
 }
 #endif
 
-void MacroAssembler::push_CPU_state() {
-    push(0x3fffffff, sp);         // integer registers except lr & sp
-
+void MacroAssembler::push_CPU_state(bool save_vectors) {
+  push(0x3fffffff, sp);         // integer registers except lr & sp
+
+  if (!save_vectors) {
     for (int i = 30; i >= 0; i -= 2)
       stpd(as_FloatRegister(i), as_FloatRegister(i+1),
            Address(pre(sp, -2 * wordSize)));
+  } else {
+    for (int i = 30; i >= 0; i -= 2)
+      stpq(as_FloatRegister(i), as_FloatRegister(i+1),
+           Address(pre(sp, -4 * wordSize)));
+  }
 }
 
-void MacroAssembler::pop_CPU_state() {
-  for (int i = 0; i < 32; i += 2)
-    ldpd(as_FloatRegister(i), as_FloatRegister(i+1),
-         Address(post(sp, 2 * wordSize)));
+void MacroAssembler::pop_CPU_state(bool restore_vectors) {
+  if (!restore_vectors) {
+    for (int i = 0; i < 32; i += 2)
+      ldpd(as_FloatRegister(i), as_FloatRegister(i+1),
+           Address(post(sp, 2 * wordSize)));
+  } else {
+    for (int i = 0; i < 32; i += 2)
+      ldpq(as_FloatRegister(i), as_FloatRegister(i+1),
+           Address(post(sp, 4 * wordSize)));
+  }
 
   pop(0x3fffffff, sp);         // integer registers except lr & sp
 }
@@ -3027,6 +3053,24 @@
   _masm->bind(_label);
 }
 
+void MacroAssembler::addptr(const Address &dst, int32_t src) {
+  Address adr;
+  switch(dst.getMode()) {
+  case Address::base_plus_offset:
+    // This is the expected mode, although we allow all the other
+    // forms below.
+    adr = form_address(rscratch2, dst.base(), dst.offset(), LogBytesPerWord);
+    break;
+  default:
+    lea(rscratch2, dst);
+    adr = Address(rscratch2);
+    break;
+  }
+  ldr(rscratch1, adr);
+  add(rscratch1, rscratch1, src);
+  str(rscratch1, adr);
+}
+
 void MacroAssembler::cmpptr(Register src1, Address src2) {
   unsigned long offset;
   adrp(rscratch1, src2, offset);
@@ -3063,11 +3107,15 @@
 
   if (UseCondCardMark) {
     Label L_already_dirty;
+    membar(StoreLoad);
     ldrb(rscratch2,  Address(obj, rscratch1));
     cbz(rscratch2, L_already_dirty);
     strb(zr, Address(obj, rscratch1));
     bind(L_already_dirty);
   } else {
+    if (UseConcMarkSweepGC && CMSPrecleaningEnabled) {
+      membar(StoreStore);
+    }
     strb(zr, Address(obj, rscratch1));
   }
 }
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -152,6 +152,13 @@
     strw(scratch, a);
   }
 
+  void bind(Label& L) {
+    Assembler::bind(L);
+    code()->clear_last_membar();
+  }
+
+  void membar(Membar_mask_bits order_constraint);
+
   // Frame creation and destruction shared between JITs.
   void build_frame(int framesize);
   void remove_frame(int framesize);
@@ -777,8 +784,8 @@
 
   DEBUG_ONLY(void verify_heapbase(const char* msg);)
 
-  void push_CPU_state();
-  void pop_CPU_state() ;
+  void push_CPU_state(bool save_vectors = false);
+  void pop_CPU_state(bool restore_vectors = false) ;
 
   // Round up to a power of two
   void round_to(Register reg, int modulus);
@@ -908,13 +915,7 @@
 
   // Arithmetics
 
-  void addptr(Address dst, int32_t src) {
-    lea(rscratch2, dst);
-    ldr(rscratch1, Address(rscratch2));
-    add(rscratch1, rscratch1, src);
-    str(rscratch1, Address(rscratch2));
-  }
-
+  void addptr(const Address &dst, int32_t src);
   void cmpptr(Register src1, Address src2);
 
   // Various forms of CAS
--- a/hotspot/src/cpu/aarch64/vm/methodHandles_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/methodHandles_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -50,7 +50,7 @@
 
 #ifdef ASSERT
 static int check_nonzero(const char* xname, int x) {
-  assert(x != 0, err_msg("%s should be nonzero", xname));
+  assert(x != 0, "%s should be nonzero", xname);
   return x;
 }
 #define NONZERO(x) check_nonzero(#x, x)
@@ -407,7 +407,7 @@
     }
 
     default:
-      fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+      fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
       break;
     }
 
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -101,6 +101,12 @@
   static bool maybe_cpool_ref(address instr) {
     return is_adrp_at(instr) || is_ldr_literal_at(instr);
   }
+
+  bool is_Membar() {
+    unsigned int insn = uint_at(0);
+    return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
+      Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
+  }
 };
 
 inline NativeInstruction* nativeInstruction_at(address address) {
@@ -487,4 +493,15 @@
   return (NativeCallTrampolineStub*)addr;
 }
 
+class NativeMembar : public NativeInstruction {
+public:
+  unsigned int get_kind() { return Instruction_aarch64::extract(uint_at(0), 11, 8); }
+  void set_kind(int order_kind) { Instruction_aarch64::patch(addr_at(0), 11, 8, order_kind); }
+};
+
+inline NativeMembar *NativeMembar_at(address addr) {
+  assert(nativeInstruction_at(addr)->is_Membar(), "no membar found");
+  return (NativeMembar*)addr;
+}
+
 #endif // CPU_AARCH64_VM_NATIVEINST_AARCH64_HPP
--- a/hotspot/src/cpu/aarch64/vm/relocInfo_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/relocInfo_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -102,12 +102,5 @@
   }
 }
 
-void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest)  {
-  if (NativeInstruction::maybe_cpool_ref(addr())) {
-    address old_addr = old_addr_for(addr(), src, dest);
-    MacroAssembler::pd_patch_instruction(addr(), MacroAssembler::target_addr_for_insn(old_addr));
-  }
-}
-
 void metadata_Relocation::pd_fix_value(address x) {
 }
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -75,8 +75,8 @@
 // FIXME -- this is used by C1
 class RegisterSaver {
  public:
-  static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words);
-  static void restore_live_registers(MacroAssembler* masm);
+  static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors = false);
+  static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false);
 
   // Offsets into the register save area
   // Used by deoptimization when it is managing result register
@@ -108,7 +108,17 @@
 
 };
 
-OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words) {
+OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
+#ifdef COMPILER2
+  if (save_vectors) {
+    // Save upper half of vector registers
+    int vect_words = 32 * 8 / wordSize;
+    additional_frame_words += vect_words;
+  }
+#else
+  assert(!save_vectors, "vectors are generated only by C2");
+#endif
+
   int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
                                      reg_save_size*BytesPerInt, 16);
   // OopMap frame size is in compiler stack slots (jint's) not bytes or words
@@ -122,7 +132,7 @@
   // Save registers, fpu state, and flags.
 
   __ enter();
-  __ push_CPU_state();
+  __ push_CPU_state(save_vectors);
 
   // Set an oopmap for the call site.  This oopmap will map all
   // oop-registers and debug-info registers as callee-saved.  This
@@ -139,14 +149,14 @@
                                     // register slots are 8 bytes
                                     // wide, 32 floating-point
                                     // registers
-      oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
+      oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset + additional_frame_slots),
                                 r->as_VMReg());
     }
   }
 
   for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
     FloatRegister r = as_FloatRegister(i);
-    int sp_offset = 2 * i;
+    int sp_offset = save_vectors ? (4 * i) : (2 * i);
     oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
                               r->as_VMReg());
   }
@@ -154,8 +164,11 @@
   return oop_map;
 }
 
-void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
-  __ pop_CPU_state();
+void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
+#ifndef COMPILER2
+  assert(!restore_vectors, "vectors are generated only by C2");
+#endif
+  __ pop_CPU_state(restore_vectors);
   __ leave();
 }
 
@@ -177,9 +190,9 @@
 }
 
 // Is vector's size (in bytes) bigger than a size saved by default?
-// 16 bytes XMM registers are saved by default using fxsave/fxrstor instructions.
+// 8 bytes vector registers are saved by default on AArch64.
 bool SharedRuntime::is_wide_vector(int size) {
-  return size > 16;
+  return size > 8;
 }
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
@@ -460,11 +473,11 @@
 }
 
 
-static void gen_i2c_adapter(MacroAssembler *masm,
-                            int total_args_passed,
-                            int comp_args_on_stack,
-                            const BasicType *sig_bt,
-                            const VMRegPair *regs) {
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
+                                    int total_args_passed,
+                                    int comp_args_on_stack,
+                                    const BasicType *sig_bt,
+                                    const VMRegPair *regs) {
 
   // Note: r13 contains the senderSP on entry. We must preserve it since
   // we may do a i2c -> c2i transition if we lose a race where compiled
@@ -1146,7 +1159,7 @@
     assert((unsigned)gpargs < 256, "eek!");
     assert((unsigned)fpargs < 32, "eek!");
     __ lea(rscratch1, RuntimeAddress(dest));
-    __ mov(rscratch2, (gpargs << 6) | (fpargs << 2) | type);
+    if (UseBuiltinSim)   __ mov(rscratch2, (gpargs << 6) | (fpargs << 2) | type);
     __ blrt(rscratch1, rscratch2);
     __ maybe_isb();
   }
@@ -1194,7 +1207,7 @@
   } else if (iid == vmIntrinsics::_invokeBasic) {
     has_receiver = true;
   } else {
-    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+    fatal("unexpected intrinsic id %d", iid);
   }
 
   if (member_reg != noreg) {
@@ -1521,14 +1534,13 @@
 
   int vep_offset = ((intptr_t)__ pc()) - start;
 
-  // Generate stack overflow check
-
   // If we have to make this method not-entrant we'll overwrite its
   // first instruction with a jump.  For this action to be legal we
   // must ensure that this first instruction is a B, BL, NOP, BKPT,
   // SVC, HVC, or SMC.  Make it a NOP.
   __ nop();
 
+  // Generate stack overflow check
   if (UseStackBanging) {
     __ bang_stack_with_offset(StackShadowPages*os::vm_page_size());
   } else {
@@ -1709,23 +1721,20 @@
   // need to spill before we call out
   int c_arg = total_c_args - total_in_args;
 
-  // Pre-load a static method's oop into r20.  Used both by locking code and
-  // the normal JNI call code.
+  // Pre-load a static method's oop into c_rarg1.
   if (method->is_static() && !is_critical_native) {
 
     //  load oop into a register
-    __ movoop(oop_handle_reg,
+    __ movoop(c_rarg1,
               JNIHandles::make_local(method->method_holder()->java_mirror()),
               /*immediate*/true);
 
     // Now handlize the static class mirror it's known not-null.
-    __ str(oop_handle_reg, Address(sp, klass_offset));
+    __ str(c_rarg1, Address(sp, klass_offset));
     map->set_oop(VMRegImpl::stack2reg(klass_slot_offset));
 
     // Now get the handle
-    __ lea(oop_handle_reg, Address(sp, klass_offset));
-    // store the klass handle as second argument
-    __ mov(c_rarg1, oop_handle_reg);
+    __ lea(c_rarg1, Address(sp, klass_offset));
     // and protect the arg if we must spill
     c_arg--;
   }
@@ -1740,19 +1749,13 @@
 
   __ set_last_Java_frame(sp, noreg, (address)the_pc, rscratch1);
 
-
-  // We have all of the arguments setup at this point. We must not touch any register
-  // argument registers at this point (what if we save/restore them there are no oop?
-
+  Label dtrace_method_entry, dtrace_method_entry_done;
   {
-    SkipIfEqual skip(masm, &DTraceMethodProbes, false);
-    // protect the args we've loaded
-    save_args(masm, total_c_args, c_arg, out_regs);
-    __ mov_metadata(c_rarg1, method());
-    __ call_VM_leaf(
-      CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
-      rthread, c_rarg1);
-    restore_args(masm, total_c_args, c_arg, out_regs);
+    unsigned long offset;
+    __ adrp(rscratch1, ExternalAddress((address)&DTraceMethodProbes), offset);
+    __ ldrb(rscratch1, Address(rscratch1, offset));
+    __ cbnzw(rscratch1, dtrace_method_entry);
+    __ bind(dtrace_method_entry_done);
   }
 
   // RedefineClasses() tracing support for obsolete method entry
@@ -1782,7 +1785,6 @@
   if (method->is_synchronized()) {
     assert(!is_critical_native, "unhandled");
 
-
     const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes();
 
     // Get the handle (the 2nd argument)
@@ -1838,7 +1840,6 @@
 
   // Finally just about ready to make the JNI call
 
-
   // get JNIEnv* which is first argument to native
   if (!is_critical_native) {
     __ lea(c_rarg0, Address(rthread, in_bytes(JavaThread::jni_environment_offset())));
@@ -1879,9 +1880,9 @@
 
   // Unpack native results.
   switch (ret_type) {
-  case T_BOOLEAN: __ ubfx(r0, r0, 0, 8);            break;
+  case T_BOOLEAN: __ ubfx(r0, r0, 0, 8);             break;
   case T_CHAR   : __ ubfx(r0, r0, 0, 16);            break;
-  case T_BYTE   : __ sbfx(r0, r0, 0, 8);            break;
+  case T_BYTE   : __ sbfx(r0, r0, 0, 8);             break;
   case T_SHORT  : __ sbfx(r0, r0, 0, 16);            break;
   case T_INT    : __ sbfx(r0, r0, 0, 32);            break;
   case T_DOUBLE :
@@ -1904,14 +1905,17 @@
   //     Thread A is resumed to finish this native method, but doesn't block here since it
   //     didn't see any synchronization is progress, and escapes.
   __ mov(rscratch1, _thread_in_native_trans);
-  __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
-  __ stlrw(rscratch1, rscratch2);
 
   if(os::is_MP()) {
     if (UseMembar) {
+      __ strw(rscratch1, Address(rthread, JavaThread::thread_state_offset()));
+
       // Force this write out before the read below
       __ dmb(Assembler::SY);
     } else {
+      __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
+      __ stlrw(rscratch1, rscratch2);
+
       // Write serialization page so VM thread can do a pseudo remote membar.
       // We use the current thread pointer to calculate a thread specific
       // offset to write to within the page. This minimizes bus traffic
@@ -1920,54 +1924,23 @@
     }
   }
 
-  Label after_transition;
-
   // check for safepoint operation in progress and/or pending suspend requests
+  Label safepoint_in_progress, safepoint_in_progress_done;
   {
-    Label Continue;
-
-    { unsigned long offset;
-      __ adrp(rscratch1,
-              ExternalAddress((address)SafepointSynchronize::address_of_state()),
-              offset);
-      __ ldrw(rscratch1, Address(rscratch1, offset));
-    }
-    __ cmpw(rscratch1, SafepointSynchronize::_not_synchronized);
-
-    Label L;
-    __ br(Assembler::NE, L);
+    assert(SafepointSynchronize::_not_synchronized == 0, "fix this code");
+    unsigned long offset;
+    __ adrp(rscratch1,
+            ExternalAddress((address)SafepointSynchronize::address_of_state()),
+            offset);
+    __ ldrw(rscratch1, Address(rscratch1, offset));
+    __ cbnzw(rscratch1, safepoint_in_progress);
     __ ldrw(rscratch1, Address(rthread, JavaThread::suspend_flags_offset()));
-    __ cbz(rscratch1, Continue);
-    __ bind(L);
-
-    // Don't use call_VM as it will see a possible pending exception and forward it
-    // and never return here preventing us from clearing _last_native_pc down below.
-    //
-    save_native_result(masm, ret_type, stack_slots);
-    __ mov(c_rarg0, rthread);
-#ifndef PRODUCT
-  assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area");
-#endif
-    if (!is_critical_native) {
-      __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)));
-    } else {
-      __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition)));
-    }
-    __ blrt(rscratch1, 1, 0, 1);
-    __ maybe_isb();
-    // Restore any method result value
-    restore_native_result(masm, ret_type, stack_slots);
-
-    if (is_critical_native) {
-      // The call above performed the transition to thread_in_Java so
-      // skip the transition logic below.
-      __ b(after_transition);
-    }
-
-    __ bind(Continue);
+    __ cbnzw(rscratch1, safepoint_in_progress);
+    __ bind(safepoint_in_progress_done);
   }
 
   // change thread state
+  Label after_transition;
   __ mov(rscratch1, _thread_in_Java);
   __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
   __ stlrw(rscratch1, rscratch2);
@@ -2024,16 +1997,15 @@
     }
 
     __ bind(done);
-
   }
+
+  Label dtrace_method_exit, dtrace_method_exit_done;
   {
-    SkipIfEqual skip(masm, &DTraceMethodProbes, false);
-    save_native_result(masm, ret_type, stack_slots);
-    __ mov_metadata(c_rarg1, method());
-    __ call_VM_leaf(
-         CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
-         rthread, c_rarg1);
-    restore_native_result(masm, ret_type, stack_slots);
+    unsigned long offset;
+    __ adrp(rscratch1, ExternalAddress((address)&DTraceMethodProbes), offset);
+    __ ldrb(rscratch1, Address(rscratch1, offset));
+    __ cbnzw(rscratch1, dtrace_method_exit);
+    __ bind(dtrace_method_exit_done);
   }
 
   __ reset_last_Java_frame(false, true);
@@ -2082,7 +2054,7 @@
   // Slow path locking & unlocking
   if (method->is_synchronized()) {
 
-    // BEGIN Slow path lock
+    __ block_comment("Slow path lock {");
     __ bind(slow_path_lock);
 
     // has last_Java_frame setup. No exceptions so do vanilla call not call_VM
@@ -2109,9 +2081,9 @@
 #endif
     __ b(lock_done);
 
-    // END Slow path lock
-
-    // BEGIN Slow path unlock
+    __ block_comment("} Slow path lock");
+
+    __ block_comment("Slow path unlock {");
     __ bind(slow_path_unlock);
 
     // If we haven't already saved the native result we must save it now as xmm registers
@@ -2149,7 +2121,7 @@
     }
     __ b(unlock_done);
 
-    // END Slow path unlock
+    __ block_comment("} Slow path unlock");
 
   } // synchronized
 
@@ -2162,6 +2134,69 @@
   // and continue
   __ b(reguard_done);
 
+  // SLOW PATH safepoint
+  {
+    __ block_comment("safepoint {");
+    __ bind(safepoint_in_progress);
+
+    // Don't use call_VM as it will see a possible pending exception and forward it
+    // and never return here preventing us from clearing _last_native_pc down below.
+    //
+    save_native_result(masm, ret_type, stack_slots);
+    __ mov(c_rarg0, rthread);
+#ifndef PRODUCT
+  assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area");
+#endif
+    if (!is_critical_native) {
+      __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)));
+    } else {
+      __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition)));
+    }
+    __ blrt(rscratch1, 1, 0, 1);
+    __ maybe_isb();
+    // Restore any method result value
+    restore_native_result(masm, ret_type, stack_slots);
+
+    if (is_critical_native) {
+      // The call above performed the transition to thread_in_Java so
+      // skip the transition logic above.
+      __ b(after_transition);
+    }
+
+    __ b(safepoint_in_progress_done);
+    __ block_comment("} safepoint");
+  }
+
+  // SLOW PATH dtrace support
+  {
+    __ block_comment("dtrace entry {");
+    __ bind(dtrace_method_entry);
+
+    // We have all of the arguments setup at this point. We must not touch any register
+    // argument registers at this point (what if we save/restore them there are no oop?
+
+    save_args(masm, total_c_args, c_arg, out_regs);
+    __ mov_metadata(c_rarg1, method());
+    __ call_VM_leaf(
+      CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
+      rthread, c_rarg1);
+    restore_args(masm, total_c_args, c_arg, out_regs);
+    __ b(dtrace_method_entry_done);
+    __ block_comment("} dtrace entry");
+  }
+
+  {
+    __ block_comment("dtrace exit {");
+    __ bind(dtrace_method_exit);
+    save_native_result(masm, ret_type, stack_slots);
+    __ mov_metadata(c_rarg1, method());
+    __ call_VM_leaf(
+         CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
+         rthread, c_rarg1);
+    restore_native_result(masm, ret_type, stack_slots);
+    __ b(dtrace_method_exit_done);
+    __ block_comment("} dtrace exit");
+  }
 
 
   __ flush();
@@ -2742,7 +2777,7 @@
   bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
 
   // Save registers, fpu state, and flags
-  map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
+  map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words, save_vectors);
 
   // The following is basically a call_VM.  However, we need the precise
   // address of the call in order to generate an oopmap. Hence, we do all the
@@ -2793,7 +2828,7 @@
   __ bind(noException);
 
   // Normal exit, restore registers and exit.
-  RegisterSaver::restore_live_registers(masm);
+  RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ ret(lr);
 
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -746,6 +746,9 @@
           const Register count = end; // 'end' register contains bytes count now
           __ mov(scratch, (address)ct->byte_map_base);
           __ add(start, start, scratch);
+          if (UseConcMarkSweepGC) {
+            __ membar(__ StoreStore);
+          }
           __ BIND(L_loop);
           __ strb(zr, Address(start, count));
           __ subs(count, count, 1);
@@ -2395,6 +2398,274 @@
     return start;
   }
 
+  /***
+   *  Arguments:
+   *
+   *  Inputs:
+   *   c_rarg0   - int   adler
+   *   c_rarg1   - byte* buff
+   *   c_rarg2   - int   len
+   *
+   * Output:
+   *   c_rarg0   - int adler result
+   */
+  address generate_updateBytesAdler32() {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "updateBytesAdler32");
+    address start = __ pc();
+
+    Label L_simple_by1_loop, L_nmax, L_nmax_loop, L_by16, L_by16_loop, L_by1_loop, L_do_mod, L_combine, L_by1;
+
+    // Aliases
+    Register adler  = c_rarg0;
+    Register s1     = c_rarg0;
+    Register s2     = c_rarg3;
+    Register buff   = c_rarg1;
+    Register len    = c_rarg2;
+    Register nmax  = r4;
+    Register base = r5;
+    Register count = r6;
+    Register temp0 = rscratch1;
+    Register temp1 = rscratch2;
+    Register temp2 = r7;
+
+    // Max number of bytes we can process before having to take the mod
+    // 0x15B0 is 5552 in decimal, the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
+    unsigned long BASE = 0xfff1;
+    unsigned long NMAX = 0x15B0;
+
+    __ mov(base, BASE);
+    __ mov(nmax, NMAX);
+
+    // s1 is initialized to the lower 16 bits of adler
+    // s2 is initialized to the upper 16 bits of adler
+    __ ubfx(s2, adler, 16, 16);  // s2 = ((adler >> 16) & 0xffff)
+    __ uxth(s1, adler);          // s1 = (adler & 0xffff)
+
+    // The pipelined loop needs at least 16 elements for 1 iteration
+    // It does check this, but it is more effective to skip to the cleanup loop
+    __ cmp(len, 16);
+    __ br(Assembler::HS, L_nmax);
+    __ cbz(len, L_combine);
+
+    __ bind(L_simple_by1_loop);
+    __ ldrb(temp0, Address(__ post(buff, 1)));
+    __ add(s1, s1, temp0);
+    __ add(s2, s2, s1);
+    __ subs(len, len, 1);
+    __ br(Assembler::HI, L_simple_by1_loop);
+
+    // s1 = s1 % BASE
+    __ subs(temp0, s1, base);
+    __ csel(s1, temp0, s1, Assembler::HS);
+
+    // s2 = s2 % BASE
+    __ lsr(temp0, s2, 16);
+    __ lsl(temp1, temp0, 4);
+    __ sub(temp1, temp1, temp0);
+    __ add(s2, temp1, s2, ext::uxth);
+
+    __ subs(temp0, s2, base);
+    __ csel(s2, temp0, s2, Assembler::HS);
+
+    __ b(L_combine);
+
+    __ bind(L_nmax);
+    __ subs(len, len, nmax);
+    __ sub(count, nmax, 16);
+    __ br(Assembler::LO, L_by16);
+
+    __ bind(L_nmax_loop);
+
+    __ ldp(temp0, temp1, Address(__ post(buff, 16)));
+
+    __ add(s1, s1, temp0, ext::uxtb);
+    __ ubfx(temp2, temp0, 8, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 16, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 24, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 32, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 40, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 48, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp0, Assembler::LSR, 56);
+    __ add(s2, s2, s1);
+
+    __ add(s1, s1, temp1, ext::uxtb);
+    __ ubfx(temp2, temp1, 8, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 16, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 24, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 32, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 40, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 48, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp1, Assembler::LSR, 56);
+    __ add(s2, s2, s1);
+
+    __ subs(count, count, 16);
+    __ br(Assembler::HS, L_nmax_loop);
+
+    // s1 = s1 % BASE
+    __ lsr(temp0, s1, 16);
+    __ lsl(temp1, temp0, 4);
+    __ sub(temp1, temp1, temp0);
+    __ add(temp1, temp1, s1, ext::uxth);
+
+    __ lsr(temp0, temp1, 16);
+    __ lsl(s1, temp0, 4);
+    __ sub(s1, s1, temp0);
+    __ add(s1, s1, temp1, ext:: uxth);
+
+    __ subs(temp0, s1, base);
+    __ csel(s1, temp0, s1, Assembler::HS);
+
+    // s2 = s2 % BASE
+    __ lsr(temp0, s2, 16);
+    __ lsl(temp1, temp0, 4);
+    __ sub(temp1, temp1, temp0);
+    __ add(temp1, temp1, s2, ext::uxth);
+
+    __ lsr(temp0, temp1, 16);
+    __ lsl(s2, temp0, 4);
+    __ sub(s2, s2, temp0);
+    __ add(s2, s2, temp1, ext:: uxth);
+
+    __ subs(temp0, s2, base);
+    __ csel(s2, temp0, s2, Assembler::HS);
+
+    __ subs(len, len, nmax);
+    __ sub(count, nmax, 16);
+    __ br(Assembler::HS, L_nmax_loop);
+
+    __ bind(L_by16);
+    __ adds(len, len, count);
+    __ br(Assembler::LO, L_by1);
+
+    __ bind(L_by16_loop);
+
+    __ ldp(temp0, temp1, Address(__ post(buff, 16)));
+
+    __ add(s1, s1, temp0, ext::uxtb);
+    __ ubfx(temp2, temp0, 8, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 16, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 24, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 32, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 40, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp0, 48, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp0, Assembler::LSR, 56);
+    __ add(s2, s2, s1);
+
+    __ add(s1, s1, temp1, ext::uxtb);
+    __ ubfx(temp2, temp1, 8, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 16, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 24, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 32, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 40, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ ubfx(temp2, temp1, 48, 8);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp2);
+    __ add(s2, s2, s1);
+    __ add(s1, s1, temp1, Assembler::LSR, 56);
+    __ add(s2, s2, s1);
+
+    __ subs(len, len, 16);
+    __ br(Assembler::HS, L_by16_loop);
+
+    __ bind(L_by1);
+    __ adds(len, len, 15);
+    __ br(Assembler::LO, L_do_mod);
+
+    __ bind(L_by1_loop);
+    __ ldrb(temp0, Address(__ post(buff, 1)));
+    __ add(s1, temp0, s1);
+    __ add(s2, s2, s1);
+    __ subs(len, len, 1);
+    __ br(Assembler::HS, L_by1_loop);
+
+    __ bind(L_do_mod);
+    // s1 = s1 % BASE
+    __ lsr(temp0, s1, 16);
+    __ lsl(temp1, temp0, 4);
+    __ sub(temp1, temp1, temp0);
+    __ add(temp1, temp1, s1, ext::uxth);
+
+    __ lsr(temp0, temp1, 16);
+    __ lsl(s1, temp0, 4);
+    __ sub(s1, s1, temp0);
+    __ add(s1, s1, temp1, ext:: uxth);
+
+    __ subs(temp0, s1, base);
+    __ csel(s1, temp0, s1, Assembler::HS);
+
+    // s2 = s2 % BASE
+    __ lsr(temp0, s2, 16);
+    __ lsl(temp1, temp0, 4);
+    __ sub(temp1, temp1, temp0);
+    __ add(temp1, temp1, s2, ext::uxth);
+
+    __ lsr(temp0, temp1, 16);
+    __ lsl(s2, temp0, 4);
+    __ sub(s2, s2, temp0);
+    __ add(s2, s2, temp1, ext:: uxth);
+
+    __ subs(temp0, s2, base);
+    __ csel(s2, temp0, s2, Assembler::HS);
+
+    // Combine lower bits and higher bits
+    __ bind(L_combine);
+    __ orr(s1, s1, s2, Assembler::LSL, 16); // adler = s1 | (s2 << 16)
+
+    __ ret(lr);
+
+    return start;
+  }
+
   /**
    *  Arguments:
    *
@@ -3613,6 +3884,11 @@
       StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
     }
 
+    // generate Adler32 intrinsics code
+    if (UseAdler32Intrinsics) {
+      StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
+    }
+
     // Safefetch stubs.
     generate_safefetch("SafeFetch32", sizeof(int),     &StubRoutines::_safefetch32_entry,
                                                        &StubRoutines::_safefetch32_fault_pc,
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -535,7 +535,7 @@
 //      r0
 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ...(param regs)
 //      rscratch1, rscratch2 (scratch regs)
-void InterpreterGenerator::lock_method(void) {
+void TemplateInterpreterGenerator::lock_method() {
   // synchronize method
   const Address access_flags(rmethod, Method::access_flags_offset());
   const Address monitor_block_top(
@@ -721,8 +721,7 @@
 
     // generate a vanilla interpreter entry as the slow path
     __ bind(slow_path);
-    (void) generate_normal_entry(false);
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals));
     return entry;
   }
 #endif // INCLUDE_ALL_GCS
@@ -779,12 +778,10 @@
 
     // generate a vanilla native entry as the slow path
     __ bind(slow_path);
-
-    (void) generate_native_entry(false);
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
     return entry;
   }
-  return generate_native_entry(false);
+  return NULL;
 }
 
 /**
@@ -841,12 +838,10 @@
 
     // generate a vanilla native entry as the slow path
     __ bind(slow_path);
-
-    (void) generate_native_entry(false);
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
     return entry;
   }
-  return generate_native_entry(false);
+  return NULL;
 }
 
 void InterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -178,9 +178,8 @@
     warning("UseCRC32 specified, but not supported on this CPU");
   }
 
-  if (UseAdler32Intrinsics) {
-    warning("Adler32Intrinsics not available on this CPU.");
-    FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
+  if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
+    FLAG_SET_DEFAULT(UseAdler32Intrinsics, true);
   }
 
   if (auxv & HWCAP_AES) {
--- a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -60,6 +60,7 @@
 define_pd_global(bool, OptoPeephole,                 false);
 define_pd_global(bool, UseCISCSpill,                 false);
 define_pd_global(bool, OptoBundling,                 false);
+define_pd_global(bool, OptoRegScheduling,            false);
 // GL:
 // Detected a problem with unscaled compressed oops and
 // narrow_oop_use_complex_address() == false.
--- a/hotspot/src/cpu/ppc/vm/compiledIC_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/compiledIC_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -94,10 +94,12 @@
 
 const int IC_pos_in_java_to_interp_stub = 8;
 #define __ _masm.
-address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {
+address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark/* = NULL*/) {
 #ifdef COMPILER2
-  // Get the mark within main instrs section which is set to the address of the call.
-  address call_addr = cbuf.insts_mark();
+  if (mark == NULL) {
+    // Get the mark within main instrs section which is set to the address of the call.
+    mark = cbuf.insts_mark();
+  }
 
   // Note that the code buffer's insts_mark is always relative to insts.
   // That's why we must use the macroassembler to generate a stub.
@@ -117,7 +119,7 @@
   // Create a static stub relocation which relates this stub
   // with the call instruction at insts_call_instruction_offset in the
   // instructions code-section.
-  __ relocate(static_stub_Relocation::spec(call_addr));
+  __ relocate(static_stub_Relocation::spec(mark));
   const int stub_start_offset = __ offset();
 
   // Now, create the stub's code:
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -46,7 +46,7 @@
   MacroAssembler::null_check_throw(a, offset, temp_reg, exception_entry);
 }
 
-void InterpreterMacroAssembler::branch_to_entry(address entry, Register Rscratch) {
+void InterpreterMacroAssembler::jump_to_entry(address entry, Register Rscratch) {
   assert(entry, "Entry must have been generated by now");
   if (is_within_range_of_b(entry, pc())) {
     b(entry);
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -39,7 +39,7 @@
 
   void null_check_throw(Register a, int offset, Register temp_reg);
 
-  void branch_to_entry(address entry, Register Rscratch);
+  void jump_to_entry(address entry, Register Rscratch);
 
   // Handy address generation macros.
 #define thread_(field_name) in_bytes(JavaThread::field_name ## _offset()), R16_thread
--- a/hotspot/src/cpu/ppc/vm/interpreterGenerator_ppc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/interpreterGenerator_ppc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,12 +31,12 @@
  private:
 
   address generate_abstract_entry(void);
-  address generate_jump_to_normal_entry(void);
-  address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
-  address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
+  address generate_accessor_entry(void) { return NULL; }
+  address generate_empty_entry(void) { return NULL; }
   address generate_Reference_get_entry(void);
 
   address generate_CRC32_update_entry();
   address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind);
+  address generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
 
 #endif // CPU_PPC_VM_INTERPRETERGENERATOR_PPC_HPP
--- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -427,18 +427,6 @@
   return entry;
 }
 
-// Call an accessor method (assuming it is resolved, otherwise drop into
-// vanilla (slow path) entry.
-address InterpreterGenerator::generate_jump_to_normal_entry(void) {
-  address entry = __ pc();
-  address normal_entry = Interpreter::entry_for_kind(Interpreter::zerolocals);
-  assert(normal_entry != NULL, "should already be generated.");
-  __ branch_to_entry(normal_entry, R11_scratch1);
-  __ flush();
-
-  return entry;
-}
-
 // Abstract method entry.
 //
 address InterpreterGenerator::generate_abstract_entry(void) {
@@ -529,13 +517,13 @@
   //   regular method entry code to generate the NPE.
   //
 
-  address entry = __ pc();
+  if (UseG1GC) {
+    address entry = __ pc();
 
-  const int referent_offset = java_lang_ref_Reference::referent_offset;
-  guarantee(referent_offset > 0, "referent offset not initialized");
+    const int referent_offset = java_lang_ref_Reference::referent_offset;
+    guarantee(referent_offset > 0, "referent offset not initialized");
 
-  if (UseG1GC) {
-     Label slow_path;
+    Label slow_path;
 
     // Debugging not possible, so can't use __ skip_if_jvmti_mode(slow_path, GR31_SCRATCH);
 
@@ -577,13 +565,11 @@
 
     // Generate regular method entry.
     __ bind(slow_path);
-    __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);
-    __ flush();
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);
     return entry;
-  } else {
-    return generate_jump_to_normal_entry();
   }
+
+  return NULL;
 }
 
 void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/ppc/vm/jvmciCodeInstaller_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 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 "jvmci/jvmciCodeInstaller.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "vmreg_ppc.inline.hpp"
+
+jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  Unimplemented();
+  return 0;
+}
+
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
+  Unimplemented();
+}
+
+void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
+  Unimplemented();
+}
+
+// convert JVMCI register indices (as used in oop maps) to HotSpot registers
+VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg) {
+  return NULL;
+}
+
+bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) {
+  return false;
+}
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -594,13 +594,6 @@
            "can't identify emitted call");
   } else {
     // variant 1:
-#if defined(ABI_ELFv2)
-    nop();
-    calculate_address_from_global_toc(R12, dest, true, true, false);
-    mtctr(R12);
-    nop();
-    nop();
-#else
     mr(R0, R11);  // spill R11 -> R0.
 
     // Load the destination address into CTR,
@@ -610,7 +603,6 @@
     mtctr(R11);
     mr(R11, R0);  // spill R11 <- R0.
     nop();
-#endif
 
     // do the call/jump
     if (link) {
@@ -4292,7 +4284,7 @@
 
 static void stop_on_request(int tp, const char* msg) {
   tty->print("PPC assembly code requires stop: (%s) %s\n", stop_types[tp%/*stop_end*/4], msg);
-  guarantee(false, err_msg("PPC assembly code requires stop: %s", msg));
+  guarantee(false, "PPC assembly code requires stop: %s", msg);
 }
 
 // Call a C-function that prints output.
--- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -60,7 +60,7 @@
 
 #ifdef ASSERT
 static int check_nonzero(const char* xname, int x) {
-  assert(x != 0, err_msg("%s should be nonzero", xname));
+  assert(x != 0, "%s should be nonzero", xname);
   return x;
 }
 #define NONZERO(x) check_nonzero(#x, x)
@@ -434,7 +434,7 @@
     }
 
     default:
-      fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+      fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
       break;
     }
 
--- a/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -149,7 +149,7 @@
   if (!NativeCall::is_call_at(addr)) {
     tty->print_cr("not a NativeCall at " PTR_FORMAT, p2i(addr));
     // TODO: PPC port: Disassembler::decode(addr - 20, addr + 20, tty);
-    fatal(err_msg("not a NativeCall at " PTR_FORMAT, p2i(addr)));
+    fatal("not a NativeCall at " PTR_FORMAT, p2i(addr));
   }
 }
 #endif // ASSERT
@@ -162,7 +162,7 @@
   if (!NativeFarCall::is_far_call_at(addr)) {
     tty->print_cr("not a NativeFarCall at " PTR_FORMAT, p2i(addr));
     // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty);
-    fatal(err_msg("not a NativeFarCall at " PTR_FORMAT, p2i(addr)));
+    fatal("not a NativeFarCall at " PTR_FORMAT, p2i(addr));
   }
 }
 #endif // ASSERT
@@ -308,7 +308,7 @@
         ! MacroAssembler::is_bl(*((int*) addr))) {
       tty->print_cr("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr));
       // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty);
-      fatal(err_msg("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr)));
+      fatal("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr));
     }
   }
 }
@@ -346,7 +346,7 @@
   if (!NativeJump::is_jump_at(addr)) {
     tty->print_cr("not a NativeJump at " PTR_FORMAT, p2i(addr));
     // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty);
-    fatal(err_msg("not a NativeJump at " PTR_FORMAT, p2i(addr)));
+    fatal("not a NativeJump at " PTR_FORMAT, p2i(addr));
   }
 }
 #endif // ASSERT
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Thu Oct 22 11:13:08 2015 -0700
@@ -2064,6 +2064,10 @@
   return true;  // Per default match rules are supported.
 }
 
+const int Matcher::float_pressure(int default_pressure_threshold) {
+  return default_pressure_threshold;
+}
+
 int Matcher::regnum_to_fpu_offset(int regnum) {
   // No user for this method?
   Unimplemented();
--- a/hotspot/src/cpu/ppc/vm/relocInfo_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/relocInfo_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -125,8 +125,5 @@
 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
 }
 
-void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
-}
-
 void metadata_Relocation::pd_fix_value(address x) {
 }
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -475,9 +475,8 @@
 
 // Is vector's size (in bytes) bigger than a size saved by default?
 bool SharedRuntime::is_wide_vector(int size) {
-  ResourceMark rm;
   // Note, MaxVectorSize == 8 on PPC64.
-  assert(size <= 8, err_msg_res("%d bytes vectors are not supported", size));
+  assert(size <= 8, "%d bytes vectors are not supported", size);
   return size > 8;
 }
 #ifdef COMPILER2
@@ -957,11 +956,11 @@
   return c2i_entrypoint;
 }
 
-static void gen_i2c_adapter(MacroAssembler *masm,
-                            int total_args_passed,
-                            int comp_args_on_stack,
-                            const BasicType *sig_bt,
-                            const VMRegPair *regs) {
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
+                                    int total_args_passed,
+                                    int comp_args_on_stack,
+                                    const BasicType *sig_bt,
+                                    const VMRegPair *regs) {
 
   // Load method's entry-point from method.
   __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method);
@@ -1631,7 +1630,7 @@
   } else if (iid == vmIntrinsics::_invokeBasic) {
     has_receiver = true;
   } else {
-    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+    fatal("unexpected intrinsic id %d", iid);
   }
 
   if (member_reg != noreg) {
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -841,7 +841,7 @@
   // Only called by MacroAssembler::verify_oop
   static void verify_oop_helper(const char* message, oop o) {
     if (!o->is_oop_or_null()) {
-      fatal(message);
+      fatal("%s", message);
     }
     ++ StubRoutines::_verify_oop_count;
   }
--- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -620,7 +620,7 @@
 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
   if (!math_entry_available(kind)) {
     NOT_PRODUCT(__ should_not_reach_here();)
-    return Interpreter::entry_for_kind(Interpreter::zerolocals);
+    return NULL;
   }
 
   address entry = __ pc();
@@ -1126,14 +1126,6 @@
 
   generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
 
-#ifdef FAST_DISPATCH
-  __ unimplemented("Fast dispatch in generate_normal_entry");
-#if 0
-  __ set((intptr_t)Interpreter::dispatch_table(), IdispatchTables);
-  // Set bytecode dispatch table base.
-#endif
-#endif
-
   // --------------------------------------------------------------------------
   // Zero out non-parameter locals.
   // Note: *Always* zero out non-parameter locals as Sparc does. It's not
@@ -1266,9 +1258,8 @@
  *   int java.util.zip.CRC32.update(int crc, int b)
  */
 address InterpreterGenerator::generate_CRC32_update_entry() {
-  address start = __ pc();  // Remember stub start address (is rtn value).
-
   if (UseCRC32Intrinsics) {
+    address start = __ pc();  // Remember stub start address (is rtn value).
     Label slow_path;
 
     // Safepoint check
@@ -1313,11 +1304,11 @@
     // Generate a vanilla native entry as the slow path.
     BLOCK_COMMENT("} CRC32_update");
     BIND(slow_path);
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), R11_scratch1);
+    return start;
   }
 
-  (void) generate_native_entry(false);
-
-  return start;
+  return NULL;
 }
 
 // CRC32 Intrinsics.
@@ -1327,9 +1318,8 @@
  *   int java.util.zip.CRC32.updateByteBuffer(int crc, long* buf, int off, int len)
  */
 address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
-  address start = __ pc();  // Remember stub start address (is rtn value).
-
   if (UseCRC32Intrinsics) {
+    address start = __ pc();  // Remember stub start address (is rtn value).
     Label slow_path;
 
     // Safepoint check
@@ -1406,11 +1396,11 @@
     // Generate a vanilla native entry as the slow path.
     BLOCK_COMMENT("} CRC32_updateBytes(Buffer)");
     BIND(slow_path);
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), R11_scratch1);
+    return start;
   }
 
-  (void) generate_native_entry(false);
-
-  return start;
+  return NULL;
 }
 
 // These should never be compiled since the interpreter will prefer
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -389,7 +389,7 @@
 
   static void assert_signed_range(intptr_t x, int nbits) {
     assert(nbits == 32 || (-(1 << nbits-1) <= x  &&  x < ( 1 << nbits-1)),
-           err_msg("value out of range: x=" INTPTR_FORMAT ", nbits=%d", x, nbits));
+           "value out of range: x=" INTPTR_FORMAT ", nbits=%d", x, nbits);
   }
 
   static void assert_signed_word_disp_range(intptr_t x, int nbits) {
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -64,6 +64,7 @@
 define_pd_global(bool, UseCISCSpill,                 false);
 define_pd_global(bool, OptoBundling,                 false);
 define_pd_global(bool, OptoScheduling,               true);
+define_pd_global(bool, OptoRegScheduling,            false);
 
 #ifdef _LP64
 // We need to make sure that all generated code is within
--- a/hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -53,14 +53,15 @@
 // ----------------------------------------------------------------------------
 
 #define __ _masm.
-address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {
-#ifdef COMPILER2
+address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
   // Stub is fixed up when the corresponding call is converted from calling
   // compiled code to calling interpreted code.
   // set (empty), G5
   // jmp -1
 
-  address mark = cbuf.insts_mark();  // Get mark within main instrs section.
+  if (mark == NULL) {
+    mark = cbuf.insts_mark();  // Get mark within main instrs section.
+  }
 
   MacroAssembler _masm(&cbuf);
 
@@ -80,12 +81,11 @@
 
   __ delayed()->nop();
 
+  assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size");
+
   // Update current stubs pointer and restore code_end.
   __ end_a_stub();
   return base;
-#else
-  ShouldNotReachHere();
-#endif
 }
 #undef __
 
--- a/hotspot/src/cpu/sparc/vm/cppInterpreterGenerator_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreterGenerator_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,6 +31,7 @@
 
   void generate_more_monitors();
   void generate_deopt_handling();
+  void lock_method(void);
   void adjust_callers_stack(Register args);
   void generate_compute_interpreter_state(const Register state,
                                           const Register prev_state,
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -468,7 +468,7 @@
 
   // If G1 is not enabled then attempt to go through the accessor entry point
   // Reference.get is an accessor
-  return generate_jump_to_normal_entry();
+  return NULL;
 }
 
 //
@@ -1164,7 +1164,7 @@
 }
 // Find preallocated  monitor and lock method (C++ interpreter)
 //
-void InterpreterGenerator::lock_method(void) {
+void CppInterpreterGenerator::lock_method() {
 // Lock the current method.
 // Destroys registers L2_scratch, L3_scratch, O0
 //
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -82,6 +82,7 @@
                                                                             \
   product(intx, UseVIS, 99,                                                 \
           "Highest supported VIS instructions set on Sparc")                \
+          range(0, 99)                                                      \
                                                                             \
   product(bool, UseCBCond, false,                                           \
           "Use compare and branch instruction on SPARC")                    \
@@ -91,12 +92,14 @@
                                                                             \
   product(intx, BlockZeroingLowLimit, 2048,                                 \
           "Minimum size in bytes when block zeroing will be used")          \
+          range(1, max_jint)                                                \
                                                                             \
   product(bool, UseBlockCopy, false,                                        \
           "Use special cpu instructions for block copy")                    \
                                                                             \
   product(intx, BlockCopyLowLimit, 2048,                                    \
           "Minimum size in bytes when block copy will be used")             \
+          range(1, max_jint)                                                \
                                                                             \
   develop(bool, UseV8InstrsOnly, false,                                     \
           "Use SPARC-V8 Compliant instruction subset")                      \
@@ -108,9 +111,11 @@
           "Do not use swap instructions, but only CAS (in a loop) on SPARC")\
                                                                             \
   product(uintx,  ArraycopySrcPrefetchDistance, 0,                          \
-          "Distance to prefetch source array in arracopy")                  \
+          "Distance to prefetch source array in arraycopy")                 \
+          constraint(ArraycopySrcPrefetchDistanceConstraintFunc, AfterErgo) \
                                                                             \
   product(uintx,  ArraycopyDstPrefetchDistance, 0,                          \
-          "Distance to prefetch destination array in arracopy")             \
+          "Distance to prefetch destination array in arraycopy")            \
+          constraint(ArraycopyDstPrefetchDistanceConstraintFunc, AfterErgo) \
 
 #endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -59,6 +59,13 @@
 
 #endif // CC_INTERP
 
+void InterpreterMacroAssembler::jump_to_entry(address entry) {
+  assert(entry, "Entry must have been generated by now");
+  AddressLiteral al(entry);
+  jump_to(al, G3_scratch);
+  delayed()->nop();
+}
+
 void InterpreterMacroAssembler::compute_extra_locals_size_in_bytes(Register args_size, Register locals_size, Register delta) {
   // Note: this algorithm is also used by C1's OSR entry sequence.
   // Any changes should also be applied to CodeEmitter::emit_osr_entry().
@@ -1643,26 +1650,73 @@
     bind(skip_receiver_profile);
 
     // The method data pointer needs to be updated to reflect the new target.
+#if INCLUDE_JVMCI
+    if (MethodProfileWidth == 0) {
+      update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
+    }
+#else
     update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
-    bind (profile_continue);
+#endif
+    bind(profile_continue);
   }
 }
 
-void InterpreterMacroAssembler::record_klass_in_profile_helper(
-                                        Register receiver, Register scratch,
-                                        int start_row, Label& done, bool is_virtual_call) {
+#if INCLUDE_JVMCI
+void InterpreterMacroAssembler::profile_called_method(Register method, Register scratch) {
+  assert_different_registers(method, scratch);
+  if (ProfileInterpreter && MethodProfileWidth > 0) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    Label done;
+    record_item_in_profile_helper(method, scratch, 0, done, MethodProfileWidth,
+      &VirtualCallData::method_offset, &VirtualCallData::method_count_offset, in_bytes(VirtualCallData::nonprofiled_receiver_count_offset()));
+    bind(done);
+
+    update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
+    bind(profile_continue);
+  }
+}
+#endif // INCLUDE_JVMCI
+
+void InterpreterMacroAssembler::record_klass_in_profile_helper(Register receiver, Register scratch,
+                                                               Label& done, bool is_virtual_call) {
   if (TypeProfileWidth == 0) {
     if (is_virtual_call) {
       increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
     }
-    return;
+#if INCLUDE_JVMCI
+    else if (EnableJVMCI) {
+      increment_mdp_data_at(in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()), scratch);
+    }
+#endif
+  } else {
+    int non_profiled_offset = -1;
+    if (is_virtual_call) {
+      non_profiled_offset = in_bytes(CounterData::count_offset());
+    }
+#if INCLUDE_JVMCI
+    else if (EnableJVMCI) {
+      non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset());
+    }
+#endif
+
+    record_item_in_profile_helper(receiver, scratch, 0, done, TypeProfileWidth,
+      &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset);
   }
-
-  int last_row = VirtualCallData::row_limit() - 1;
+}
+
+void InterpreterMacroAssembler::record_item_in_profile_helper(Register item,
+                                          Register scratch, int start_row, Label& done, int total_rows,
+                                          OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn,
+                                          int non_profiled_offset) {
+  int last_row = total_rows - 1;
   assert(start_row <= last_row, "must be work left to do");
-  // Test this row for both the receiver and for null.
+  // Test this row for both the item and for null.
   // Take any of three different outcomes:
-  //   1. found receiver => increment count and goto done
+  //   1. found item => increment count and goto done
   //   2. found null => keep looking for case 1, maybe allocate this cell
   //   3. found something else => keep looking for cases 1 and 2
   // Case 3 is handled by a recursive call.
@@ -1670,28 +1724,28 @@
     Label next_test;
     bool test_for_null_also = (row == start_row);
 
-    // See if the receiver is receiver[n].
-    int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));
-    test_mdp_data_at(recvr_offset, receiver, next_test, scratch);
+    // See if the item is item[n].
+    int item_offset = in_bytes(item_offset_fn(row));
+    test_mdp_data_at(item_offset, item, next_test, scratch);
     // delayed()->tst(scratch);
 
-    // The receiver is receiver[n].  Increment count[n].
-    int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
+    // The receiver is item[n].  Increment count[n].
+    int count_offset = in_bytes(item_count_offset_fn(row));
     increment_mdp_data_at(count_offset, scratch);
     ba_short(done);
     bind(next_test);
 
     if (test_for_null_also) {
       Label found_null;
-      // Failed the equality check on receiver[n]...  Test for null.
+      // Failed the equality check on item[n]...  Test for null.
       if (start_row == last_row) {
         // The only thing left to do is handle the null case.
-        if (is_virtual_call) {
+        if (non_profiled_offset >= 0) {
           brx(Assembler::zero, false, Assembler::pn, found_null);
           delayed()->nop();
-          // Receiver did not match any saved receiver and there is no empty row for it.
+          // Item did not match any saved item and there is no empty row for it.
           // Increment total counter to indicate polymorphic case.
-          increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
+          increment_mdp_data_at(non_profiled_offset, scratch);
           ba_short(done);
           bind(found_null);
         } else {
@@ -1705,21 +1759,22 @@
       delayed()->nop();
 
       // Put all the "Case 3" tests here.
-      record_klass_in_profile_helper(receiver, scratch, start_row + 1, done, is_virtual_call);
-
-      // Found a null.  Keep searching for a matching receiver,
+      record_item_in_profile_helper(item, scratch, start_row + 1, done, total_rows,
+        item_offset_fn, item_count_offset_fn, non_profiled_offset);
+
+      // Found a null.  Keep searching for a matching item,
       // but remember that this is an empty (unused) slot.
       bind(found_null);
     }
   }
 
-  // In the fall-through case, we found no matching receiver, but we
-  // observed the receiver[start_row] is NULL.
-
-  // Fill in the receiver field and increment the count.
-  int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));
-  set_mdp_data_at(recvr_offset, receiver);
-  int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
+  // In the fall-through case, we found no matching item, but we
+  // observed the item[start_row] is NULL.
+
+  // Fill in the item field and increment the count.
+  int item_offset = in_bytes(item_offset_fn(start_row));
+  set_mdp_data_at(item_offset, item);
+  int count_offset = in_bytes(item_count_offset_fn(start_row));
   mov(DataLayout::counter_increment, scratch);
   set_mdp_data_at(count_offset, scratch);
   if (start_row > 0) {
@@ -1732,7 +1787,7 @@
   assert(ProfileInterpreter, "must be profiling");
   Label done;
 
-  record_klass_in_profile_helper(receiver, scratch, 0, done, is_virtual_call);
+  record_klass_in_profile_helper(receiver, scratch, done, is_virtual_call);
 
   bind (done);
 }
@@ -1788,7 +1843,7 @@
     // The method data pointer needs to be updated.
     int mdp_delta = in_bytes(BitData::bit_data_size());
     if (TypeProfileCasts) {
-      mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
+      mdp_delta = in_bytes(ReceiverTypeData::receiver_type_data_size());
     }
     update_mdp_by_constant(mdp_delta);
 
@@ -1806,7 +1861,7 @@
 
     int mdp_delta = in_bytes(BitData::bit_data_size());
     if (TypeProfileCasts) {
-      mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
+      mdp_delta = in_bytes(ReceiverTypeData::receiver_type_data_size());
 
       // Record the object type.
       record_klass_in_profile(klass, scratch, false);
@@ -1828,7 +1883,7 @@
 
     int count_offset = in_bytes(CounterData::count_offset());
     // Back up the address, since we have already bumped the mdp.
-    count_offset -= in_bytes(VirtualCallData::virtual_call_data_size());
+    count_offset -= in_bytes(ReceiverTypeData::receiver_type_data_size());
 
     // *Decrement* the counter.  We expect to see zero or small negatives.
     increment_mdp_data_at(count_offset, scratch, true);
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,6 +30,8 @@
 
 // This file specializes the assember with interpreter-specific macros
 
+typedef ByteSize (*OffsetFunction)(uint);
+
 REGISTER_DECLARATION(     Register, Otos_i , O0); // tos for ints, etc
 REGISTER_DECLARATION(     Register, Otos_l , O0); // for longs
 REGISTER_DECLARATION(     Register, Otos_l1, O0); // for 1st part of longs
@@ -80,6 +82,8 @@
   InterpreterMacroAssembler(CodeBuffer* c)
     : MacroAssembler(c) {}
 
+  void jump_to_entry(address entry);
+
 #ifndef CC_INTERP
   virtual void load_earlyret_value(TosState state);
 
@@ -299,7 +303,11 @@
 
   void record_klass_in_profile(Register receiver, Register scratch, bool is_virtual_call);
   void record_klass_in_profile_helper(Register receiver, Register scratch,
-                                      int start_row, Label& done, bool is_virtual_call);
+                                      Label& done, bool is_virtual_call);
+  void record_item_in_profile_helper(Register item,
+                                     Register scratch, int start_row, Label& done, int total_rows,
+                                     OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn,
+                                     int non_profiled_offset);
 
   void update_mdp_by_offset(int offset_of_disp, Register scratch);
   void update_mdp_by_offset(Register reg, int offset_of_disp,
@@ -312,6 +320,7 @@
   void profile_call(Register scratch);
   void profile_final_call(Register scratch);
   void profile_virtual_call(Register receiver, Register scratch, bool receiver_can_be_null = false);
+  void profile_called_method(Register method, Register scratch) NOT_JVMCI_RETURN;
   void profile_ret(TosState state, Register return_bci, Register scratch);
   void profile_null_seen(Register scratch);
   void profile_typecheck(Register klass, Register scratch);
--- a/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -34,11 +34,9 @@
   address generate_abstract_entry(void);
   // there are no math intrinsics on sparc
   address generate_math_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
-  address generate_jump_to_normal_entry(void);
-  address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
-  address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
+  address generate_accessor_entry(void) { return NULL; }
+  address generate_empty_entry(void) { return NULL; }
   address generate_Reference_get_entry(void);
-  void lock_method(void);
   void save_native_result(void);
   void restore_native_result(void);
 
@@ -48,4 +46,5 @@
   // Not supported
   address generate_CRC32_update_entry() { return NULL; }
   address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
+  address generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
 #endif // CPU_SPARC_VM_INTERPRETERGENERATOR_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -241,15 +241,6 @@
 
 // Various method entries
 
-address InterpreterGenerator::generate_jump_to_normal_entry(void) {
-  address entry = __ pc();
-  assert(Interpreter::entry_for_kind(Interpreter::zerolocals) != NULL, "should already be generated");
-  AddressLiteral al(Interpreter::entry_for_kind(Interpreter::zerolocals));
-  __ jump_to(al, G3_scratch);
-  __ delayed()->nop();
-  return entry;
-}
-
 // Abstract method entry
 // Attempt to execute abstract method. Throw exception
 //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2013, 2015, 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 "jvmci/jvmciCodeInstaller.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "vmreg_sparc.inline.hpp"
+
+jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  if (inst->is_call() || inst->is_jump()) {
+    return pc_offset + NativeCall::instruction_size;
+  } else if (inst->is_call_reg()) {
+    return pc_offset + NativeCallReg::instruction_size;
+  } else if (inst->is_sethi()) {
+    return pc_offset + NativeFarCall::instruction_size;
+  } else {
+    fatal("unsupported type of instruction for call site");
+    return 0;
+  }
+}
+
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
+  address pc = _instructions->start() + pc_offset;
+  Handle obj = HotSpotObjectConstantImpl::object(constant);
+  jobject value = JNIHandles::make_local(obj());
+  if (HotSpotObjectConstantImpl::compressed(constant)) {
+#ifdef _LP64
+    int oop_index = _oop_recorder->find_index(value);
+    RelocationHolder rspec = oop_Relocation::spec(oop_index);
+    _instructions->relocate(pc, rspec, 1);
+#else
+    fatal("compressed oop on 32bit");
+#endif
+  } else {
+    NativeMovConstReg* move = nativeMovConstReg_at(pc);
+    move->set_data((intptr_t) value);
+
+    // We need two relocations:  one on the sethi and one on the add.
+    int oop_index = _oop_recorder->find_index(value);
+    RelocationHolder rspec = oop_Relocation::spec(oop_index);
+    _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec);
+    _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec);
+  }
+}
+
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
+  address pc = _instructions->start() + pc_offset;
+  NativeInstruction* inst = nativeInstruction_at(pc);
+  NativeInstruction* inst1 = nativeInstruction_at(pc + 4);
+  if(inst->is_sethi() && inst1->is_nop()) {
+      address const_start = _constants->start();
+      address dest = _constants->start() + data_offset;
+      if(_constants_size > 0) {
+        _instructions->relocate(pc + NativeMovConstReg::sethi_offset, internal_word_Relocation::spec((address) dest));
+        _instructions->relocate(pc + NativeMovConstReg::add_offset, internal_word_Relocation::spec((address) dest));
+      }
+      TRACE_jvmci_3("relocating at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset);
+  }else {
+    int const_size = align_size_up(_constants->end()-_constants->start(), CodeEntryAlignment);
+    NativeMovRegMem* load = nativeMovRegMem_at(pc);
+    // This offset must match with SPARCLoadConstantTableBaseOp.emitCode
+    load->set_offset(- (const_size - data_offset + Assembler::min_simm13()));
+    TRACE_jvmci_3("relocating ld at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset);
+  }
+}
+
+void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp");
+}
+
+void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  address pc = (address) inst;
+  if (inst->is_call()) {
+    NativeCall* call = nativeCall_at(pc);
+    call->set_destination((address) foreign_call_destination);
+    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec());
+  } else if (inst->is_sethi()) {
+    NativeJump* jump = nativeJump_at(pc);
+    jump->set_jump_destination((address) foreign_call_destination);
+    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec());
+  } else {
+    fatal(err_msg("unknown call or jump instruction at " PTR_FORMAT, p2i(pc)));
+  }
+  TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
+}
+
+void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
+#ifdef ASSERT
+  Method* method = NULL;
+  // we need to check, this might also be an unresolved method
+  if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
+    method = getMethodFromHotSpotMethod(hotspot_method);
+  }
+#endif
+  switch (_next_call_type) {
+    case INLINE_INVOKE:
+      break;
+    case INVOKEVIRTUAL:
+    case INVOKEINTERFACE: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc));
+      break;
+    }
+    case INVOKESTATIC: {
+      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
+      _instructions->relocate(call->instruction_address(), relocInfo::static_call_type);
+      break;
+    }
+    case INVOKESPECIAL: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type);
+      break;
+    }
+    default:
+      fatal("invalid _next_call_type value");
+      break;
+  }
+}
+
+void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
+  switch (mark) {
+    case POLL_NEAR:
+      fatal("unimplemented");
+      break;
+    case POLL_FAR:
+      _instructions->relocate(pc, relocInfo::poll_type);
+      break;
+    case POLL_RETURN_NEAR:
+      fatal("unimplemented");
+      break;
+    case POLL_RETURN_FAR:
+      _instructions->relocate(pc, relocInfo::poll_return_type);
+      break;
+    default:
+      fatal("invalid mark value");
+      break;
+  }
+}
+
+// convert JVMCI register indices (as used in oop maps) to HotSpot registers
+VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg) {
+  if (jvmci_reg < RegisterImpl::number_of_registers) {
+    return as_Register(jvmci_reg)->as_VMReg();
+  } else {
+    jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers;
+    floatRegisterNumber += MAX2(0, floatRegisterNumber-32); // Beginning with f32, only every second register is going to be addressed
+    if (floatRegisterNumber < FloatRegisterImpl::number_of_registers) {
+      return as_FloatRegister(floatRegisterNumber)->as_VMReg();
+    }
+    ShouldNotReachHere();
+    return NULL;
+  }
+}
+
+bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) {
+  return !hotspotRegister->is_FloatRegister();
+}
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1596,7 +1596,7 @@
   else {
      ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg);
   }
-  assert(false, err_msg("DEBUG MESSAGE: %s", msg));
+  assert(false, "DEBUG MESSAGE: %s", msg);
 }
 
 
--- a/hotspot/src/cpu/sparc/vm/memset_with_concurrent_readers_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/memset_with_concurrent_readers_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -61,8 +61,8 @@
     " sub %[offset], %[end], %[offset]\n\t" // offset := start - end
     " sllx %[offset], 2, %[offset]\n\t" // scale offset for instruction size of 4
     " add %[offset], 40, %[offset]\n\t" // offset += 10 * instruction size
-    " rd %pc, %[pc]\n\t"                // dispatch on scaled offset
-    " jmpl %[pc]+%[offset], %g0\n\t"
+    " rd %%pc, %[pc]\n\t"               // dispatch on scaled offset
+    " jmpl %[pc]+%[offset], %%g0\n\t"
     "  nop\n\t"
     // DISPATCH: no direct reference, but without it the store block may be elided.
     "1:\n\t"
@@ -108,7 +108,7 @@
       // Unroll loop x8.
       " sub %[aend], %[ato], %[temp]\n\t"
       " cmp %[temp], 56\n\t"           // cc := (aligned_end - aligned_to) > 7 words
-      " ba %xcc, 2f\n\t"               // goto TEST always
+      " ba %%xcc, 2f\n\t"              // goto TEST always
       "  sub %[aend], 56, %[temp]\n\t" // limit := aligned_end - 7 words
       // LOOP:
       "1:\n\t"                         // unrolled x8 store loop top
@@ -123,7 +123,7 @@
       " stx %[xvalue], [%[ato]-8]\n\t"
       // TEST:
       "2:\n\t"
-      " bgu,a %xcc, 1b\n\t"            // goto LOOP if more than 7 words remaining
+      " bgu,a %%xcc, 1b\n\t"           // goto LOOP if more than 7 words remaining
       "  add %[ato], 64, %[ato]\n\t"   // aligned_to += 8, for next iteration
       // Fill remaining < 8 full words.
       // Dispatch on (aligned_end - aligned_to).
@@ -132,8 +132,8 @@
       " sub %[ato], %[aend], %[ato]\n\t" // offset := aligned_to - aligned_end
       " srax %[ato], 1, %[ato]\n\t"      // scale offset for instruction size of 4
       " add %[ato], 40, %[ato]\n\t"      // offset += 10 * instruction size
-      " rd %pc, %[temp]\n\t"             // dispatch on scaled offset
-      " jmpl %[temp]+%[ato], %g0\n\t"
+      " rd %%pc, %[temp]\n\t"            // dispatch on scaled offset
+      " jmpl %[temp]+%[ato], %%g0\n\t"
       "  nop\n\t"
       // DISPATCH: no direct reference, but without it the store block may be elided.
       "3:\n\t"
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -56,7 +56,7 @@
 
 #ifdef ASSERT
 static int check_nonzero(const char* xname, int x) {
-  assert(x != 0, err_msg("%s should be nonzero", xname));
+  assert(x != 0, "%s should be nonzero", xname);
   return x;
 }
 #define NONZERO(x) check_nonzero(#x, x)
@@ -453,7 +453,7 @@
     }
 
     default:
-      fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+      fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
       break;
     }
 
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -53,6 +53,7 @@
 
   bool is_nop()                        { return long_at(0) == nop_instruction(); }
   bool is_call()                       { return is_op(long_at(0), Assembler::call_op); }
+  bool is_call_reg()                   { return is_op(long_at(0), Assembler::arith_op); }
   bool is_sethi()                      { return (is_op2(long_at(0), Assembler::sethi_op2)
                                           && inv_rd(long_at(0)) != G0); }
 
@@ -415,6 +416,19 @@
   return call;
 }
 
+class NativeCallReg: public NativeInstruction {
+ public:
+  enum Sparc_specific_constants {
+    instruction_size      = 8,
+    return_address_offset = 8,
+    instruction_offset    = 0
+  };
+
+  address next_instruction_address() const {
+    return addr_at(instruction_size);
+  }
+};
+
 // The NativeFarCall is an abstraction for accessing/manipulating native call-anywhere
 // instructions in the sparcv9 vm.  Used to call native methods which may be loaded
 // anywhere in the address space, possibly out of reach of a call instruction.
--- a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -197,8 +197,5 @@
 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
 }
 
-void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
-}
-
 void metadata_Relocation::pd_fix_value(address x) {
 }
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,6 +43,9 @@
 #include "compiler/compileBroker.hpp"
 #include "shark/sharkCompiler.hpp"
 #endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciJavaClasses.hpp"
+#endif
 
 #define __ masm->
 
@@ -316,7 +319,7 @@
 // 8 bytes FP registers are saved by default on SPARC.
 bool SharedRuntime::is_wide_vector(int size) {
   // Note, MaxVectorSize == 8 on SPARC.
-  assert(size <= 8, err_msg_res("%d bytes vectors are not supported", size));
+  assert(size <= 8, "%d bytes vectors are not supported", size);
   return size > 8;
 }
 
@@ -464,7 +467,7 @@
       break;
 
     default:
-      fatal(err_msg_res("unknown basic type %d", sig_bt[i]));
+      fatal("unknown basic type %d", sig_bt[i]);
       break;
     }
   }
@@ -513,10 +516,10 @@
                               const VMRegPair *regs,
                               Label& skip_fixup);
   void gen_i2c_adapter(int total_args_passed,
-                              // VMReg max_arg,
-                              int comp_args_on_stack, // VMRegStackSlots
-                              const BasicType *sig_bt,
-                              const VMRegPair *regs);
+                       // VMReg max_arg,
+                       int comp_args_on_stack, // VMRegStackSlots
+                       const BasicType *sig_bt,
+                       const VMRegPair *regs);
 
   AdapterGenerator(MacroAssembler *_masm) : masm(_masm) {}
 };
@@ -760,13 +763,11 @@
   __ bind(L_fail);
 }
 
-void AdapterGenerator::gen_i2c_adapter(
-                            int total_args_passed,
-                            // VMReg max_arg,
-                            int comp_args_on_stack, // VMRegStackSlots
-                            const BasicType *sig_bt,
-                            const VMRegPair *regs) {
-
+void AdapterGenerator::gen_i2c_adapter(int total_args_passed,
+                                       // VMReg max_arg,
+                                       int comp_args_on_stack, // VMRegStackSlots
+                                       const BasicType *sig_bt,
+                                       const VMRegPair *regs) {
   // Generate an I2C adapter: adjust the I-frame to make space for the C-frame
   // layout.  Lesp was saved by the calling I-frame and will be restored on
   // return.  Meanwhile, outgoing arg space is all owned by the callee
@@ -990,6 +991,21 @@
 
   // Jump to the compiled code just as if compiled code was doing it.
   __ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3);
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    // check if this call should be routed towards a specific entry point
+    __ ld(Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), G1);
+    __ cmp(G0, G1);
+    Label no_alternative_target;
+    __ br(Assembler::equal, false, Assembler::pn, no_alternative_target);
+    __ delayed()->nop();
+
+    __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset()), G3);
+    __ st_ptr(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
+
+    __ bind(no_alternative_target);
+  }
+#endif // INCLUDE_JVMCI
 
   // 6243940 We might end up in handle_wrong_method if
   // the callee is deoptimized as we race thru here. If that
@@ -1006,6 +1022,15 @@
   __ delayed()->nop();
 }
 
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
+                                    int total_args_passed,
+                                    int comp_args_on_stack,
+                                    const BasicType *sig_bt,
+                                    const VMRegPair *regs) {
+  AdapterGenerator agen(masm);
+  agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
+}
+
 // ---------------------------------------------------------------
 AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
                                                             int total_args_passed,
@@ -1016,9 +1041,7 @@
                                                             AdapterFingerPrint* fingerprint) {
   address i2c_entry = __ pc();
 
-  AdapterGenerator agen(masm);
-
-  agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
+  gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
 
 
   // -------------------------------------------------------------------------
@@ -1063,7 +1086,7 @@
   }
 
   address c2i_entry = __ pc();
-
+  AdapterGenerator agen(masm);
   agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, L_skip_fixup);
 
   __ flush();
@@ -1859,7 +1882,7 @@
   } else if (iid == vmIntrinsics::_invokeBasic) {
     has_receiver = true;
   } else {
-    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+    fatal("unexpected intrinsic id %d", iid);
   }
 
   if (member_reg != noreg) {
@@ -2916,6 +2939,11 @@
     pad += StackShadowPages*16 + 32;
   }
 #endif
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    pad += 1000; // Increase the buffer size when compiling for JVMCI
+  }
+#endif
 #ifdef _LP64
   CodeBuffer buffer("deopt_blob", 2100+pad, 512);
 #else
@@ -2982,6 +3010,45 @@
   __ ba(cont);
   __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
 
+
+#if INCLUDE_JVMCI
+  Label after_fetch_unroll_info_call;
+  int implicit_exception_uncommon_trap_offset = 0;
+  int uncommon_trap_offset = 0;
+
+  if (EnableJVMCI) {
+    masm->block_comment("BEGIN implicit_exception_uncommon_trap");
+    implicit_exception_uncommon_trap_offset = __ offset() - start;
+
+    __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()), O7);
+    __ st_ptr(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
+    __ add(O7, -8, O7);
+
+    uncommon_trap_offset = __ offset() - start;
+
+    // Save everything in sight.
+    (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
+    __ set_last_Java_frame(SP, NULL);
+
+    __ ld(G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()), O1);
+    __ sub(G0, 1, L1);
+    __ st(L1, G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()));
+
+    __ mov((int32_t)Deoptimization::Unpack_reexecute, L0deopt_mode);
+    __ mov(G2_thread, O0);
+    __ call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap));
+    __ delayed()->nop();
+    oop_maps->add_gc_map( __ offset()-start, map->deep_copy());
+    __ get_thread();
+    __ add(O7, 8, O7);
+    __ reset_last_Java_frame();
+
+    __ ba(after_fetch_unroll_info_call);
+    __ delayed()->nop(); // Delay slot
+    masm->block_comment("END implicit_exception_uncommon_trap");
+  } // EnableJVMCI
+#endif // INCLUDE_JVMCI
+
   int exception_offset = __ offset() - start;
 
   // restore G2, the trampoline destroyed it
@@ -3004,6 +3071,7 @@
   int exception_in_tls_offset = __ offset() - start;
 
   // No need to update oop_map  as each call to save_live_registers will produce identical oopmap
+  // Opens a new stack frame
   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
 
   // Restore G2_thread
@@ -3035,7 +3103,12 @@
   // Reexecute entry, similar to c2 uncommon trap
   //
   int reexecute_offset = __ offset() - start;
-
+#if INCLUDE_JVMCI && !defined(COMPILER1)
+  if (EnableJVMCI && UseJVMCICompiler) {
+    // JVMCI does not use this kind of deoptimization
+    __ should_not_reach_here();
+  }
+#endif
   // No need to update oop_map  as each call to save_live_registers will produce identical oopmap
   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
 
@@ -3059,6 +3132,11 @@
 
   __ reset_last_Java_frame();
 
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    __ bind(after_fetch_unroll_info_call);
+  }
+#endif
   // NOTE: we know that only O0/O1 will be reloaded by restore_result_registers
   // so this move will survive
 
@@ -3124,6 +3202,12 @@
   masm->flush();
   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_words);
   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
+    _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
+  }
+#endif
 }
 
 #ifdef COMPILER2
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Thu Oct 22 11:13:08 2015 -0700
@@ -1098,7 +1098,7 @@
   Register r = as_Register(ra_->get_encode(this));
   CodeSection* consts_section = __ code()->consts();
   int consts_size = consts_section->align_at_start(consts_section->size());
-  assert(constant_table.size() == consts_size, err_msg("must be: %d == %d", constant_table.size(), consts_size));
+  assert(constant_table.size() == consts_size, "must be: %d == %d", constant_table.size(), consts_size);
 
   if (UseRDPCForConstantTableBase) {
     // For the following RDPC logic to work correctly the consts
@@ -1860,6 +1860,10 @@
   return true;  // Per default match rules are supported.
 }
 
+const int Matcher::float_pressure(int default_pressure_threshold) {
+  return default_pressure_threshold;
+}
+
 int Matcher::regnum_to_fpu_offset(int regnum) {
   return regnum - 32; // The FP registers are in the second chunk
 }
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -204,6 +204,20 @@
 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
   address entry = __ pc();
   __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
+#if INCLUDE_JVMCI
+  // Check if we need to take lock at entry of synchronized method.
+  if (UseJVMCICompiler) {
+    Label L;
+    Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset());
+    __ ldbool(pending_monitor_enter_addr, Gtemp);  // Load if pending monitor enter
+    __ cmp_and_br_short(Gtemp, G0, Assembler::equal, Assembler::pn, L);
+    // Clear flag.
+    __ stbool(G0, pending_monitor_enter_addr);
+    // Take lock.
+    lock_method();
+    __ bind(L);
+  }
+#endif
   { Label L;
     Address exception_addr(G2_thread, Thread::pending_exception_offset());
     __ ld_ptr(exception_addr, Gtemp);  // Load pending exception.
@@ -349,7 +363,7 @@
 // Allocate monitor and lock method (asm interpreter)
 // ebx - Method*
 //
-void InterpreterGenerator::lock_method(void) {
+void TemplateInterpreterGenerator::lock_method() {
   __ ld(Lmethod, in_bytes(Method::access_flags_offset()), O0);  // Load access flags.
 
 #ifdef ASSERT
@@ -779,14 +793,14 @@
 
     // Generate regular method entry
     __ bind(slow_path);
-    (void) generate_normal_entry(false);
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals));
     return entry;
   }
 #endif // INCLUDE_ALL_GCS
 
   // If G1 is not enabled then attempt to go through the accessor entry point
   // Reference.get is an accessor
-  return generate_jump_to_normal_entry();
+  return NULL;
 }
 
 //
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,9 +37,9 @@
 #ifdef _LP64
   // The sethi() instruction generates lots more instructions when shell
   // stack limit is unlimited, so that's why this is much bigger.
-  const static int InterpreterCodeSize = 210 * K;
+  const static int InterpreterCodeSize = 260 * K;
 #else
-  const static int InterpreterCodeSize = 180 * K;
+  const static int InterpreterCodeSize = 230 * K;
 #endif
 
 #endif // CPU_SPARC_VM_TEMPLATEINTERPRETER_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -2949,12 +2949,14 @@
 
 
 void TemplateTable::generate_vtable_call(Register Rrecv, Register Rindex, Register Rret) {
+  Register Rtemp = G4_scratch;
   Register Rcall = Rindex;
   assert_different_registers(Rcall, G5_method, Gargs, Rret);
 
   // get target Method* & entry point
   __ lookup_virtual_method(Rrecv, Rindex, G5_method);
   __ profile_arguments_type(G5_method, Rcall, Gargs, true);
+  __ profile_called_method(G5_method, Rtemp);
   __ call_from_interpreter(Rcall, Gargs, Rret);
 }
 
@@ -3211,6 +3213,7 @@
   assert_different_registers(Rcall, G5_method, Gargs, Rret);
 
   __ profile_arguments_type(G5_method, Rcall, Gargs, true);
+  __ profile_called_method(G5_method, Rscratch);
   __ call_from_interpreter(Rcall, Gargs, Rret);
 }
 
@@ -3486,7 +3489,8 @@
   Register RspecifiedKlass = O4;
 
   // Check for casting a NULL
-  __ br_null_short(Otos_i, Assembler::pn, is_null);
+  __ br_null(Otos_i, false, Assembler::pn, is_null);
+  __ delayed()->nop();
 
   // Get value klass in RobjKlass
   __ load_klass(Otos_i, RobjKlass); // get value klass
@@ -3542,7 +3546,8 @@
   Register RspecifiedKlass = O4;
 
   // Check for casting a NULL
-  __ br_null_short(Otos_i, Assembler::pt, is_null);
+  __ br_null(Otos_i, false, Assembler::pt, is_null);
+  __ delayed()->nop();
 
   // Get value klass in RobjKlass
   __ load_klass(Otos_i, RobjKlass); // get value klass
--- a/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,10 +37,11 @@
   /******************************/                                                                                                   \
   /* JavaFrameAnchor            */                                                                                                   \
   /******************************/                                                                                                   \
-  volatile_nonstatic_field(JavaFrameAnchor,     _flags,                                          int)
+  volatile_nonstatic_field(JavaFrameAnchor,     _flags,                                          int)                                \
+  static_field(VM_Version, _features, int)
 
-#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
-
+#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
+  declare_toplevel_type(VM_Version)
 
 #define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)                                                              \
   /******************************/                                        \
@@ -78,7 +79,11 @@
   declare_c2_constant(R_G4_num)                                           \
   declare_c2_constant(R_G5_num)                                           \
   declare_c2_constant(R_G6_num)                                           \
-  declare_c2_constant(R_G7_num)
+  declare_c2_constant(R_G7_num)                                           \
+  declare_constant(VM_Version::vis1_instructions_m)                       \
+  declare_constant(VM_Version::vis2_instructions_m)                       \
+  declare_constant(VM_Version::vis3_instructions_m)                       \
+  declare_constant(VM_Version::cbcond_instructions_m)
 
 #define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
 
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -40,10 +40,6 @@
   PrefetchScanIntervalInBytes = prefetch_scan_interval_in_bytes();
   PrefetchFieldsAhead         = prefetch_fields_ahead();
 
-  assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 1, "invalid value");
-  if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0;
-  if( AllocatePrefetchInstr > 1 ) AllocatePrefetchInstr = 0;
-
   // Allocation prefetch settings
   intx cache_line_size = prefetch_data_size();
   if( cache_line_size > AllocatePrefetchStepSize )
@@ -59,13 +55,6 @@
   AllocatePrefetchDistance = allocate_prefetch_distance();
   AllocatePrefetchStyle    = allocate_prefetch_style();
 
-  assert((AllocatePrefetchDistance % AllocatePrefetchStepSize) == 0 &&
-         (AllocatePrefetchDistance > 0), "invalid value");
-  if ((AllocatePrefetchDistance % AllocatePrefetchStepSize) != 0 ||
-      (AllocatePrefetchDistance <= 0)) {
-    AllocatePrefetchDistance = AllocatePrefetchStepSize;
-  }
-
   if (AllocatePrefetchStyle == 3 && !has_blk_init()) {
     warning("BIS instructions are not available on this CPU");
     FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
@@ -73,13 +62,6 @@
 
   guarantee(VM_Version::has_v9(), "only SPARC v9 is supported");
 
-  assert(ArraycopySrcPrefetchDistance < 4096, "invalid value");
-  if (ArraycopySrcPrefetchDistance >= 4096)
-    ArraycopySrcPrefetchDistance = 4064;
-  assert(ArraycopyDstPrefetchDistance < 4096, "invalid value");
-  if (ArraycopyDstPrefetchDistance >= 4096)
-    ArraycopyDstPrefetchDistance = 4064;
-
   UseSSE = 0; // Only on x86 and x64
 
   _supports_cx8 = has_v9();
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,6 +29,7 @@
 #include "runtime/vm_version.hpp"
 
 class VM_Version: public Abstract_VM_Version {
+  friend class VMStructs;
 protected:
   enum Feature_Flag {
     v8_instructions      = 0,
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -733,11 +733,11 @@
     // these asserts are somewhat nonsensical
 #ifndef _LP64
     assert(which == imm_operand || which == disp32_operand,
-           err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip)));
+           "which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
 #else
     assert((which == call32_operand || which == imm_operand) && is_64bit ||
            which == narrow_oop_operand && !is_64bit,
-           err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip)));
+           "which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
 #endif // _LP64
     return ip;
 
@@ -770,6 +770,7 @@
     case 0x55: // andnps
     case 0x56: // orps
     case 0x57: // xorps
+    case 0x59: //mulpd
     case 0x6E: // movd
     case 0x7E: // movd
     case 0xAE: // ldmxcsr, stmxcsr, fxrstor, fxsave, clflush
@@ -877,21 +878,35 @@
     // Check second byte
     NOT_LP64(assert((0xC0 & *ip) == 0xC0, "shouldn't have LDS and LES instructions"));
 
+    int vex_opcode;
     // First byte
     if ((0xFF & *inst) == VEX_3bytes) {
+      vex_opcode = VEX_OPCODE_MASK & *ip;
       ip++; // third byte
       is_64bit = ((VEX_W & *ip) == VEX_W);
+    } else {
+      vex_opcode = VEX_OPCODE_0F;
     }
     ip++; // opcode
     // To find the end of instruction (which == end_pc_operand).
-    switch (0xFF & *ip) {
-    case 0x61: // pcmpestri r, r/a, #8
-    case 0x70: // pshufd r, r/a, #8
-    case 0x73: // psrldq r, #8
-      tail_size = 1;  // the imm8
-      break;
-    default:
-      break;
+    switch (vex_opcode) {
+      case VEX_OPCODE_0F:
+        switch (0xFF & *ip) {
+        case 0x70: // pshufd r, r/a, #8
+        case 0x71: // ps[rl|ra|ll]w r, #8
+        case 0x72: // ps[rl|ra|ll]d r, #8
+        case 0x73: // ps[rl|ra|ll]q r, #8
+        case 0xC2: // cmp[ps|pd|ss|sd] r, r, r/a, #8
+        case 0xC4: // pinsrw r, r, r/a, #8
+        case 0xC5: // pextrw r/a, r, #8
+        case 0xC6: // shufp[s|d] r, r, r/a, #8
+          tail_size = 1;  // the imm8
+          break;
+        }
+        break;
+      case VEX_OPCODE_0F_3A:
+        tail_size = 1;
+        break;
     }
     ip++; // skip opcode
     debug_only(has_disp32 = true); // has both kinds of operands!
@@ -1604,6 +1619,85 @@
   emit_int8((unsigned char)0xA2);
 }
 
+// Opcode / Instruction                      Op /  En  64 - Bit Mode     Compat / Leg Mode Description                  Implemented
+// F2 0F 38 F0 / r       CRC32 r32, r / m8   RM        Valid             Valid             Accumulate CRC32 on r / m8.  v
+// F2 REX 0F 38 F0 / r   CRC32 r32, r / m8*  RM        Valid             N.E.              Accumulate CRC32 on r / m8.  -
+// F2 REX.W 0F 38 F0 / r CRC32 r64, r / m8   RM        Valid             N.E.              Accumulate CRC32 on r / m8.  -
+//
+// F2 0F 38 F1 / r       CRC32 r32, r / m16  RM        Valid             Valid             Accumulate CRC32 on r / m16. v
+//
+// F2 0F 38 F1 / r       CRC32 r32, r / m32  RM        Valid             Valid             Accumulate CRC32 on r / m32. v
+//
+// F2 REX.W 0F 38 F1 / r CRC32 r64, r / m64  RM        Valid             N.E.              Accumulate CRC32 on r / m64. v
+void Assembler::crc32(Register crc, Register v, int8_t sizeInBytes) {
+  assert(VM_Version::supports_sse4_2(), "");
+  int8_t w = 0x01;
+  Prefix p = Prefix_EMPTY;
+
+  emit_int8((int8_t)0xF2);
+  switch (sizeInBytes) {
+  case 1:
+    w = 0;
+    break;
+  case 2:
+  case 4:
+    break;
+  LP64_ONLY(case 8:)
+    // This instruction is not valid in 32 bits
+    // Note:
+    // http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
+    //
+    // Page B - 72   Vol. 2C says
+    // qwreg2 to qwreg            1111 0010 : 0100 1R0B : 0000 1111 : 0011 1000 : 1111 0000 : 11 qwreg1 qwreg2
+    // mem64 to qwreg             1111 0010 : 0100 1R0B : 0000 1111 : 0011 1000 : 1111 0000 : mod qwreg r / m
+    //                                                                            F0!!!
+    // while 3 - 208 Vol. 2A
+    // F2 REX.W 0F 38 F1 / r       CRC32 r64, r / m64             RM         Valid      N.E.Accumulate CRC32 on r / m64.
+    //
+    // the 0 on a last bit is reserved for a different flavor of this instruction :
+    // F2 REX.W 0F 38 F0 / r       CRC32 r64, r / m8              RM         Valid      N.E.Accumulate CRC32 on r / m8.
+    p = REX_W;
+    break;
+  default:
+    assert(0, "Unsupported value for a sizeInBytes argument");
+    break;
+  }
+  LP64_ONLY(prefix(crc, v, p);)
+  emit_int8((int8_t)0x0F);
+  emit_int8(0x38);
+  emit_int8((int8_t)(0xF0 | w));
+  emit_int8(0xC0 | ((crc->encoding() & 0x7) << 3) | (v->encoding() & 7));
+}
+
+void Assembler::crc32(Register crc, Address adr, int8_t sizeInBytes) {
+  assert(VM_Version::supports_sse4_2(), "");
+  InstructionMark im(this);
+  int8_t w = 0x01;
+  Prefix p = Prefix_EMPTY;
+
+  emit_int8((int8_t)0xF2);
+  switch (sizeInBytes) {
+  case 1:
+    w = 0;
+    break;
+  case 2:
+  case 4:
+    break;
+  LP64_ONLY(case 8:)
+    // This instruction is not valid in 32 bits
+    p = REX_W;
+    break;
+  default:
+    assert(0, "Unsupported value for a sizeInBytes argument");
+    break;
+  }
+  LP64_ONLY(prefix(crc, adr, p);)
+  emit_int8((int8_t)0x0F);
+  emit_int8(0x38);
+  emit_int8((int8_t)(0xF0 | w));
+  emit_operand(crc, adr);
+}
+
 void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith_nonds(0xE6, dst, src, VEX_SIMD_F3, /* no_mask_reg */ false, /* legacy_mode */ true);
@@ -2399,7 +2493,7 @@
 
 void Assembler::movsbl(Register dst, Register src) { // movsxb
   NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
-  int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
+  int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
   emit_int8(0x0F);
   emit_int8((unsigned char)0xBE);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -2516,7 +2610,7 @@
 
 void Assembler::movzbl(Register dst, Register src) { // movzxb
   NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
-  int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
+  int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
   emit_int8(0x0F);
   emit_int8((unsigned char)0xB6);
   emit_int8(0xC0 | encode);
@@ -2951,6 +3045,15 @@
   emit_int8(imm8);
 }
 
+void Assembler::pextrw(Register dst, XMMRegister src, int imm8) {
+  assert(VM_Version::supports_sse2(), "");
+  int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
+  emit_int8((unsigned char)0xC5);
+  emit_int8((unsigned char)(0xC0 | encode));
+  emit_int8(imm8);
+}
+
 void Assembler::pinsrd(XMMRegister dst, Register src, int imm8) {
   assert(VM_Version::supports_sse4_1(), "");
   int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, /* no_mask_reg */ true,
@@ -2969,6 +3072,15 @@
   emit_int8(imm8);
 }
 
+void Assembler::pinsrw(XMMRegister dst, Register src, int imm8) {
+  assert(VM_Version::supports_sse2(), "");
+  int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
+  emit_int8((unsigned char)0xC4);
+  emit_int8((unsigned char)(0xC0 | encode));
+  emit_int8(imm8);
+}
+
 void Assembler::pmovzxbw(XMMRegister dst, Address src) {
   assert(VM_Version::supports_sse4_1(), "");
   if (VM_Version::supports_evex()) {
@@ -3984,6 +4096,16 @@
   }
 }
 
+void Assembler::mulpd(XMMRegister dst, Address src) {
+  _instruction_uses_vl = true;
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  if (VM_Version::supports_evex()) {
+    emit_simd_arith_q(0x59, dst, src, VEX_SIMD_66);
+  } else {
+    emit_simd_arith(0x59, dst, src, VEX_SIMD_66);
+  }
+}
+
 void Assembler::mulps(XMMRegister dst, XMMRegister src) {
   _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
@@ -4172,6 +4294,26 @@
   emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_NONE, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
+void Assembler::unpckhpd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  if (VM_Version::supports_evex()) {
+    emit_simd_arith_q(0x15, dst, src, VEX_SIMD_66);
+  } else {
+    emit_simd_arith(0x15, dst, src, VEX_SIMD_66);
+  }
+}
+
+void Assembler::unpcklpd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  if (VM_Version::supports_evex()) {
+    emit_simd_arith_q(0x14, dst, src, VEX_SIMD_66);
+  } else {
+    emit_simd_arith(0x14, dst, src, VEX_SIMD_66);
+  }
+}
+
 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_avx512dq()) {
@@ -4792,8 +4934,9 @@
 }
 
 
-// AND packed integers
+// logical operations packed integers
 void Assembler::pand(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xDB, dst, src, VEX_SIMD_66);
 }
@@ -4814,6 +4957,17 @@
   emit_vex_arith(0xDB, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
+void Assembler::pandn(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  if (VM_Version::supports_evex()) {
+    emit_simd_arith_q(0xDF, dst, src, VEX_SIMD_66);
+  }
+  else {
+    emit_simd_arith(0xDF, dst, src, VEX_SIMD_66);
+  }
+}
+
 void Assembler::por(XMMRegister dst, XMMRegister src) {
   _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
@@ -6223,6 +6377,14 @@
   emit_int8((unsigned char)(0xC0 | src->encoding() << 3 | dst->encoding()));
 }
 
+// 0F A4 / r ib
+void Assembler::shldl(Register dst, Register src, int8_t imm8) {
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xA4);
+  emit_int8((unsigned char)(0xC0 | src->encoding() << 3 | dst->encoding()));
+  emit_int8(imm8);
+}
+
 void Assembler::shrdl(Register dst, Register src) {
   emit_int8(0x0F);
   emit_int8((unsigned char)0xAD);
@@ -6362,12 +6524,12 @@
   return reg_enc;
 }
 
-int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) {
+int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte) {
   if (dst_enc < 8) {
     if (src_enc >= 8) {
       prefix(REX_B);
       src_enc -= 8;
-    } else if (byteinst && src_enc >= 4) {
+    } else if ((src_is_byte && src_enc >= 4) || (dst_is_byte && dst_enc >= 4)) {
       prefix(REX);
     }
   } else {
@@ -6408,6 +6570,40 @@
   }
 }
 
+void Assembler::prefix(Register dst, Register src, Prefix p) {
+  if (src->encoding() >= 8) {
+    p = (Prefix)(p | REX_B);
+  }
+  if (dst->encoding() >= 8) {
+    p = (Prefix)( p | REX_R);
+  }
+  if (p != Prefix_EMPTY) {
+    // do not generate an empty prefix
+    prefix(p);
+  }
+}
+
+void Assembler::prefix(Register dst, Address adr, Prefix p) {
+  if (adr.base_needs_rex()) {
+    if (adr.index_needs_rex()) {
+      assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
+    } else {
+      prefix(REX_B);
+    }
+  } else {
+    if (adr.index_needs_rex()) {
+      assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
+    }
+  }
+  if (dst->encoding() >= 8) {
+    p = (Prefix)(p | REX_R);
+  }
+  if (p != Prefix_EMPTY) {
+    // do not generate an empty prefix
+    prefix(p);
+  }
+}
+
 void Assembler::prefix(Address adr) {
   if (adr.base_needs_rex()) {
     if (adr.index_needs_rex()) {
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -506,7 +506,8 @@
 
     VEX_3bytes = 0xC4,
     VEX_2bytes = 0xC5,
-    EVEX_4bytes = 0x62
+    EVEX_4bytes = 0x62,
+    Prefix_EMPTY = 0x0
   };
 
   enum VexPrefix {
@@ -535,7 +536,8 @@
     VEX_OPCODE_NONE  = 0x0,
     VEX_OPCODE_0F    = 0x1,
     VEX_OPCODE_0F_38 = 0x2,
-    VEX_OPCODE_0F_3A = 0x3
+    VEX_OPCODE_0F_3A = 0x3,
+    VEX_OPCODE_MASK  = 0x1F
   };
 
   enum AvxVectorLen {
@@ -611,10 +613,15 @@
   int prefix_and_encode(int reg_enc, bool byteinst = false);
   int prefixq_and_encode(int reg_enc);
 
-  int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false);
+  int prefix_and_encode(int dst_enc, int src_enc) {
+    return prefix_and_encode(dst_enc, false, src_enc, false);
+  }
+  int prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte);
   int prefixq_and_encode(int dst_enc, int src_enc);
 
   void prefix(Register reg);
+  void prefix(Register dst, Register src, Prefix p);
+  void prefix(Register dst, Address adr, Prefix p);
   void prefix(Address adr);
   void prefixq(Address adr);
 
@@ -1177,6 +1184,10 @@
   // Identify processor type and features
   void cpuid();
 
+  // CRC32C
+  void crc32(Register crc, Register v, int8_t sizeInBytes);
+  void crc32(Register crc, Address adr, int8_t sizeInBytes);
+
   // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
   void cvtsd2ss(XMMRegister dst, XMMRegister src);
   void cvtsd2ss(XMMRegister dst, Address src);
@@ -1672,10 +1683,14 @@
   // SSE 4.1 extract
   void pextrd(Register dst, XMMRegister src, int imm8);
   void pextrq(Register dst, XMMRegister src, int imm8);
+  // SSE 2 extract
+  void pextrw(Register dst, XMMRegister src, int imm8);
 
   // SSE 4.1 insert
   void pinsrd(XMMRegister dst, Register src, int imm8);
   void pinsrq(XMMRegister dst, Register src, int imm8);
+  // SSE 2 insert
+  void pinsrw(XMMRegister dst, Register src, int imm8);
 
   // SSE4.1 packed move
   void pmovzxbw(XMMRegister dst, XMMRegister src);
@@ -1783,6 +1798,7 @@
   void setb(Condition cc, Register dst);
 
   void shldl(Register dst, Register src);
+  void shldl(Register dst, Register src, int8_t imm8);
 
   void shll(Register dst, int imm8);
   void shll(Register dst);
@@ -1925,6 +1941,7 @@
 
   // Multiply Packed Floating-Point Values
   void mulpd(XMMRegister dst, XMMRegister src);
+  void mulpd(XMMRegister dst, Address src);
   void mulps(XMMRegister dst, XMMRegister src);
   void vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
   void vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
@@ -1951,6 +1968,9 @@
   void vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
   void vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
 
+  void unpckhpd(XMMRegister dst, XMMRegister src);
+  void unpcklpd(XMMRegister dst, XMMRegister src);
+
   // Bitwise Logical XOR of Packed Floating-Point Values
   void xorpd(XMMRegister dst, XMMRegister src);
   void xorps(XMMRegister dst, XMMRegister src);
@@ -2046,6 +2066,9 @@
   void vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
   void vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
 
+  // Andn packed integers
+  void pandn(XMMRegister dst, XMMRegister src);
+
   // Or packed integers
   void por(XMMRegister dst, XMMRegister src);
   void vpor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -33,10 +33,12 @@
 inline int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { return reg_enc; }
 inline int Assembler::prefixq_and_encode(int reg_enc) { return reg_enc; }
 
-inline int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { return dst_enc << 3 | src_enc; }
+inline int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte) { return dst_enc << 3 | src_enc; }
 inline int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { return dst_enc << 3 | src_enc; }
 
 inline void Assembler::prefix(Register reg) {}
+inline void Assembler::prefix(Register dst, Register src, Prefix p) {}
+inline void Assembler::prefix(Register dst, Address adr, Prefix p) {}
 inline void Assembler::prefix(Address adr) {}
 inline void Assembler::prefixq(Address adr) {}
 
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -2457,9 +2457,6 @@
         // Should consider not saving rbx, if not necessary
         __ trigfunc('t', op->as_Op2()->fpu_stack_size());
         break;
-      case lir_exp :
-        __ exp_with_fallback(op->as_Op2()->fpu_stack_size());
-        break;
       case lir_pow :
         __ pow_with_fallback(op->as_Op2()->fpu_stack_size());
         break;
@@ -2684,7 +2681,7 @@
 #endif // _LP64
         }
       } else {
-        fatal(err_msg("unexpected type: %s", basictype_to_str(c->type())));
+        fatal("unexpected type: %s", basictype_to_str(c->type()));
       }
       // cpu register - address
     } else if (opr2->is_address()) {
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -808,6 +808,12 @@
 
 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
   assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
+
+  if (x->id() == vmIntrinsics::_dexp) {
+    do_ExpIntrinsic(x);
+    return;
+  }
+
   LIRItem value(x->argument_at(0), this);
 
   bool use_fpu = false;
@@ -818,7 +824,6 @@
       case vmIntrinsics::_dtan:
       case vmIntrinsics::_dlog:
       case vmIntrinsics::_dlog10:
-      case vmIntrinsics::_dexp:
       case vmIntrinsics::_dpow:
         use_fpu = true;
     }
@@ -870,7 +875,6 @@
     case vmIntrinsics::_dtan:   __ tan  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dlog:   __ log  (calc_input, calc_result, tmp1);                    break;
     case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1);                    break;
-    case vmIntrinsics::_dexp:   __ exp  (calc_input, calc_result,              tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
     case vmIntrinsics::_dpow:   __ pow  (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
     default:                    ShouldNotReachHere();
   }
@@ -880,6 +884,32 @@
   }
 }
 
+void LIRGenerator::do_ExpIntrinsic(Intrinsic* x) {
+  LIRItem value(x->argument_at(0), this);
+  value.set_destroys_register();
+
+  LIR_Opr calc_result = rlock_result(x);
+  LIR_Opr result_reg = result_register_for(x->type());
+
+  BasicTypeList signature(1);
+  signature.append(T_DOUBLE);
+  CallingConvention* cc = frame_map()->c_calling_convention(&signature);
+
+  value.load_item_force(cc->at(0));
+
+#ifndef _LP64
+  LIR_Opr tmp = FrameMap::fpu0_double_opr;
+  result_reg = tmp;
+  if (VM_Version::supports_sse2()) {
+    __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
+  } else {
+    __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());
+  }
+#else
+  __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
+#endif
+  __ move(result_reg, calc_result);
+}
 
 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
   assert(x->number_of_arguments() == 5, "wrong type");
--- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -814,8 +814,7 @@
 
     case lir_tan:
     case lir_sin:
-    case lir_cos:
-    case lir_exp: {
+    case lir_cos: {
       // sin, cos and exp need two temporary fpu stack slots, so there are two temporary
       // registers (stored in right and temp of the operation).
       // the stack allocator must guarantee that the stack slots are really free,
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -48,11 +48,11 @@
 
 define_pd_global(intx, OnStackReplacePercentage,     140);
 define_pd_global(intx, ConditionalMoveLimit,         3);
-define_pd_global(intx, FLOATPRESSURE,                6);
 define_pd_global(intx, FreqInlineSize,               325);
 define_pd_global(intx, MinJumpTableSize,             10);
 #ifdef AMD64
 define_pd_global(intx, INTPRESSURE,                  13);
+define_pd_global(intx, FLOATPRESSURE,                14);
 define_pd_global(intx, InteriorEntryAlignment,       16);
 define_pd_global(size_t, NewSizeThreadIncrease,      ScaleForWordSize(4*K));
 define_pd_global(intx, LoopUnrollLimit,              60);
@@ -64,6 +64,7 @@
 define_pd_global(uint64_t, MaxRAM,                   128ULL*G);
 #else
 define_pd_global(intx, INTPRESSURE,                  6);
+define_pd_global(intx, FLOATPRESSURE,                6);
 define_pd_global(intx, InteriorEntryAlignment,       4);
 define_pd_global(size_t, NewSizeThreadIncrease,      4*K);
 define_pd_global(intx, LoopUnrollLimit,              50);     // Design center runs on 1.3.1
@@ -82,6 +83,7 @@
 define_pd_global(bool, UseCISCSpill,                 true);
 define_pd_global(bool, OptoScheduling,               false);
 define_pd_global(bool, OptoBundling,                 false);
+define_pd_global(bool, OptoRegScheduling,            true);
 
 define_pd_global(intx, ReservedCodeCacheSize,        48*M);
 define_pd_global(intx, NonProfiledCodeHeapSize,      21*M);
--- a/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -50,13 +50,15 @@
 // ----------------------------------------------------------------------------
 
 #define __ _masm.
-address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {
+address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
   // Stub is fixed up when the corresponding call is converted from
   // calling compiled code to calling interpreted code.
   // movq rbx, 0
   // jmp -5 # to self
 
-  address mark = cbuf.insts_mark();  // Get mark within main instrs section.
+  if (mark == NULL) {
+    mark = cbuf.insts_mark();  // Get mark within main instrs section.
+  }
 
   // Note that the code buffer's insts_mark is always relative to insts.
   // That's why we must use the macroassembler to generate a stub.
@@ -73,6 +75,8 @@
   // This is recognized as unresolved by relocs/nativeinst/ic code.
   __ jump(RuntimeAddress(__ pc()));
 
+  assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size");
+
   // Update current stubs pointer and restore insts_end.
   __ end_a_stub();
   return base;
@@ -104,10 +108,15 @@
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
 
-  assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
+#ifdef ASSERT
+  // read the value once
+  intptr_t data = method_holder->data();
+  address destination = jump->jump_destination();
+  assert(data == 0 || data == (intptr_t)callee(),
          "a) MT-unsafe modification of inline cache");
-  assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,
+  assert(destination == (address)-1 || destination == entry,
          "b) MT-unsafe modification of inline cache");
+#endif
 
   // Update stub.
   method_holder->set_data((intptr_t)callee());
@@ -124,11 +133,12 @@
   assert(stub != NULL, "stub not found");
   // Creation also verifies the object.
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
-  NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
   method_holder->set_data(0);
+  NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
   jump->set_jump_destination((address)-1);
 }
 
+
 //-----------------------------------------------------------------------------
 // Non-product mode code
 #ifndef PRODUCT
@@ -150,5 +160,4 @@
   // Verify state.
   assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
 }
-
 #endif // !PRODUCT
--- a/hotspot/src/cpu/x86/vm/cppInterpreterGenerator_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/cppInterpreterGenerator_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,6 +29,7 @@
 
   void generate_more_monitors();
   void generate_deopt_handling();
+  void lock_method(void);
   address generate_interpreter_frame_manager(bool synchronized); // C++ interpreter only
   void generate_compute_interpreter_state(const Register state,
                                           const Register prev_state,
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -741,7 +741,7 @@
 // Find preallocated  monitor and lock method (C++ interpreter)
 // rbx - Method*
 //
-void InterpreterGenerator::lock_method(void) {
+void CppInterpreterGenerator::lock_method() {
   // assumes state == rsi/r13 == pointer to current interpreterState
   // minimally destroys rax, rdx|c_rarg1, rdi
   //
@@ -807,7 +807,7 @@
 
   // If G1 is not enabled then attempt to go through the accessor entry point
   // Reference.get is an accessor
-  return generate_jump_to_normal_entry();
+  return NULL;
 }
 
 //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/x86/vm/crc32c.h	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2015, 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.
+*
+*/
+
+enum {
+  // S. Gueron / Information Processing Letters 112 (2012) 184
+  // shows than anything above 6K and below 32K is a good choice
+  // 32K does not deliver any further performance gains
+  // 6K=8*256 (*3 as we compute 3 blocks together)
+  //
+  // Thus selecting the smallest value so it could apply to the largest number
+  // of buffer sizes.
+  CRC32C_HIGH = 8 * 256,
+
+  // empirical
+  // based on ubench study using methodology described in
+  // V. Gopal et al. / Fast CRC Computation for iSCSI Polynomial Using CRC32 Instruction April 2011 8
+  //
+  // arbitrary value between 27 and 256
+  CRC32C_MIDDLE = 8 * 86,
+
+  // V. Gopal et al. / Fast CRC Computation for iSCSI Polynomial Using CRC32 Instruction April 2011 9
+  // shows that 240 and 1024 are equally good choices as the 216==8*27
+  //
+  // Selecting the smallest value which resulted in a significant performance improvement over
+  // sequential version
+  CRC32C_LOW = 8 * 27,
+
+  CRC32C_NUM_ChunkSizeInBytes = 3,
+
+  // We need to compute powers of 64N and 128N for each "chunk" size
+  CRC32C_NUM_PRECOMPUTED_CONSTANTS = ( 2 * CRC32C_NUM_ChunkSizeInBytes )
+};
+// Notes:
+// 1. Why we need to choose a "chunk" approach?
+// Overhead of computing a powers and powers of for an arbitrary buffer of size N is significant
+// (implementation approaches a library perf.)
+// 2. Why only 3 "chunks"?
+// Performance experiments results showed that a HIGH+LOW was not delivering a stable speedup
+// curve.
+//
+// Disclaimer:
+// If you ever decide to increase/decrease number of "chunks" be sure to modify
+// a) constants table generation (hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp)
+// b) constant fetch from that table (macroAssembler_x86.cpp)
+// c) unrolled for loop (macroAssembler_x86.cpp)
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -48,8 +48,6 @@
 }
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Profiling/safepoint support
 
 bool frame::safe_for_sender(JavaThread *thread) {
@@ -280,7 +278,7 @@
   address* pc_addr = &(((address*) sp())[-1]);
   if (TracePcPatching) {
     tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]",
-                  pc_addr, *pc_addr, pc);
+                  p2i(pc_addr), p2i(*pc_addr), p2i(pc));
   }
   // Either the return address is the original one or we are going to
   // patch in the same address that's already there.
@@ -458,11 +456,11 @@
   // This is the sp before any possible extension (adapter/locals).
   intptr_t* unextended_sp = interpreter_frame_sender_sp();
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   if (map->update_map()) {
     update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
   }
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 
   return frame(sender_sp, unextended_sp, link(), sender_pc());
 }
@@ -683,10 +681,19 @@
     DESCRIBE_FP_OFFSET(interpreter_frame_locals);
     DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
     DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
-#endif
+#ifdef AMD64
+  } else if (is_entry_frame()) {
+    // This could be more descriptive if we use the enum in
+    // stubGenerator to map to real names but it's most important to
+    // claim these frame slots so the error checking works.
+    for (int i = 0; i < entry_frame_after_call_words; i++) {
+      values.describe(frame_no, fp() - i, err_msg("call_stub word fp - %d", i));
+    }
+#endif // AMD64
   }
+#endif
 }
-#endif
+#endif // !PRODUCT
 
 intptr_t *frame::initial_deoptimization_info() {
   // used to reset the saved FP
--- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -78,7 +78,11 @@
     assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod");
     _deopt_state = is_deoptimized;
   } else {
-    _deopt_state = not_deoptimized;
+    if (_cb->is_deoptimization_stub()) {
+      _deopt_state = is_deoptimized;
+    } else {
+      _deopt_state = not_deoptimized;
+    }
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -46,7 +46,7 @@
 // the the vep is aligned at CodeEntryAlignment whereas c2 only aligns
 // the uep and the vep doesn't get real alignment but just slops on by
 // only assured that the entry instruction meets the 5 byte size requirement.
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
 define_pd_global(intx, CodeEntryAlignment,       32);
 #else
 define_pd_global(intx, CodeEntryAlignment,       16);
@@ -91,6 +91,7 @@
                                                                             \
   product(intx, UseAVX, 99,                                                 \
           "Highest supported AVX instructions set on x86/x64")              \
+          range(0, 99)                                                      \
                                                                             \
   product(bool, UseCLMUL, false,                                            \
           "Control whether CLMUL instructions can be used on x86/x64")      \
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -40,6 +40,11 @@
 
 // Implementation of InterpreterMacroAssembler
 
+void InterpreterMacroAssembler::jump_to_entry(address entry) {
+  assert(entry, "Entry must have been generated by now");
+  jump(RuntimeAddress(entry));
+}
+
 #ifndef CC_INTERP
 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
   Label update, next, none;
@@ -1497,13 +1502,39 @@
     bind(skip_receiver_profile);
 
     // The method data pointer needs to be updated to reflect the new target.
+#if INCLUDE_JVMCI
+    if (MethodProfileWidth == 0) {
+      update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size()));
+    }
+#else // INCLUDE_JVMCI
     update_mdp_by_constant(mdp,
                            in_bytes(VirtualCallData::
                                     virtual_call_data_size()));
+#endif // INCLUDE_JVMCI
     bind(profile_continue);
   }
 }
 
+#if INCLUDE_JVMCI
+void InterpreterMacroAssembler::profile_called_method(Register method, Register mdp, Register reg2) {
+  assert_different_registers(method, mdp, reg2);
+  if (ProfileInterpreter && MethodProfileWidth > 0) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(mdp, profile_continue);
+
+    Label done;
+    record_item_in_profile_helper(method, mdp, reg2, 0, done, MethodProfileWidth,
+      &VirtualCallData::method_offset, &VirtualCallData::method_count_offset, in_bytes(VirtualCallData::nonprofiled_receiver_count_offset()));
+    bind(done);
+
+    update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size()));
+    bind(profile_continue);
+  }
+}
+#endif // INCLUDE_JVMCI
+
 // This routine creates a state machine for updating the multi-row
 // type profile at a virtual call site (or other type-sensitive bytecode).
 // The machine visits each row (of receiver/count) until the receiver type
@@ -1523,14 +1554,36 @@
     if (is_virtual_call) {
       increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
     }
-    return;
-  }
+#if INCLUDE_JVMCI
+    else if (EnableJVMCI) {
+      increment_mdp_data_at(mdp, in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()));
+    }
+#endif // INCLUDE_JVMCI
+  } else {
+    int non_profiled_offset = -1;
+    if (is_virtual_call) {
+      non_profiled_offset = in_bytes(CounterData::count_offset());
+    }
+#if INCLUDE_JVMCI
+    else if (EnableJVMCI) {
+      non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset());
+    }
+#endif // INCLUDE_JVMCI
 
-  int last_row = VirtualCallData::row_limit() - 1;
+    record_item_in_profile_helper(receiver, mdp, reg2, 0, done, TypeProfileWidth,
+        &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset);
+  }
+}
+
+void InterpreterMacroAssembler::record_item_in_profile_helper(Register item, Register mdp,
+                                        Register reg2, int start_row, Label& done, int total_rows,
+                                        OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn,
+                                        int non_profiled_offset) {
+  int last_row = total_rows - 1;
   assert(start_row <= last_row, "must be work left to do");
-  // Test this row for both the receiver and for null.
+  // Test this row for both the item and for null.
   // Take any of three different outcomes:
-  //   1. found receiver => increment count and goto done
+  //   1. found item => increment count and goto done
   //   2. found null => keep looking for case 1, maybe allocate this cell
   //   3. found something else => keep looking for cases 1 and 2
   // Case 3 is handled by a recursive call.
@@ -1538,30 +1591,30 @@
     Label next_test;
     bool test_for_null_also = (row == start_row);
 
-    // See if the receiver is receiver[n].
-    int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));
-    test_mdp_data_at(mdp, recvr_offset, receiver,
+    // See if the item is item[n].
+    int item_offset = in_bytes(item_offset_fn(row));
+    test_mdp_data_at(mdp, item_offset, item,
                      (test_for_null_also ? reg2 : noreg),
                      next_test);
-    // (Reg2 now contains the receiver from the CallData.)
+    // (Reg2 now contains the item from the CallData.)
 
-    // The receiver is receiver[n].  Increment count[n].
-    int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
+    // The item is item[n].  Increment count[n].
+    int count_offset = in_bytes(item_count_offset_fn(row));
     increment_mdp_data_at(mdp, count_offset);
     jmp(done);
     bind(next_test);
 
     if (test_for_null_also) {
       Label found_null;
-      // Failed the equality check on receiver[n]...  Test for null.
+      // Failed the equality check on item[n]...  Test for null.
       testptr(reg2, reg2);
       if (start_row == last_row) {
         // The only thing left to do is handle the null case.
-        if (is_virtual_call) {
+        if (non_profiled_offset >= 0) {
           jccb(Assembler::zero, found_null);
-          // Receiver did not match any saved receiver and there is no empty row for it.
+          // Item did not match any saved item and there is no empty row for it.
           // Increment total counter to indicate polymorphic case.
-          increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+          increment_mdp_data_at(mdp, non_profiled_offset);
           jmp(done);
           bind(found_null);
         } else {
@@ -1573,21 +1626,22 @@
       jcc(Assembler::zero, found_null);
 
       // Put all the "Case 3" tests here.
-      record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
+      record_item_in_profile_helper(item, mdp, reg2, start_row + 1, done, total_rows,
+        item_offset_fn, item_count_offset_fn, non_profiled_offset);
 
-      // Found a null.  Keep searching for a matching receiver,
+      // Found a null.  Keep searching for a matching item,
       // but remember that this is an empty (unused) slot.
       bind(found_null);
     }
   }
 
-  // In the fall-through case, we found no matching receiver, but we
-  // observed the receiver[start_row] is NULL.
+  // In the fall-through case, we found no matching item, but we
+  // observed the item[start_row] is NULL.
 
-  // Fill in the receiver field and increment the count.
-  int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));
-  set_mdp_data_at(mdp, recvr_offset, receiver);
-  int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
+  // Fill in the item field and increment the count.
+  int item_offset = in_bytes(item_offset_fn(start_row));
+  set_mdp_data_at(mdp, item_offset, item);
+  int count_offset = in_bytes(item_count_offset_fn(start_row));
   movl(reg2, DataLayout::counter_increment);
   set_mdp_data_at(mdp, count_offset, reg2);
   if (start_row > 0) {
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -32,6 +32,7 @@
 
 // This file specializes the assember with interpreter-specific macros
 
+typedef ByteSize (*OffsetFunction)(uint);
 
 class InterpreterMacroAssembler: public MacroAssembler {
 
@@ -60,6 +61,8 @@
     _locals_register(LP64_ONLY(r14) NOT_LP64(rdi)),
     _bcp_register(LP64_ONLY(r13) NOT_LP64(rsi)) {}
 
+  void jump_to_entry(address entry);
+
   void load_earlyret_value(TosState state);
 
 #ifdef CC_INTERP
@@ -249,6 +252,10 @@
   void record_klass_in_profile_helper(Register receiver, Register mdp,
                                       Register reg2, int start_row,
                                       Label& done, bool is_virtual_call);
+  void record_item_in_profile_helper(Register item, Register mdp,
+                                     Register reg2, int start_row, Label& done, int total_rows,
+                                     OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn,
+                                     int non_profiled_offset);
 
   void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
   void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp);
@@ -262,6 +269,7 @@
   void profile_virtual_call(Register receiver, Register mdp,
                             Register scratch2,
                             bool receiver_can_be_null = false);
+  void profile_called_method(Register method, Register mdp, Register reg2) NOT_JVMCI_RETURN;
   void profile_ret(Register return_bci, Register mdp);
   void profile_null_seen(Register mdp);
   void profile_typecheck(Register mdp, Register klass, Register scratch);
--- a/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,17 +31,6 @@
 
 #define __ _masm->
 
-// Jump into normal path for accessor and empty entry to jump to normal entry
-// The "fast" optimization don't update compilation count therefore can disable inlining
-// for these functions that should be inlined.
-address InterpreterGenerator::generate_jump_to_normal_entry(void) {
-  address entry_point = __ pc();
-
-  assert(Interpreter::entry_for_kind(Interpreter::zerolocals) != NULL, "should already be generated");
-  __ jump(RuntimeAddress(Interpreter::entry_for_kind(Interpreter::zerolocals)));
-  return entry_point;
-}
-
 // Abstract method entry
 // Attempt to execute abstract method. Throw exception
 address InterpreterGenerator::generate_abstract_entry(void) {
--- a/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,19 +36,18 @@
   address generate_native_entry(bool synchronized);
   address generate_abstract_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
-  address generate_jump_to_normal_entry(void);
-  address generate_accessor_entry(void) { return generate_jump_to_normal_entry(); }
-  address generate_empty_entry(void) { return generate_jump_to_normal_entry(); }
+  address generate_accessor_entry(void) { return NULL; }
+  address generate_empty_entry(void) { return NULL; }
   address generate_Reference_get_entry();
   address generate_CRC32_update_entry();
   address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind);
+  address generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind);
 #ifndef _LP64
   address generate_Float_intBitsToFloat_entry();
   address generate_Float_floatToRawIntBits_entry();
   address generate_Double_longBitsToDouble_entry();
   address generate_Double_doubleToRawLongBits_entry();
 #endif
-  void lock_method(void);
   void generate_stack_overflow_check(void);
 
   void generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue);
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -151,11 +151,15 @@
       __ pop_fTOS();
       break;
     case Interpreter::java_lang_math_exp:
-      __ exp_with_fallback(0);
-      // Store to stack to convert 80bit precision back to 64bits
-      __ push_fTOS();
-      __ pop_fTOS();
-      break;
+      __ subptr(rsp, 2*wordSize);
+      __ fstp_d(Address(rsp, 0));
+      if (VM_Version::supports_sse2()) {
+        __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
+      } else {
+        __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dexp)));
+      }
+      __ addptr(rsp, 2*wordSize);
+    break;
     default                              :
         ShouldNotReachHere();
   }
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -52,8 +52,6 @@
 
 #define __ _masm->
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef _WIN64
 address AbstractInterpreterGenerator::generate_slow_signature_handler() {
   address entry = __ pc();
@@ -252,6 +250,9 @@
 
   if (kind == Interpreter::java_lang_math_sqrt) {
     __ sqrtsd(xmm0, Address(rsp, wordSize));
+  } else if (kind == Interpreter::java_lang_math_exp) {
+    __ movdbl(xmm0, Address(rsp, wordSize));
+    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
   } else {
     __ fld_d(Address(rsp, wordSize));
     switch (kind) {
@@ -278,9 +279,6 @@
                                               // empty stack slot)
           __ pow_with_fallback(0);
           break;
-      case Interpreter::java_lang_math_exp:
-          __ exp_with_fallback(0);
-           break;
       default                              :
           ShouldNotReachHere();
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2013, 2015, 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 "compiler/disassembler.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "jvmci/jvmciCodeInstaller.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "asm/register.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "code/vmreg.hpp"
+#include "vmreg_x86.inline.hpp"
+
+jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  if (inst->is_call() || inst->is_jump()) {
+    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
+    return (pc_offset + NativeCall::instruction_size);
+  } else if (inst->is_mov_literal64()) {
+    // mov+call instruction pair
+    jint offset = pc_offset + NativeMovConstReg::instruction_size;
+    u_char* call = (u_char*) (_instructions->start() + offset);
+    if (call[0] == Assembler::REX_B) {
+      offset += 1; /* prefix byte for extended register R8-R15 */
+      call++;
+    }
+    assert(call[0] == 0xFF, "expected call");
+    offset += 2; /* opcode byte + modrm byte */
+    return (offset);
+  } else if (inst->is_call_reg()) {
+    // the inlined vtable stub contains a "call register" instruction
+    assert(method != NULL, "only valid for virtual calls");
+    return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
+  } else if (inst->is_cond_jump()) {
+    address pc = (address) (inst);
+    return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc);
+  } else {
+    fatal("unsupported type of instruction for call site");
+    return 0;
+  }
+}
+
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
+  address pc = _instructions->start() + pc_offset;
+  Handle obj = HotSpotObjectConstantImpl::object(constant);
+  jobject value = JNIHandles::make_local(obj());
+  if (HotSpotObjectConstantImpl::compressed(constant)) {
+#ifdef _LP64
+    address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
+    int oop_index = _oop_recorder->find_index(value);
+    _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
+    TRACE_jvmci_3("relocating (narrow oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
+#else
+    fatal("compressed oop on 32bit");
+#endif
+  } else {
+    address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
+    *((jobject*) operand) = value;
+    _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+    TRACE_jvmci_3("relocating (oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
+  }
+}
+
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
+  address pc = _instructions->start() + pc_offset;
+
+  address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
+  address next_instruction = Assembler::locate_next_instruction(pc);
+  address dest = _constants->start() + data_offset;
+
+  long disp = dest - next_instruction;
+  assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+  *((jint*) operand) = (jint) disp;
+
+  _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+  TRACE_jvmci_3("relocating at " PTR_FORMAT "/" PTR_FORMAT " with destination at " PTR_FORMAT " (%d)", p2i(pc), p2i(operand), p2i(dest), data_offset);
+}
+
+void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  if (cb->is_nmethod()) {
+    nmethod* nm = (nmethod*) cb;
+    nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
+  } else {
+    nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
+  }
+  _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+}
+
+void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  address pc = (address) inst;
+  if (inst->is_call()) {
+    // NOTE: for call without a mov, the offset must fit a 32-bit immediate
+    //       see also CompilerToVM.getMaxCallTargetOffset()
+    NativeCall* call = nativeCall_at(pc);
+    call->set_destination((address) foreign_call_destination);
+    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
+  } else if (inst->is_mov_literal64()) {
+    NativeMovConstReg* mov = nativeMovConstReg_at(pc);
+    mov->set_data((intptr_t) foreign_call_destination);
+    _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
+  } else if (inst->is_jump()) {
+    NativeJump* jump = nativeJump_at(pc);
+    jump->set_jump_destination((address) foreign_call_destination);
+    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
+  } else if (inst->is_cond_jump()) {
+    address old_dest = nativeGeneralJump_at(pc)->jump_destination();
+    address disp = Assembler::locate_operand(pc, Assembler::call32_operand);
+    *(jint*) disp += ((address) foreign_call_destination) - old_dest;
+    _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand);
+  } else {
+    fatal("unsupported relocation for foreign call");
+  }
+
+  TRACE_jvmci_3("relocating (foreign call)  at " PTR_FORMAT, p2i(inst));
+}
+
+void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
+#ifdef ASSERT
+  Method* method = NULL;
+  // we need to check, this might also be an unresolved method
+  if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
+    method = getMethodFromHotSpotMethod(hotspot_method);
+  }
+#endif
+  switch (_next_call_type) {
+    case INLINE_INVOKE:
+      break;
+    case INVOKEVIRTUAL:
+    case INVOKEINTERFACE: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
+
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                                             virtual_call_Relocation::spec(_invoke_mark_pc),
+                                             Assembler::call32_operand);
+      break;
+    }
+    case INVOKESTATIC: {
+      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
+
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                                             relocInfo::static_call_type, Assembler::call32_operand);
+      break;
+    }
+    case INVOKESPECIAL: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                              relocInfo::opt_virtual_call_type, Assembler::call32_operand);
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+static void relocate_poll_near(address pc) {
+  NativeInstruction* ni = nativeInstruction_at(pc);
+  int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand);
+  int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
+  intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
+  *disp = (int32_t)new_disp;
+}
+
+
+void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
+  switch (mark) {
+    case POLL_NEAR: {
+      relocate_poll_near(pc);
+      _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand);
+      break;
+    }
+    case POLL_FAR:
+      // This is a load from a register so there is no relocatable operand.
+      // We just have to ensure that the format is not disp32_operand
+      // so that poll_Relocation::fix_relocation_after_move does the right
+      // thing (i.e. ignores this relocation record)
+      _instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand);
+      break;
+    case POLL_RETURN_NEAR: {
+      relocate_poll_near(pc);
+      _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::disp32_operand);
+      break;
+    }
+    case POLL_RETURN_FAR:
+      // see comment above for POLL_FAR
+      _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand);
+      break;
+    default:
+      fatal("invalid mark value");
+      break;
+  }
+}
+
+// convert JVMCI register indices (as used in oop maps) to HotSpot registers
+VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg) {
+  if (jvmci_reg < RegisterImpl::number_of_registers) {
+    return as_Register(jvmci_reg)->as_VMReg();
+  } else {
+    jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers;
+    if (floatRegisterNumber < XMMRegisterImpl::number_of_registers) {
+      return as_XMMRegister(floatRegisterNumber)->as_VMReg();
+    }
+    ShouldNotReachHere();
+    return NULL;
+  }
+}
+
+bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) {
+  return !(hotspotRegister->is_FloatRegister() || hotspotRegister->is_XMMRegister());
+}
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -45,6 +45,7 @@
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc/g1/heapRegion.hpp"
 #endif // INCLUDE_ALL_GCS
+#include "crc32c.h"
 
 #ifdef PRODUCT
 #define BLOCK_COMMENT(str) /* nothing */
@@ -56,8 +57,6 @@
 
 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef ASSERT
 bool AbstractAssembler::pd_check_instruction_mark() { return true; }
 #endif
@@ -417,7 +416,7 @@
     ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg);
   }
   // Don't assert holding the ttyLock
-    assert(false, err_msg("DEBUG MESSAGE: %s", msg));
+    assert(false, "DEBUG MESSAGE: %s", msg);
   ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
 }
 
@@ -883,7 +882,7 @@
     ttyLocker ttyl;
     ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n",
                     msg);
-    assert(false, err_msg("DEBUG MESSAGE: %s", msg));
+    assert(false, "DEBUG MESSAGE: %s", msg);
   }
 }
 
@@ -2888,7 +2887,7 @@
 }
 
 // !defined(COMPILER2) is because of stupid core builds
-#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2)
+#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) || INCLUDE_JVMCI
 void MacroAssembler::empty_FPU_stack() {
   if (VM_Version::supports_mmx()) {
     emms();
@@ -2896,7 +2895,7 @@
     for (int i = 8; i-- > 0; ) ffree(i);
   }
 }
-#endif // !LP64 || C1 || !C2
+#endif // !LP64 || C1 || !C2 || INCLUDE_JVMCI
 
 
 // Defines obj, preserves var_size_in_bytes
@@ -3032,6 +3031,15 @@
   Assembler::fldcw(as_Address(src));
 }
 
+void MacroAssembler::mulpd(XMMRegister dst, AddressLiteral src) {
+  if (reachable(src)) {
+    Assembler::mulpd(dst, as_Address(src));
+  } else {
+    lea(rscratch1, src);
+    Assembler::mulpd(dst, Address(rscratch1, 0));
+  }
+}
+
 void MacroAssembler::pow_exp_core_encoding() {
   // kills rax, rcx, rdx
   subptr(rsp,sizeof(jdouble));
@@ -3104,19 +3112,7 @@
   BLOCK_COMMENT("} fast_pow");
 }
 
-void MacroAssembler::fast_exp() {
-  // computes exp(X) = 2^(X * log2(e))
-  // if fast computation is not possible, result is NaN. Requires
-  // fallback from user of this macro.
-  // increase precision for intermediate steps of the computation
-  increase_precision();
-  fldl2e();                // Stack: log2(e) X ...
-  fmulp(1);                // Stack: (X*log2(e)) ...
-  pow_exp_core_encoding(); // Stack: exp(X) ...
-  restore_precision();
-}
-
-void MacroAssembler::pow_or_exp(bool is_exp, int num_fpu_regs_in_use) {
+void MacroAssembler::pow_or_exp(int num_fpu_regs_in_use) {
   // kills rax, rcx, rdx
   // pow and exp needs 2 extra registers on the fpu stack.
   Label slow_case, done;
@@ -3128,182 +3124,164 @@
   Register tmp2 = rax;
   Register tmp3 = rcx;
 
-  if (is_exp) {
-    // Stack: X
-    fld_s(0);                   // duplicate argument for runtime call. Stack: X X
-    fast_exp();                 // Stack: exp(X) X
-    fcmp(tmp, 0, false, false); // Stack: exp(X) X
-    // exp(X) not equal to itself: exp(X) is NaN go to slow case.
-    jcc(Assembler::parity, slow_case);
-    // get rid of duplicate argument. Stack: exp(X)
-    if (num_fpu_regs_in_use > 0) {
-      fxch();
-      fpop();
-    } else {
-      ffree(1);
-    }
-    jmp(done);
-  } else {
-    // Stack: X Y
-    Label x_negative, y_not_2;
-
-    static double two = 2.0;
-    ExternalAddress two_addr((address)&two);
-
-    // constant maybe too far on 64 bit
-    lea(tmp2, two_addr);
-    fld_d(Address(tmp2, 0));    // Stack: 2 X Y
-    fcmp(tmp, 2, true, false);  // Stack: X Y
-    jcc(Assembler::parity, y_not_2);
-    jcc(Assembler::notEqual, y_not_2);
-
-    fxch(); fpop();             // Stack: X
-    fmul(0);                    // Stack: X*X
-
-    jmp(done);
-
-    bind(y_not_2);
-
-    fldz();                     // Stack: 0 X Y
-    fcmp(tmp, 1, true, false);  // Stack: X Y
-    jcc(Assembler::above, x_negative);
-
-    // X >= 0
-
-    fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
-    fld_s(1);                   // Stack: X Y X Y
-    fast_pow();                 // Stack: X^Y X Y
-    fcmp(tmp, 0, false, false); // Stack: X^Y X Y
-    // X^Y not equal to itself: X^Y is NaN go to slow case.
-    jcc(Assembler::parity, slow_case);
-    // get rid of duplicate arguments. Stack: X^Y
-    if (num_fpu_regs_in_use > 0) {
-      fxch(); fpop();
-      fxch(); fpop();
-    } else {
-      ffree(2);
-      ffree(1);
-    }
-    jmp(done);
-
-    // X <= 0
-    bind(x_negative);
-
-    fld_s(1);                   // Stack: Y X Y
-    frndint();                  // Stack: int(Y) X Y
-    fcmp(tmp, 2, false, false); // Stack: int(Y) X Y
-    jcc(Assembler::notEqual, slow_case);
-
-    subptr(rsp, 8);
-
-    // For X^Y, when X < 0, Y has to be an integer and the final
-    // result depends on whether it's odd or even. We just checked
-    // that int(Y) == Y.  We move int(Y) to gp registers as a 64 bit
-    // integer to test its parity. If int(Y) is huge and doesn't fit
-    // in the 64 bit integer range, the integer indefinite value will
-    // end up in the gp registers. Huge numbers are all even, the
-    // integer indefinite number is even so it's fine.
+  // Stack: X Y
+  Label x_negative, y_not_2;
+
+  static double two = 2.0;
+  ExternalAddress two_addr((address)&two);
+
+  // constant maybe too far on 64 bit
+  lea(tmp2, two_addr);
+  fld_d(Address(tmp2, 0));    // Stack: 2 X Y
+  fcmp(tmp, 2, true, false);  // Stack: X Y
+  jcc(Assembler::parity, y_not_2);
+  jcc(Assembler::notEqual, y_not_2);
+
+  fxch(); fpop();             // Stack: X
+  fmul(0);                    // Stack: X*X
+
+  jmp(done);
+
+  bind(y_not_2);
+
+  fldz();                     // Stack: 0 X Y
+  fcmp(tmp, 1, true, false);  // Stack: X Y
+  jcc(Assembler::above, x_negative);
+
+  // X >= 0
+
+  fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
+  fld_s(1);                   // Stack: X Y X Y
+  fast_pow();                 // Stack: X^Y X Y
+  fcmp(tmp, 0, false, false); // Stack: X^Y X Y
+  // X^Y not equal to itself: X^Y is NaN go to slow case.
+  jcc(Assembler::parity, slow_case);
+  // get rid of duplicate arguments. Stack: X^Y
+  if (num_fpu_regs_in_use > 0) {
+    fxch(); fpop();
+    fxch(); fpop();
+  } else {
+    ffree(2);
+    ffree(1);
+  }
+  jmp(done);
+
+  // X <= 0
+  bind(x_negative);
+
+  fld_s(1);                   // Stack: Y X Y
+  frndint();                  // Stack: int(Y) X Y
+  fcmp(tmp, 2, false, false); // Stack: int(Y) X Y
+  jcc(Assembler::notEqual, slow_case);
+
+  subptr(rsp, 8);
+
+  // For X^Y, when X < 0, Y has to be an integer and the final
+  // result depends on whether it's odd or even. We just checked
+  // that int(Y) == Y.  We move int(Y) to gp registers as a 64 bit
+  // integer to test its parity. If int(Y) is huge and doesn't fit
+  // in the 64 bit integer range, the integer indefinite value will
+  // end up in the gp registers. Huge numbers are all even, the
+  // integer indefinite number is even so it's fine.
 
 #ifdef ASSERT
-    // Let's check we don't end up with an integer indefinite number
-    // when not expected. First test for huge numbers: check whether
-    // int(Y)+1 == int(Y) which is true for very large numbers and
-    // those are all even. A 64 bit integer is guaranteed to not
-    // overflow for numbers where y+1 != y (when precision is set to
-    // double precision).
-    Label y_not_huge;
-
-    fld1();                     // Stack: 1 int(Y) X Y
-    fadd(1);                    // Stack: 1+int(Y) int(Y) X Y
+  // Let's check we don't end up with an integer indefinite number
+  // when not expected. First test for huge numbers: check whether
+  // int(Y)+1 == int(Y) which is true for very large numbers and
+  // those are all even. A 64 bit integer is guaranteed to not
+  // overflow for numbers where y+1 != y (when precision is set to
+  // double precision).
+  Label y_not_huge;
+
+  fld1();                     // Stack: 1 int(Y) X Y
+  fadd(1);                    // Stack: 1+int(Y) int(Y) X Y
 
 #ifdef _LP64
-    // trip to memory to force the precision down from double extended
-    // precision
-    fstp_d(Address(rsp, 0));
-    fld_d(Address(rsp, 0));
+  // trip to memory to force the precision down from double extended
+  // precision
+  fstp_d(Address(rsp, 0));
+  fld_d(Address(rsp, 0));
 #endif
 
-    fcmp(tmp, 1, true, false);  // Stack: int(Y) X Y
+  fcmp(tmp, 1, true, false);  // Stack: int(Y) X Y
 #endif
 
-    // move int(Y) as 64 bit integer to thread's stack
-    fistp_d(Address(rsp,0));    // Stack: X Y
+  // move int(Y) as 64 bit integer to thread's stack
+  fistp_d(Address(rsp,0));    // Stack: X Y
 
 #ifdef ASSERT
-    jcc(Assembler::notEqual, y_not_huge);
-
-    // Y is huge so we know it's even. It may not fit in a 64 bit
-    // integer and we don't want the debug code below to see the
-    // integer indefinite value so overwrite int(Y) on the thread's
-    // stack with 0.
-    movl(Address(rsp, 0), 0);
-    movl(Address(rsp, 4), 0);
-
-    bind(y_not_huge);
+  jcc(Assembler::notEqual, y_not_huge);
+
+  // Y is huge so we know it's even. It may not fit in a 64 bit
+  // integer and we don't want the debug code below to see the
+  // integer indefinite value so overwrite int(Y) on the thread's
+  // stack with 0.
+  movl(Address(rsp, 0), 0);
+  movl(Address(rsp, 4), 0);
+
+  bind(y_not_huge);
 #endif
 
-    fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
-    fld_s(1);                   // Stack: X Y X Y
-    fabs();                     // Stack: abs(X) Y X Y
-    fast_pow();                 // Stack: abs(X)^Y X Y
-    fcmp(tmp, 0, false, false); // Stack: abs(X)^Y X Y
-    // abs(X)^Y not equal to itself: abs(X)^Y is NaN go to slow case.
-
-    pop(tmp2);
-    NOT_LP64(pop(tmp3));
-    jcc(Assembler::parity, slow_case);
+  fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
+  fld_s(1);                   // Stack: X Y X Y
+  fabs();                     // Stack: abs(X) Y X Y
+  fast_pow();                 // Stack: abs(X)^Y X Y
+  fcmp(tmp, 0, false, false); // Stack: abs(X)^Y X Y
+  // abs(X)^Y not equal to itself: abs(X)^Y is NaN go to slow case.
+
+  pop(tmp2);
+  NOT_LP64(pop(tmp3));
+  jcc(Assembler::parity, slow_case);
 
 #ifdef ASSERT
-    // Check that int(Y) is not integer indefinite value (int
-    // overflow). Shouldn't happen because for values that would
-    // overflow, 1+int(Y)==Y which was tested earlier.
+  // Check that int(Y) is not integer indefinite value (int
+  // overflow). Shouldn't happen because for values that would
+  // overflow, 1+int(Y)==Y which was tested earlier.
 #ifndef _LP64
-    {
-      Label integer;
-      testl(tmp2, tmp2);
-      jcc(Assembler::notZero, integer);
-      cmpl(tmp3, 0x80000000);
-      jcc(Assembler::notZero, integer);
-      STOP("integer indefinite value shouldn't be seen here");
-      bind(integer);
-    }
+  {
+    Label integer;
+    testl(tmp2, tmp2);
+    jcc(Assembler::notZero, integer);
+    cmpl(tmp3, 0x80000000);
+    jcc(Assembler::notZero, integer);
+    STOP("integer indefinite value shouldn't be seen here");
+    bind(integer);
+  }
 #else
-    {
-      Label integer;
-      mov(tmp3, tmp2); // preserve tmp2 for parity check below
-      shlq(tmp3, 1);
-      jcc(Assembler::carryClear, integer);
-      jcc(Assembler::notZero, integer);
-      STOP("integer indefinite value shouldn't be seen here");
-      bind(integer);
-    }
+  {
+    Label integer;
+    mov(tmp3, tmp2); // preserve tmp2 for parity check below
+    shlq(tmp3, 1);
+    jcc(Assembler::carryClear, integer);
+    jcc(Assembler::notZero, integer);
+    STOP("integer indefinite value shouldn't be seen here");
+    bind(integer);
+  }
 #endif
 #endif
 
-    // get rid of duplicate arguments. Stack: X^Y
-    if (num_fpu_regs_in_use > 0) {
-      fxch(); fpop();
-      fxch(); fpop();
-    } else {
-      ffree(2);
-      ffree(1);
-    }
-
-    testl(tmp2, 1);
-    jcc(Assembler::zero, done); // X <= 0, Y even: X^Y = abs(X)^Y
-    // X <= 0, Y even: X^Y = -abs(X)^Y
-
-    fchs();                     // Stack: -abs(X)^Y Y
-    jmp(done);
-  }
+  // get rid of duplicate arguments. Stack: X^Y
+  if (num_fpu_regs_in_use > 0) {
+    fxch(); fpop();
+    fxch(); fpop();
+  } else {
+    ffree(2);
+    ffree(1);
+  }
+
+  testl(tmp2, 1);
+  jcc(Assembler::zero, done); // X <= 0, Y even: X^Y = abs(X)^Y
+  // X <= 0, Y even: X^Y = -abs(X)^Y
+
+  fchs();                     // Stack: -abs(X)^Y Y
+  jmp(done);
 
   // slow case: runtime call
   bind(slow_case);
 
   fpop();                       // pop incorrect result or int(Y)
 
-  fp_runtime_fallback(is_exp ? CAST_FROM_FN_PTR(address, SharedRuntime::dexp) : CAST_FROM_FN_PTR(address, SharedRuntime::dpow),
-                      is_exp ? 1 : 2, num_fpu_regs_in_use);
+  fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), 2, num_fpu_regs_in_use);
 
   // Come here with result in F-TOS
   bind(done);
@@ -6267,7 +6245,9 @@
     // Save caller's stack pointer into RBP if the frame pointer is preserved.
     if (PreserveFramePointer) {
       movptr(rbp, rsp);
-      addptr(rbp, framesize + wordSize);
+      if (framesize > 0) {
+        addptr(rbp, framesize);
+      }
     }
   }
 
@@ -8636,6 +8616,471 @@
   notl(crc); // ~c
 }
 
+#ifdef _LP64
+// S. Gueron / Information Processing Letters 112 (2012) 184
+// Algorithm 4: Computing carry-less multiplication using a precomputed lookup table.
+// Input: A 32 bit value B = [byte3, byte2, byte1, byte0].
+// Output: the 64-bit carry-less product of B * CONST
+void MacroAssembler::crc32c_ipl_alg4(Register in, uint32_t n,
+                                     Register tmp1, Register tmp2, Register tmp3) {
+  lea(tmp3, ExternalAddress(StubRoutines::crc32c_table_addr()));
+  if (n > 0) {
+    addq(tmp3, n * 256 * 8);
+  }
+  //    Q1 = TABLEExt[n][B & 0xFF];
+  movl(tmp1, in);
+  andl(tmp1, 0x000000FF);
+  shll(tmp1, 3);
+  addq(tmp1, tmp3);
+  movq(tmp1, Address(tmp1, 0));
+
+  //    Q2 = TABLEExt[n][B >> 8 & 0xFF];
+  movl(tmp2, in);
+  shrl(tmp2, 8);
+  andl(tmp2, 0x000000FF);
+  shll(tmp2, 3);
+  addq(tmp2, tmp3);
+  movq(tmp2, Address(tmp2, 0));
+
+  shlq(tmp2, 8);
+  xorq(tmp1, tmp2);
+
+  //    Q3 = TABLEExt[n][B >> 16 & 0xFF];
+  movl(tmp2, in);
+  shrl(tmp2, 16);
+  andl(tmp2, 0x000000FF);
+  shll(tmp2, 3);
+  addq(tmp2, tmp3);
+  movq(tmp2, Address(tmp2, 0));
+
+  shlq(tmp2, 16);
+  xorq(tmp1, tmp2);
+
+  //    Q4 = TABLEExt[n][B >> 24 & 0xFF];
+  shrl(in, 24);
+  andl(in, 0x000000FF);
+  shll(in, 3);
+  addq(in, tmp3);
+  movq(in, Address(in, 0));
+
+  shlq(in, 24);
+  xorq(in, tmp1);
+  //    return Q1 ^ Q2 << 8 ^ Q3 << 16 ^ Q4 << 24;
+}
+
+void MacroAssembler::crc32c_pclmulqdq(XMMRegister w_xtmp1,
+                                      Register in_out,
+                                      uint32_t const_or_pre_comp_const_index, bool is_pclmulqdq_supported,
+                                      XMMRegister w_xtmp2,
+                                      Register tmp1,
+                                      Register n_tmp2, Register n_tmp3) {
+  if (is_pclmulqdq_supported) {
+    movdl(w_xtmp1, in_out); // modified blindly
+
+    movl(tmp1, const_or_pre_comp_const_index);
+    movdl(w_xtmp2, tmp1);
+    pclmulqdq(w_xtmp1, w_xtmp2, 0);
+
+    movdq(in_out, w_xtmp1);
+  } else {
+    crc32c_ipl_alg4(in_out, const_or_pre_comp_const_index, tmp1, n_tmp2, n_tmp3);
+  }
+}
+
+// Recombination Alternative 2: No bit-reflections
+// T1 = (CRC_A * U1) << 1
+// T2 = (CRC_B * U2) << 1
+// C1 = T1 >> 32
+// C2 = T2 >> 32
+// T1 = T1 & 0xFFFFFFFF
+// T2 = T2 & 0xFFFFFFFF
+// T1 = CRC32(0, T1)
+// T2 = CRC32(0, T2)
+// C1 = C1 ^ T1
+// C2 = C2 ^ T2
+// CRC = C1 ^ C2 ^ CRC_C
+void MacroAssembler::crc32c_rec_alt2(uint32_t const_or_pre_comp_const_index_u1, uint32_t const_or_pre_comp_const_index_u2, bool is_pclmulqdq_supported, Register in_out, Register in1, Register in2,
+                                     XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                                     Register tmp1, Register tmp2,
+                                     Register n_tmp3) {
+  crc32c_pclmulqdq(w_xtmp1, in_out, const_or_pre_comp_const_index_u1, is_pclmulqdq_supported, w_xtmp3, tmp1, tmp2, n_tmp3);
+  crc32c_pclmulqdq(w_xtmp2, in1, const_or_pre_comp_const_index_u2, is_pclmulqdq_supported, w_xtmp3, tmp1, tmp2, n_tmp3);
+  shlq(in_out, 1);
+  movl(tmp1, in_out);
+  shrq(in_out, 32);
+  xorl(tmp2, tmp2);
+  crc32(tmp2, tmp1, 4);
+  xorl(in_out, tmp2); // we don't care about upper 32 bit contents here
+  shlq(in1, 1);
+  movl(tmp1, in1);
+  shrq(in1, 32);
+  xorl(tmp2, tmp2);
+  crc32(tmp2, tmp1, 4);
+  xorl(in1, tmp2);
+  xorl(in_out, in1);
+  xorl(in_out, in2);
+}
+
+// Set N to predefined value
+// Subtract from a lenght of a buffer
+// execute in a loop:
+// CRC_A = 0xFFFFFFFF, CRC_B = 0, CRC_C = 0
+// for i = 1 to N do
+//  CRC_A = CRC32(CRC_A, A[i])
+//  CRC_B = CRC32(CRC_B, B[i])
+//  CRC_C = CRC32(CRC_C, C[i])
+// end for
+// Recombine
+void MacroAssembler::crc32c_proc_chunk(uint32_t size, uint32_t const_or_pre_comp_const_index_u1, uint32_t const_or_pre_comp_const_index_u2, bool is_pclmulqdq_supported,
+                                       Register in_out1, Register in_out2, Register in_out3,
+                                       Register tmp1, Register tmp2, Register tmp3,
+                                       XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                                       Register tmp4, Register tmp5,
+                                       Register n_tmp6) {
+  Label L_processPartitions;
+  Label L_processPartition;
+  Label L_exit;
+
+  bind(L_processPartitions);
+  cmpl(in_out1, 3 * size);
+  jcc(Assembler::less, L_exit);
+    xorl(tmp1, tmp1);
+    xorl(tmp2, tmp2);
+    movq(tmp3, in_out2);
+    addq(tmp3, size);
+
+    bind(L_processPartition);
+      crc32(in_out3, Address(in_out2, 0), 8);
+      crc32(tmp1, Address(in_out2, size), 8);
+      crc32(tmp2, Address(in_out2, size * 2), 8);
+      addq(in_out2, 8);
+      cmpq(in_out2, tmp3);
+      jcc(Assembler::less, L_processPartition);
+    crc32c_rec_alt2(const_or_pre_comp_const_index_u1, const_or_pre_comp_const_index_u2, is_pclmulqdq_supported, in_out3, tmp1, tmp2,
+            w_xtmp1, w_xtmp2, w_xtmp3,
+            tmp4, tmp5,
+            n_tmp6);
+    addq(in_out2, 2 * size);
+    subl(in_out1, 3 * size);
+    jmp(L_processPartitions);
+
+  bind(L_exit);
+}
+#else
+void MacroAssembler::crc32c_ipl_alg4(Register in_out, uint32_t n,
+                                     Register tmp1, Register tmp2, Register tmp3,
+                                     XMMRegister xtmp1, XMMRegister xtmp2) {
+  lea(tmp3, ExternalAddress(StubRoutines::crc32c_table_addr()));
+  if (n > 0) {
+    addl(tmp3, n * 256 * 8);
+  }
+  //    Q1 = TABLEExt[n][B & 0xFF];
+  movl(tmp1, in_out);
+  andl(tmp1, 0x000000FF);
+  shll(tmp1, 3);
+  addl(tmp1, tmp3);
+  movq(xtmp1, Address(tmp1, 0));
+
+  //    Q2 = TABLEExt[n][B >> 8 & 0xFF];
+  movl(tmp2, in_out);
+  shrl(tmp2, 8);
+  andl(tmp2, 0x000000FF);
+  shll(tmp2, 3);
+  addl(tmp2, tmp3);
+  movq(xtmp2, Address(tmp2, 0));
+
+  psllq(xtmp2, 8);
+  pxor(xtmp1, xtmp2);
+
+  //    Q3 = TABLEExt[n][B >> 16 & 0xFF];
+  movl(tmp2, in_out);
+  shrl(tmp2, 16);
+  andl(tmp2, 0x000000FF);
+  shll(tmp2, 3);
+  addl(tmp2, tmp3);
+  movq(xtmp2, Address(tmp2, 0));
+
+  psllq(xtmp2, 16);
+  pxor(xtmp1, xtmp2);
+
+  //    Q4 = TABLEExt[n][B >> 24 & 0xFF];
+  shrl(in_out, 24);
+  andl(in_out, 0x000000FF);
+  shll(in_out, 3);
+  addl(in_out, tmp3);
+  movq(xtmp2, Address(in_out, 0));
+
+  psllq(xtmp2, 24);
+  pxor(xtmp1, xtmp2); // Result in CXMM
+  //    return Q1 ^ Q2 << 8 ^ Q3 << 16 ^ Q4 << 24;
+}
+
+void MacroAssembler::crc32c_pclmulqdq(XMMRegister w_xtmp1,
+                                      Register in_out,
+                                      uint32_t const_or_pre_comp_const_index, bool is_pclmulqdq_supported,
+                                      XMMRegister w_xtmp2,
+                                      Register tmp1,
+                                      Register n_tmp2, Register n_tmp3) {
+  if (is_pclmulqdq_supported) {
+    movdl(w_xtmp1, in_out);
+
+    movl(tmp1, const_or_pre_comp_const_index);
+    movdl(w_xtmp2, tmp1);
+    pclmulqdq(w_xtmp1, w_xtmp2, 0);
+    // Keep result in XMM since GPR is 32 bit in length
+  } else {
+    crc32c_ipl_alg4(in_out, const_or_pre_comp_const_index, tmp1, n_tmp2, n_tmp3, w_xtmp1, w_xtmp2);
+  }
+}
+
+void MacroAssembler::crc32c_rec_alt2(uint32_t const_or_pre_comp_const_index_u1, uint32_t const_or_pre_comp_const_index_u2, bool is_pclmulqdq_supported, Register in_out, Register in1, Register in2,
+                                     XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                                     Register tmp1, Register tmp2,
+                                     Register n_tmp3) {
+  crc32c_pclmulqdq(w_xtmp1, in_out, const_or_pre_comp_const_index_u1, is_pclmulqdq_supported, w_xtmp3, tmp1, tmp2, n_tmp3);
+  crc32c_pclmulqdq(w_xtmp2, in1, const_or_pre_comp_const_index_u2, is_pclmulqdq_supported, w_xtmp3, tmp1, tmp2, n_tmp3);
+
+  psllq(w_xtmp1, 1);
+  movdl(tmp1, w_xtmp1);
+  psrlq(w_xtmp1, 32);
+  movdl(in_out, w_xtmp1);
+
+  xorl(tmp2, tmp2);
+  crc32(tmp2, tmp1, 4);
+  xorl(in_out, tmp2);
+
+  psllq(w_xtmp2, 1);
+  movdl(tmp1, w_xtmp2);
+  psrlq(w_xtmp2, 32);
+  movdl(in1, w_xtmp2);
+
+  xorl(tmp2, tmp2);
+  crc32(tmp2, tmp1, 4);
+  xorl(in1, tmp2);
+  xorl(in_out, in1);
+  xorl(in_out, in2);
+}
+
+void MacroAssembler::crc32c_proc_chunk(uint32_t size, uint32_t const_or_pre_comp_const_index_u1, uint32_t const_or_pre_comp_const_index_u2, bool is_pclmulqdq_supported,
+                                       Register in_out1, Register in_out2, Register in_out3,
+                                       Register tmp1, Register tmp2, Register tmp3,
+                                       XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                                       Register tmp4, Register tmp5,
+                                       Register n_tmp6) {
+  Label L_processPartitions;
+  Label L_processPartition;
+  Label L_exit;
+
+  bind(L_processPartitions);
+  cmpl(in_out1, 3 * size);
+  jcc(Assembler::less, L_exit);
+    xorl(tmp1, tmp1);
+    xorl(tmp2, tmp2);
+    movl(tmp3, in_out2);
+    addl(tmp3, size);
+
+    bind(L_processPartition);
+      crc32(in_out3, Address(in_out2, 0), 4);
+      crc32(tmp1, Address(in_out2, size), 4);
+      crc32(tmp2, Address(in_out2, size*2), 4);
+      crc32(in_out3, Address(in_out2, 0+4), 4);
+      crc32(tmp1, Address(in_out2, size+4), 4);
+      crc32(tmp2, Address(in_out2, size*2+4), 4);
+      addl(in_out2, 8);
+      cmpl(in_out2, tmp3);
+      jcc(Assembler::less, L_processPartition);
+
+        push(tmp3);
+        push(in_out1);
+        push(in_out2);
+        tmp4 = tmp3;
+        tmp5 = in_out1;
+        n_tmp6 = in_out2;
+
+      crc32c_rec_alt2(const_or_pre_comp_const_index_u1, const_or_pre_comp_const_index_u2, is_pclmulqdq_supported, in_out3, tmp1, tmp2,
+            w_xtmp1, w_xtmp2, w_xtmp3,
+            tmp4, tmp5,
+            n_tmp6);
+
+        pop(in_out2);
+        pop(in_out1);
+        pop(tmp3);
+
+    addl(in_out2, 2 * size);
+    subl(in_out1, 3 * size);
+    jmp(L_processPartitions);
+
+  bind(L_exit);
+}
+#endif //LP64
+
+#ifdef _LP64
+// Algorithm 2: Pipelined usage of the CRC32 instruction.
+// Input: A buffer I of L bytes.
+// Output: the CRC32C value of the buffer.
+// Notations:
+// Write L = 24N + r, with N = floor (L/24).
+// r = L mod 24 (0 <= r < 24).
+// Consider I as the concatenation of A|B|C|R, where A, B, C, each,
+// N quadwords, and R consists of r bytes.
+// A[j] = I [8j+7:8j], j= 0, 1, ..., N-1
+// B[j] = I [N + 8j+7:N + 8j], j= 0, 1, ..., N-1
+// C[j] = I [2N + 8j+7:2N + 8j], j= 0, 1, ..., N-1
+// if r > 0 R[j] = I [3N +j], j= 0, 1, ...,r-1
+void MacroAssembler::crc32c_ipl_alg2_alt2(Register in_out, Register in1, Register in2,
+                                          Register tmp1, Register tmp2, Register tmp3,
+                                          Register tmp4, Register tmp5, Register tmp6,
+                                          XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                                          bool is_pclmulqdq_supported) {
+  uint32_t const_or_pre_comp_const_index[CRC32C_NUM_PRECOMPUTED_CONSTANTS];
+  Label L_wordByWord;
+  Label L_byteByByteProlog;
+  Label L_byteByByte;
+  Label L_exit;
+
+  if (is_pclmulqdq_supported ) {
+    const_or_pre_comp_const_index[1] = *(uint32_t *)StubRoutines::_crc32c_table_addr;
+    const_or_pre_comp_const_index[0] = *((uint32_t *)StubRoutines::_crc32c_table_addr+1);
+
+    const_or_pre_comp_const_index[3] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 2);
+    const_or_pre_comp_const_index[2] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 3);
+
+    const_or_pre_comp_const_index[5] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 4);
+    const_or_pre_comp_const_index[4] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 5);
+    assert((CRC32C_NUM_PRECOMPUTED_CONSTANTS - 1 ) == 5, "Checking whether you declared all of the constants based on the number of \"chunks\"");
+  } else {
+    const_or_pre_comp_const_index[0] = 1;
+    const_or_pre_comp_const_index[1] = 0;
+
+    const_or_pre_comp_const_index[2] = 3;
+    const_or_pre_comp_const_index[3] = 2;
+
+    const_or_pre_comp_const_index[4] = 5;
+    const_or_pre_comp_const_index[5] = 4;
+   }
+  crc32c_proc_chunk(CRC32C_HIGH, const_or_pre_comp_const_index[0], const_or_pre_comp_const_index[1], is_pclmulqdq_supported,
+                    in2, in1, in_out,
+                    tmp1, tmp2, tmp3,
+                    w_xtmp1, w_xtmp2, w_xtmp3,
+                    tmp4, tmp5,
+                    tmp6);
+  crc32c_proc_chunk(CRC32C_MIDDLE, const_or_pre_comp_const_index[2], const_or_pre_comp_const_index[3], is_pclmulqdq_supported,
+                    in2, in1, in_out,
+                    tmp1, tmp2, tmp3,
+                    w_xtmp1, w_xtmp2, w_xtmp3,
+                    tmp4, tmp5,
+                    tmp6);
+  crc32c_proc_chunk(CRC32C_LOW, const_or_pre_comp_const_index[4], const_or_pre_comp_const_index[5], is_pclmulqdq_supported,
+                    in2, in1, in_out,
+                    tmp1, tmp2, tmp3,
+                    w_xtmp1, w_xtmp2, w_xtmp3,
+                    tmp4, tmp5,
+                    tmp6);
+  movl(tmp1, in2);
+  andl(tmp1, 0x00000007);
+  negl(tmp1);
+  addl(tmp1, in2);
+  addq(tmp1, in1);
+
+  BIND(L_wordByWord);
+  cmpq(in1, tmp1);
+  jcc(Assembler::greaterEqual, L_byteByByteProlog);
+    crc32(in_out, Address(in1, 0), 4);
+    addq(in1, 4);
+    jmp(L_wordByWord);
+
+  BIND(L_byteByByteProlog);
+  andl(in2, 0x00000007);
+  movl(tmp2, 1);
+
+  BIND(L_byteByByte);
+  cmpl(tmp2, in2);
+  jccb(Assembler::greater, L_exit);
+    crc32(in_out, Address(in1, 0), 1);
+    incq(in1);
+    incl(tmp2);
+    jmp(L_byteByByte);
+
+  BIND(L_exit);
+}
+#else
+void MacroAssembler::crc32c_ipl_alg2_alt2(Register in_out, Register in1, Register in2,
+                                          Register tmp1, Register  tmp2, Register tmp3,
+                                          Register tmp4, Register  tmp5, Register tmp6,
+                                          XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                                          bool is_pclmulqdq_supported) {
+  uint32_t const_or_pre_comp_const_index[CRC32C_NUM_PRECOMPUTED_CONSTANTS];
+  Label L_wordByWord;
+  Label L_byteByByteProlog;
+  Label L_byteByByte;
+  Label L_exit;
+
+  if (is_pclmulqdq_supported) {
+    const_or_pre_comp_const_index[1] = *(uint32_t *)StubRoutines::_crc32c_table_addr;
+    const_or_pre_comp_const_index[0] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 1);
+
+    const_or_pre_comp_const_index[3] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 2);
+    const_or_pre_comp_const_index[2] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 3);
+
+    const_or_pre_comp_const_index[5] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 4);
+    const_or_pre_comp_const_index[4] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 5);
+  } else {
+    const_or_pre_comp_const_index[0] = 1;
+    const_or_pre_comp_const_index[1] = 0;
+
+    const_or_pre_comp_const_index[2] = 3;
+    const_or_pre_comp_const_index[3] = 2;
+
+    const_or_pre_comp_const_index[4] = 5;
+    const_or_pre_comp_const_index[5] = 4;
+  }
+  crc32c_proc_chunk(CRC32C_HIGH, const_or_pre_comp_const_index[0], const_or_pre_comp_const_index[1], is_pclmulqdq_supported,
+                    in2, in1, in_out,
+                    tmp1, tmp2, tmp3,
+                    w_xtmp1, w_xtmp2, w_xtmp3,
+                    tmp4, tmp5,
+                    tmp6);
+  crc32c_proc_chunk(CRC32C_MIDDLE, const_or_pre_comp_const_index[2], const_or_pre_comp_const_index[3], is_pclmulqdq_supported,
+                    in2, in1, in_out,
+                    tmp1, tmp2, tmp3,
+                    w_xtmp1, w_xtmp2, w_xtmp3,
+                    tmp4, tmp5,
+                    tmp6);
+  crc32c_proc_chunk(CRC32C_LOW, const_or_pre_comp_const_index[4], const_or_pre_comp_const_index[5], is_pclmulqdq_supported,
+                    in2, in1, in_out,
+                    tmp1, tmp2, tmp3,
+                    w_xtmp1, w_xtmp2, w_xtmp3,
+                    tmp4, tmp5,
+                    tmp6);
+  movl(tmp1, in2);
+  andl(tmp1, 0x00000007);
+  negl(tmp1);
+  addl(tmp1, in2);
+  addl(tmp1, in1);
+
+  BIND(L_wordByWord);
+  cmpl(in1, tmp1);
+  jcc(Assembler::greaterEqual, L_byteByByteProlog);
+    crc32(in_out, Address(in1,0), 4);
+    addl(in1, 4);
+    jmp(L_wordByWord);
+
+  BIND(L_byteByByteProlog);
+  andl(in2, 0x00000007);
+  movl(tmp2, 1);
+
+  BIND(L_byteByByte);
+  cmpl(tmp2, in2);
+  jccb(Assembler::greater, L_exit);
+    movb(tmp1, Address(in1, 0));
+    crc32(in_out, tmp1, 1);
+    incl(in1);
+    incl(tmp2);
+    jmp(L_byteByByte);
+
+  BIND(L_exit);
+}
+#endif // LP64
 #undef BIND
 #undef BLOCK_COMMENT
 
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -907,14 +907,14 @@
   // all corner cases and may result in NaN and require fallback to a
   // runtime call.
   void fast_pow();
-  void fast_exp();
+  void fast_exp(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xmm2, XMMRegister xmm3,
+                XMMRegister xmm4, XMMRegister xmm5, XMMRegister xmm6, XMMRegister xmm7,
+                Register rax, Register rcx, Register rdx, Register tmp);
   void increase_precision();
   void restore_precision();
 
-  // computes exp(x). Fallback to runtime call included.
-  void exp_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(true, num_fpu_regs_in_use); }
   // computes pow(x,y). Fallback to runtime call included.
-  void pow_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(false, num_fpu_regs_in_use); }
+  void pow_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(num_fpu_regs_in_use); }
 
 private:
 
@@ -925,7 +925,7 @@
   void pow_exp_core_encoding();
 
   // computes pow(x,y) or exp(x). Fallback to runtime call included.
-  void pow_or_exp(bool is_exp, int num_fpu_regs_in_use);
+  void pow_or_exp(int num_fpu_regs_in_use);
 
   // these are private because users should be doing movflt/movdbl
 
@@ -971,6 +971,10 @@
   void movsd(XMMRegister dst, Address src)     { Assembler::movsd(dst, src); }
   void movsd(XMMRegister dst, AddressLiteral src);
 
+  void mulpd(XMMRegister dst, XMMRegister src)    { Assembler::mulpd(dst, src); }
+  void mulpd(XMMRegister dst, Address src)        { Assembler::mulpd(dst, src); }
+  void mulpd(XMMRegister dst, AddressLiteral src);
+
   void mulsd(XMMRegister dst, XMMRegister src)    { Assembler::mulsd(dst, src); }
   void mulsd(XMMRegister dst, Address src)        { Assembler::mulsd(dst, src); }
   void mulsd(XMMRegister dst, AddressLiteral src);
@@ -1278,9 +1282,42 @@
                Register raxReg);
 #endif
 
-  // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
+  // CRC32 code for java.util.zip.CRC32::updateBytes() intrinsic.
   void update_byte_crc32(Register crc, Register val, Register table);
   void kernel_crc32(Register crc, Register buf, Register len, Register table, Register tmp);
+  // CRC32C code for java.util.zip.CRC32C::updateBytes() intrinsic
+  // Note on a naming convention:
+  // Prefix w = register only used on a Westmere+ architecture
+  // Prefix n = register only used on a Nehalem architecture
+#ifdef _LP64
+  void crc32c_ipl_alg4(Register in_out, uint32_t n,
+                       Register tmp1, Register tmp2, Register tmp3);
+#else
+  void crc32c_ipl_alg4(Register in_out, uint32_t n,
+                       Register tmp1, Register tmp2, Register tmp3,
+                       XMMRegister xtmp1, XMMRegister xtmp2);
+#endif
+  void crc32c_pclmulqdq(XMMRegister w_xtmp1,
+                        Register in_out,
+                        uint32_t const_or_pre_comp_const_index, bool is_pclmulqdq_supported,
+                        XMMRegister w_xtmp2,
+                        Register tmp1,
+                        Register n_tmp2, Register n_tmp3);
+  void crc32c_rec_alt2(uint32_t const_or_pre_comp_const_index_u1, uint32_t const_or_pre_comp_const_index_u2, bool is_pclmulqdq_supported, Register in_out, Register in1, Register in2,
+                       XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                       Register tmp1, Register tmp2,
+                       Register n_tmp3);
+  void crc32c_proc_chunk(uint32_t size, uint32_t const_or_pre_comp_const_index_u1, uint32_t const_or_pre_comp_const_index_u2, bool is_pclmulqdq_supported,
+                         Register in_out1, Register in_out2, Register in_out3,
+                         Register tmp1, Register tmp2, Register tmp3,
+                         XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                         Register tmp4, Register tmp5,
+                         Register n_tmp6);
+  void crc32c_ipl_alg2_alt2(Register in_out, Register in1, Register in2,
+                            Register tmp1, Register tmp2, Register tmp3,
+                            Register tmp4, Register tmp5, Register tmp6,
+                            XMMRegister w_xtmp1, XMMRegister w_xtmp2, XMMRegister w_xtmp3,
+                            bool is_pclmulqdq_supported);
   // Fold 128-bit data chunk
   void fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, Register buf, int offset);
   void fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, XMMRegister xbuf);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86_libm.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,677 @@
+/*
+ * Copyright (c) 2015, Intel Corporation.
+ * Intel Math Library (LIBM) Source Code
+ *
+ * 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.
+ *
+ */
+
+/******************************************************************************/
+//                     ALGORITHM DESCRIPTION
+//                     ---------------------
+//
+// Description:
+//  Let K = 64 (table size).
+//        x    x/log(2)     n
+//       e  = 2          = 2 * T[j] * (1 + P(y))
+//  where
+//       x = m*log(2)/K + y,    y in [-log(2)/K..log(2)/K]
+//       m = n*K + j,           m,n,j - signed integer, j in [-K/2..K/2]
+//                  j/K
+//       values of 2   are tabulated as T[j] = T_hi[j] ( 1 + T_lo[j]).
+//
+//       P(y) is a minimax polynomial approximation of exp(x)-1
+//       on small interval [-log(2)/K..log(2)/K] (were calculated by Maple V).
+//
+//  To avoid problems with arithmetic overflow and underflow,
+//            n                        n1  n2
+//  value of 2  is safely computed as 2 * 2 where n1 in [-BIAS/2..BIAS/2]
+//  where BIAS is a value of exponent bias.
+//
+// Special cases:
+//  exp(NaN) = NaN
+//  exp(+INF) = +INF
+//  exp(-INF) = 0
+//  exp(x) = 1 for subnormals
+//  for finite argument, only exp(0)=1 is exact
+//  For IEEE double
+//    if x >  709.782712893383973096 then exp(x) overflow
+//    if x < -745.133219101941108420 then exp(x) underflow
+//
+/******************************************************************************/
+
+
+#include "precompiled.hpp"
+#include "asm/assembler.hpp"
+#include "asm/assembler.inline.hpp"
+#include "macroAssembler_x86.hpp"
+
+#ifdef _MSC_VER
+#define ALIGNED_(x) __declspec(align(x))
+#else
+#define ALIGNED_(x) __attribute__ ((aligned(x)))
+#endif
+
+#ifdef _LP64
+
+ALIGNED_(16) juint _cv[] =
+{
+    0x652b82feUL, 0x40571547UL, 0x652b82feUL, 0x40571547UL, 0xfefa0000UL,
+    0x3f862e42UL, 0xfefa0000UL, 0x3f862e42UL, 0xbc9e3b3aUL, 0x3d1cf79aUL,
+    0xbc9e3b3aUL, 0x3d1cf79aUL, 0xfffffffeUL, 0x3fdfffffUL, 0xfffffffeUL,
+    0x3fdfffffUL, 0xe3289860UL, 0x3f56c15cUL, 0x555b9e25UL, 0x3fa55555UL,
+    0xc090cf0fUL, 0x3f811115UL, 0x55548ba1UL, 0x3fc55555UL
+};
+
+ALIGNED_(16) juint _shifter[] =
+{
+    0x00000000UL, 0x43380000UL, 0x00000000UL, 0x43380000UL
+};
+
+ALIGNED_(16) juint _mmask[] =
+{
+    0xffffffc0UL, 0x00000000UL, 0xffffffc0UL, 0x00000000UL
+};
+
+ALIGNED_(16) juint _bias[] =
+{
+    0x0000ffc0UL, 0x00000000UL, 0x0000ffc0UL, 0x00000000UL
+};
+
+ALIGNED_(16) juint _Tbl_addr[] =
+{
+    0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0e03754dUL,
+    0x3cad7bbfUL, 0x3e778060UL, 0x00002c9aUL, 0x3567f613UL, 0x3c8cd252UL,
+    0xd3158574UL, 0x000059b0UL, 0x61e6c861UL, 0x3c60f74eUL, 0x18759bc8UL,
+    0x00008745UL, 0x5d837b6cUL, 0x3c979aa6UL, 0x6cf9890fUL, 0x0000b558UL,
+    0x702f9cd1UL, 0x3c3ebe3dUL, 0x32d3d1a2UL, 0x0000e3ecUL, 0x1e63bcd8UL,
+    0x3ca3516eUL, 0xd0125b50UL, 0x00011301UL, 0x26f0387bUL, 0x3ca4c554UL,
+    0xaea92ddfUL, 0x0001429aUL, 0x62523fb6UL, 0x3ca95153UL, 0x3c7d517aUL,
+    0x000172b8UL, 0x3f1353bfUL, 0x3c8b898cUL, 0xeb6fcb75UL, 0x0001a35bUL,
+    0x3e3a2f5fUL, 0x3c9aecf7UL, 0x3168b9aaUL, 0x0001d487UL, 0x44a6c38dUL,
+    0x3c8a6f41UL, 0x88628cd6UL, 0x0002063bUL, 0xe3a8a894UL, 0x3c968efdUL,
+    0x6e756238UL, 0x0002387aUL, 0x981fe7f2UL, 0x3c80472bUL, 0x65e27cddUL,
+    0x00026b45UL, 0x6d09ab31UL, 0x3c82f7e1UL, 0xf51fdee1UL, 0x00029e9dUL,
+    0x720c0ab3UL, 0x3c8b3782UL, 0xa6e4030bUL, 0x0002d285UL, 0x4db0abb6UL,
+    0x3c834d75UL, 0x0a31b715UL, 0x000306feUL, 0x5dd3f84aUL, 0x3c8fdd39UL,
+    0xb26416ffUL, 0x00033c08UL, 0xcc187d29UL, 0x3ca12f8cUL, 0x373aa9caUL,
+    0x000371a7UL, 0x738b5e8bUL, 0x3ca7d229UL, 0x34e59ff6UL, 0x0003a7dbUL,
+    0xa72a4c6dUL, 0x3c859f48UL, 0x4c123422UL, 0x0003dea6UL, 0x259d9205UL,
+    0x3ca8b846UL, 0x21f72e29UL, 0x0004160aUL, 0x60c2ac12UL, 0x3c4363edUL,
+    0x6061892dUL, 0x00044e08UL, 0xdaa10379UL, 0x3c6ecce1UL, 0xb5c13cd0UL,
+    0x000486a2UL, 0xbb7aafb0UL, 0x3c7690ceUL, 0xd5362a27UL, 0x0004bfdaUL,
+    0x9b282a09UL, 0x3ca083ccUL, 0x769d2ca6UL, 0x0004f9b2UL, 0xc1aae707UL,
+    0x3ca509b0UL, 0x569d4f81UL, 0x0005342bUL, 0x18fdd78eUL, 0x3c933505UL,
+    0x36b527daUL, 0x00056f47UL, 0xe21c5409UL, 0x3c9063e1UL, 0xdd485429UL,
+    0x0005ab07UL, 0x2b64c035UL, 0x3c9432e6UL, 0x15ad2148UL, 0x0005e76fUL,
+    0x99f08c0aUL, 0x3ca01284UL, 0xb03a5584UL, 0x0006247eUL, 0x0073dc06UL,
+    0x3c99f087UL, 0x82552224UL, 0x00066238UL, 0x0da05571UL, 0x3c998d4dUL,
+    0x667f3bccUL, 0x0006a09eUL, 0x86ce4786UL, 0x3ca52bb9UL, 0x3c651a2eUL,
+    0x0006dfb2UL, 0x206f0dabUL, 0x3ca32092UL, 0xe8ec5f73UL, 0x00071f75UL,
+    0x8e17a7a6UL, 0x3ca06122UL, 0x564267c8UL, 0x00075febUL, 0x461e9f86UL,
+    0x3ca244acUL, 0x73eb0186UL, 0x0007a114UL, 0xabd66c55UL, 0x3c65ebe1UL,
+    0x36cf4e62UL, 0x0007e2f3UL, 0xbbff67d0UL, 0x3c96fe9fUL, 0x994cce12UL,
+    0x00082589UL, 0x14c801dfUL, 0x3c951f14UL, 0x9b4492ecUL, 0x000868d9UL,
+    0xc1f0eab4UL, 0x3c8db72fUL, 0x422aa0dbUL, 0x0008ace5UL, 0x59f35f44UL,
+    0x3c7bf683UL, 0x99157736UL, 0x0008f1aeUL, 0x9c06283cUL, 0x3ca360baUL,
+    0xb0cdc5e4UL, 0x00093737UL, 0x20f962aaUL, 0x3c95e8d1UL, 0x9fde4e4fUL,
+    0x00097d82UL, 0x2b91ce27UL, 0x3c71affcUL, 0x82a3f090UL, 0x0009c491UL,
+    0x589a2ebdUL, 0x3c9b6d34UL, 0x7b5de564UL, 0x000a0c66UL, 0x9ab89880UL,
+    0x3c95277cUL, 0xb23e255cUL, 0x000a5503UL, 0x6e735ab3UL, 0x3c846984UL,
+    0x5579fdbfUL, 0x000a9e6bUL, 0x92cb3387UL, 0x3c8c1a77UL, 0x995ad3adUL,
+    0x000ae89fUL, 0xdc2d1d96UL, 0x3ca22466UL, 0xb84f15faUL, 0x000b33a2UL,
+    0xb19505aeUL, 0x3ca1112eUL, 0xf2fb5e46UL, 0x000b7f76UL, 0x0a5fddcdUL,
+    0x3c74ffd7UL, 0x904bc1d2UL, 0x000bcc1eUL, 0x30af0cb3UL, 0x3c736eaeUL,
+    0xdd85529cUL, 0x000c199bUL, 0xd10959acUL, 0x3c84e08fUL, 0x2e57d14bUL,
+    0x000c67f1UL, 0x6c921968UL, 0x3c676b2cUL, 0xdcef9069UL, 0x000cb720UL,
+    0x36df99b3UL, 0x3c937009UL, 0x4a07897bUL, 0x000d072dUL, 0xa63d07a7UL,
+    0x3c74a385UL, 0xdcfba487UL, 0x000d5818UL, 0xd5c192acUL, 0x3c8e5a50UL,
+    0x03db3285UL, 0x000da9e6UL, 0x1c4a9792UL, 0x3c98bb73UL, 0x337b9b5eUL,
+    0x000dfc97UL, 0x603a88d3UL, 0x3c74b604UL, 0xe78b3ff6UL, 0x000e502eUL,
+    0x92094926UL, 0x3c916f27UL, 0xa2a490d9UL, 0x000ea4afUL, 0x41aa2008UL,
+    0x3c8ec3bcUL, 0xee615a27UL, 0x000efa1bUL, 0x31d185eeUL, 0x3c8a64a9UL,
+    0x5b6e4540UL, 0x000f5076UL, 0x4d91cd9dUL, 0x3c77893bUL, 0x819e90d8UL,
+    0x000fa7c1UL
+};
+
+ALIGNED_(16) juint _ALLONES[] =
+{
+    0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL
+};
+
+ALIGNED_(16) juint _ebias[] =
+{
+    0x00000000UL, 0x3ff00000UL, 0x00000000UL, 0x3ff00000UL
+};
+
+ALIGNED_(4) juint _XMAX[] =
+{
+    0xffffffffUL, 0x7fefffffUL
+};
+
+ALIGNED_(4) juint _XMIN[] =
+{
+    0x00000000UL, 0x00100000UL
+};
+
+ALIGNED_(4) juint _INF[] =
+{
+    0x00000000UL, 0x7ff00000UL
+};
+
+ALIGNED_(4) juint _ZERO[] =
+{
+    0x00000000UL, 0x00000000UL
+};
+
+ALIGNED_(4) juint _ONE_val[] =
+{
+    0x00000000UL, 0x3ff00000UL
+};
+
+
+// Registers:
+// input: xmm0
+// scratch: xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
+//          rax, rdx, rcx, tmp - r11
+
+// Code generated by Intel C compiler for LIBM library
+
+void MacroAssembler::fast_exp(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xmm2, XMMRegister xmm3, XMMRegister xmm4, XMMRegister xmm5, XMMRegister xmm6, XMMRegister xmm7, Register eax, Register ecx, Register edx, Register tmp) {
+  Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2;
+  Label L_2TAG_PACKET_4_0_2, L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2, L_2TAG_PACKET_7_0_2;
+  Label L_2TAG_PACKET_8_0_2, L_2TAG_PACKET_9_0_2, L_2TAG_PACKET_10_0_2, L_2TAG_PACKET_11_0_2;
+  Label L_2TAG_PACKET_12_0_2, B1_3, B1_5, start;
+
+  assert_different_registers(tmp, eax, ecx, edx);
+  jmp(start);
+  address cv = (address)_cv;
+  address Shifter = (address)_shifter;
+  address mmask = (address)_mmask;
+  address bias = (address)_bias;
+  address Tbl_addr = (address)_Tbl_addr;
+  address ALLONES = (address)_ALLONES;
+  address ebias = (address)_ebias;
+  address XMAX = (address)_XMAX;
+  address XMIN = (address)_XMIN;
+  address INF = (address)_INF;
+  address ZERO = (address)_ZERO;
+  address ONE_val = (address)_ONE_val;
+
+  bind(start);
+  subq(rsp, 24);
+  movsd(Address(rsp, 8), xmm0);
+  unpcklpd(xmm0, xmm0);
+  movdqu(xmm1, ExternalAddress(cv));       // 0x652b82feUL, 0x40571547UL, 0x652b82feUL, 0x40571547UL
+  movdqu(xmm6, ExternalAddress(Shifter));  // 0x00000000UL, 0x43380000UL, 0x00000000UL, 0x43380000UL
+  movdqu(xmm2, ExternalAddress(16+cv));    // 0xfefa0000UL, 0x3f862e42UL, 0xfefa0000UL, 0x3f862e42UL
+  movdqu(xmm3, ExternalAddress(32+cv));    // 0xbc9e3b3aUL, 0x3d1cf79aUL, 0xbc9e3b3aUL, 0x3d1cf79aUL
+  pextrw(eax, xmm0, 3);
+  andl(eax, 32767);
+  movl(edx, 16527);
+  subl(edx, eax);
+  subl(eax, 15504);
+  orl(edx, eax);
+  cmpl(edx, INT_MIN);
+  jcc(Assembler::aboveEqual, L_2TAG_PACKET_0_0_2);
+  mulpd(xmm1, xmm0);
+  addpd(xmm1, xmm6);
+  movapd(xmm7, xmm1);
+  subpd(xmm1, xmm6);
+  mulpd(xmm2, xmm1);
+  movdqu(xmm4, ExternalAddress(64+cv));    // 0xe3289860UL, 0x3f56c15cUL, 0x555b9e25UL, 0x3fa55555UL
+  mulpd(xmm3, xmm1);
+  movdqu(xmm5, ExternalAddress(80+cv));    // 0xc090cf0fUL, 0x3f811115UL, 0x55548ba1UL, 0x3fc55555UL
+  subpd(xmm0, xmm2);
+  movdl(eax, xmm7);
+  movl(ecx, eax);
+  andl(ecx, 63);
+  shll(ecx, 4);
+  sarl(eax, 6);
+  movl(edx, eax);
+  movdqu(xmm6, ExternalAddress(mmask));    // 0xffffffc0UL, 0x00000000UL, 0xffffffc0UL, 0x00000000UL
+  pand(xmm7, xmm6);
+  movdqu(xmm6, ExternalAddress(bias));     // 0x0000ffc0UL, 0x00000000UL, 0x0000ffc0UL, 0x00000000UL
+  paddq(xmm7, xmm6);
+  psllq(xmm7, 46);
+  subpd(xmm0, xmm3);
+  lea(tmp, ExternalAddress(Tbl_addr));
+  movdqu(xmm2, Address(ecx,tmp));
+  mulpd(xmm4, xmm0);
+  movapd(xmm6, xmm0);
+  movapd(xmm1, xmm0);
+  mulpd(xmm6, xmm6);
+  mulpd(xmm0, xmm6);
+  addpd(xmm5, xmm4);
+  mulsd(xmm0, xmm6);
+  mulpd(xmm6, ExternalAddress(48+cv));     // 0xfffffffeUL, 0x3fdfffffUL, 0xfffffffeUL, 0x3fdfffffUL
+  addsd(xmm1, xmm2);
+  unpckhpd(xmm2, xmm2);
+  mulpd(xmm0, xmm5);
+  addsd(xmm1, xmm0);
+  por(xmm2, xmm7);
+  unpckhpd(xmm0, xmm0);
+  addsd(xmm0, xmm1);
+  addsd(xmm0, xmm6);
+  addl(edx, 894);
+  cmpl(edx, 1916);
+  jcc (Assembler::above, L_2TAG_PACKET_1_0_2);
+  mulsd(xmm0, xmm2);
+  addsd(xmm0, xmm2);
+  jmp (B1_5);
+
+  bind(L_2TAG_PACKET_1_0_2);
+  xorpd(xmm3, xmm3);
+  movdqu(xmm4, ExternalAddress(ALLONES));  // 0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL
+  movl(edx, -1022);
+  subl(edx, eax);
+  movdl(xmm5, edx);
+  psllq(xmm4, xmm5);
+  movl(ecx, eax);
+  sarl(eax, 1);
+  pinsrw(xmm3, eax, 3);
+  movdqu(xmm6, ExternalAddress(ebias));    // 0x00000000UL, 0x3ff00000UL, 0x00000000UL, 0x3ff00000UL
+  psllq(xmm3, 4);
+  psubd(xmm2, xmm3);
+  mulsd(xmm0, xmm2);
+  cmpl(edx, 52);
+  jcc(Assembler::greater, L_2TAG_PACKET_2_0_2);
+  pand(xmm4, xmm2);
+  paddd(xmm3, xmm6);
+  subsd(xmm2, xmm4);
+  addsd(xmm0, xmm2);
+  cmpl(ecx, 1023);
+  jcc(Assembler::greaterEqual, L_2TAG_PACKET_3_0_2);
+  pextrw(ecx, xmm0, 3);
+  andl(ecx, 32768);
+  orl(edx, ecx);
+  cmpl(edx, 0);
+  jcc(Assembler::equal, L_2TAG_PACKET_4_0_2);
+  movapd(xmm6, xmm0);
+  addsd(xmm0, xmm4);
+  mulsd(xmm0, xmm3);
+  pextrw(ecx, xmm0, 3);
+  andl(ecx, 32752);
+  cmpl(ecx, 0);
+  jcc(Assembler::equal, L_2TAG_PACKET_5_0_2);
+  jmp(B1_5);
+
+  bind(L_2TAG_PACKET_5_0_2);
+  mulsd(xmm6, xmm3);
+  mulsd(xmm4, xmm3);
+  movdqu(xmm0, xmm6);
+  pxor(xmm6, xmm4);
+  psrad(xmm6, 31);
+  pshufd(xmm6, xmm6, 85);
+  psllq(xmm0, 1);
+  psrlq(xmm0, 1);
+  pxor(xmm0, xmm6);
+  psrlq(xmm6, 63);
+  paddq(xmm0, xmm6);
+  paddq(xmm0, xmm4);
+  movl(Address(rsp,0), 15);
+  jmp(L_2TAG_PACKET_6_0_2);
+
+  bind(L_2TAG_PACKET_4_0_2);
+  addsd(xmm0, xmm4);
+  mulsd(xmm0, xmm3);
+  jmp(B1_5);
+
+  bind(L_2TAG_PACKET_3_0_2);
+  addsd(xmm0, xmm4);
+  mulsd(xmm0, xmm3);
+  pextrw(ecx, xmm0, 3);
+  andl(ecx, 32752);
+  cmpl(ecx, 32752);
+  jcc(Assembler::aboveEqual, L_2TAG_PACKET_7_0_2);
+  jmp(B1_5);
+
+  bind(L_2TAG_PACKET_2_0_2);
+  paddd(xmm3, xmm6);
+  addpd(xmm0, xmm2);
+  mulsd(xmm0, xmm3);
+  movl(Address(rsp,0), 15);
+  jmp(L_2TAG_PACKET_6_0_2);
+
+  bind(L_2TAG_PACKET_8_0_2);
+  cmpl(eax, 2146435072);
+  jcc(Assembler::aboveEqual, L_2TAG_PACKET_9_0_2);
+  movl(eax, Address(rsp,12));
+  cmpl(eax, INT_MIN);
+  jcc(Assembler::aboveEqual, L_2TAG_PACKET_10_0_2);
+  movsd(xmm0, ExternalAddress(XMAX));      // 0xffffffffUL, 0x7fefffffUL
+  mulsd(xmm0, xmm0);
+
+  bind(L_2TAG_PACKET_7_0_2);
+  movl(Address(rsp,0), 14);
+  jmp(L_2TAG_PACKET_6_0_2);
+
+  bind(L_2TAG_PACKET_10_0_2);
+  movsd(xmm0, ExternalAddress(XMIN));      // 0x00000000UL, 0x00100000UL
+  mulsd(xmm0, xmm0);
+  movl(Address(rsp,0), 15);
+  jmp(L_2TAG_PACKET_6_0_2);
+
+  bind(L_2TAG_PACKET_9_0_2);
+  movl(edx, Address(rsp,8));
+  cmpl(eax, 2146435072);
+  jcc(Assembler::above, L_2TAG_PACKET_11_0_2);
+  cmpl(edx, 0);
+  jcc(Assembler::notEqual, L_2TAG_PACKET_11_0_2);
+  movl(eax, Address(rsp,12));
+  cmpl(eax, 2146435072);
+  jcc(Assembler::notEqual, L_2TAG_PACKET_12_0_2);
+  movsd(xmm0, ExternalAddress(INF));       // 0x00000000UL, 0x7ff00000UL
+  jmp(B1_5);
+
+  bind(L_2TAG_PACKET_12_0_2);
+  movsd(xmm0, ExternalAddress(ZERO));      // 0x00000000UL, 0x00000000UL
+  jmp(B1_5);
+
+  bind(L_2TAG_PACKET_11_0_2);
+  movsd(xmm0, Address(rsp, 8));
+  addsd(xmm0, xmm0);
+  jmp(B1_5);
+
+  bind(L_2TAG_PACKET_0_0_2);
+  movl(eax, Address(rsp, 12));
+  andl(eax, 2147483647);
+  cmpl(eax, 1083179008);
+  jcc(Assembler::aboveEqual, L_2TAG_PACKET_8_0_2);
+  movsd(Address(rsp, 8), xmm0);
+  addsd(xmm0, ExternalAddress(ONE_val));   // 0x00000000UL, 0x3ff00000UL
+  jmp(B1_5);
+
+  bind(L_2TAG_PACKET_6_0_2);
+  movq(Address(rsp, 16), xmm0);
+
+  bind(B1_3);
+  movq(xmm0, Address(rsp, 16));
+
+  bind(B1_5);
+  addq(rsp, 24);
+}
+#endif
+
+#ifndef _LP64
+
+ALIGNED_(16) juint _static_const_table[] =
+{
+    0x00000000UL, 0xfff00000UL, 0x00000000UL, 0xfff00000UL, 0xffffffc0UL,
+    0x00000000UL, 0xffffffc0UL, 0x00000000UL, 0x0000ffc0UL, 0x00000000UL,
+    0x0000ffc0UL, 0x00000000UL, 0x00000000UL, 0x43380000UL, 0x00000000UL,
+    0x43380000UL, 0x652b82feUL, 0x40571547UL, 0x652b82feUL, 0x40571547UL,
+    0xfefa0000UL, 0x3f862e42UL, 0xfefa0000UL, 0x3f862e42UL, 0xbc9e3b3aUL,
+    0x3d1cf79aUL, 0xbc9e3b3aUL, 0x3d1cf79aUL, 0xfffffffeUL, 0x3fdfffffUL,
+    0xfffffffeUL, 0x3fdfffffUL, 0xe3289860UL, 0x3f56c15cUL, 0x555b9e25UL,
+    0x3fa55555UL, 0xc090cf0fUL, 0x3f811115UL, 0x55548ba1UL, 0x3fc55555UL,
+    0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0e03754dUL,
+    0x3cad7bbfUL, 0x3e778060UL, 0x00002c9aUL, 0x3567f613UL, 0x3c8cd252UL,
+    0xd3158574UL, 0x000059b0UL, 0x61e6c861UL, 0x3c60f74eUL, 0x18759bc8UL,
+    0x00008745UL, 0x5d837b6cUL, 0x3c979aa6UL, 0x6cf9890fUL, 0x0000b558UL,
+    0x702f9cd1UL, 0x3c3ebe3dUL, 0x32d3d1a2UL, 0x0000e3ecUL, 0x1e63bcd8UL,
+    0x3ca3516eUL, 0xd0125b50UL, 0x00011301UL, 0x26f0387bUL, 0x3ca4c554UL,
+    0xaea92ddfUL, 0x0001429aUL, 0x62523fb6UL, 0x3ca95153UL, 0x3c7d517aUL,
+    0x000172b8UL, 0x3f1353bfUL, 0x3c8b898cUL, 0xeb6fcb75UL, 0x0001a35bUL,
+    0x3e3a2f5fUL, 0x3c9aecf7UL, 0x3168b9aaUL, 0x0001d487UL, 0x44a6c38dUL,
+    0x3c8a6f41UL, 0x88628cd6UL, 0x0002063bUL, 0xe3a8a894UL, 0x3c968efdUL,
+    0x6e756238UL, 0x0002387aUL, 0x981fe7f2UL, 0x3c80472bUL, 0x65e27cddUL,
+    0x00026b45UL, 0x6d09ab31UL, 0x3c82f7e1UL, 0xf51fdee1UL, 0x00029e9dUL,
+    0x720c0ab3UL, 0x3c8b3782UL, 0xa6e4030bUL, 0x0002d285UL, 0x4db0abb6UL,
+    0x3c834d75UL, 0x0a31b715UL, 0x000306feUL, 0x5dd3f84aUL, 0x3c8fdd39UL,
+    0xb26416ffUL, 0x00033c08UL, 0xcc187d29UL, 0x3ca12f8cUL, 0x373aa9caUL,
+    0x000371a7UL, 0x738b5e8bUL, 0x3ca7d229UL, 0x34e59ff6UL, 0x0003a7dbUL,
+    0xa72a4c6dUL, 0x3c859f48UL, 0x4c123422UL, 0x0003dea6UL, 0x259d9205UL,
+    0x3ca8b846UL, 0x21f72e29UL, 0x0004160aUL, 0x60c2ac12UL, 0x3c4363edUL,
+    0x6061892dUL, 0x00044e08UL, 0xdaa10379UL, 0x3c6ecce1UL, 0xb5c13cd0UL,
+    0x000486a2UL, 0xbb7aafb0UL, 0x3c7690ceUL, 0xd5362a27UL, 0x0004bfdaUL,
+    0x9b282a09UL, 0x3ca083ccUL, 0x769d2ca6UL, 0x0004f9b2UL, 0xc1aae707UL,
+    0x3ca509b0UL, 0x569d4f81UL, 0x0005342bUL, 0x18fdd78eUL, 0x3c933505UL,
+    0x36b527daUL, 0x00056f47UL, 0xe21c5409UL, 0x3c9063e1UL, 0xdd485429UL,
+    0x0005ab07UL, 0x2b64c035UL, 0x3c9432e6UL, 0x15ad2148UL, 0x0005e76fUL,
+    0x99f08c0aUL, 0x3ca01284UL, 0xb03a5584UL, 0x0006247eUL, 0x0073dc06UL,
+    0x3c99f087UL, 0x82552224UL, 0x00066238UL, 0x0da05571UL, 0x3c998d4dUL,
+    0x667f3bccUL, 0x0006a09eUL, 0x86ce4786UL, 0x3ca52bb9UL, 0x3c651a2eUL,
+    0x0006dfb2UL, 0x206f0dabUL, 0x3ca32092UL, 0xe8ec5f73UL, 0x00071f75UL,
+    0x8e17a7a6UL, 0x3ca06122UL, 0x564267c8UL, 0x00075febUL, 0x461e9f86UL,
+    0x3ca244acUL, 0x73eb0186UL, 0x0007a114UL, 0xabd66c55UL, 0x3c65ebe1UL,
+    0x36cf4e62UL, 0x0007e2f3UL, 0xbbff67d0UL, 0x3c96fe9fUL, 0x994cce12UL,
+    0x00082589UL, 0x14c801dfUL, 0x3c951f14UL, 0x9b4492ecUL, 0x000868d9UL,
+    0xc1f0eab4UL, 0x3c8db72fUL, 0x422aa0dbUL, 0x0008ace5UL, 0x59f35f44UL,
+    0x3c7bf683UL, 0x99157736UL, 0x0008f1aeUL, 0x9c06283cUL, 0x3ca360baUL,
+    0xb0cdc5e4UL, 0x00093737UL, 0x20f962aaUL, 0x3c95e8d1UL, 0x9fde4e4fUL,
+    0x00097d82UL, 0x2b91ce27UL, 0x3c71affcUL, 0x82a3f090UL, 0x0009c491UL,
+    0x589a2ebdUL, 0x3c9b6d34UL, 0x7b5de564UL, 0x000a0c66UL, 0x9ab89880UL,
+    0x3c95277cUL, 0xb23e255cUL, 0x000a5503UL, 0x6e735ab3UL, 0x3c846984UL,
+    0x5579fdbfUL, 0x000a9e6bUL, 0x92cb3387UL, 0x3c8c1a77UL, 0x995ad3adUL,
+    0x000ae89fUL, 0xdc2d1d96UL, 0x3ca22466UL, 0xb84f15faUL, 0x000b33a2UL,
+    0xb19505aeUL, 0x3ca1112eUL, 0xf2fb5e46UL, 0x000b7f76UL, 0x0a5fddcdUL,
+    0x3c74ffd7UL, 0x904bc1d2UL, 0x000bcc1eUL, 0x30af0cb3UL, 0x3c736eaeUL,
+    0xdd85529cUL, 0x000c199bUL, 0xd10959acUL, 0x3c84e08fUL, 0x2e57d14bUL,
+    0x000c67f1UL, 0x6c921968UL, 0x3c676b2cUL, 0xdcef9069UL, 0x000cb720UL,
+    0x36df99b3UL, 0x3c937009UL, 0x4a07897bUL, 0x000d072dUL, 0xa63d07a7UL,
+    0x3c74a385UL, 0xdcfba487UL, 0x000d5818UL, 0xd5c192acUL, 0x3c8e5a50UL,
+    0x03db3285UL, 0x000da9e6UL, 0x1c4a9792UL, 0x3c98bb73UL, 0x337b9b5eUL,
+    0x000dfc97UL, 0x603a88d3UL, 0x3c74b604UL, 0xe78b3ff6UL, 0x000e502eUL,
+    0x92094926UL, 0x3c916f27UL, 0xa2a490d9UL, 0x000ea4afUL, 0x41aa2008UL,
+    0x3c8ec3bcUL, 0xee615a27UL, 0x000efa1bUL, 0x31d185eeUL, 0x3c8a64a9UL,
+    0x5b6e4540UL, 0x000f5076UL, 0x4d91cd9dUL, 0x3c77893bUL, 0x819e90d8UL,
+    0x000fa7c1UL, 0x00000000UL, 0x3ff00000UL, 0x00000000UL, 0x7ff00000UL,
+    0x00000000UL, 0x00000000UL, 0xffffffffUL, 0x7fefffffUL, 0x00000000UL,
+    0x00100000UL
+};
+
+//registers,
+// input: (rbp + 8)
+// scratch: xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
+//          rax, rdx, rcx, rbx (tmp)
+
+// Code generated by Intel C compiler for LIBM library
+
+void MacroAssembler::fast_exp(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xmm2, XMMRegister xmm3, XMMRegister xmm4, XMMRegister xmm5, XMMRegister xmm6, XMMRegister xmm7, Register eax, Register ecx, Register edx, Register tmp) {
+  Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2;
+  Label L_2TAG_PACKET_4_0_2, L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2, L_2TAG_PACKET_7_0_2;
+  Label L_2TAG_PACKET_8_0_2, L_2TAG_PACKET_9_0_2, L_2TAG_PACKET_10_0_2, L_2TAG_PACKET_11_0_2;
+  Label L_2TAG_PACKET_12_0_2, L_2TAG_PACKET_13_0_2, B1_3, B1_5, start;
+
+  assert_different_registers(tmp, eax, ecx, edx);
+  jmp(start);
+  address static_const_table = (address)_static_const_table;
+
+  bind(start);
+  subl(rsp, 120);
+  movl(Address(rsp, 64), tmp);
+  lea(tmp, ExternalAddress(static_const_table));
+  movdqu(xmm0, Address(rsp, 128));
+  unpcklpd(xmm0, xmm0);
+  movdqu(xmm1, Address(tmp, 64));          // 0x652b82feUL, 0x40571547UL, 0x652b82feUL, 0x40571547UL
+  movdqu(xmm6, Address(tmp, 48));          // 0x00000000UL, 0x43380000UL, 0x00000000UL, 0x43380000UL
+  movdqu(xmm2, Address(tmp, 80));          // 0xfefa0000UL, 0x3f862e42UL, 0xfefa0000UL, 0x3f862e42UL
+  movdqu(xmm3, Address(tmp, 96));          // 0xbc9e3b3aUL, 0x3d1cf79aUL, 0xbc9e3b3aUL, 0x3d1cf79aUL
+  pextrw(eax, xmm0, 3);
+  andl(eax, 32767);
+  movl(edx, 16527);
+  subl(edx, eax);
+  subl(eax, 15504);
+  orl(edx, eax);
+  cmpl(edx, INT_MIN);
+  jcc(Assembler::aboveEqual, L_2TAG_PACKET_0_0_2);
+  mulpd(xmm1, xmm0);
+  addpd(xmm1, xmm6);
+  movapd(xmm7, xmm1);
+  subpd(xmm1, xmm6);
+  mulpd(xmm2, xmm1);
+  movdqu(xmm4, Address(tmp, 128));         // 0xe3289860UL, 0x3f56c15cUL, 0x555b9e25UL, 0x3fa55555UL
+  mulpd(xmm3, xmm1);
+  movdqu(xmm5, Address(tmp, 144));         // 0xc090cf0fUL, 0x3f811115UL, 0x55548ba1UL, 0x3fc55555UL
+  subpd(xmm0, xmm2);
+  movdl(eax, xmm7);
+  movl(ecx, eax);
+  andl(ecx, 63);
+  shll(ecx, 4);
+  sarl(eax, 6);
+  movl(edx, eax);
+  movdqu(xmm6, Address(tmp, 16));          // 0xffffffc0UL, 0x00000000UL, 0xffffffc0UL, 0x00000000UL
+  pand(xmm7, xmm6);
+  movdqu(xmm6, Address(tmp, 32));          // 0x0000ffc0UL, 0x00000000UL, 0x0000ffc0UL, 0x00000000UL
+  paddq(xmm7, xmm6);
+  psllq(xmm7, 46);
+  subpd(xmm0, xmm3);
+  movdqu(xmm2, Address(tmp, ecx, Address::times_1, 160));
+  mulpd(xmm4, xmm0);
+  movapd(xmm6, xmm0);
+  movapd(xmm1, xmm0);
+  mulpd(xmm6, xmm6);
+  mulpd(xmm0, xmm6);
+  addpd(xmm5, xmm4);
+  mulsd(xmm0, xmm6);
+  mulpd(xmm6, Address(tmp, 112));          // 0xfffffffeUL, 0x3fdfffffUL, 0xfffffffeUL, 0x3fdfffffUL
+  addsd(xmm1, xmm2);
+  unpckhpd(xmm2, xmm2);
+  mulpd(xmm0, xmm5);
+  addsd(xmm1, xmm0);
+  por(xmm2, xmm7);
+  unpckhpd(xmm0, xmm0);
+  addsd(xmm0, xmm1);
+  addsd(xmm0, xmm6);
+  addl(edx, 894);
+  cmpl(edx, 1916);
+  jcc (Assembler::above, L_2TAG_PACKET_1_0_2);
+  mulsd(xmm0, xmm2);
+  addsd(xmm0, xmm2);
+  jmp(L_2TAG_PACKET_2_0_2);
+
+  bind(L_2TAG_PACKET_1_0_2);
+  fnstcw(Address(rsp, 24));
+  movzwl(edx, Address(rsp, 24));
+  orl(edx, 768);
+  movw(Address(rsp, 28), edx);
+  fldcw(Address(rsp, 28));
+  movl(edx, eax);
+  sarl(eax, 1);
+  subl(edx, eax);
+  movdqu(xmm6, Address(tmp, 0));           // 0x00000000UL, 0xfff00000UL, 0x00000000UL, 0xfff00000UL
+  pandn(xmm6, xmm2);
+  addl(eax, 1023);
+  movdl(xmm3, eax);
+  psllq(xmm3, 52);
+  por(xmm6, xmm3);
+  addl(edx, 1023);
+  movdl(xmm4, edx);
+  psllq(xmm4, 52);
+  movsd(Address(rsp, 8), xmm0);
+  fld_d(Address(rsp, 8));
+  movsd(Address(rsp, 16), xmm6);
+  fld_d(Address(rsp, 16));
+  fmula(1);
+  faddp(1);
+  movsd(Address(rsp, 8), xmm4);
+  fld_d(Address(rsp, 8));
+  fmulp(1);
+  fstp_d(Address(rsp, 8));
+  movsd(xmm0,Address(rsp, 8));
+  fldcw(Address(rsp, 24));
+  pextrw(ecx, xmm0, 3);
+  andl(ecx, 32752);
+  cmpl(ecx, 32752);
+  jcc(Assembler::greaterEqual, L_2TAG_PACKET_3_0_2);
+  cmpl(ecx, 0);
+  jcc(Assembler::equal, L_2TAG_PACKET_4_0_2);
+  jmp(L_2TAG_PACKET_2_0_2);
+  cmpl(ecx, INT_MIN);
+  jcc(Assembler::less, L_2TAG_PACKET_3_0_2);
+  cmpl(ecx, -1064950997);
+  jcc(Assembler::less, L_2TAG_PACKET_2_0_2);
+  jcc(Assembler::greater, L_2TAG_PACKET_4_0_2);
+  movl(edx, Address(rsp, 128));
+  cmpl(edx ,-17155601);
+  jcc(Assembler::less, L_2TAG_PACKET_2_0_2);
+  jmp(L_2TAG_PACKET_4_0_2);
+
+  bind(L_2TAG_PACKET_3_0_2);
+  movl(edx, 14);
+  jmp(L_2TAG_PACKET_5_0_2);
+
+  bind(L_2TAG_PACKET_4_0_2);
+  movl(edx, 15);
+
+  bind(L_2TAG_PACKET_5_0_2);
+  movsd(Address(rsp, 0), xmm0);
+  movsd(xmm0, Address(rsp, 128));
+  fld_d(Address(rsp, 0));
+  jmp(L_2TAG_PACKET_6_0_2);
+
+  bind(L_2TAG_PACKET_7_0_2);
+  cmpl(eax, 2146435072);
+  jcc(Assembler::greaterEqual, L_2TAG_PACKET_8_0_2);
+  movl(eax, Address(rsp, 132));
+  cmpl(eax, INT_MIN);
+  jcc(Assembler::greaterEqual, L_2TAG_PACKET_9_0_2);
+  movsd(xmm0, Address(tmp, 1208));         // 0xffffffffUL, 0x7fefffffUL
+  mulsd(xmm0, xmm0);
+  movl(edx, 14);
+  jmp(L_2TAG_PACKET_5_0_2);
+
+  bind(L_2TAG_PACKET_9_0_2);
+  movsd(xmm0, Address(tmp, 1216));
+  mulsd(xmm0, xmm0);
+  movl(edx, 15);
+  jmp(L_2TAG_PACKET_5_0_2);
+
+  bind(L_2TAG_PACKET_8_0_2);
+  movl(edx, Address(rsp, 128));
+  cmpl(eax, 2146435072);
+  jcc(Assembler::above, L_2TAG_PACKET_10_0_2);
+  cmpl(edx, 0);
+  jcc(Assembler::notEqual, L_2TAG_PACKET_10_0_2);
+  movl(eax, Address(rsp, 132));
+  cmpl(eax, 2146435072);
+  jcc(Assembler::notEqual, L_2TAG_PACKET_11_0_2);
+  movsd(xmm0, Address(tmp, 1192));         // 0x00000000UL, 0x7ff00000UL
+  jmp(L_2TAG_PACKET_2_0_2);
+
+  bind(L_2TAG_PACKET_11_0_2);
+  movsd(xmm0, Address(tmp, 1200));         // 0x00000000UL, 0x00000000UL
+  jmp(L_2TAG_PACKET_2_0_2);
+
+  bind(L_2TAG_PACKET_10_0_2);
+  movsd(xmm0, Address(rsp, 128));
+  addsd(xmm0, xmm0);
+  jmp(L_2TAG_PACKET_2_0_2);
+
+  bind(L_2TAG_PACKET_0_0_2);
+  movl(eax, Address(rsp, 132));
+  andl(eax, 2147483647);
+  cmpl(eax, 1083179008);
+  jcc(Assembler::aboveEqual, L_2TAG_PACKET_7_0_2);
+  movsd(xmm0, Address(rsp, 128));
+  addsd(xmm0, Address(tmp, 1184));         // 0x00000000UL, 0x3ff00000UL
+  jmp(L_2TAG_PACKET_2_0_2);
+
+  bind(L_2TAG_PACKET_2_0_2);
+  movsd(Address(rsp, 48), xmm0);
+  fld_d(Address(rsp, 48));
+
+  bind(L_2TAG_PACKET_6_0_2);
+  movl(tmp, Address(rsp, 64));
+}
+
+#endif
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,8 +30,6 @@
 #include "memory/allocation.inline.hpp"
 #include "prims/methodHandles.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #define __ _masm->
 
 #ifdef PRODUCT
@@ -53,7 +51,7 @@
 
 #ifdef ASSERT
 static int check_nonzero(const char* xname, int x) {
-  assert(x != 0, err_msg("%s should be nonzero", xname));
+  assert(x != 0, "%s should be nonzero", xname);
   return x;
 }
 #define NONZERO(x) check_nonzero(#x, x)
@@ -456,7 +454,7 @@
     }
 
     default:
-      fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+      fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
       break;
     }
 
@@ -488,7 +486,7 @@
   const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx";
   tty->print_cr("MH %s %s=" PTR_FORMAT " sp=" PTR_FORMAT,
                 adaptername, mh_reg_name,
-                (void *)mh, entry_sp);
+                p2i(mh), p2i(entry_sp));
 
   if (Verbose) {
     tty->print_cr("Registers:");
--- a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -35,18 +35,15 @@
 #include "c1/c1_Runtime1.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 void NativeInstruction::wrote(int offset) {
   ICache::invalidate_word(addr_at(offset));
 }
 
-
 void NativeCall::verify() {
   // Make sure code pattern is actually a call imm32 instruction.
   int inst = ubyte_at(0);
   if (inst != instruction_code) {
-    tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", instruction_address(),
+    tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()),
                                                         inst);
     fatal("not a call disp32");
   }
@@ -63,7 +60,7 @@
 
 void NativeCall::print() {
   tty->print_cr(PTR_FORMAT ": call " PTR_FORMAT,
-                instruction_address(), destination());
+                p2i(instruction_address()), p2i(destination()));
 }
 
 // Inserts a native call instruction at a given pc
@@ -230,7 +227,7 @@
 
 void NativeMovConstReg::print() {
   tty->print_cr(PTR_FORMAT ": mov reg, " INTPTR_FORMAT,
-                instruction_address(), data());
+                p2i(instruction_address()), data());
 }
 
 //-------------------------------------------------------------------
@@ -396,7 +393,7 @@
 
 
 void NativeMovRegMem::print() {
-  tty->print_cr("0x%x: mov reg, [reg + %x]", instruction_address(), offset());
+  tty->print_cr(PTR_FORMAT ": mov reg, [reg + %x]", p2i(instruction_address()), offset());
 }
 
 //-------------------------------------------------------------------
@@ -418,7 +415,7 @@
 
 
 void NativeLoadAddress::print() {
-  tty->print_cr("0x%x: lea [reg + %x], reg", instruction_address(), offset());
+  tty->print_cr(PTR_FORMAT ": lea [reg + %x], reg", p2i(instruction_address()), offset());
 }
 
 //--------------------------------------------------------------------------------
@@ -474,6 +471,7 @@
 //
 // In C2 the 5+ byte sized instruction is enforced by code in MachPrologNode::emit.
 // In C1 the restriction is enforced by CodeEmitter::method_entry
+// In JVMCI, the restriction is enforced by HotSpotFrameContext.enter(...)
 //
 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
   // complete jump instruction (to be inserted) is in code_buffer;
--- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -60,6 +60,7 @@
 
   bool is_nop()                        { return ubyte_at(0) == nop_instruction_code; }
   inline bool is_call();
+  inline bool is_call_reg();
   inline bool is_illegal();
   inline bool is_return();
   inline bool is_jump();
@@ -180,6 +181,24 @@
   return call;
 }
 
+class NativeCallReg: public NativeInstruction {
+ public:
+  enum Intel_specific_constants {
+    instruction_code            = 0xFF,
+    instruction_offset          =    0,
+    return_address_offset_norex =    2,
+    return_address_offset_rex   =    3
+  };
+
+  int next_instruction_offset() const  {
+    if (ubyte_at(0) == NativeCallReg::instruction_code) {
+      return return_address_offset_norex;
+    } else {
+      return return_address_offset_rex;
+    }
+  }
+};
+
 // An interface for accessing/manipulating native mov reg, imm32 instructions.
 // (used to manipulate inlined 32bit data dll calls, etc.)
 class NativeMovConstReg: public NativeInstruction {
@@ -519,6 +538,9 @@
 
 inline bool NativeInstruction::is_illegal()      { return (short)int_at(0) == (short)NativeIllegalInstruction::instruction_code; }
 inline bool NativeInstruction::is_call()         { return ubyte_at(0) == NativeCall::instruction_code; }
+inline bool NativeInstruction::is_call_reg()     { return ubyte_at(0) == NativeCallReg::instruction_code ||
+                                                          (ubyte_at(1) == NativeCallReg::instruction_code &&
+                                                           (ubyte_at(0) == Assembler::REX || ubyte_at(0) == Assembler::REX_B)); }
 inline bool NativeInstruction::is_return()       { return ubyte_at(0) == NativeReturn::instruction_code ||
                                                           ubyte_at(0) == NativeReturnX::instruction_code; }
 inline bool NativeInstruction::is_jump()         { return ubyte_at(0) == NativeJump::instruction_code ||
@@ -527,26 +549,24 @@
                                                           (ubyte_at(0) & 0xF0) == 0x70;  /* short jump */ }
 inline bool NativeInstruction::is_safepoint_poll() {
 #ifdef AMD64
-  if (Assembler::is_polling_page_far()) {
-    // two cases, depending on the choice of the base register in the address.
-    if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
-         ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
-         (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
-        ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
-        (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) {
-      return true;
-    } else {
-      return false;
-    }
-  } else {
-    if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
-        ubyte_at(1) == 0x05) { // 00 rax 101
-      address fault = addr_at(6) + int_at(2);
-      return os::is_poll_address(fault);
-    } else {
-      return false;
-    }
+  // Try decoding a near safepoint first:
+  if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
+      ubyte_at(1) == 0x05) { // 00 rax 101
+    address fault = addr_at(6) + int_at(2);
+    NOT_JVMCI(assert(!Assembler::is_polling_page_far(), "unexpected poll encoding");)
+    return os::is_poll_address(fault);
   }
+  // Now try decoding a far safepoint:
+  // two cases, depending on the choice of the base register in the address.
+  if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
+       ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
+       (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
+      ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
+      (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) {
+    NOT_JVMCI(assert(Assembler::is_polling_page_far(), "unexpected poll encoding");)
+    return true;
+  }
+  return false;
 #else
   return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
            ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) &&
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/x86/vm/registerMap_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, 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 "runtime/registerMap.hpp"
+#include "vmreg_x86.inline.hpp"
+
+address RegisterMap::pd_location(VMReg reg) const {
+  if (reg->is_XMMRegister()) {
+    int regBase = reg->value() - ConcreteRegisterImpl::max_fpr;
+    if (regBase % 4 == 0) {
+      // Reads of the low and high 16 byte parts should be handled by location itself
+      // because they have separate callee saved entries.
+      // See RegisterSaver::save_live_registers().
+      return NULL;
+    }
+    VMReg baseReg = as_XMMRegister(regBase / XMMRegisterImpl::max_slots_per_register)->as_VMReg();
+    intptr_t offset = (reg->value() - baseReg->value()) * VMRegImpl::stack_slot_size; // offset in bytes
+    if (offset >= 16) {
+      // The high part of YMM registers are saved in a their own area in the frame
+      baseReg = baseReg->next()->next()->next()->next();
+      offset -= 16;
+    }
+    address baseLocation = location(baseReg);
+    if (baseLocation != NULL) {
+      return baseLocation + offset;
+    }
+  }
+  return NULL;
+}
--- a/hotspot/src/cpu/x86/vm/registerMap_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/registerMap_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,11 +31,7 @@
  private:
   // This is the hook for finding a register in an "well-known" location,
   // such as a register block of a predetermined format.
-  // Since there is none, we just return NULL.
-  // See registerMap_sparc.hpp for an example of grabbing registers
-  // from register save areas of a standard layout.
-   address pd_location(VMReg reg) const {return NULL;}
-
+  address pd_location(VMReg reg) const;
   // no PD state to clear or copy:
   void pd_clear() {}
   void pd_initialize() {}
--- a/hotspot/src/cpu/x86/vm/register_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/register_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -69,6 +69,31 @@
   return is_valid() ? names[encoding()] : "xnoreg";
 }
 
+const char* XMMRegisterImpl::sub_word_name(int i) const {
+  const char* names[number_of_registers * 8] = {
+      "xmm0:0", "xmm0:1", "xmm0:2", "xmm0:3", "xmm0:4", "xmm0:5", "xmm0:6", "xmm0:7",
+      "xmm1:0", "xmm1:1", "xmm1:2", "xmm1:3", "xmm1:4", "xmm1:5", "xmm1:6", "xmm1:7",
+      "xmm2:0", "xmm2:1", "xmm2:2", "xmm2:3", "xmm2:4", "xmm2:5", "xmm2:6", "xmm2:7",
+      "xmm3:0", "xmm3:1", "xmm3:2", "xmm3:3", "xmm3:4", "xmm3:5", "xmm3:6", "xmm3:7",
+      "xmm4:0", "xmm4:1", "xmm4:2", "xmm4:3", "xmm4:4", "xmm4:5", "xmm4:6", "xmm4:7",
+      "xmm5:0", "xmm5:1", "xmm5:2", "xmm5:3", "xmm5:4", "xmm5:5", "xmm5:6", "xmm5:7",
+      "xmm6:0", "xmm6:1", "xmm6:2", "xmm6:3", "xmm6:4", "xmm6:5", "xmm6:6", "xmm6:7",
+      "xmm7:0", "xmm7:1", "xmm7:2", "xmm7:3", "xmm7:4", "xmm7:5", "xmm7:6", "xmm7:7",
+#ifdef AMD64
+      "xmm8:0", "xmm8:1", "xmm8:2", "xmm8:3", "xmm8:4", "xmm8:5", "xmm8:6", "xmm8:7",
+      "xmm9:0", "xmm9:1", "xmm9:2", "xmm9:3", "xmm9:4", "xmm9:5", "xmm9:6", "xmm9:7",
+      "xmm10:0", "xmm10:1", "xmm10:2", "xmm10:3", "xmm10:4", "xmm10:5", "xmm10:6", "xmm10:7",
+      "xmm11:0", "xmm11:1", "xmm11:2", "xmm11:3", "xmm11:4", "xmm11:5", "xmm11:6", "xmm11:7",
+      "xmm12:0", "xmm12:1", "xmm12:2", "xmm12:3", "xmm12:4", "xmm12:5", "xmm12:6", "xmm12:7",
+      "xmm13:0", "xmm13:1", "xmm13:2", "xmm13:3", "xmm13:4", "xmm13:5", "xmm13:6", "xmm13:7",
+      "xmm14:0", "xmm14:1", "xmm14:2", "xmm14:3", "xmm14:4", "xmm14:5", "xmm14:6", "xmm14:7",
+      "xmm15:0", "xmm15:1", "xmm15:2", "xmm15:3", "xmm15:4", "xmm15:5", "xmm15:6", "xmm15:7",
+#endif // AMD64
+  };
+  assert(i >= 0 && i < 8, "offset too large");
+  return is_valid() ? names[encoding() * 8 + i] : "xnoreg";
+}
+
 const char* KRegisterImpl::name() const {
   const char* names[number_of_registers] = {
     "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7"
--- a/hotspot/src/cpu/x86/vm/register_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/register_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -162,9 +162,10 @@
   XMMRegister successor() const                          { return as_XMMRegister(encoding() + 1); }
 
   // accessors
-  int   encoding() const                          { assert(is_valid(), err_msg("invalid register (%d)", (int)(intptr_t)this )); return (intptr_t)this; }
+  int   encoding() const                          { assert(is_valid(), "invalid register (%d)", (int)(intptr_t)this ); return (intptr_t)this; }
   bool  is_valid() const                          { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
   const char* name() const;
+  const char* sub_word_name(int offset) const;
 };
 
 
@@ -245,7 +246,7 @@
   KRegister successor() const                          { return as_KRegister(encoding() + 1); }
 
   // accessors
-  int   encoding() const                          { assert(is_valid(), err_msg("invalid register (%d)", (int)(intptr_t)this)); return (intptr_t)this; }
+  int   encoding() const                          { assert(is_valid(), "invalid register (%d)", (int)(intptr_t)this); return (intptr_t)this; }
   bool  is_valid() const                          { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
   const char* name() const;
 };
--- a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -180,39 +180,17 @@
 
 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
 #ifdef _LP64
-  if (!Assembler::is_polling_page_far()) {
-    typedef Assembler::WhichOperand WhichOperand;
-    WhichOperand which = (WhichOperand) format();
-    // This format is imm but it is really disp32
-    which = Assembler::disp32_operand;
+  typedef Assembler::WhichOperand WhichOperand;
+  WhichOperand which = (WhichOperand) format();
+#if !INCLUDE_JVMCI
+  assert((which == Assembler::disp32_operand) == !Assembler::is_polling_page_far(), "format not set correctly");
+#endif
+  if (which == Assembler::disp32_operand) {
     address orig_addr = old_addr_for(addr(), src, dest);
     NativeInstruction* oni = nativeInstruction_at(orig_addr);
     int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
     // This poll_addr is incorrect by the size of the instruction it is irrelevant
     intptr_t poll_addr = (intptr_t)oni + *orig_disp;
-
-    NativeInstruction* ni = nativeInstruction_at(addr());
-    intptr_t new_disp = poll_addr - (intptr_t) ni;
-
-    int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
-    * disp = (int32_t)new_disp;
-  }
-#endif // _LP64
-}
-
-void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
-#ifdef _LP64
-  if (!Assembler::is_polling_page_far()) {
-    typedef Assembler::WhichOperand WhichOperand;
-    WhichOperand which = (WhichOperand) format();
-    // This format is imm but it is really disp32
-    which = Assembler::disp32_operand;
-    address orig_addr = old_addr_for(addr(), src, dest);
-    NativeInstruction* oni = nativeInstruction_at(orig_addr);
-    int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
-    // This poll_addr is incorrect by the size of the instruction it is irrelevant
-    intptr_t poll_addr = (intptr_t)oni + *orig_disp;
-
     NativeInstruction* ni = nativeInstruction_at(addr());
     intptr_t new_disp = poll_addr - (intptr_t) ni;
 
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -699,12 +699,11 @@
   __ bind(L_fail);
 }
 
-static void gen_i2c_adapter(MacroAssembler *masm,
-                            int total_args_passed,
-                            int comp_args_on_stack,
-                            const BasicType *sig_bt,
-                            const VMRegPair *regs) {
-
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
+                                    int total_args_passed,
+                                    int comp_args_on_stack,
+                                    const BasicType *sig_bt,
+                                    const VMRegPair *regs) {
   // Note: rsi contains the senderSP on entry. We must preserve it since
   // we may do a i2c -> c2i transition if we lose a race where compiled
   // code goes non-entrant while we get args ready.
@@ -1434,7 +1433,7 @@
   } else if (iid == vmIntrinsics::_invokeBasic) {
     has_receiver = true;
   } else {
-    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+    fatal("unexpected intrinsic id %d", iid);
   }
 
   if (member_reg != noreg) {
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,6 +43,9 @@
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciJavaClasses.hpp"
+#endif
 
 #define __ masm->
 
@@ -158,23 +161,25 @@
 
 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
   int vect_words = 0;
+  int ymmhi_offset = -1;
   int off = 0;
   int num_xmm_regs = XMMRegisterImpl::number_of_registers;
   if (UseAVX < 3) {
     num_xmm_regs = num_xmm_regs/2;
   }
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   if (save_vectors) {
     assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
     assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
     // Save upper half of YMM registers
     vect_words = 16 * num_xmm_regs / wordSize;
     if (UseAVX < 3) {
+      ymmhi_offset = additional_frame_words;
       additional_frame_words += vect_words;
     }
   }
 #else
-  assert(!save_vectors, "vectors are generated only by C2");
+  assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
 #endif
 
   // Always make the frame size 16-byte aligned
@@ -220,6 +225,7 @@
   OopMap* map = new OopMap(frame_size_in_slots, 0);
 
 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots)
+#define YMMHI_STACK_OFFSET(x) VMRegImpl::stack2reg((x / VMRegImpl::stack_slot_size) + ymmhi_offset)
 
   map->set_callee_saved(STACK_OFFSET( rax_off ), rax->as_VMReg());
   map->set_callee_saved(STACK_OFFSET( rcx_off ), rcx->as_VMReg());
@@ -257,6 +263,28 @@
     }
   }
 
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  if (save_vectors) {
+    assert(ymmhi_offset != -1, "save area must exist");
+    map->set_callee_saved(YMMHI_STACK_OFFSET(  0), xmm0->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET( 16), xmm1->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET( 32), xmm2->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET( 48), xmm3->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET( 64), xmm4->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET( 80), xmm5->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET( 96), xmm6->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(112), xmm7->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(128), xmm8->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(144), xmm9->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(160), xmm10->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(176), xmm11->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(192), xmm12->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(208), xmm13->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(224), xmm14->as_VMReg()->next(4));
+    map->set_callee_saved(YMMHI_STACK_OFFSET(240), xmm15->as_VMReg()->next(4));
+  }
+#endif // COMPILER2 || INCLUDE_JVMCI
+
   // %%% These should all be a waste but we'll keep things as they were for now
   if (true) {
     map->set_callee_saved(STACK_OFFSET( raxH_off ), rax->as_VMReg()->next());
@@ -307,7 +335,7 @@
     // Pop arg register save area
     __ addptr(rsp, frame::arg_reg_save_area_bytes);
   }
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   // On EVEX enabled targets everything is handled in pop fpu state
   if ((restore_vectors) && (UseAVX < 3)) {
     assert(UseAVX > 0, "256/512-bit vectors are supported only with AVX");
@@ -320,7 +348,7 @@
     __ addptr(rsp, num_xmm_regs*16);
   }
 #else
-  assert(!restore_vectors, "vectors are generated only by C2");
+  assert(!restore_vectors, "vectors are generated only by C2 and JVMCI");
 #endif
   // Recover CPU state
   __ pop_CPU_state();
@@ -655,11 +683,11 @@
   __ bind(L_fail);
 }
 
-static void gen_i2c_adapter(MacroAssembler *masm,
-                            int total_args_passed,
-                            int comp_args_on_stack,
-                            const BasicType *sig_bt,
-                            const VMRegPair *regs) {
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
+                                    int total_args_passed,
+                                    int comp_args_on_stack,
+                                    const BasicType *sig_bt,
+                                    const VMRegPair *regs) {
 
   // Note: r13 contains the senderSP on entry. We must preserve it since
   // we may do a i2c -> c2i transition if we lose a race where compiled
@@ -752,6 +780,18 @@
   // Pre-load the register-jump target early, to schedule it better.
   __ movptr(r11, Address(rbx, in_bytes(Method::from_compiled_offset())));
 
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    // check if this call should be routed towards a specific entry point
+    __ cmpptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
+    Label no_alternative_target;
+    __ jcc(Assembler::equal, no_alternative_target);
+    __ movptr(r11, Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
+    __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
+    __ bind(no_alternative_target);
+  }
+#endif // INCLUDE_JVMCI
+
   // Now generate the shuffle code.  Pick up all register args and move the
   // rest through the floating point stack top.
   for (int i = 0; i < total_args_passed; i++) {
@@ -1695,7 +1735,7 @@
   } else if (iid == vmIntrinsics::_invokeBasic) {
     has_receiver = true;
   } else {
-    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+    fatal("unexpected intrinsic id %d", iid);
   }
 
   if (member_reg != noreg) {
@@ -2685,7 +2725,13 @@
   // Allocate space for the code
   ResourceMark rm;
   // Setup code generation tools
-  CodeBuffer buffer("deopt_blob", 2048, 1024);
+  int pad = 0;
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    pad += 512; // Increase the buffer size when compiling for JVMCI
+  }
+#endif
+  CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
   MacroAssembler* masm = new MacroAssembler(&buffer);
   int frame_size_in_words;
   OopMap* map = NULL;
@@ -2734,6 +2780,12 @@
   __ jmp(cont);
 
   int reexecute_offset = __ pc() - start;
+#if INCLUDE_JVMCI && !defined(COMPILER1)
+  if (EnableJVMCI && UseJVMCICompiler) {
+    // JVMCI does not use this kind of deoptimization
+    __ should_not_reach_here();
+  }
+#endif
 
   // Reexecute case
   // return address is the pc describes what bci to do re-execute at
@@ -2744,6 +2796,38 @@
   __ movl(r14, Deoptimization::Unpack_reexecute); // callee-saved
   __ jmp(cont);
 
+#if INCLUDE_JVMCI
+  Label after_fetch_unroll_info_call;
+  int implicit_exception_uncommon_trap_offset = 0;
+  int uncommon_trap_offset = 0;
+
+  if (EnableJVMCI) {
+    implicit_exception_uncommon_trap_offset = __ pc() - start;
+
+    __ pushptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
+    __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())), (int32_t)NULL_WORD);
+
+    uncommon_trap_offset = __ pc() - start;
+
+    // Save everything in sight.
+    RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
+    // fetch_unroll_info needs to call last_java_frame()
+    __ set_last_Java_frame(noreg, noreg, NULL);
+
+    __ movl(c_rarg1, Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())));
+    __ movl(Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())), -1);
+
+    __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
+    __ mov(c_rarg0, r15_thread);
+    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
+    oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
+
+    __ reset_last_Java_frame(false, false);
+
+    __ jmp(after_fetch_unroll_info_call);
+  } // EnableJVMCI
+#endif // INCLUDE_JVMCI
+
   int exception_offset = __ pc() - start;
 
   // Prolog for exception case
@@ -2829,6 +2913,12 @@
 
   __ reset_last_Java_frame(false, false);
 
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    __ bind(after_fetch_unroll_info_call);
+  }
+#endif
+
   // Load UnrollBlock* into rdi
   __ mov(rdi, rax);
 
@@ -3003,6 +3093,12 @@
 
   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
+    _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
+  }
+#endif
 }
 
 #ifdef COMPILER2
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -2135,14 +2135,6 @@
       __ ret(0);
     }
     {
-      StubCodeMark mark(this, "StubRoutines", "exp");
-      StubRoutines::_intrinsic_exp = (double (*)(double)) __ pc();
-
-      __ fld_d(Address(rsp, 4));
-      __ exp_with_fallback(0);
-      __ ret(0);
-    }
-    {
       StubCodeMark mark(this, "StubRoutines", "pow");
       StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc();
 
@@ -2991,6 +2983,89 @@
     return start;
   }
 
+  /**
+  *  Arguments:
+  *
+  * Inputs:
+  *   rsp(4)   - int crc
+  *   rsp(8)   - byte* buf
+  *   rsp(12)  - int length
+  *   rsp(16)  - table_start - optional (present only when doing a library_calll,
+  *              not used by x86 algorithm)
+  *
+  * Ouput:
+  *       rax  - int crc result
+  */
+  address generate_updateBytesCRC32C(bool is_pclmulqdq_supported) {
+    assert(UseCRC32CIntrinsics, "need SSE4_2");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C");
+    address start = __ pc();
+    const Register crc = rax;  // crc
+    const Register buf = rcx;  // source java byte array address
+    const Register len = rdx;  // length
+    const Register d = rbx;
+    const Register g = rsi;
+    const Register h = rdi;
+    const Register empty = 0; // will never be used, in order not
+                              // to change a signature for crc32c_IPL_Alg2_Alt2
+                              // between 64/32 I'm just keeping it here
+    assert_different_registers(crc, buf, len, d, g, h);
+
+    BLOCK_COMMENT("Entry:");
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+    Address crc_arg(rsp, 4 + 4 + 0); // ESP+4 +
+                                     // we need to add additional 4 because __ enter
+                                     // have just pushed ebp on a stack
+    Address buf_arg(rsp, 4 + 4 + 4);
+    Address len_arg(rsp, 4 + 4 + 8);
+      // Load up:
+      __ movl(crc, crc_arg);
+      __ movl(buf, buf_arg);
+      __ movl(len, len_arg);
+      __ push(d);
+      __ push(g);
+      __ push(h);
+      __ crc32c_ipl_alg2_alt2(crc, buf, len,
+                              d, g, h,
+                              empty, empty, empty,
+                              xmm0, xmm1, xmm2,
+                              is_pclmulqdq_supported);
+      __ pop(h);
+      __ pop(g);
+      __ pop(d);
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+  }
+
+ address generate_libmExp() {
+    address start = __ pc();
+
+    const XMMRegister x0  = xmm0;
+    const XMMRegister x1  = xmm1;
+    const XMMRegister x2  = xmm2;
+    const XMMRegister x3  = xmm3;
+
+    const XMMRegister x4  = xmm4;
+    const XMMRegister x5  = xmm5;
+    const XMMRegister x6  = xmm6;
+    const XMMRegister x7  = xmm7;
+
+    const Register tmp   = rbx;
+
+    BLOCK_COMMENT("Entry:");
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+    __ fast_exp(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp);
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+
+  }
+
+
   // Safefetch stubs.
   void generate_safefetch(const char* name, int size, address* entry,
                           address* fault_pc, address* continuation_pc) {
@@ -3204,6 +3279,16 @@
       StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table;
       StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
     }
+
+    if (UseCRC32CIntrinsics) {
+      bool supports_clmul = VM_Version::supports_clmul();
+      StubRoutines::x86::generate_CRC32C_table(supports_clmul);
+      StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table;
+      StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
+    }
+    if (VM_Version::supports_sse2()) {
+      StubRoutines::_dexp = generate_libmExp();
+    }
   }
 
 
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -3039,19 +3039,6 @@
       __ ret(0);
     }
     {
-      StubCodeMark mark(this, "StubRoutines", "exp");
-      StubRoutines::_intrinsic_exp = (double (*)(double)) __ pc();
-
-      __ subq(rsp, 8);
-      __ movdbl(Address(rsp, 0), xmm0);
-      __ fld_d(Address(rsp, 0));
-      __ exp_with_fallback(0);
-      __ fstp_d(Address(rsp, 0));
-      __ movdbl(xmm0, Address(rsp, 0));
-      __ addq(rsp, 8);
-      __ ret(0);
-    }
-    {
       StubCodeMark mark(this, "StubRoutines", "pow");
       StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc();
 
@@ -3958,6 +3945,64 @@
     return start;
   }
 
+  /**
+  *  Arguments:
+  *
+  * Inputs:
+  *   c_rarg0   - int crc
+  *   c_rarg1   - byte* buf
+  *   c_rarg2   - long length
+  *   c_rarg3   - table_start - optional (present only when doing a library_calll,
+  *              not used by x86 algorithm)
+  *
+  * Ouput:
+  *       rax   - int crc result
+  */
+  address generate_updateBytesCRC32C(bool is_pclmulqdq_supported) {
+      assert(UseCRC32CIntrinsics, "need SSE4_2");
+      __ align(CodeEntryAlignment);
+      StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C");
+      address start = __ pc();
+      //reg.arg        int#0        int#1        int#2        int#3        int#4        int#5        float regs
+      //Windows        RCX          RDX          R8           R9           none         none         XMM0..XMM3
+      //Lin / Sol      RDI          RSI          RDX          RCX          R8           R9           XMM0..XMM7
+      const Register crc = c_rarg0;  // crc
+      const Register buf = c_rarg1;  // source java byte array address
+      const Register len = c_rarg2;  // length
+      const Register a = rax;
+      const Register j = r9;
+      const Register k = r10;
+      const Register l = r11;
+#ifdef _WIN64
+      const Register y = rdi;
+      const Register z = rsi;
+#else
+      const Register y = rcx;
+      const Register z = r8;
+#endif
+      assert_different_registers(crc, buf, len, a, j, k, l, y, z);
+
+      BLOCK_COMMENT("Entry:");
+      __ enter(); // required for proper stackwalking of RuntimeStub frame
+#ifdef _WIN64
+      __ push(y);
+      __ push(z);
+#endif
+      __ crc32c_ipl_alg2_alt2(crc, buf, len,
+                              a, j, k,
+                              l, y, z,
+                              c_farg0, c_farg1, c_farg2,
+                              is_pclmulqdq_supported);
+      __ movl(rax, crc);
+#ifdef _WIN64
+      __ pop(z);
+      __ pop(y);
+#endif
+      __ leave(); // required for proper stackwalking of RuntimeStub frame
+      __ ret(0);
+
+      return start;
+  }
 
   /**
    *  Arguments:
@@ -4122,6 +4167,44 @@
     return start;
   }
 
+  address generate_libmExp() {
+    address start = __ pc();
+
+    const XMMRegister x0  = xmm0;
+    const XMMRegister x1  = xmm1;
+    const XMMRegister x2  = xmm2;
+    const XMMRegister x3  = xmm3;
+
+    const XMMRegister x4  = xmm4;
+    const XMMRegister x5  = xmm5;
+    const XMMRegister x6  = xmm6;
+    const XMMRegister x7  = xmm7;
+
+    const Register tmp   = r11;
+
+    BLOCK_COMMENT("Entry:");
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+#ifdef _WIN64
+    // save the xmm registers which must be preserved 6-7
+    __ movdqu(xmm_save(6), as_XMMRegister(6));
+    __ movdqu(xmm_save(7), as_XMMRegister(7));
+#endif
+      __ fast_exp(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp);
+
+#ifdef _WIN64
+    // restore xmm regs belonging to calling function
+    __ movdqu(as_XMMRegister(6), xmm_save(6));
+    __ movdqu(as_XMMRegister(7), xmm_save(7));
+#endif
+
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+
+  }
+
 
 #undef __
 #define __ masm->
@@ -4302,6 +4385,14 @@
       StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table;
       StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
     }
+
+    if (UseCRC32CIntrinsics) {
+      bool supports_clmul = VM_Version::supports_clmul();
+      StubRoutines::x86::generate_CRC32C_table(supports_clmul);
+      StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table;
+      StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
+    }
+    StubRoutines::_dexp = generate_libmExp();
   }
 
   void generate_all() {
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -27,6 +27,7 @@
 #include "runtime/frame.inline.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
+#include "crc32c.h"
 
 // Implementation of the platform-specific part of StubRoutines - for
 // a description of how to extend it, see the stubRoutines.hpp file.
@@ -130,3 +131,107 @@
     0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
     0x2d02ef8dUL
 };
+
+#define D 32
+#define P 0x82F63B78 // Reflection of Castagnoli (0x11EDC6F41)
+
+#define TILL_CYCLE 31
+uint32_t _crc32c_pow_2k_table[TILL_CYCLE]; // because _crc32c_pow_2k_table[TILL_CYCLE == 31] == _crc32c_pow_2k_table[0]
+
+// A. Kadatch and B. Jenkins / Everything we know about CRC but afraid to forget September 3, 2010 8
+// Listing 1: Multiplication of normalized polynomials
+// "a" and "b" occupy D least significant bits.
+uint32_t crc32c_multiply(uint32_t a, uint32_t b) {
+  uint32_t product = 0;
+  uint32_t b_pow_x_table[D + 1]; // b_pow_x_table[k] = (b * x**k) mod P
+  b_pow_x_table[0] = b;
+  for (int k = 0; k < D; ++k) {
+    // If "a" has non-zero coefficient at x**k,/ add ((b * x**k) mod P) to the result.
+    if ((a & (uint64_t)(1 << (D - 1 - k))) != 0) product ^= b_pow_x_table[k];
+
+    // Compute b_pow_x_table[k+1] = (b ** x**(k+1)) mod P.
+    if (b_pow_x_table[k] & 1) {
+      // If degree of (b_pow_x_table[k] * x) is D, then
+      // degree of (b_pow_x_table[k] * x - P) is less than D.
+      b_pow_x_table[k + 1] = (b_pow_x_table[k] >> 1) ^ P;
+    }
+    else {
+      b_pow_x_table[k + 1] = b_pow_x_table[k] >> 1;
+    }
+  }
+  return product;
+}
+#undef D
+#undef P
+
+// A. Kadatch and B. Jenkins / Everything we know about CRC but afraid to forget September 3, 2010 9
+void crc32c_init_pow_2k(void) {
+  // _crc32c_pow_2k_table(0) =
+  // x^(2^k) mod P(x) = x mod P(x) = x
+  // Since we are operating on a reflected values
+  // x = 10b, reflect(x) = 0x40000000
+  _crc32c_pow_2k_table[0] = 0x40000000;
+
+  for (int k = 1; k < TILL_CYCLE; k++) {
+    // _crc32c_pow_2k_table(k+1) = _crc32c_pow_2k_table(k-1)^2 mod P(x)
+    uint32_t tmp = _crc32c_pow_2k_table[k - 1];
+    _crc32c_pow_2k_table[k] = crc32c_multiply(tmp, tmp);
+  }
+}
+
+// x^N mod P(x)
+uint32_t crc32c_f_pow_n(uint32_t n) {
+  //            result = 1 (polynomial)
+  uint32_t one, result = 0x80000000, i = 0;
+
+  while (one = (n & 1), (n == 1 || n - one > 0)) {
+    if (one) {
+      result = crc32c_multiply(result, _crc32c_pow_2k_table[i]);
+    }
+    n >>= 1;
+    i++;
+  }
+
+  return result;
+}
+
+juint *StubRoutines::x86::_crc32c_table;
+
+void StubRoutines::x86::generate_CRC32C_table(bool is_pclmulqdq_table_supported) {
+
+  static juint pow_n[CRC32C_NUM_PRECOMPUTED_CONSTANTS];
+
+  crc32c_init_pow_2k();
+
+  pow_n[0] = crc32c_f_pow_n(CRC32C_HIGH * 8);      // 8N * 8 = 64N
+  pow_n[1] = crc32c_f_pow_n(CRC32C_HIGH * 8 * 2);  // 128N
+
+  pow_n[2] = crc32c_f_pow_n(CRC32C_MIDDLE * 8);
+  pow_n[3] = crc32c_f_pow_n(CRC32C_MIDDLE * 8 * 2);
+
+  pow_n[4] = crc32c_f_pow_n(CRC32C_LOW * 8);
+  pow_n[CRC32C_NUM_PRECOMPUTED_CONSTANTS - 1] =
+            crc32c_f_pow_n(CRC32C_LOW * 8 * 2);
+
+  if (is_pclmulqdq_table_supported) {
+    _crc32c_table = pow_n;
+  } else {
+    static julong pclmulqdq_table[CRC32C_NUM_PRECOMPUTED_CONSTANTS * 256];
+
+    for (int j = 0; j < CRC32C_NUM_PRECOMPUTED_CONSTANTS; j++) {
+      static juint X_CONST = pow_n[j];
+      for (int64_t i = 0; i < 256; i++) { // to force 64 bit wide computations
+      // S. Gueron / Information Processing Letters 112 (2012) 184
+      // Algorithm 3: Generating a carry-less multiplication lookup table.
+      // Input: A 32-bit constant, X_CONST.
+      // Output: A table of 256 entries, each one is a 64-bit quadword,
+      // that can be used for computing "byte" * X_CONST, for a given byte.
+        pclmulqdq_table[j * 256 + i] =
+          ((i & 1) * X_CONST) ^ ((i & 2) * X_CONST) ^ ((i & 4) * X_CONST) ^
+          ((i & 8) * X_CONST) ^ ((i & 16) * X_CONST) ^ ((i & 32) * X_CONST) ^
+          ((i & 64) * X_CONST) ^ ((i & 128) * X_CONST);
+      }
+    }
+    _crc32c_table = (juint*)pclmulqdq_table;
+  }
+}
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,6 +36,8 @@
   // masks and table for CRC32
   static uint64_t _crc_by128_masks[];
   static juint    _crc_table[];
+  // table for CRC32C
+  static juint* _crc32c_table;
   // swap mask for ghash
   static address _ghash_long_swap_mask_addr;
   static address _ghash_byte_swap_mask_addr;
@@ -46,5 +48,6 @@
   static address crc_by128_masks_addr()  { return (address)_crc_by128_masks; }
   static address ghash_long_swap_mask_addr() { return _ghash_long_swap_mask_addr; }
   static address ghash_byte_swap_mask_addr() { return _ghash_byte_swap_mask_addr; }
+  static void generate_CRC32C_table(bool is_pclmulqdq_supported);
 
 #endif // CPU_X86_VM_STUBROUTINES_X86_32_HPP
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -538,7 +538,7 @@
 // Allocate monitor and lock method (asm interpreter)
 // rbx, - Method*
 //
-void InterpreterGenerator::lock_method(void) {
+void TemplateInterpreterGenerator::lock_method() {
   // synchronize method
   const Address access_flags      (rbx, Method::access_flags_offset());
   const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
@@ -697,15 +697,14 @@
     __ jmp(rdi);
 
     __ bind(slow_path);
-    (void) generate_normal_entry(false);
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals));
     return entry;
   }
 #endif // INCLUDE_ALL_GCS
 
   // If G1 is not enabled then attempt to go through the accessor entry point
   // Reference.get is an accessor
-  return generate_jump_to_normal_entry();
+  return NULL;
 }
 
 /**
@@ -753,12 +752,10 @@
 
     // generate a vanilla native entry as the slow path
     __ bind(slow_path);
-
-    (void) generate_native_entry(false);
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
     return entry;
   }
-  return generate_native_entry(false);
+  return NULL;
 }
 
 /**
@@ -790,18 +787,25 @@
     const Register buf = rdx;  // source java byte array address
     const Register len = rdi;  // length
 
+    // value              x86_32
+    // interp. arg ptr    ESP + 4
+    // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
+    //                                         3           2      1        0
+    // int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
+    //                                              4         2,3      1        0
+
     // Arguments are reversed on java expression stack
-    __ movl(len,   Address(rsp,   wordSize)); // Length
+    __ movl(len,   Address(rsp,   4 + 0)); // Length
     // Calculate address of start element
     if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
-      __ movptr(buf, Address(rsp, 3*wordSize)); // long buf
-      __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
-      __ movl(crc,   Address(rsp, 5*wordSize)); // Initial CRC
+      __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
+      __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
+      __ movl(crc,   Address(rsp, 4 + 4 * wordSize)); // Initial CRC
     } else {
-      __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
+      __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
       __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
-      __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
-      __ movl(crc,   Address(rsp, 4*wordSize)); // Initial CRC
+      __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
+      __ movl(crc,   Address(rsp, 4 + 3 * wordSize)); // Initial CRC
     }
 
     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
@@ -814,12 +818,57 @@
 
     // generate a vanilla native entry as the slow path
     __ bind(slow_path);
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
+    return entry;
+  }
+  return NULL;
+}
 
-    (void) generate_native_entry(false);
+/**
+* Method entry for static native methods:
+*   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
+*   int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
+*/
+address InterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
+  if (UseCRC32CIntrinsics) {
+    address entry = __ pc();
+    // Load parameters
+    const Register crc = rax;  // crc
+    const Register buf = rcx;  // source java byte array address
+    const Register len = rdx;  // length
+    const Register end = len;
+
+    // value              x86_32
+    // interp. arg ptr    ESP + 4
+    // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
+    //                                         3           2      1        0
+    // int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
+    //                                              4         2,3          1        0
+
+    // Arguments are reversed on java expression stack
+    __ movl(end, Address(rsp, 4 + 0)); // end
+    __ subl(len, Address(rsp, 4 + 1 * wordSize));  // end - offset == length
+    // Calculate address of start element
+    if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
+      __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
+      __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
+      __ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
+    } else {
+      __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
+      __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
+      __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
+      __ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
+    }
+    __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
+    // result in rax
+    // _areturn
+    __ pop(rdi);                // get return address
+    __ mov(rsp, rsi);           // set sp to sender sp
+    __ jmp(rdi);
 
     return entry;
   }
-  return generate_native_entry(false);
+  return NULL;
 }
 
 /**
@@ -827,10 +876,8 @@
  *    java.lang.Float.intBitsToFloat(int bits)
  */
 address InterpreterGenerator::generate_Float_intBitsToFloat_entry() {
-  address entry;
-
   if (UseSSE >= 1) {
-    entry = __ pc();
+    address entry = __ pc();
 
     // rsi: the sender's SP
 
@@ -844,11 +891,10 @@
     __ pop(rdi); // get return address
     __ mov(rsp, rsi); // set rsp to the sender's SP
     __ jmp(rdi);
-  } else {
-    entry = generate_native_entry(false);
+    return entry;
   }
 
-  return entry;
+  return NULL;
 }
 
 /**
@@ -856,10 +902,8 @@
  *    java.lang.Float.floatToRawIntBits(float value)
  */
 address InterpreterGenerator::generate_Float_floatToRawIntBits_entry() {
-  address entry;
-
   if (UseSSE >= 1) {
-    entry = __ pc();
+    address entry = __ pc();
 
     // rsi: the sender's SP
 
@@ -873,11 +917,10 @@
     __ pop(rdi); // get return address
     __ mov(rsp, rsi); // set rsp to the sender's SP
     __ jmp(rdi);
-  } else {
-    entry = generate_native_entry(false);
+    return entry;
   }
 
-  return entry;
+  return NULL;
 }
 
 
@@ -886,10 +929,8 @@
  *    java.lang.Double.longBitsToDouble(long bits)
  */
 address InterpreterGenerator::generate_Double_longBitsToDouble_entry() {
-  address entry;
-
    if (UseSSE >= 2) {
-     entry = __ pc();
+     address entry = __ pc();
 
      // rsi: the sender's SP
 
@@ -903,11 +944,10 @@
      __ pop(rdi); // get return address
      __ mov(rsp, rsi); // set rsp to the sender's SP
      __ jmp(rdi);
-   } else {
-     entry = generate_native_entry(false);
+     return entry;
    }
 
-   return entry;
+   return NULL;
 }
 
 /**
@@ -915,10 +955,8 @@
  *    java.lang.Double.doubleToRawLongBits(double value)
  */
 address InterpreterGenerator::generate_Double_doubleToRawLongBits_entry() {
-  address entry;
-
   if (UseSSE >= 2) {
-    entry = __ pc();
+    address entry = __ pc();
 
     // rsi: the sender's SP
 
@@ -933,11 +971,10 @@
     __ pop(rdi); // get return address
     __ mov(rsp, rsi); // set rsp to the sender's SP
     __ jmp(rdi);
-  } else {
-    entry = generate_native_entry(false);
+    return entry;
   }
 
-  return entry;
+  return NULL;
 }
 
 //
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -198,13 +198,27 @@
 }
 
 
-address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state,
-                                                               int step) {
+address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
   address entry = __ pc();
   // NULL last_sp until next java call
   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
   __ restore_bcp();
   __ restore_locals();
+#if INCLUDE_JVMCI
+  // Check if we need to take lock at entry of synchronized method.
+  if (UseJVMCICompiler) {
+    Label L;
+    __ cmpb(Address(r15_thread, JavaThread::pending_monitorenter_offset()), 0);
+    __ jcc(Assembler::zero, L);
+    // Clear flag.
+    __ movb(Address(r15_thread, JavaThread::pending_monitorenter_offset()), 0);
+    // Satisfy calling convention for lock_method().
+    __ get_method(rbx);
+    // Take lock.
+    lock_method();
+    __ bind(L);
+  }
+#endif
   // handle exceptions
   {
     Label L;
@@ -500,7 +514,7 @@
 //      rax
 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ...(param regs)
 //      rscratch1, rscratch2 (scratch regs)
-void InterpreterGenerator::lock_method(void) {
+void TemplateInterpreterGenerator::lock_method() {
   // synchronize method
   const Address access_flags(rbx, Method::access_flags_offset());
   const Address monitor_block_top(
@@ -677,15 +691,14 @@
 
     // generate a vanilla interpreter entry as the slow path
     __ bind(slow_path);
-    (void) generate_normal_entry(false);
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals));
     return entry;
   }
 #endif // INCLUDE_ALL_GCS
 
   // If G1 is not enabled then attempt to go through the accessor entry point
   // Reference.get is an accessor
-  return generate_jump_to_normal_entry();
+  return NULL;
 }
 
 /**
@@ -733,12 +746,10 @@
 
     // generate a vanilla native entry as the slow path
     __ bind(slow_path);
-
-    (void) generate_native_entry(false);
-
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
     return entry;
   }
-  return generate_native_entry(false);
+  return NULL;
 }
 
 /**
@@ -796,12 +807,61 @@
 
     // generate a vanilla native entry as the slow path
     __ bind(slow_path);
+    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
+    return entry;
+  }
+  return NULL;
+}
 
-    (void) generate_native_entry(false);
+/**
+* Method entry for static native methods:
+*   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
+*   int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
+*/
+address InterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
+  if (UseCRC32CIntrinsics) {
+    address entry = __ pc();
+    // Load parameters
+    const Register crc = c_rarg0;  // crc
+    const Register buf = c_rarg1;  // source java byte array address
+    const Register len = c_rarg2;
+    const Register off = c_rarg3;  // offset
+    const Register end = len;
+
+    // Arguments are reversed on java expression stack
+    // Calculate address of start element
+    if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
+      __ movptr(buf, Address(rsp, 3 * wordSize)); // long buf
+      __ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
+      __ addq(buf, off); // + offset
+      __ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC
+      // Note on 5 * wordSize vs. 4 * wordSize:
+      // *   int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
+      //                                                   4         2,3          1        0
+      // end starts at SP + 8
+      // The Java(R) Virtual Machine Specification Java SE 7 Edition
+      // 4.10.2.3. Values of Types long and double
+      //    "When calculating operand stack length, values of type long and double have length two."
+    } else {
+      __ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array
+      __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
+      __ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
+      __ addq(buf, off); // + offset
+      __ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC
+    }
+    __ movl(end, Address(rsp, wordSize)); // end
+    __ subl(end, off); // end - off
+    __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
+    // result in rax
+    // _areturn
+    __ pop(rdi);                // get return address
+    __ mov(rsp, r13);           // set sp to sender sp
+    __ jmp(rdi);
 
     return entry;
   }
-  return generate_native_entry(false);
+
+  return NULL;
 }
 
 // Interpreter stub for calling a native method. (asm interpreter)
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -3595,6 +3595,8 @@
   __ profile_virtual_call(rax, rlocals, rdx);
   // get target Method* & entry point
   __ lookup_virtual_method(rax, index, method);
+  __ profile_called_method(method, rdx, rbcp);
+
   __ profile_arguments_type(rdx, method, rbcp, true);
   __ jump_from_interpreted(method, rdx);
 }
@@ -3694,6 +3696,7 @@
   __ testptr(rbx, rbx);
   __ jcc(Assembler::zero, no_such_method);
 
+  __ profile_called_method(rbx, rbcp, rdx);
   __ profile_arguments_type(rdx, rbx, rbcp, true);
 
   // do the call
--- a/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,13 +37,50 @@
   /******************************/                                                                                                   \
   /* JavaFrameAnchor            */                                                                                                   \
   /******************************/                                                                                                   \
-  volatile_nonstatic_field(JavaFrameAnchor,     _last_Java_fp,                                    intptr_t*)
+  volatile_nonstatic_field(JavaFrameAnchor,     _last_Java_fp,                                    intptr_t*)                         \
+  static_field(VM_Version, _cpuFeatures, uint64_t)
 
 
 
-#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
+#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
+  declare_toplevel_type(VM_Version)
 
-#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
+  LP64_ONLY(declare_constant(frame::arg_reg_save_area_bytes))       \
+  declare_constant(frame::interpreter_frame_sender_sp_offset)       \
+  declare_constant(frame::interpreter_frame_last_sp_offset)         \
+  declare_constant(VM_Version::CPU_CX8)                             \
+  declare_constant(VM_Version::CPU_CMOV)                            \
+  declare_constant(VM_Version::CPU_FXSR)                            \
+  declare_constant(VM_Version::CPU_HT)                              \
+  declare_constant(VM_Version::CPU_MMX)                             \
+  declare_constant(VM_Version::CPU_3DNOW_PREFETCH)                  \
+  declare_constant(VM_Version::CPU_SSE)                             \
+  declare_constant(VM_Version::CPU_SSE2)                            \
+  declare_constant(VM_Version::CPU_SSE3)                            \
+  declare_constant(VM_Version::CPU_SSSE3)                           \
+  declare_constant(VM_Version::CPU_SSE4A)                           \
+  declare_constant(VM_Version::CPU_SSE4_1)                          \
+  declare_constant(VM_Version::CPU_SSE4_2)                          \
+  declare_constant(VM_Version::CPU_POPCNT)                          \
+  declare_constant(VM_Version::CPU_LZCNT)                           \
+  declare_constant(VM_Version::CPU_TSC)                             \
+  declare_constant(VM_Version::CPU_TSCINV)                          \
+  declare_constant(VM_Version::CPU_AVX)                             \
+  declare_constant(VM_Version::CPU_AVX2)                            \
+  declare_constant(VM_Version::CPU_AES)                             \
+  declare_constant(VM_Version::CPU_ERMS)                            \
+  declare_constant(VM_Version::CPU_CLMUL)                           \
+  declare_constant(VM_Version::CPU_BMI1)                            \
+  declare_constant(VM_Version::CPU_BMI2)                            \
+  declare_constant(VM_Version::CPU_RTM)                             \
+  declare_constant(VM_Version::CPU_ADX)                             \
+  declare_constant(VM_Version::CPU_AVX512F)                         \
+  declare_constant(VM_Version::CPU_AVX512DQ)                        \
+  declare_constant(VM_Version::CPU_AVX512PF)                        \
+  declare_constant(VM_Version::CPU_AVX512ER)                        \
+  declare_constant(VM_Version::CPU_AVX512CD)                        \
+  declare_constant(VM_Version::CPU_AVX512BW)
 
 #define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
 
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -661,6 +661,18 @@
     FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
   }
 
+  if (supports_sse4_2()) {
+    if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
+      UseCRC32CIntrinsics = true;
+    }
+  }
+  else if (UseCRC32CIntrinsics) {
+    if (!FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
+      warning("CRC32C intrinsics are not available on this CPU");
+    }
+    FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
+  }
+
   // The AES intrinsic stubs require AES instruction support (of course)
   // but also require sse3 mode for instructions it use.
   if (UseAES && (UseSSE > 2)) {
@@ -704,12 +716,6 @@
     FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
   }
 
-  if (UseCRC32CIntrinsics) {
-    if (!FLAG_IS_DEFAULT(UseCRC32CIntrinsics))
-      warning("CRC32C intrinsics are not available on this CPU");
-    FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
-  }
-
   if (UseAdler32Intrinsics) {
     warning("Adler32Intrinsics not available on this CPU.");
     FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
@@ -781,6 +787,8 @@
       FLAG_SET_DEFAULT(UseFPUForSpilling, false);
     }
   }
+#endif
+#if defined(COMPILER2) || INCLUDE_JVMCI
   if (MaxVectorSize > 0) {
     if (!is_power_of_2(MaxVectorSize)) {
       warning("MaxVectorSize must be a power of 2");
@@ -797,7 +805,7 @@
       // Vectors (in XMM) are only supported with SSE2+
       FLAG_SET_DEFAULT(MaxVectorSize, 0);
     }
-#ifdef ASSERT
+#if defined(COMPILER2) && defined(ASSERT)
     if (supports_avx() && PrintMiscellaneous && Verbose && TraceNewVectors) {
       tty->print_cr("State of YMM registers after signal handle:");
       int nreg = 2 LP64_ONLY(+2);
@@ -810,9 +818,11 @@
         tty->cr();
       }
     }
-#endif
+#endif // COMPILER2 && ASSERT
   }
+#endif // COMPILER2 || INCLUDE_JVMCI
 
+#ifdef COMPILER2
 #ifdef _LP64
   if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
     UseMultiplyToLenIntrinsic = true;
@@ -1082,11 +1092,6 @@
   }
 #endif // COMPILER2
 
-  assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 3, "invalid value");
-
-  // set valid Prefetch instruction
-  if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0;
-  if( AllocatePrefetchInstr > 3 ) AllocatePrefetchInstr = 3;
   if( AllocatePrefetchInstr == 3 && !supports_3dnow_prefetch() ) AllocatePrefetchInstr=0;
   if( !supports_sse() && supports_3dnow_prefetch() ) AllocatePrefetchInstr = 3;
 
@@ -1125,7 +1130,6 @@
     }
 #endif
   }
-  assert(AllocatePrefetchDistance % AllocatePrefetchStepSize == 0, "invalid value");
 
 #ifdef _LP64
   // Prefetch settings
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,6 +29,7 @@
 #include "runtime/vm_version.hpp"
 
 class VM_Version : public Abstract_VM_Version {
+  friend class VMStructs;
 public:
   // cpuid result register layouts.  These are all unions of a uint32_t
   // (in case anyone wants access to the register as a whole) and a bitfield.
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -35,8 +35,6 @@
 #include "opto/runtime.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // machine-dependent part of VtableStubs: create VtableStub of correct size and
 // initialize its code
 
@@ -113,7 +111,7 @@
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
     tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
-                  vtable_index, s->entry_point(),
+                  vtable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
   }
@@ -206,7 +204,7 @@
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
     tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
-                  itable_index, s->entry_point(),
+                  itable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
   }
--- a/hotspot/src/cpu/x86/vm/x86.ad	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86.ad	Thu Oct 22 11:13:08 2015 -0700
@@ -1712,6 +1712,18 @@
   return ret_value;  // Per default match rules are supported.
 }
 
+const int Matcher::float_pressure(int default_pressure_threshold) {
+  int float_pressure_threshold = default_pressure_threshold;
+#ifdef _LP64
+  if (UseAVX > 2) {
+    // Increase pressure threshold on machines with AVX3 which have
+    // 2x more XMM registers.
+    float_pressure_threshold = default_pressure_threshold * 2;
+  }
+#endif
+  return float_pressure_threshold;
+}
+
 // Max vector size in bytes. 0 if not supported.
 const int Matcher::vector_width_in_bytes(BasicType bt) {
   assert(is_java_primitive(bt), "only primitive type vectors");
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Thu Oct 22 11:13:08 2015 -0700
@@ -580,7 +580,11 @@
     st->print("MOV    [ESP + #%d], EBP\t# Save EBP",framesize);
     if (PreserveFramePointer) {
       st->print("\n\t");
-      st->print("MOV    EBP, [ESP + #%d]\t# Save the caller's SP into EBP", (framesize + wordSize));
+      st->print("MOV    EBP, ESP\t# Save the caller's SP into EBP");
+      if (framesize > 0) {
+        st->print("\n\t");
+        st->print("ADD    EBP, #%d", framesize);
+      }
     }
   }
 
@@ -9911,35 +9915,6 @@
   ins_pipe( pipe_slow );
 %}
 
-
-instruct expDPR_reg(regDPR1 dpr1, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{
-  predicate (UseSSE<=1);
-  match(Set dpr1 (ExpD dpr1));
-  effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
-  format %{ "fast_exp $dpr1 -> $dpr1  // KILL $rax, $rcx, $rdx" %}
-  ins_encode %{
-    __ fast_exp();
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-instruct expD_reg(regD dst, regD src, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{
-  predicate (UseSSE>=2);
-  match(Set dst (ExpD src));
-  effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
-  format %{ "fast_exp $dst -> $src  // KILL $rax, $rcx, $rdx" %}
-  ins_encode %{
-    __ subptr(rsp, 8);
-    __ movdbl(Address(rsp, 0), $src$$XMMRegister);
-    __ fld_d(Address(rsp, 0));
-    __ fast_exp();
-    __ fstp_d(Address(rsp, 0));
-    __ movdbl($dst$$XMMRegister, Address(rsp, 0));
-    __ addptr(rsp, 8);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 instruct log10DPR_reg(regDPR1 dst, regDPR1 src) %{
   predicate (UseSSE<=1);
   // The source Double operand on FPU stack
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Thu Oct 22 11:13:08 2015 -0700
@@ -867,7 +867,11 @@
     st->print("movq    [rsp + #%d], rbp\t# Save rbp",framesize);
     if (PreserveFramePointer) {
       st->print("\n\t");
-      st->print("movq    rbp, [rsp + #%d]\t# Save the caller's SP into rbp", (framesize + wordSize));
+      st->print("movq    rbp, rsp\t# Save the caller's SP into rbp");
+      if (framesize > 0) {
+        st->print("\n\t");
+        st->print("addq    rbp, #%d", framesize);
+      }      
     }
   }
 
@@ -2136,12 +2140,13 @@
                      RELOC_DISP32);
     }
     if (_method) {
-      // Emit stub for static call.
-      address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
+      // Emit stubs for static call.
+      address mark = cbuf.insts_mark();
+      address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark);
       if (stub == NULL) {
         ciEnv::current()->record_failure("CodeCache is full");
         return;
-      } 
+      }
     }
   %}
 
@@ -3767,6 +3772,22 @@
   %}
 %}
 
+operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale)
+%{
+  constraint(ALLOC_IN_RC(ptr_reg));
+  predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
+  match(AddP reg (LShiftL (ConvI2L idx) scale));
+
+  op_cost(10);
+  format %{"[$reg + pos $idx << $scale]" %}
+  interface(MEMORY_INTER) %{
+    base($reg);
+    index($idx);
+    scale($scale);
+    disp(0x0);
+  %}
+%}
+
 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
 %{
@@ -4159,7 +4180,7 @@
 // case of this is memory operands.
 
 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
-               indIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset,
+               indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset,
                indCompressedOopOffset,
                indirectNarrow, indOffset8Narrow, indOffset32Narrow,
                indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
@@ -5186,6 +5207,17 @@
   ins_pipe(ialu_reg_reg_fat);
 %}
 
+instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem)
+%{
+  match(Set dst mem);
+
+  ins_cost(110);
+  format %{ "leaq    $dst, $mem\t# ptr idxscale" %}
+  opcode(0x8D);
+  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
+  ins_pipe(ialu_reg_reg_fat);
+%}
+
 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
 %{
   match(Set dst mem);
@@ -9871,22 +9903,6 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
-  match(Set dst (ExpD src));
-  effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
-  format %{ "fast_exp $dst -> $src  // KILL $rax, $rcx, $rdx" %}
-  ins_encode %{
-    __ subptr(rsp, 8);
-    __ movdbl(Address(rsp, 0), $src$$XMMRegister);
-    __ fld_d(Address(rsp, 0));
-    __ fast_exp();
-    __ fstp_d(Address(rsp, 0));
-    __ movdbl($dst$$XMMRegister, Address(rsp, 0));
-    __ addptr(rsp, 8);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 //----------Arithmetic Conversion Instructions---------------------------------
 
 instruct roundFloat_nop(regF dst)
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -816,7 +816,7 @@
 
   // If G1 is not enabled then attempt to go through the normal entry point
   // Reference.get could be instrumented by jvmti
-  return generate_normal_entry(false);
+  return NULL;
 }
 
 address InterpreterGenerator::generate_native_entry(bool synchronized) {
--- a/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,4 +42,5 @@
   // Not supported
   address generate_CRC32_update_entry() { return NULL; }
   address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
+  address generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return NULL; }
 #endif // CPU_ZERO_VM_INTERPRETERGENERATOR_ZERO_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.amd64;
+
+import static jdk.vm.ci.code.MemoryBarriers.*;
+import static jdk.vm.ci.code.Register.*;
+
+import java.nio.*;
+import java.util.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.Register.RegisterCategory;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents the AMD64 architecture.
+ */
+public class AMD64 extends Architecture {
+
+    public static final RegisterCategory CPU = new RegisterCategory("CPU");
+
+    // @formatter:off
+
+    // General purpose CPU registers
+    public static final Register rax = new Register(0, 0, "rax", CPU);
+    public static final Register rcx = new Register(1, 1, "rcx", CPU);
+    public static final Register rdx = new Register(2, 2, "rdx", CPU);
+    public static final Register rbx = new Register(3, 3, "rbx", CPU);
+    public static final Register rsp = new Register(4, 4, "rsp", CPU);
+    public static final Register rbp = new Register(5, 5, "rbp", CPU);
+    public static final Register rsi = new Register(6, 6, "rsi", CPU);
+    public static final Register rdi = new Register(7, 7, "rdi", CPU);
+
+    public static final Register r8  = new Register(8,  8,  "r8", CPU);
+    public static final Register r9  = new Register(9,  9,  "r9", CPU);
+    public static final Register r10 = new Register(10, 10, "r10", CPU);
+    public static final Register r11 = new Register(11, 11, "r11", CPU);
+    public static final Register r12 = new Register(12, 12, "r12", CPU);
+    public static final Register r13 = new Register(13, 13, "r13", CPU);
+    public static final Register r14 = new Register(14, 14, "r14", CPU);
+    public static final Register r15 = new Register(15, 15, "r15", CPU);
+
+    public static final Register[] cpuRegisters = {
+        rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
+        r8, r9, r10, r11, r12, r13, r14, r15
+    };
+
+    private static final int XMM_REFERENCE_MAP_SHIFT = 2;
+
+    public static final RegisterCategory XMM = new RegisterCategory("XMM", cpuRegisters.length, XMM_REFERENCE_MAP_SHIFT);
+
+    // XMM registers
+    public static final Register xmm0 = new Register(16, 0, "xmm0", XMM);
+    public static final Register xmm1 = new Register(17, 1, "xmm1", XMM);
+    public static final Register xmm2 = new Register(18, 2, "xmm2", XMM);
+    public static final Register xmm3 = new Register(19, 3, "xmm3", XMM);
+    public static final Register xmm4 = new Register(20, 4, "xmm4", XMM);
+    public static final Register xmm5 = new Register(21, 5, "xmm5", XMM);
+    public static final Register xmm6 = new Register(22, 6, "xmm6", XMM);
+    public static final Register xmm7 = new Register(23, 7, "xmm7", XMM);
+
+    public static final Register xmm8 =  new Register(24,  8, "xmm8",  XMM);
+    public static final Register xmm9 =  new Register(25,  9, "xmm9",  XMM);
+    public static final Register xmm10 = new Register(26, 10, "xmm10", XMM);
+    public static final Register xmm11 = new Register(27, 11, "xmm11", XMM);
+    public static final Register xmm12 = new Register(28, 12, "xmm12", XMM);
+    public static final Register xmm13 = new Register(29, 13, "xmm13", XMM);
+    public static final Register xmm14 = new Register(30, 14, "xmm14", XMM);
+    public static final Register xmm15 = new Register(31, 15, "xmm15", XMM);
+
+    public static final Register[] xmmRegisters = {
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+    };
+
+    public static final Register[] cpuxmmRegisters = {
+        rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
+        r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+    };
+
+    /**
+     * Register used to construct an instruction-relative address.
+     */
+    public static final Register rip = new Register(32, -1, "rip", SPECIAL);
+
+    public static final Register[] allRegisters = {
+        rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
+        r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
+        rip
+    };
+
+    // @formatter:on
+
+    /**
+     * Basic set of CPU features mirroring what is returned from the cpuid instruction. See:
+     * {@code VM_Version::cpuFeatureFlags}.
+     */
+    public static enum CPUFeature {
+        CX8,
+        CMOV,
+        FXSR,
+        HT,
+        MMX,
+        AMD_3DNOW_PREFETCH,
+        SSE,
+        SSE2,
+        SSE3,
+        SSSE3,
+        SSE4A,
+        SSE4_1,
+        SSE4_2,
+        POPCNT,
+        LZCNT,
+        TSC,
+        TSCINV,
+        AVX,
+        AVX2,
+        AES,
+        ERMS,
+        CLMUL,
+        BMI1,
+        BMI2,
+        RTM,
+        ADX,
+        AVX512F,
+        AVX512DQ,
+        AVX512PF,
+        AVX512ER,
+        AVX512CD,
+        AVX512BW
+    }
+
+    private final EnumSet<CPUFeature> features;
+
+    /**
+     * Set of flags to control code emission.
+     */
+    public static enum Flag {
+        UseCountLeadingZerosInstruction,
+        UseCountTrailingZerosInstruction
+    }
+
+    private final EnumSet<Flag> flags;
+
+    public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
+        super("AMD64", JavaKind.Long, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + (xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT), 8);
+        this.features = features;
+        this.flags = flags;
+        assert features.contains(CPUFeature.SSE2) : "minimum config for x64";
+    }
+
+    public EnumSet<CPUFeature> getFeatures() {
+        return features;
+    }
+
+    public EnumSet<Flag> getFlags() {
+        return flags;
+    }
+
+    @Override
+    public PlatformKind getPlatformKind(JavaKind javaKind) {
+        if (javaKind.isObject()) {
+            return getWordKind();
+        } else {
+            return javaKind;
+        }
+    }
+
+    @Override
+    public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
+        if (!(platformKind instanceof JavaKind)) {
+            return false;
+        }
+
+        JavaKind kind = (JavaKind) platformKind;
+        if (category.equals(CPU)) {
+            switch (kind) {
+                case Boolean:
+                case Byte:
+                case Char:
+                case Short:
+                case Int:
+                case Long:
+                    return true;
+            }
+        } else if (category.equals(XMM)) {
+            switch (kind) {
+                case Float:
+                case Double:
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public PlatformKind getLargestStorableKind(RegisterCategory category) {
+        if (category.equals(CPU)) {
+            return JavaKind.Long;
+        } else if (category.equals(XMM)) {
+            return JavaKind.Double;
+        } else {
+            return JavaKind.Illegal;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/overview.html	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+This code is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+version 2 for more details (a copy is included in the LICENSE file that
+accompanied this code).
+
+You should have received a copy of the GNU General Public License version
+2 along with this work; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+or visit www.oracle.com if you need additional information or have any
+questions.
+-->
+
+</head>
+<body>
+
+The <code>jdk.vm.ci.code</code> project provides an API to the runtime's native code cache.
+It allows installation and execution of native code.
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/AbstractAddress.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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 jdk.vm.ci.code;
+
+/**
+ * Abstract base class that represents a platform specific address.
+ */
+public abstract class AbstractAddress {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+import java.nio.*;
+import java.util.*;
+
+import jdk.vm.ci.code.Register.RegisterCategory;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a CPU architecture, including information such as its endianness, CPU registers, word
+ * width, etc.
+ */
+public abstract class Architecture {
+
+    /**
+     * The number of entries required in a {@link ReferenceMap} covering all the registers that may
+     * store references. The index of a register in the reference map is given by
+     * {@link Register#getReferenceMapIndex()}.
+     */
+    private final int registerReferenceMapSize;
+
+    /**
+     * The architecture specific type of a native word.
+     */
+    private final PlatformKind wordKind;
+
+    /**
+     * The name of this architecture (e.g. "AMD64", "SPARCv9").
+     */
+    private final String name;
+
+    /**
+     * Array of all available registers on this architecture. The index of each register in this
+     * array is equal to its {@linkplain Register#number number}.
+     */
+    private final Register[] registers;
+
+    /**
+     * The byte ordering can be either little or big endian.
+     */
+    private final ByteOrder byteOrder;
+
+    /**
+     * Whether the architecture supports unaligned memory accesses.
+     */
+    private final boolean unalignedMemoryAccess;
+
+    /**
+     * Mask of the barrier constants denoting the barriers that are not required to be explicitly
+     * inserted under this architecture.
+     */
+    private final int implicitMemoryBarriers;
+
+    /**
+     * Offset in bytes from the beginning of a call instruction to the displacement.
+     */
+    private final int machineCodeCallDisplacementOffset;
+
+    /**
+     * The size of the return address pushed to the stack by a call instruction. A value of 0
+     * denotes that call linkage uses registers instead (e.g. SPARC).
+     */
+    private final int returnAddressSize;
+
+    protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset,
+                    int registerReferenceMapSize, int returnAddressSize) {
+        this.name = name;
+        this.registers = registers;
+        this.wordKind = wordKind;
+        this.byteOrder = byteOrder;
+        this.unalignedMemoryAccess = unalignedMemoryAccess;
+        this.implicitMemoryBarriers = implicitMemoryBarriers;
+        this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
+        this.registerReferenceMapSize = registerReferenceMapSize;
+        this.returnAddressSize = returnAddressSize;
+    }
+
+    /**
+     * Converts this architecture to a string.
+     *
+     * @return the string representation of this architecture
+     */
+    @Override
+    public final String toString() {
+        return getName().toLowerCase();
+    }
+
+    public int getRegisterReferenceMapSize() {
+        return registerReferenceMapSize;
+    }
+
+    /**
+     * Gets the natural size of words (typically registers and pointers) of this architecture, in
+     * bytes.
+     */
+    public int getWordSize() {
+        return wordKind.getSizeInBytes();
+    }
+
+    public PlatformKind getWordKind() {
+        return wordKind;
+    }
+
+    /**
+     * Gets the name of this architecture.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Gets an array of all available registers on this architecture. The index of each register in
+     * this array is equal to its {@linkplain Register#number number}.
+     */
+    public Register[] getRegisters() {
+        return registers.clone();
+    }
+
+    public ByteOrder getByteOrder() {
+        return byteOrder;
+    }
+
+    /**
+     * @return true if the architecture supports unaligned memory accesses.
+     */
+    public boolean supportsUnalignedMemoryAccess() {
+        return unalignedMemoryAccess;
+    }
+
+    /**
+     * Gets the size of the return address pushed to the stack by a call instruction. A value of 0
+     * denotes that call linkage uses registers instead.
+     */
+    public int getReturnAddressSize() {
+        return returnAddressSize;
+    }
+
+    /**
+     * Gets the offset in bytes from the beginning of a call instruction to the displacement.
+     */
+    public int getMachineCodeCallDisplacementOffset() {
+        return machineCodeCallDisplacementOffset;
+    }
+
+    /**
+     * Determines the barriers in a given barrier mask that are explicitly required on this
+     * architecture.
+     *
+     * @param barriers a mask of the barrier constants
+     * @return the value of {@code barriers} minus the barriers unnecessary on this architecture
+     */
+    public final int requiredBarriers(int barriers) {
+        return barriers & ~implicitMemoryBarriers;
+    }
+
+    /**
+     * Determine whether a kind can be stored in a register of a given category.
+     *
+     * @param category the category of the register
+     * @param kind the kind that should be stored in the register
+     */
+    public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind);
+
+    /**
+     * Return the largest kind that can be stored in a register of a given category.
+     *
+     * @param category the category of the register
+     * @return the largest kind that can be stored in a register {@code category}
+     */
+    public abstract PlatformKind getLargestStorableKind(RegisterCategory category);
+
+    /**
+     * Return the {@link PlatformKind} that is used to store values of a given {@link JavaKind}.
+     */
+    public abstract PlatformKind getPlatformKind(JavaKind javaKind);
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Architecture) {
+            Architecture that = (Architecture) obj;
+            if (this.name.equals(that.name)) {
+                assert this.byteOrder.equals(that.byteOrder);
+                assert this.implicitMemoryBarriers == that.implicitMemoryBarriers;
+                assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset;
+                assert this.registerReferenceMapSize == that.registerReferenceMapSize;
+                assert Arrays.equals(this.registers, that.registers);
+                assert this.returnAddressSize == that.returnAddressSize;
+                assert this.unalignedMemoryAccess == that.unalignedMemoryAccess;
+                assert this.wordKind == that.wordKind;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return name.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BailoutException.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+import java.util.*;
+
+/**
+ * Exception thrown when the compiler refuses to compile a method because of problems with the
+ * method. e.g. bytecode wouldn't verify, too big, JSR/ret too complicated, etc. This exception is
+ * <i>not</i> meant to indicate problems with the compiler itself.
+ */
+public class BailoutException extends RuntimeException {
+
+    public static final long serialVersionUID = 8974598793458772L;
+    private final boolean permanent;
+
+    /**
+     * Creates a new {@link BailoutException}.
+     *
+     *
+     * @param args parameters to the formatter
+     */
+    public BailoutException(String format, Object... args) {
+        super(String.format(Locale.ENGLISH, format, args));
+        this.permanent = true;
+    }
+
+    /**
+     * Creates a new {@link BailoutException}.
+     *
+     *
+     * @param args parameters to the formatter
+     */
+    public BailoutException(Throwable cause, String format, Object... args) {
+        super(String.format(Locale.ENGLISH, format, args), cause);
+        this.permanent = true;
+    }
+
+    /**
+     * Creates a new {@link BailoutException}.
+     *
+     * @param permanent specifies whether this exception will occur again if compilation is retried
+     * @param args parameters to the formatter
+     */
+    public BailoutException(boolean permanent, String format, Object... args) {
+        super(String.format(Locale.ENGLISH, format, args));
+        this.permanent = permanent;
+    }
+
+    /**
+     * @return whether this exception will occur again if compilation is retried
+     */
+    public boolean isPermanent() {
+        return permanent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents the Java bytecode frame state(s) at a given position including {@link Value locations}
+ * where to find the local variables, operand stack values and locked objects of the bytecode
+ * frame(s).
+ */
+public class BytecodeFrame extends BytecodePosition {
+
+    /**
+     * An array of values representing how to reconstruct the state of the Java frame. This is array
+     * is partitioned as follows:
+     * <p>
+     * <table summary="" border="1" cellpadding="5" frame="void" rules="all">
+     * <tr>
+     * <th>Start index (inclusive)</th>
+     * <th>End index (exclusive)</th>
+     * <th>Description</th>
+     * </tr>
+     * <tr>
+     * <td>0</td>
+     * <td>numLocals</td>
+     * <td>Local variables</td>
+     * </tr>
+     * <tr>
+     * <td>numLocals</td>
+     * <td>numLocals + numStack</td>
+     * <td>Operand stack</td>
+     * </tr>
+     * <tr>
+     * <td>numLocals + numStack</td>
+     * <td>values.length</td>
+     * <td>Locked objects</td>
+     * </tr>
+     * </table>
+     * <p>
+     * Note that the number of locals and the number of stack slots may be smaller than the maximum
+     * number of locals and stack slots as specified in the compiled method.
+     */
+    public final JavaValue[] values;
+
+    /**
+     * An array describing the Java kind of the {@link #values}. It records a kind for the locals
+     * and the operand stack.
+     */
+    public final JavaKind[] slotKinds;
+
+    /**
+     * The number of locals in the values array.
+     */
+    public final int numLocals;
+
+    /**
+     * The number of stack slots in the values array.
+     */
+    public final int numStack;
+
+    /**
+     * The number of locks in the values array.
+     */
+    public final int numLocks;
+
+    /**
+     * True if this is a position inside an exception handler before the exception object has been
+     * consumed. In this case, {@link #numStack} {@code == 1} and {@link #getStackValue(int)
+     * getStackValue(0)} is the location of the exception object. If deoptimization happens at this
+     * position, the interpreter will rethrow the exception instead of executing the bytecode
+     * instruction at this position.
+     */
+    public final boolean rethrowException;
+
+    public final boolean duringCall;
+
+    /**
+     * This BCI should be used for frame states that are built for code with no meaningful BCI.
+     */
+    public static final int UNKNOWN_BCI = -5;
+
+    /**
+     * The BCI for exception unwind. This is synthetic code and has no representation in bytecode.
+     * In contrast with {@link #AFTER_EXCEPTION_BCI}, at this point, if the method is synchronized,
+     * the monitor is still held.
+     */
+    public static final int UNWIND_BCI = -1;
+
+    /**
+     * The BCI for the state before starting to execute a method. Note that if the method is
+     * synchronized, the monitor is not yet held.
+     */
+    public static final int BEFORE_BCI = -2;
+
+    /**
+     * The BCI for the state after finishing the execution of a method and returning normally. Note
+     * that if the method was synchronized the monitor is already released.
+     */
+    public static final int AFTER_BCI = -3;
+
+    /**
+     * The BCI for exception unwind. This is synthetic code and has no representation in bytecode.
+     * In contrast with {@link #UNWIND_BCI}, at this point, if the method is synchronized, the
+     * monitor is already released.
+     */
+    public static final int AFTER_EXCEPTION_BCI = -4;
+
+    /**
+     * This BCI should be used for states that cannot be the target of a deoptimization, like
+     * snippet frame states.
+     */
+    public static final int INVALID_FRAMESTATE_BCI = -6;
+
+    /**
+     * Determines if a given BCI matches one of the placeholder BCI constants defined in this class.
+     */
+    public static boolean isPlaceholderBci(int bci) {
+        return bci < 0;
+    }
+
+    /**
+     * Gets the name of a given placeholder BCI.
+     */
+    public static String getPlaceholderBciName(int bci) {
+        assert isPlaceholderBci(bci);
+        if (bci == BytecodeFrame.AFTER_BCI) {
+            return "AFTER_BCI";
+        } else if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
+            return "AFTER_EXCEPTION_BCI";
+        } else if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {
+            return "INVALID_FRAMESTATE_BCI";
+        } else if (bci == BytecodeFrame.BEFORE_BCI) {
+            return "BEFORE_BCI";
+        } else if (bci == BytecodeFrame.UNKNOWN_BCI) {
+            return "UNKNOWN_BCI";
+        } else {
+            assert bci == BytecodeFrame.UNWIND_BCI;
+            return "UNWIND_BCI";
+        }
+    }
+
+    /**
+     * Creates a new frame object.
+     *
+     * @param caller the caller frame (which may be {@code null})
+     * @param method the method
+     * @param bci a BCI within the method
+     * @param rethrowException specifies if the VM should re-throw the pending exception when
+     *            deopt'ing using this frame
+     * @param values the frame state {@link #values}
+     * @param numLocals the number of local variables
+     * @param numStack the depth of the stack
+     * @param numLocks the number of locked objects
+     */
+    public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, JavaValue[] values, JavaKind[] slotKinds, int numLocals, int numStack,
+                    int numLocks) {
+        super(caller, method, bci);
+        assert values != null;
+        this.rethrowException = rethrowException;
+        this.duringCall = duringCall;
+        this.values = values;
+        this.slotKinds = slotKinds;
+        this.numLocals = numLocals;
+        this.numStack = numStack;
+        this.numLocks = numLocks;
+        assert !rethrowException || numStack == 1 : "must have exception on top of the stack";
+    }
+
+    /**
+     * Ensure that the frame state is formatted as expected by the JVM, with null or Illegal in the
+     * slot following a double word item. This should really be checked in FrameState itself but
+     * because of Word type rewriting and alternative backends that can't be done.
+     */
+    public boolean validateFormat() {
+        if (caller() != null) {
+            caller().validateFormat();
+        }
+        for (int i = 0; i < numLocals + numStack; i++) {
+            if (values[i] != null) {
+                JavaKind kind = slotKinds[i];
+                if (kind.needsTwoSlots()) {
+                    assert slotKinds.length > i + 1 : String.format("missing second word %s", this);
+                    assert slotKinds[i + 1] == JavaKind.Illegal : this;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Gets the value representing the specified local variable.
+     *
+     * @param i the local variable index
+     * @return the value that can be used to reconstruct the local's current value
+     */
+    public JavaValue getLocalValue(int i) {
+        return values[i];
+    }
+
+    /**
+     * Gets the value representing the specified stack slot.
+     *
+     * @param i the stack index
+     * @return the value that can be used to reconstruct the stack slot's current value
+     */
+    public JavaValue getStackValue(int i) {
+        return values[i + numLocals];
+    }
+
+    /**
+     * Gets the value representing the specified lock.
+     *
+     * @param i the lock index
+     * @return the value that can be used to reconstruct the lock's current value
+     */
+    public JavaValue getLockValue(int i) {
+        return values[i + numLocals + numStack];
+    }
+
+    /**
+     * Gets the caller of this frame.
+     *
+     * @return {@code null} if this frame has no caller
+     */
+    public BytecodeFrame caller() {
+        return (BytecodeFrame) getCaller();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof BytecodeFrame && super.equals(obj)) {
+            BytecodeFrame that = (BytecodeFrame) obj;
+            // @formatter:off
+            if (this.duringCall == that.duringCall &&
+                this.rethrowException == that.rethrowException &&
+                this.numLocals == that.numLocals &&
+                this.numLocks == that.numLocks &&
+                this.numStack == that.numStack &&
+                Arrays.equals(this.values, that.values)) {
+                return true;
+            }
+            // @formatter:off
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return CodeUtil.append(new StringBuilder(100), this).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a code position, that is, a chain of inlined methods with bytecode locations, that is
+ * communicated from the compiler to the runtime system. A code position can be used by the runtime
+ * system to reconstruct a source-level stack trace for exceptions and to create
+ * {@linkplain BytecodeFrame frames} for deoptimization.
+ */
+public class BytecodePosition {
+
+    private final BytecodePosition caller;
+    private final ResolvedJavaMethod method;
+    private final int bci;
+
+    /**
+     * Constructs a new object representing a given parent/caller, a given method, and a given BCI.
+     *
+     * @param caller the parent position
+     * @param method the method
+     * @param bci a BCI within the method
+     */
+    public BytecodePosition(BytecodePosition caller, ResolvedJavaMethod method, int bci) {
+        assert method != null;
+        this.caller = caller;
+        this.method = method;
+        this.bci = bci;
+    }
+
+    /**
+     * Converts this code position to a string representation.
+     *
+     * @return a string representation of this code position
+     */
+    @Override
+    public String toString() {
+        return CodeUtil.append(new StringBuilder(100), this).toString();
+    }
+
+    /**
+     * Deep equality test.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj != null && getClass() == obj.getClass()) {
+            BytecodePosition that = (BytecodePosition) obj;
+            if (this.bci == that.bci && Objects.equals(this.getMethod(), that.getMethod()) && Objects.equals(this.caller, that.caller)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return getBCI();
+    }
+
+    /**
+     * @return The location within the method, as a bytecode index. The constant {@code -1} may be
+     *         used to indicate the location is unknown, for example within code synthesized by the
+     *         compiler.
+     */
+    public int getBCI() {
+        return bci;
+    }
+
+    /**
+     * @return The runtime interface method for this position.
+     */
+    public ResolvedJavaMethod getMethod() {
+        return method;
+    }
+
+    /**
+     * The position where this position has been called, {@code null} if none.
+     */
+    public BytecodePosition getCaller() {
+        return caller;
+    }
+
+    /**
+     * Adds a caller to the current position returning the new position.
+     */
+    public BytecodePosition addCaller(BytecodePosition link) {
+        if (getCaller() == null) {
+            return new BytecodePosition(link, getMethod(), getBCI());
+        } else {
+            return new BytecodePosition(getCaller().addCaller(link), getMethod(), getBCI());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CallingConvention.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+package jdk.vm.ci.code;
+
+import static jdk.vm.ci.code.ValueUtil.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * A calling convention describes the locations in which the arguments for a call are placed and the
+ * location in which the return value is placed if the call is not void.
+ */
+public class CallingConvention {
+
+    /**
+     * Constants denoting the type of a call for which a calling convention is requested.
+     */
+    public enum Type {
+        /**
+         * A request for the outgoing argument locations at a call site to Java code.
+         */
+        JavaCall(true),
+
+        /**
+         * A request for the incoming argument locations.
+         */
+        JavaCallee(false),
+
+        /**
+         * A request for the outgoing argument locations at a call site to external native code that
+         * complies with the platform ABI.
+         */
+        NativeCall(true);
+
+        /**
+         * Determines if this is a request for the outgoing argument locations at a call site.
+         */
+        public final boolean out;
+
+        public static final Type[] VALUES = values();
+
+        private Type(boolean out) {
+            this.out = out;
+        }
+    }
+
+    /**
+     * The amount of stack space (in bytes) required for the stack-based arguments of the call.
+     */
+    private final int stackSize;
+
+    private final AllocatableValue returnLocation;
+
+    /**
+     * The ordered locations in which the arguments are placed.
+     */
+    private final AllocatableValue[] argumentLocations;
+
+    /**
+     * Creates a description of the registers and stack locations used by a call.
+     *
+     * @param stackSize amount of stack space (in bytes) required for the stack-based arguments of
+     *            the call
+     * @param returnLocation the location for the return value or {@link Value#ILLEGAL} if a void
+     *            call
+     * @param argumentLocations the ordered locations in which the arguments are placed
+     */
+    public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) {
+        assert argumentLocations != null;
+        assert returnLocation != null;
+        this.argumentLocations = argumentLocations;
+        this.stackSize = stackSize;
+        this.returnLocation = returnLocation;
+        assert verify();
+    }
+
+    /**
+     * Gets the location for the return value or {@link Value#ILLEGAL} if a void call.
+     */
+    public AllocatableValue getReturn() {
+        return returnLocation;
+    }
+
+    /**
+     * Gets the location for the {@code index}'th argument.
+     */
+    public AllocatableValue getArgument(int index) {
+        return argumentLocations[index];
+    }
+
+    /**
+     * Gets the amount of stack space (in bytes) required for the stack-based arguments of the call.
+     */
+    public int getStackSize() {
+        return stackSize;
+    }
+
+    /**
+     * Gets the number of locations required for the arguments.
+     */
+    public int getArgumentCount() {
+        return argumentLocations.length;
+    }
+
+    /**
+     * Gets the locations required for the arguments.
+     */
+    public AllocatableValue[] getArguments() {
+        if (argumentLocations.length == 0) {
+            return argumentLocations;
+        }
+        return argumentLocations.clone();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("CallingConvention[");
+        String sep = "";
+        for (Value op : argumentLocations) {
+            sb.append(sep).append(op);
+            sep = ", ";
+        }
+        if (!returnLocation.equals(Value.ILLEGAL)) {
+            sb.append(" -> ").append(returnLocation);
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    private boolean verify() {
+        for (int i = 0; i < argumentLocations.length; i++) {
+            Value location = argumentLocations[i];
+            assert isStackSlot(location) || isAllocatableValue(location);
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009, 2014, 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 jdk.vm.ci.code;
+
+import jdk.vm.ci.code.CompilationResult.*;
+import jdk.vm.ci.code.DataSection.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Access to code cache related details and requirements.
+ */
+public interface CodeCacheProvider {
+
+    /**
+     * Adds the given compilation result as an implementation of the given method without making it
+     * the default implementation.
+     *
+     * @param method a method to which the executable code is begin added
+     * @param compResult the compilation result to be added
+     * @param speculationLog the speculation log to be used
+     * @return a reference to the compiled and ready-to-run code or throws a
+     *         {@link BailoutException} if the code installation failed
+     */
+    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode);
+
+    /**
+     * Sets the given compilation result as the default implementation of the given method.
+     *
+     * @param method a method to which the executable code is begin added
+     * @param compResult the compilation result to be added
+     * @return a reference to the compiled and ready-to-run code or null if the code installation
+     *         failed
+     */
+    InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult);
+
+    /**
+     * Gets a name for a {@link Mark} mark.
+     */
+    default String getMarkName(Mark mark) {
+        return String.valueOf(mark.id);
+    }
+
+    /**
+     * Gets a name for the {@linkplain Call#target target} of a {@link Call}.
+     */
+    default String getTargetName(Call call) {
+        return String.valueOf(call.target);
+    }
+
+    /**
+     * Gets the register configuration to use when compiling a given method.
+     */
+    RegisterConfig getRegisterConfig();
+
+    /**
+     * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all
+     * cases, even when the compiled method has no regular call instructions.
+     *
+     * @return the minimum size of the outgoing parameter area in bytes
+     */
+    int getMinimumOutgoingSize();
+
+    /**
+     * Determines if a {@link DataPatch} should be created for a given primitive constant that is
+     * part of a {@link CompilationResult}. A data patch is always created for an object constant.
+     */
+    boolean needsDataPatch(JavaConstant constant);
+
+    /**
+     * Create a {@link Data} item for one or more {@link Constant Constants}, that can be used in a
+     * {@link DataPatch}. If more than one {@link Constant} is given, then they are tightly packed
+     * into a single {@link Data} item.
+     */
+    Data createDataItem(Constant... constants);
+
+    /**
+     * Gets a description of the target architecture.
+     */
+    TargetDescription getTarget();
+
+    /**
+     * Create a new speculation log for the target runtime.
+     */
+    SpeculationLog createSpeculationLog();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2010, 2015, 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 jdk.vm.ci.code;
+
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.code} and its clients.
+ */
+public class CodeUtil {
+
+    public static final String NEW_LINE = String.format("%n");
+
+    public static final int K = 1024;
+    public static final int M = 1024 * 1024;
+
+    public static boolean isOdd(int n) {
+        return (n & 1) == 1;
+    }
+
+    public static boolean isEven(int n) {
+        return (n & 1) == 0;
+    }
+
+    /**
+     * Checks whether the specified integer is a power of two.
+     *
+     * @param val the value to check
+     * @return {@code true} if the value is a power of two; {@code false} otherwise
+     */
+    public static boolean isPowerOf2(int val) {
+        return val > 0 && (val & val - 1) == 0;
+    }
+
+    /**
+     * Checks whether the specified long is a power of two.
+     *
+     * @param val the value to check
+     * @return {@code true} if the value is a power of two; {@code false} otherwise
+     */
+    public static boolean isPowerOf2(long val) {
+        return val > 0 && (val & val - 1) == 0;
+    }
+
+    /**
+     * Computes the log (base 2) of the specified integer, rounding down. (E.g {@code log2(8) = 3},
+     * {@code log2(21) = 4} )
+     *
+     * @param val the value
+     * @return the log base 2 of the value
+     */
+    public static int log2(int val) {
+        assert val > 0;
+        return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(val);
+    }
+
+    /**
+     * Computes the log (base 2) of the specified long, rounding down. (E.g {@code log2(8) = 3},
+     * {@code log2(21) = 4})
+     *
+     * @param val the value
+     * @return the log base 2 of the value
+     */
+    public static int log2(long val) {
+        assert val > 0;
+        return (Long.SIZE - 1) - Long.numberOfLeadingZeros(val);
+    }
+
+    /**
+     * Narrow an integer value to a given bit width, and return the result as a signed long.
+     *
+     * @param value the value
+     * @param resultBits the result bit width
+     * @return {@code value} interpreted as {@code resultBits} bit number, encoded as signed long
+     */
+    public static long narrow(long value, int resultBits) {
+        long ret = value & mask(resultBits);
+        return signExtend(ret, resultBits);
+    }
+
+    /**
+     * Sign extend an integer.
+     *
+     * @param value the input value
+     * @param inputBits the bit width of the input value
+     * @return a signed long with the same value as the signed {@code inputBits}-bit number
+     *         {@code value}
+     */
+    public static long signExtend(long value, int inputBits) {
+        if (inputBits < 64) {
+            if ((value >>> (inputBits - 1) & 1) == 1) {
+                return value | (-1L << inputBits);
+            } else {
+                return value & ~(-1L << inputBits);
+            }
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Zero extend an integer.
+     *
+     * @param value the input value
+     * @param inputBits the bit width of the input value
+     * @return an unsigned long with the same value as the unsigned {@code inputBits}-bit number
+     *         {@code value}
+     */
+    public static long zeroExtend(long value, int inputBits) {
+        if (inputBits < 64) {
+            return value & ~(-1L << inputBits);
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Convert an integer to long.
+     *
+     * @param value the input value
+     * @param inputBits the bit width of the input value
+     * @param unsigned whether the values should be interpreted as signed or unsigned
+     * @return a long with the same value as the {@code inputBits}-bit number {@code value}
+     */
+    public static long convert(long value, int inputBits, boolean unsigned) {
+        if (unsigned) {
+            return zeroExtend(value, inputBits);
+        } else {
+            return signExtend(value, inputBits);
+        }
+    }
+
+    /**
+     * Get a bitmask with the low {@code bits} bit set and the high {@code 64 - bits} bit clear.
+     */
+    public static long mask(int bits) {
+        assert 0 <= bits && bits <= 64;
+        if (bits == 64) {
+            return 0xffffffffffffffffL;
+        } else {
+            return (1L << bits) - 1;
+        }
+    }
+
+    /**
+     * Get the minimum value representable in a {@code bits} bit signed integer.
+     */
+    public static long minValue(int bits) {
+        assert 0 < bits && bits <= 64;
+        return -1L << (bits - 1);
+    }
+
+    /**
+     * Get the maximum value representable in a {@code bits} bit signed integer.
+     */
+    public static long maxValue(int bits) {
+        assert 0 < bits && bits <= 64;
+        return mask(bits - 1);
+    }
+
+    /**
+     * Formats the values in a frame as a tabulated string.
+     *
+     * @param frame
+     * @return the values in {@code frame} as a tabulated string
+     */
+    public static String tabulateValues(BytecodeFrame frame) {
+        int cols = Math.max(frame.numLocals, Math.max(frame.numStack, frame.numLocks));
+        assert cols > 0;
+        ArrayList<Object> cells = new ArrayList<>();
+        cells.add("");
+        for (int i = 0; i < cols; i++) {
+            cells.add(i);
+        }
+        cols++;
+        if (frame.numLocals != 0) {
+            cells.add("locals:");
+            cells.addAll(Arrays.asList(frame.values).subList(0, frame.numLocals));
+            cells.addAll(Collections.nCopies(cols - frame.numLocals - 1, ""));
+        }
+        if (frame.numStack != 0) {
+            cells.add("stack:");
+            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals, frame.numLocals + frame.numStack));
+            cells.addAll(Collections.nCopies(cols - frame.numStack - 1, ""));
+        }
+        if (frame.numLocks != 0) {
+            cells.add("locks:");
+            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals + frame.numStack, frame.values.length));
+            cells.addAll(Collections.nCopies(cols - frame.numLocks - 1, ""));
+        }
+        Object[] cellArray = cells.toArray();
+        for (int i = 0; i < cellArray.length; i++) {
+            if ((i % cols) != 0) {
+                cellArray[i] = "|" + cellArray[i];
+            }
+        }
+        return CodeUtil.tabulate(cellArray, cols, 1, 1);
+    }
+
+    /**
+     * Formats a given table as a string. The value of each cell is produced by
+     * {@link String#valueOf(Object)}.
+     *
+     * @param cells the cells of the table in row-major order
+     * @param cols the number of columns per row
+     * @param lpad the number of space padding inserted before each formatted cell value
+     * @param rpad the number of space padding inserted after each formatted cell value
+     * @return a string with one line per row and each column left-aligned
+     */
+    public static String tabulate(Object[] cells, int cols, int lpad, int rpad) {
+        int rows = (cells.length + (cols - 1)) / cols;
+        int[] colWidths = new int[cols];
+        for (int col = 0; col < cols; col++) {
+            for (int row = 0; row < rows; row++) {
+                int index = col + (row * cols);
+                if (index < cells.length) {
+                    Object cell = cells[index];
+                    colWidths[col] = Math.max(colWidths[col], String.valueOf(cell).length());
+                }
+            }
+        }
+        StringBuilder sb = new StringBuilder();
+        String nl = NEW_LINE;
+        for (int row = 0; row < rows; row++) {
+            for (int col = 0; col < cols; col++) {
+                int index = col + (row * cols);
+                if (index < cells.length) {
+                    for (int i = 0; i < lpad; i++) {
+                        sb.append(' ');
+                    }
+                    Object cell = cells[index];
+                    String s = String.valueOf(cell);
+                    int w = s.length();
+                    sb.append(s);
+                    while (w < colWidths[col]) {
+                        sb.append(' ');
+                        w++;
+                    }
+                    for (int i = 0; i < rpad; i++) {
+                        sb.append(' ');
+                    }
+                }
+            }
+            sb.append(nl);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Appends a formatted code position to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param pos the code position to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, BytecodePosition pos) {
+        MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI());
+        if (pos.getCaller() != null) {
+            sb.append(NEW_LINE);
+            append(sb, pos.getCaller());
+        }
+        return sb;
+    }
+
+    /**
+     * Appends a formatted frame to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param frame the frame to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, BytecodeFrame frame) {
+        MetaUtil.appendLocation(sb.append("at "), frame.getMethod(), frame.getBCI());
+        assert sb.charAt(sb.length() - 1) == ']';
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(", duringCall: ").append(frame.duringCall).append(", rethrow: ").append(frame.rethrowException).append(']');
+        if (frame.values != null && frame.values.length > 0) {
+            sb.append(NEW_LINE);
+            String table = tabulateValues(frame);
+            String[] rows = table.split(NEW_LINE);
+            for (int i = 0; i < rows.length; i++) {
+                String row = rows[i];
+                if (!row.trim().isEmpty()) {
+                    sb.append("  ").append(row);
+                    if (i != rows.length - 1) {
+                        sb.append(NEW_LINE);
+                    }
+                }
+            }
+        }
+        if (frame.caller() != null) {
+            sb.append(NEW_LINE);
+            append(sb, frame.caller());
+        } else if (frame.getCaller() != null) {
+            sb.append(NEW_LINE);
+            append(sb, frame.getCaller());
+        }
+        return sb;
+    }
+
+    public interface RefMapFormatter {
+
+        String formatStackSlot(int frameRefMapIndex);
+
+        String formatRegister(int regRefMapIndex);
+    }
+
+    /**
+     * Formats a location in a register reference map.
+     */
+    public static class DefaultRegFormatter implements RefMapFormatter {
+
+        private final Register[] registers;
+
+        public DefaultRegFormatter(Architecture arch) {
+            registers = new Register[arch.getRegisterReferenceMapSize()];
+            for (Register r : arch.getRegisters()) {
+                if (r.getReferenceMapIndex() >= 0) {
+                    registers[r.getReferenceMapIndex()] = r;
+                }
+            }
+        }
+
+        public String formatStackSlot(int frameRefMapIndex) {
+            return null;
+        }
+
+        public String formatRegister(int regRefMapIndex) {
+            int i = regRefMapIndex;
+            int idx = 0;
+            while (registers[i] == null) {
+                i--;
+                idx++;
+            }
+            if (idx == 0) {
+                return registers[i].toString();
+            } else {
+                return String.format("%s+%d", registers[i].toString(), idx);
+            }
+        }
+    }
+
+    /**
+     * Formats a location present in a register or frame reference map.
+     */
+    public static class DefaultRefMapFormatter extends DefaultRegFormatter {
+
+        /**
+         * The size of a stack slot.
+         */
+        public final int slotSize;
+
+        /**
+         * The register used as the frame pointer.
+         */
+        public final Register fp;
+
+        /**
+         * The offset (in bytes) from the slot pointed to by {@link #fp} to the slot corresponding
+         * to bit 0 in the frame reference map.
+         */
+        public final int refMapToFPOffset;
+
+        public DefaultRefMapFormatter(Architecture arch, int slotSize, Register fp, int refMapToFPOffset) {
+            super(arch);
+            this.slotSize = slotSize;
+            this.fp = fp;
+            this.refMapToFPOffset = refMapToFPOffset;
+        }
+
+        @Override
+        public String formatStackSlot(int frameRefMapIndex) {
+            int refMapOffset = frameRefMapIndex * slotSize;
+            int fpOffset = refMapOffset + refMapToFPOffset;
+            if (fpOffset >= 0) {
+                return fp + "+" + fpOffset;
+            }
+            return fp.name + fpOffset;
+        }
+    }
+
+    public static class NumberedRefMapFormatter implements RefMapFormatter {
+
+        public String formatStackSlot(int frameRefMapIndex) {
+            return "s" + frameRefMapIndex;
+        }
+
+        public String formatRegister(int regRefMapIndex) {
+            return "r" + regRefMapIndex;
+        }
+    }
+
+    /**
+     * Appends a formatted debug info to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param info the debug info to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatterArg) {
+        RefMapFormatter formatter = formatterArg;
+        if (formatter == null) {
+            formatter = new NumberedRefMapFormatter();
+        }
+        String nl = NEW_LINE;
+        ReferenceMap refMap = info.getReferenceMap();
+        if (refMap != null) {
+            sb.append(refMap.toString());
+        }
+        RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo();
+        if (calleeSaveInfo != null) {
+            sb.append("callee-save-info:").append(nl);
+            Map<Integer, Register> map = calleeSaveInfo.slotsToRegisters(true);
+            for (Map.Entry<Integer, Register> e : map.entrySet()) {
+                sb.append("    ").append(e.getValue()).append(" -> ").append(formatter.formatStackSlot(e.getKey())).append(nl);
+            }
+        }
+        BytecodeFrame frame = info.frame();
+        if (frame != null) {
+            append(sb, frame);
+        } else if (info.getBytecodePosition() != null) {
+            append(sb, info.getBytecodePosition());
+        }
+        return sb;
+    }
+
+    /**
+     * Create a calling convention from a {@link ResolvedJavaMethod}.
+     */
+    public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, boolean stackOnly) {
+        Signature sig = method.getSignature();
+        JavaType retType = sig.getReturnType(null);
+        int sigCount = sig.getParameterCount(false);
+        JavaType[] argTypes;
+        int argIndex = 0;
+        if (!method.isStatic()) {
+            argTypes = new JavaType[sigCount + 1];
+            argTypes[argIndex++] = method.getDeclaringClass();
+        } else {
+            argTypes = new JavaType[sigCount];
+        }
+        for (int i = 0; i < sigCount; i++) {
+            argTypes[argIndex++] = sig.getParameterType(i, null);
+        }
+
+        RegisterConfig registerConfig = codeCache.getRegisterConfig();
+        return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget(), stackOnly);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1054 @@
+/*
+ * Copyright (c) 2009, 2014, 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 jdk.vm.ci.code;
+
+import static java.util.Collections.*;
+import static jdk.vm.ci.meta.MetaUtil.*;
+
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Assumptions.*;
+
+/**
+ * Represents the output from compiling a method, including the compiled machine code, associated
+ * data and references, relocation information, deoptimization information, etc.
+ */
+public class CompilationResult {
+
+    /**
+     * Represents a code position with associated additional information.
+     */
+    public abstract static class Site {
+
+        /**
+         * The position (or offset) of this site with respect to the start of the target method.
+         */
+        public final int pcOffset;
+
+        public Site(int pos) {
+            this.pcOffset = pos;
+        }
+
+        @Override
+        public final int hashCode() {
+            throw new UnsupportedOperationException("hashCode");
+        }
+
+        @Override
+        public String toString() {
+            return identityHashCodeString(this);
+        }
+
+        @Override
+        public abstract boolean equals(Object obj);
+    }
+
+    /**
+     * Represents an infopoint with associated debug info. Note that safepoints are also infopoints.
+     */
+    public static class Infopoint extends Site implements Comparable<Infopoint> {
+
+        public final DebugInfo debugInfo;
+
+        public final InfopointReason reason;
+
+        public Infopoint(int pcOffset, DebugInfo debugInfo, InfopointReason reason) {
+            super(pcOffset);
+            this.debugInfo = debugInfo;
+            this.reason = reason;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(pcOffset);
+            sb.append("[<infopoint>]");
+            appendDebugInfo(sb, debugInfo);
+            return sb.toString();
+        }
+
+        @Override
+        public int compareTo(Infopoint o) {
+            if (pcOffset < o.pcOffset) {
+                return -1;
+            } else if (pcOffset > o.pcOffset) {
+                return 1;
+            }
+            return this.reason.compareTo(o.reason);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj != null && obj.getClass() == getClass()) {
+                Infopoint that = (Infopoint) obj;
+                if (this.pcOffset == that.pcOffset && Objects.equals(this.debugInfo, that.debugInfo) && Objects.equals(this.reason, that.reason)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    public enum MetaSpaceAccessType {
+        Move,
+        Store, // store only works for compressed oops (memory <- 32bit value). Compressed oops is
+               // not supported using AOT. TODO: Look at HotSpotStoreConstantOp
+        Compare; // HotSpotCompareMemoryConstantOp, HotSpotCompareConstantOp
+
+        private MetaSpaceAccessType() {
+        }
+    }
+
+    /**
+     * Represents a meta space pointer access in the code.
+     */
+    public static final class MetaSpaceAccess extends Infopoint {
+
+        private static final long serialVersionUID = 1701958512608684706L;
+
+        /**
+         * Metaspace reference.
+         */
+        public final Object reference; // Object here is a HotSpotResolvedObjectType or a
+                                       // HotSpotMetaSpaceConstant
+
+        public final MetaSpaceAccessType type;
+
+        /**
+         * Instruction size.
+         */
+        public final int instructionSize;
+
+        public MetaSpaceAccess(Object reference, int instructionSize, MetaSpaceAccessType type, int pcOffset, DebugInfo debugInfo) {
+            super(pcOffset, debugInfo, InfopointReason.METASPACE_ACCESS);
+            this.type = type;
+            this.reference = reference;
+            this.instructionSize = instructionSize;
+        }
+    }
+
+    /**
+     * Represents a call in the code.
+     */
+    public static final class Call extends Infopoint {
+
+        /**
+         * The target of the call.
+         */
+        public final InvokeTarget target;
+
+        /**
+         * The size of the call instruction.
+         */
+        public final int size;
+
+        /**
+         * Specifies if this call is direct or indirect. A direct call has an immediate operand
+         * encoding the absolute or relative (to the call itself) address of the target. An indirect
+         * call has a register or memory operand specifying the target address of the call.
+         */
+        public final boolean direct;
+
+        public Call(InvokeTarget target, int pcOffset, int size, boolean direct, DebugInfo debugInfo) {
+            super(pcOffset, debugInfo, InfopointReason.CALL);
+            this.size = size;
+            this.target = target;
+            this.direct = direct;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof Call && super.equals(obj)) {
+                Call that = (Call) obj;
+                if (this.size == that.size && this.direct == that.direct && Objects.equals(this.target, that.target)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(pcOffset);
+            sb.append('[');
+            sb.append(target);
+            sb.append(']');
+
+            if (debugInfo != null) {
+                appendDebugInfo(sb, debugInfo);
+            }
+
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Represents some external data that is referenced by the code.
+     */
+    public abstract static class Reference {
+
+        @Override
+        public abstract int hashCode();
+
+        @Override
+        public abstract boolean equals(Object obj);
+    }
+
+    public static final class ConstantReference extends Reference {
+
+        private final VMConstant constant;
+
+        public ConstantReference(VMConstant constant) {
+            this.constant = constant;
+        }
+
+        public VMConstant getConstant() {
+            return constant;
+        }
+
+        @Override
+        public String toString() {
+            return constant.toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return constant.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof ConstantReference) {
+                ConstantReference that = (ConstantReference) obj;
+                return Objects.equals(this.constant, that.constant);
+            }
+            return false;
+        }
+    }
+
+    public static final class DataSectionReference extends Reference {
+
+        private boolean initialized;
+        private int offset;
+
+        public DataSectionReference() {
+            // will be set after the data section layout is fixed
+            offset = 0xDEADDEAD;
+        }
+
+        public int getOffset() {
+            assert initialized;
+
+            return offset;
+        }
+
+        public void setOffset(int offset) {
+            assert !initialized;
+            initialized = true;
+
+            this.offset = offset;
+        }
+
+        @Override
+        public int hashCode() {
+            return offset;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof DataSectionReference) {
+                DataSectionReference that = (DataSectionReference) obj;
+                return this.offset == that.offset;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Represents a code site that references some data. The associated data can be either a
+     * {@link DataSectionReference reference} to the data section, or it may be an inlined
+     * {@link JavaConstant} that needs to be patched.
+     */
+    public static final class DataPatch extends Site {
+
+        public Reference reference;
+        public Object note;
+
+        public DataPatch(int pcOffset, Reference reference) {
+            super(pcOffset);
+            this.reference = reference;
+            this.note = null;
+        }
+
+        public DataPatch(int pcOffset, Reference reference, Object note) {
+            super(pcOffset);
+            this.reference = reference;
+            this.note = note;
+        }
+
+        @Override
+        public String toString() {
+            if (note != null) {
+                return String.format("%d[<data patch referring to %s>, note: %s]", pcOffset, reference.toString(), note.toString());
+            } else {
+                return String.format("%d[<data patch referring to %s>]", pcOffset, reference.toString());
+            }
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof DataPatch) {
+                DataPatch that = (DataPatch) obj;
+                if (this.pcOffset == that.pcOffset && Objects.equals(this.reference, that.reference) && Objects.equals(this.note, that.note)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Provides extra information about instructions or data at specific positions in
+     * {@link CompilationResult#getTargetCode()}. This is optional information that can be used to
+     * enhance a disassembly of the code.
+     */
+    public abstract static class CodeAnnotation {
+
+        public final int position;
+
+        public CodeAnnotation(int position) {
+            this.position = position;
+        }
+
+        @Override
+        public final int hashCode() {
+            throw new UnsupportedOperationException("hashCode");
+        }
+
+        @Override
+        public String toString() {
+            return identityHashCodeString(this);
+        }
+
+        @Override
+        public abstract boolean equals(Object obj);
+    }
+
+    /**
+     * A string comment about one or more instructions at a specific position in the code.
+     */
+    public static final class CodeComment extends CodeAnnotation {
+
+        public final String value;
+
+        public CodeComment(int position, String comment) {
+            super(position);
+            this.value = comment;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof CodeComment) {
+                CodeComment that = (CodeComment) obj;
+                if (this.position == that.position && this.value.equals(that.value)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": " + value;
+        }
+    }
+
+    /**
+     * Describes a table of signed offsets embedded in the code. The offsets are relative to the
+     * starting address of the table. This type of table maybe generated when translating a
+     * multi-way branch based on a key value from a dense value set (e.g. the {@code tableswitch}
+     * JVM instruction).
+     *
+     * The table is indexed by the contiguous range of integers from {@link #low} to {@link #high}
+     * inclusive.
+     */
+    public static final class JumpTable extends CodeAnnotation {
+
+        /**
+         * The low value in the key range (inclusive).
+         */
+        public final int low;
+
+        /**
+         * The high value in the key range (inclusive).
+         */
+        public final int high;
+
+        /**
+         * The size (in bytes) of each table entry.
+         */
+        public final int entrySize;
+
+        public JumpTable(int position, int low, int high, int entrySize) {
+            super(position);
+            this.low = low;
+            this.high = high;
+            this.entrySize = entrySize;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof JumpTable) {
+                JumpTable that = (JumpTable) obj;
+                if (this.position == that.position && this.entrySize == that.entrySize && this.low == that.low && this.high == that.high) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": [" + low + " .. " + high + "]";
+        }
+    }
+
+    /**
+     * Represents exception handler information for a specific code position. It includes the catch
+     * code position as well as the caught exception type.
+     */
+    public static final class ExceptionHandler extends Site {
+
+        public final int handlerPos;
+
+        ExceptionHandler(int pcOffset, int handlerPos) {
+            super(pcOffset);
+            this.handlerPos = handlerPos;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%d[<exception edge to %d>]", pcOffset, handlerPos);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof ExceptionHandler) {
+                ExceptionHandler that = (ExceptionHandler) obj;
+                if (this.pcOffset == that.pcOffset && this.handlerPos == that.handlerPos) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Represents a mark in the machine code that can be used by the runtime for its own purposes. A
+     * mark can reference other marks.
+     */
+    public static final class Mark extends Site {
+
+        public final Object id;
+
+        public Mark(int pcOffset, Object id) {
+            super(pcOffset);
+            this.id = id;
+        }
+
+        @Override
+        public String toString() {
+            if (id == null) {
+                return String.format("%d[<mar>]", pcOffset);
+            } else if (id instanceof Integer) {
+                return String.format("%d[<mark with id %s>]", pcOffset, Integer.toHexString((Integer) id));
+            } else {
+                return String.format("%d[<mark with id %s>]", pcOffset, id.toString());
+            }
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof Mark) {
+                Mark that = (Mark) obj;
+                if (this.pcOffset == that.pcOffset && Objects.equals(this.id, that.id)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    private int id = -1;
+
+    /**
+     * Specifies whether this compilation is a {@code +ImmutableCode} {@code +GeneratePIC}
+     * compilation.
+     */
+    private final boolean isImmutablePIC;
+
+    private int entryBCI = -1;
+
+    private final DataSection dataSection = new DataSection();
+
+    private final List<Infopoint> infopoints = new ArrayList<>();
+    private final List<DataPatch> dataPatches = new ArrayList<>();
+    private final List<ExceptionHandler> exceptionHandlers = new ArrayList<>();
+    private final List<Mark> marks = new ArrayList<>();
+
+    private int totalFrameSize = -1;
+    private int customStackAreaOffset = -1;
+
+    private final String name;
+
+    /**
+     * The buffer containing the emitted machine code.
+     */
+    private byte[] targetCode;
+
+    /**
+     * The leading number of bytes in {@link #targetCode} containing the emitted machine code.
+     */
+    private int targetCodeSize;
+
+    private ArrayList<CodeAnnotation> annotations;
+
+    private Assumption[] assumptions;
+
+    /**
+     * The list of the methods whose bytecodes were used as input to the compilation. If
+     * {@code null}, then the compilation did not record method dependencies. Otherwise, the first
+     * element of this array is the root method of the compilation.
+     */
+    private ResolvedJavaMethod[] methods;
+
+    private int bytecodeSize;
+
+    private boolean hasUnsafeAccess;
+
+    public CompilationResult() {
+        this(null);
+    }
+
+    public CompilationResult(String name) {
+        this.name = name;
+        this.isImmutablePIC = false;
+    }
+
+    public CompilationResult(boolean isImmutablePIC) {
+        this.name = null;
+        this.isImmutablePIC = isImmutablePIC;
+    }
+
+    @Override
+    public int hashCode() {
+        // CompilationResult instances should not be used as hash map keys
+        throw new UnsupportedOperationException("hashCode");
+    }
+
+    @Override
+    public String toString() {
+        if (methods != null) {
+            return getClass().getName() + "[" + methods[0].format("%H.%n(%p)%r") + "]";
+        }
+        return identityHashCodeString(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj != null && obj.getClass() == getClass()) {
+            CompilationResult that = (CompilationResult) obj;
+            // @formatter:off
+            if (this.entryBCI == that.entryBCI &&
+                this.id == that.id &&
+                this.customStackAreaOffset == that.customStackAreaOffset &&
+                this.totalFrameSize == that.totalFrameSize &&
+                this.targetCodeSize == that.targetCodeSize &&
+                Objects.equals(this.name, that.name) &&
+                Objects.equals(this.annotations, that.annotations) &&
+                Objects.equals(this.dataSection, that.dataSection) &&
+                Objects.equals(this.exceptionHandlers, that.exceptionHandlers) &&
+                Objects.equals(this.dataPatches, that.dataPatches) &&
+                Objects.equals(this.infopoints, that.infopoints) &&
+                Objects.equals(this.marks,  that.marks) &&
+                Arrays.equals(this.assumptions, that.assumptions) &&
+                Arrays.equals(targetCode, that.targetCode)) {
+                return true;
+            }
+            // @formatter:on
+        }
+        return false;
+    }
+
+    /**
+     * @return the compile id
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * @param id the compile id to set
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * @return true is this is a {@code +ImmutableCode} {@code +GeneratePIC} compilation, false
+     *         otherwise.
+     */
+    public boolean isImmutablePIC() {
+        return isImmutablePIC;
+    }
+
+    /**
+     * @return the entryBCI
+     */
+    public int getEntryBCI() {
+        return entryBCI;
+    }
+
+    /**
+     * @param entryBCI the entryBCI to set
+     */
+    public void setEntryBCI(int entryBCI) {
+        this.entryBCI = entryBCI;
+    }
+
+    /**
+     * Sets the assumptions made during compilation.
+     */
+    public void setAssumptions(Assumption[] assumptions) {
+        this.assumptions = assumptions;
+    }
+
+    /**
+     * Gets the assumptions made during compilation.
+     */
+    public Assumption[] getAssumptions() {
+        return assumptions;
+    }
+
+    /**
+     * Sets the methods whose bytecodes were used as input to the compilation.
+     *
+     * @param rootMethod the root method of the compilation
+     * @param inlinedMethods the methods inlined during compilation
+     */
+    public void setMethods(ResolvedJavaMethod rootMethod, Collection<ResolvedJavaMethod> inlinedMethods) {
+        assert rootMethod != null;
+        assert inlinedMethods != null;
+        if (inlinedMethods.contains(rootMethod)) {
+            methods = inlinedMethods.toArray(new ResolvedJavaMethod[inlinedMethods.size()]);
+            for (int i = 0; i < methods.length; i++) {
+                if (methods[i].equals(rootMethod)) {
+                    if (i != 0) {
+                        ResolvedJavaMethod tmp = methods[0];
+                        methods[0] = methods[i];
+                        methods[i] = tmp;
+                    }
+                    break;
+                }
+            }
+        } else {
+            methods = new ResolvedJavaMethod[1 + inlinedMethods.size()];
+            methods[0] = rootMethod;
+            int i = 1;
+            for (ResolvedJavaMethod m : inlinedMethods) {
+                methods[i++] = m;
+            }
+        }
+    }
+
+    /**
+     * Gets the methods whose bytecodes were used as input to the compilation.
+     *
+     * @return {@code null} if the compilation did not record method dependencies otherwise the
+     *         methods whose bytecodes were used as input to the compilation with the first element
+     *         being the root method of the compilation
+     */
+    public ResolvedJavaMethod[] getMethods() {
+        return methods;
+    }
+
+    public void setBytecodeSize(int bytecodeSize) {
+        this.bytecodeSize = bytecodeSize;
+    }
+
+    public int getBytecodeSize() {
+        return bytecodeSize;
+    }
+
+    public DataSection getDataSection() {
+        return dataSection;
+    }
+
+    /**
+     * The total frame size of the method in bytes. This includes the return address pushed onto the
+     * stack, if any.
+     *
+     * @return the frame size
+     */
+    public int getTotalFrameSize() {
+        assert totalFrameSize != -1 : "frame size not yet initialized!";
+        return totalFrameSize;
+    }
+
+    /**
+     * Sets the total frame size in bytes. This includes the return address pushed onto the stack,
+     * if any.
+     *
+     * @param size the size of the frame in bytes
+     */
+    public void setTotalFrameSize(int size) {
+        totalFrameSize = size;
+    }
+
+    /**
+     * Sets the machine that has been generated by the compiler.
+     *
+     * @param code the machine code generated
+     * @param size the size of the machine code
+     */
+    public void setTargetCode(byte[] code, int size) {
+        targetCode = code;
+        targetCodeSize = size;
+    }
+
+    /**
+     * Records a data patch in the code section. The data patch can refer to something in the
+     * {@link DataSectionReference data section} or directly to an {@link ConstantReference inlined
+     * constant}.
+     *
+     * @param codePos The position in the code that needs to be patched.
+     * @param ref The reference that should be inserted in the code.
+     */
+    public void recordDataPatch(int codePos, Reference ref) {
+        assert codePos >= 0 && ref != null;
+        dataPatches.add(new DataPatch(codePos, ref));
+    }
+
+    /**
+     * Records a data patch in the code section. The data patch can refer to something in the
+     * {@link DataSectionReference data section} or directly to an {@link ConstantReference inlined
+     * constant}.
+     *
+     * @param codePos The position in the code that needs to be patched.
+     * @param ref The reference that should be inserted in the code.
+     * @param note The note attached to data patch for use by post-processing tools
+     */
+    public void recordDataPatchWithNote(int codePos, Reference ref, Object note) {
+        assert codePos >= 0 && ref != null;
+        dataPatches.add(new DataPatch(codePos, ref, note));
+    }
+
+    /**
+     * Records metaspace access.
+     */
+    public void recordMetaspaceAccess(Object reference, int instructionSize, MetaSpaceAccessType type, int codePos, DebugInfo debugInfo) {
+        final MetaSpaceAccess metaspace = new MetaSpaceAccess(reference, instructionSize, type, codePos, debugInfo);
+        addInfopoint(metaspace);
+    }
+
+    /**
+     * Records a call in the code array.
+     *
+     * @param codePos the position of the call in the code array
+     * @param size the size of the call instruction
+     * @param target the being called
+     * @param debugInfo the debug info for the call
+     * @param direct specifies if this is a {@linkplain Call#direct direct} call
+     */
+    public void recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) {
+        final Call call = new Call(target, codePos, size, direct, debugInfo);
+        addInfopoint(call);
+    }
+
+    /**
+     * Records an exception handler for this method.
+     *
+     * @param codePos the position in the code that is covered by the handler
+     * @param handlerPos the position of the handler
+     */
+    public void recordExceptionHandler(int codePos, int handlerPos) {
+        assert validateExceptionHandlerAdd(codePos, handlerPos) : String.format("Duplicate exception handler for pc 0x%x handlerPos 0x%x", codePos, handlerPos);
+        exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos));
+    }
+
+    /**
+     * Validate if the exception handler for codePos already exists and handlerPos is different.
+     *
+     * @param codePos
+     * @param handlerPos
+     * @return true if the validation is successful
+     */
+    private boolean validateExceptionHandlerAdd(int codePos, int handlerPos) {
+        ExceptionHandler exHandler = getExceptionHandlerForCodePos(codePos);
+        return exHandler == null || exHandler.handlerPos == handlerPos;
+    }
+
+    /**
+     * Returns the first ExceptionHandler which matches codePos.
+     *
+     * @param codePos position to search for
+     * @return first matching ExceptionHandler
+     */
+    private ExceptionHandler getExceptionHandlerForCodePos(int codePos) {
+        for (ExceptionHandler h : exceptionHandlers) {
+            if (h.pcOffset == codePos) {
+                return h;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Records an infopoint in the code array.
+     *
+     * @param codePos the position of the infopoint in the code array
+     * @param debugInfo the debug info for the infopoint
+     */
+    public void recordInfopoint(int codePos, DebugInfo debugInfo, InfopointReason reason) {
+        addInfopoint(new Infopoint(codePos, debugInfo, reason));
+    }
+
+    /**
+     * Records a custom infopoint in the code section.
+     *
+     * Compiler implementations can use this method to record non-standard infopoints, which are not
+     * handled by the dedicated methods like {@link #recordCall}.
+     *
+     * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint}
+     */
+    public void addInfopoint(Infopoint infopoint) {
+        // The infopoints list must always be sorted
+        if (!infopoints.isEmpty()) {
+            Infopoint previousInfopoint = infopoints.get(infopoints.size() - 1);
+            if (previousInfopoint.pcOffset > infopoint.pcOffset) {
+                // This re-sorting should be very rare
+                Collections.sort(infopoints);
+                previousInfopoint = infopoints.get(infopoints.size() - 1);
+            }
+            if (previousInfopoint.pcOffset == infopoint.pcOffset) {
+                if (infopoint.reason.canBeOmitted()) {
+                    return;
+                }
+                if (previousInfopoint.reason.canBeOmitted()) {
+                    Infopoint removed = infopoints.remove(infopoints.size() - 1);
+                    assert removed == previousInfopoint;
+                } else {
+                    throw new RuntimeException("Infopoints that can not be omited should have distinct PCs");
+                }
+            }
+        }
+        infopoints.add(infopoint);
+    }
+
+    /**
+     * Records an instruction mark within this method.
+     *
+     * @param codePos the position in the code that is covered by the handler
+     * @param markId the identifier for this mark
+     */
+    public Mark recordMark(int codePos, Object markId) {
+        Mark mark = new Mark(codePos, markId);
+        marks.add(mark);
+        return mark;
+    }
+
+    /**
+     * Offset in bytes for the custom stack area (relative to sp).
+     *
+     * @return the offset in bytes
+     */
+    public int getCustomStackAreaOffset() {
+        return customStackAreaOffset;
+    }
+
+    /**
+     * @see #getCustomStackAreaOffset()
+     * @param offset
+     */
+    public void setCustomStackAreaOffset(int offset) {
+        customStackAreaOffset = offset;
+    }
+
+    /**
+     * @return the machine code generated for this method
+     */
+    public byte[] getTargetCode() {
+        return targetCode;
+    }
+
+    /**
+     * @return the size of the machine code generated for this method
+     */
+    public int getTargetCodeSize() {
+        return targetCodeSize;
+    }
+
+    /**
+     * @return the code annotations or {@code null} if there are none
+     */
+    public List<CodeAnnotation> getAnnotations() {
+        if (annotations == null) {
+            return Collections.emptyList();
+        }
+        return annotations;
+    }
+
+    public void addAnnotation(CodeAnnotation annotation) {
+        assert annotation != null;
+        if (annotations == null) {
+            annotations = new ArrayList<>();
+        }
+        annotations.add(annotation);
+    }
+
+    private static void appendDebugInfo(StringBuilder sb, DebugInfo info) {
+        if (info != null) {
+            ReferenceMap refMap = info.getReferenceMap();
+            if (refMap != null) {
+                sb.append(refMap.toString());
+                sb.append(']');
+            }
+            RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo();
+            if (calleeSaveInfo != null) {
+                sb.append(" callee-save-info[");
+                String sep = "";
+                for (Map.Entry<Register, Integer> e : calleeSaveInfo.registersToSlots(true).entrySet()) {
+                    sb.append(sep).append(e.getKey()).append("->").append(e.getValue());
+                    sep = ", ";
+                }
+                sb.append(']');
+            }
+            BytecodePosition codePos = info.getBytecodePosition();
+            if (codePos != null) {
+                MetaUtil.appendLocation(sb.append(" "), codePos.getMethod(), codePos.getBCI());
+                if (info.hasFrame()) {
+                    sb.append(" #locals=").append(info.frame().numLocals).append(" #expr=").append(info.frame().numStack);
+                    if (info.frame().numLocks > 0) {
+                        sb.append(" #locks=").append(info.frame().numLocks);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * @return the list of infopoints, sorted by {@link Site#pcOffset}
+     */
+    public List<Infopoint> getInfopoints() {
+        if (infopoints.isEmpty()) {
+            return emptyList();
+        }
+        return unmodifiableList(infopoints);
+    }
+
+    /**
+     * @return the list of data references
+     */
+    public List<DataPatch> getDataPatches() {
+        if (dataPatches.isEmpty()) {
+            return emptyList();
+        }
+        return unmodifiableList(dataPatches);
+    }
+
+    /**
+     * @return the list of exception handlers
+     */
+    public List<ExceptionHandler> getExceptionHandlers() {
+        if (exceptionHandlers.isEmpty()) {
+            return emptyList();
+        }
+        return unmodifiableList(exceptionHandlers);
+    }
+
+    /**
+     * @return the list of marks
+     */
+    public List<Mark> getMarks() {
+        if (marks.isEmpty()) {
+            return emptyList();
+        }
+        return unmodifiableList(marks);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setHasUnsafeAccess(boolean hasUnsafeAccess) {
+        this.hasUnsafeAccess = hasUnsafeAccess;
+    }
+
+    public boolean hasUnsafeAccess() {
+        return hasUnsafeAccess;
+    }
+
+    public void reset() {
+        hasUnsafeAccess = false;
+        infopoints.clear();
+        dataPatches.clear();
+        exceptionHandlers.clear();
+        marks.clear();
+        dataSection.clear();
+        if (annotations != null) {
+            annotations.clear();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DataSection.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.code;
+
+import static jdk.vm.ci.meta.MetaUtil.*;
+
+import java.nio.*;
+import java.util.*;
+import java.util.function.*;
+
+import jdk.vm.ci.code.CompilationResult.*;
+import jdk.vm.ci.code.DataSection.*;
+import jdk.vm.ci.meta.*;
+
+public final class DataSection implements Iterable<Data> {
+
+    @FunctionalInterface
+    public interface DataBuilder {
+
+        void emit(ByteBuffer buffer, Consumer<DataPatch> patch);
+
+        static DataBuilder raw(byte[] data) {
+            return (buffer, patch) -> buffer.put(data);
+        }
+
+        static DataBuilder serializable(SerializableConstant c) {
+            return (buffer, patch) -> c.serialize(buffer);
+        }
+
+        static DataBuilder zero(int size) {
+            switch (size) {
+                case 1:
+                    return (buffer, patch) -> buffer.put((byte) 0);
+                case 2:
+                    return (buffer, patch) -> buffer.putShort((short) 0);
+                case 4:
+                    return (buffer, patch) -> buffer.putInt(0);
+                case 8:
+                    return (buffer, patch) -> buffer.putLong(0L);
+                default:
+                    return (buffer, patch) -> {
+                        int rest = size;
+                        while (rest > 8) {
+                            buffer.putLong(0L);
+                            rest -= 8;
+                        }
+                        while (rest > 0) {
+                            buffer.put((byte) 0);
+                            rest--;
+                        }
+                    };
+            }
+        }
+    }
+
+    public static final class Data {
+
+        private int alignment;
+        private final int size;
+        private final DataBuilder builder;
+
+        private DataSectionReference ref;
+
+        public Data(int alignment, int size, DataBuilder builder) {
+            this.alignment = alignment;
+            this.size = size;
+            this.builder = builder;
+
+            // initialized in DataSection.insertData(Data)
+            ref = null;
+        }
+
+        public void updateAlignment(int newAlignment) {
+            if (newAlignment == alignment) {
+                return;
+            }
+            alignment = lcm(alignment, newAlignment);
+        }
+
+        public int getAlignment() {
+            return alignment;
+        }
+
+        public int getSize() {
+            return size;
+        }
+
+        public DataBuilder getBuilder() {
+            return builder;
+        }
+
+        @Override
+        public int hashCode() {
+            // Data instances should not be used as hash map keys
+            throw new UnsupportedOperationException("hashCode");
+        }
+
+        @Override
+        public String toString() {
+            return identityHashCodeString(this);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            assert ref != null;
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof Data) {
+                Data that = (Data) obj;
+                if (this.alignment == that.alignment && this.size == that.size && this.ref.equals(that.ref)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    private final ArrayList<Data> dataItems = new ArrayList<>();
+
+    private boolean finalLayout;
+    private int sectionAlignment;
+    private int sectionSize;
+
+    @Override
+    public int hashCode() {
+        // DataSection instances should not be used as hash map keys
+        throw new UnsupportedOperationException("hashCode");
+    }
+
+    @Override
+    public String toString() {
+        return identityHashCodeString(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DataSection) {
+            DataSection that = (DataSection) obj;
+            if (this.finalLayout == that.finalLayout && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Insert a {@link Data} item into the data section. If the item is already in the data section,
+     * the same {@link DataSectionReference} is returned.
+     *
+     * @param data the {@link Data} item to be inserted
+     * @return a unique {@link DataSectionReference} identifying the {@link Data} item
+     */
+    public DataSectionReference insertData(Data data) {
+        assert !finalLayout;
+        if (data.ref == null) {
+            data.ref = new DataSectionReference();
+            dataItems.add(data);
+        }
+        return data.ref;
+    }
+
+    /**
+     * Compute the layout of the data section. This can be called only once, and after it has been
+     * called, the data section can no longer be modified.
+     */
+    public void finalizeLayout() {
+        assert !finalLayout;
+        finalLayout = true;
+
+        // simple heuristic: put items with larger alignment requirement first
+        dataItems.sort((a, b) -> a.alignment - b.alignment);
+
+        int position = 0;
+        for (Data d : dataItems) {
+            sectionAlignment = lcm(sectionAlignment, d.alignment);
+            position = align(position, d.alignment);
+
+            d.ref.setOffset(position);
+            position += d.size;
+        }
+
+        sectionSize = position;
+    }
+
+    public boolean isFinalized() {
+        return finalLayout;
+    }
+
+    /**
+     * Get the size of the data section. Can only be called after {@link #finalizeLayout}.
+     */
+    public int getSectionSize() {
+        assert finalLayout;
+        return sectionSize;
+    }
+
+    /**
+     * Get the minimum alignment requirement of the data section. Can only be called after
+     * {@link #finalizeLayout}.
+     */
+    public int getSectionAlignment() {
+        assert finalLayout;
+        return sectionAlignment;
+    }
+
+    /**
+     * Build the data section. Can only be called after {@link #finalizeLayout}.
+     *
+     * @param buffer The {@link ByteBuffer} where the data section should be built. The buffer must
+     *            hold at least {@link #getSectionSize()} bytes.
+     * @param patch A {@link Consumer} to receive {@link DataPatch data patches} for relocations in
+     *            the data section.
+     */
+    public void buildDataSection(ByteBuffer buffer, Consumer<DataPatch> patch) {
+        assert finalLayout;
+        for (Data d : dataItems) {
+            buffer.position(d.ref.getOffset());
+            d.builder.emit(buffer, patch);
+        }
+    }
+
+    public Data findData(DataSectionReference ref) {
+        for (Data d : dataItems) {
+            if (d.ref == ref) {
+                return d;
+            }
+        }
+        return null;
+    }
+
+    public Iterator<Data> iterator() {
+        return dataItems.iterator();
+    }
+
+    public static int lcm(int x, int y) {
+        if (x == 0) {
+            return y;
+        } else if (y == 0) {
+            return x;
+        }
+
+        int a = Math.max(x, y);
+        int b = Math.min(x, y);
+        while (b > 0) {
+            int tmp = a % b;
+            a = b;
+            b = tmp;
+        }
+
+        int gcd = a;
+        return x * y / gcd;
+    }
+
+    private static int align(int position, int alignment) {
+        return ((position + alignment - 1) / alignment) * alignment;
+    }
+
+    public void clear() {
+        assert !finalLayout;
+        this.dataItems.clear();
+        this.sectionAlignment = 0;
+        this.sectionSize = 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DebugInfo.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+import java.util.*;
+
+/**
+ * Represents the debugging information for a particular point of execution. This information
+ * includes:
+ * <ul>
+ * <li>a {@linkplain #getBytecodePosition() bytecode position}</li>
+ * <li>a reference map for registers and stack slots in the current frame</li>
+ * <li>a map from bytecode locals and operand stack slots to their values or locations from which
+ * their values can be read</li>
+ * <li>a map from the registers (in the caller's frame) to the slots where they are saved in the
+ * current frame</li>
+ * </ul>
+ */
+public final class DebugInfo {
+
+    private final BytecodePosition bytecodePosition;
+    private ReferenceMap referenceMap;
+    @SuppressWarnings("unused") private final VirtualObject[] virtualObjectMapping;
+    private RegisterSaveLayout calleeSaveInfo;
+
+    /**
+     * Creates a new {@link DebugInfo} from the given values.
+     *
+     * @param codePos the {@linkplain BytecodePosition code position} or {@linkplain BytecodeFrame
+     *            frame} info
+     * @param virtualObjectMapping the mapping of {@link VirtualObject}s to their real values
+     */
+    public DebugInfo(BytecodePosition codePos, VirtualObject[] virtualObjectMapping) {
+        this.bytecodePosition = codePos;
+        this.virtualObjectMapping = virtualObjectMapping;
+    }
+
+    public DebugInfo(BytecodePosition codePos) {
+        this(codePos, null);
+    }
+
+    public void setReferenceMap(ReferenceMap referenceMap) {
+        this.referenceMap = referenceMap;
+    }
+
+    /**
+     * @return {@code true} if this debug information has a frame
+     */
+    public boolean hasFrame() {
+        return getBytecodePosition() instanceof BytecodeFrame;
+    }
+
+    /**
+     * Gets the deoptimization information for each inlined frame (if available).
+     *
+     * @return {@code null} if no frame de-opt info is {@linkplain #hasFrame() available}
+     */
+    public BytecodeFrame frame() {
+        if (hasFrame()) {
+            return (BytecodeFrame) getBytecodePosition();
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return CodeUtil.append(new StringBuilder(100), this, null).toString();
+    }
+
+    /**
+     * @return The code position (including all inlined methods) of this debug info. If this is a
+     *         {@link BytecodeFrame} instance, then it is also the deoptimization information for
+     *         each inlined frame.
+     */
+    public BytecodePosition getBytecodePosition() {
+        return bytecodePosition;
+    }
+
+    public ReferenceMap getReferenceMap() {
+        return referenceMap;
+    }
+
+    /**
+     * Sets the map from the registers (in the caller's frame) to the slots where they are saved in
+     * the current frame.
+     */
+    public void setCalleeSaveInfo(RegisterSaveLayout calleeSaveInfo) {
+        this.calleeSaveInfo = calleeSaveInfo;
+    }
+
+    /**
+     * Gets the map from the registers (in the caller's frame) to the slots where they are saved in
+     * the current frame. If no such information is available, {@code null} is returned.
+     */
+    public RegisterSaveLayout getCalleeSaveInfo() {
+        return calleeSaveInfo;
+    }
+
+    @Override
+    public int hashCode() {
+        throw new UnsupportedOperationException("hashCode");
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DebugInfo) {
+            DebugInfo that = (DebugInfo) obj;
+            if (Objects.equals(this.bytecodePosition, that.bytecodePosition) && Objects.equals(this.calleeSaveInfo, that.calleeSaveInfo) && Objects.equals(this.referenceMap, that.referenceMap)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InfopointReason.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,47 @@
+/*
+ * 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 jdk.vm.ci.code;
+
+/**
+ * A reason for infopoint insertion.
+ */
+public enum InfopointReason {
+    UNKNOWN(false),
+    SAFEPOINT(false),
+    CALL(false),
+    IMPLICIT_EXCEPTION(false),
+    METHOD_START(true),
+    METHOD_END(true),
+    LINE_NUMBER(true),
+    METASPACE_ACCESS(true);
+
+    private InfopointReason(boolean canBeOmitted) {
+        this.canBeOmitted = canBeOmitted;
+    }
+
+    private final boolean canBeOmitted;
+
+    public boolean canBeOmitted() {
+        return canBeOmitted;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+/**
+ * Represents a compiled instance of a method. It may have been invalidated or removed in the
+ * meantime.
+ */
+public class InstalledCode {
+
+    /**
+     * Raw address of this code blob.
+     */
+    private long address;
+
+    /**
+     * Counts how often the address field was reassigned.
+     */
+    private long version;
+
+    protected final String name;
+
+    public InstalledCode(String name) {
+        this.name = name;
+    }
+
+    public final void setAddress(long address) {
+        this.address = address;
+        version++;
+    }
+
+    /**
+     * @return the address of this code blob
+     */
+    public final long getAddress() {
+        return address;
+    }
+
+    /**
+     * @return the address of this code blob
+     */
+    public final long getVersion() {
+        return version;
+    }
+
+    /**
+     * Returns the name of this code blob.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the start address of this installed code if it is {@linkplain #isValid() valid}, 0
+     * otherwise.
+     */
+    public long getStart() {
+        return 0;
+    }
+
+    /**
+     * Returns the number of instruction bytes for this code.
+     */
+    public long getCodeSize() {
+        return 0;
+    }
+
+    /**
+     * Returns a copy of this installed code if it is {@linkplain #isValid() valid}, null otherwise.
+     */
+    public byte[] getCode() {
+        return null;
+    }
+
+    /**
+     * @return true if the code represented by this object is still valid, false otherwise (may
+     *         happen due to deopt, etc.)
+     */
+    public boolean isValid() {
+        return address != 0;
+    }
+
+    /**
+     * Invalidates this installed code such that any subsequent
+     * {@linkplain #executeVarargs(Object...) invocation} will throw an
+     * {@link InvalidInstalledCodeException}.
+     */
+    public void invalidate() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Executes the installed code with a variable number of arguments.
+     *
+     * @param args the array of object arguments
+     * @return the value returned by the executed code
+     */
+    @SuppressWarnings("unused")
+    public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InvalidInstalledCodeException.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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 jdk.vm.ci.code;
+
+/**
+ * Exception thrown by the runtime in case an invalidated machine code is called.
+ */
+public final class InvalidInstalledCodeException extends Exception {
+
+    private static final long serialVersionUID = -3540232440794244844L;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Location.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.code;
+
+/**
+ * Represents a location where a value can be stored. This can be either a {@link Register} or a
+ * stack slot.
+ */
+public final class Location {
+
+    public final Register reg;
+    public final int offset;
+
+    private Location(Register reg, int offset) {
+        this.reg = reg;
+        this.offset = offset;
+    }
+
+    /**
+     * Create a {@link Location} for a register.
+     */
+    public static Location register(Register reg) {
+        return new Location(reg, 0);
+    }
+
+    /**
+     * Create a {@link Location} for a vector subregister.
+     *
+     * @param reg the {@link Register vector register}
+     * @param offset the offset in bytes into the vector register
+     */
+    public static Location subregister(Register reg, int offset) {
+        return new Location(reg, offset);
+    }
+
+    /**
+     * Create a {@link Location} for a stack slot.
+     */
+    public static Location stack(int offset) {
+        return new Location(null, offset);
+    }
+
+    public boolean isRegister() {
+        return reg != null;
+    }
+
+    public boolean isStack() {
+        return reg == null;
+    }
+
+    @Override
+    public String toString() {
+        String regName;
+        if (isRegister()) {
+            regName = reg.name + ":";
+        } else {
+            regName = "stack:";
+        }
+        return regName + offset;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+/**
+ * Constants and intrinsic definition for memory barriers.
+ *
+ * The documentation for each constant is taken from Doug Lea's <a
+ * href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler
+ * Writers</a>.
+ * <p>
+ * The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory
+ * Model with respect to volatile field accesses. Their values are explained by this comment from
+ * templateTable_i486.cpp in the HotSpot source code:
+ *
+ * <pre>
+ * Volatile variables demand their effects be made known to all CPU's in
+ * order.  Store buffers on most chips allow reads &amp; writes to reorder; the
+ * JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
+ * memory barrier (i.e., it's not sufficient that the interpreter does not
+ * reorder volatile references, the hardware also must not reorder them).
+ *
+ * According to the new Java Memory Model (JMM):
+ * (1) All volatiles are serialized wrt to each other.
+ * ALSO reads &amp; writes act as acquire &amp; release, so:
+ * (2) A read cannot let unrelated NON-volatile memory refs that happen after
+ * the read float up to before the read.  It's OK for non-volatile memory refs
+ * that happen before the volatile read to float down below it.
+ * (3) Similarly, a volatile write cannot let unrelated NON-volatile memory refs
+ * that happen BEFORE the write float down to after the write.  It's OK for
+ * non-volatile memory refs that happen after the volatile write to float up
+ * before it.
+ *
+ * We only put in barriers around volatile refs (they are expensive), not
+ * _between_ memory refs (which would require us to track the flavor of the
+ * previous memory refs).  Requirements (2) and (3) require some barriers
+ * before volatile stores and after volatile loads.  These nearly cover
+ * requirement (1) but miss the volatile-store-volatile-load case.  This final
+ * case is placed after volatile-stores although it could just as well go
+ * before volatile-loads.
+ * </pre>
+ */
+public class MemoryBarriers {
+
+    /**
+     * The sequence {@code Load1; LoadLoad; Load2} ensures that {@code Load1}'s data are loaded
+     * before data accessed by {@code Load2} and all subsequent load instructions are loaded. In
+     * general, explicit {@code LoadLoad} barriers are needed on processors that perform speculative
+     * loads and/or out-of-order processing in which waiting load instructions can bypass waiting
+     * stores. On processors that guarantee to always preserve load ordering, these barriers amount
+     * to no-ops.
+     */
+    public static final int LOAD_LOAD = 0x0001;
+
+    /**
+     * The sequence {@code Load1; LoadStore; Store2} ensures that {@code Load1}'s data are loaded
+     * before all data associated with {@code Store2} and subsequent store instructions are flushed.
+     * {@code LoadStore} barriers are needed only on those out-of-order processors in which waiting
+     * store instructions can bypass loads.
+     */
+    public static final int LOAD_STORE = 0x0002;
+
+    /**
+     * The sequence {@code Store1; StoreLoad; Load2} ensures that {@code Store1}'s data are made
+     * visible to other processors (i.e., flushed to main memory) before data accessed by
+     * {@code Load2} and all subsequent load instructions are loaded. {@code StoreLoad} barriers
+     * protect against a subsequent load incorrectly using {@code Store1}'s data value rather than
+     * that from a more recent store to the same location performed by a different processor.
+     * Because of this, on the processors discussed below, a {@code StoreLoad} is strictly necessary
+     * only for separating stores from subsequent loads of the same location(s) as were stored
+     * before the barrier. {@code StoreLoad} barriers are needed on nearly all recent
+     * multiprocessors, and are usually the most expensive kind. Part of the reason they are
+     * expensive is that they must disable mechanisms that ordinarily bypass cache to satisfy loads
+     * from write-buffers. This might be implemented by letting the buffer fully flush, among other
+     * possible stalls.
+     */
+    public static final int STORE_LOAD = 0x0004;
+
+    /**
+     * The sequence {@code Store1; StoreStore; Store2} ensures that {@code Store1}'s data are
+     * visible to other processors (i.e., flushed to memory) before the data associated with
+     * {@code Store2} and all subsequent store instructions. In general, {@code StoreStore} barriers
+     * are needed on processors that do not otherwise guarantee strict ordering of flushes from
+     * write buffers and/or caches to other processors or main memory.
+     */
+    public static final int STORE_STORE = 0x0008;
+
+    public static final int JMM_PRE_VOLATILE_WRITE = LOAD_STORE | STORE_STORE;
+    public static final int JMM_POST_VOLATILE_WRITE = STORE_LOAD | STORE_STORE;
+    public static final int JMM_PRE_VOLATILE_READ = 0;
+    public static final int JMM_POST_VOLATILE_READ = LOAD_LOAD | LOAD_STORE;
+
+    public static String barriersString(int barriers) {
+        StringBuilder sb = new StringBuilder();
+        sb.append((barriers & LOAD_LOAD) != 0 ? "LOAD_LOAD " : "");
+        sb.append((barriers & LOAD_STORE) != 0 ? "LOAD_STORE " : "");
+        sb.append((barriers & STORE_LOAD) != 0 ? "STORE_LOAD " : "");
+        sb.append((barriers & STORE_STORE) != 0 ? "STORE_STORE " : "");
+        return sb.toString().trim();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ReferenceMap.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+public abstract class ReferenceMap {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a target machine register.
+ */
+public final class Register implements Comparable<Register> {
+
+    public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL");
+
+    /**
+     * Invalid register.
+     */
+    public static final Register None = new Register(-1, -1, "noreg", SPECIAL);
+
+    /**
+     * Frame pointer of the current method. All spill slots and outgoing stack-based arguments are
+     * addressed relative to this register.
+     */
+    public static final Register Frame = new Register(-2, -2, "framereg", SPECIAL);
+
+    public static final Register CallerFrame = new Register(-3, -3, "callerframereg", SPECIAL);
+
+    /**
+     * The identifier for this register that is unique across all the registers in a
+     * {@link Architecture}. A valid register has {@code number > 0}.
+     */
+    public final int number;
+
+    /**
+     * The mnemonic of this register.
+     */
+    public final String name;
+
+    /**
+     * The actual encoding in a target machine instruction for this register, which may or may not
+     * be the same as {@link #number}.
+     */
+    public final int encoding;
+
+    /**
+     * The assembler calls this method to get the register's encoding.
+     */
+    public int encoding() {
+        return encoding;
+    }
+
+    /**
+     * A platform specific register category that describes which values can be stored in a
+     * register.
+     */
+    private final RegisterCategory registerCategory;
+
+    /**
+     * A platform specific register type that describes which values can be stored in a register.
+     */
+    public static class RegisterCategory {
+
+        private final String name;
+
+        private final int referenceMapOffset;
+        private final int referenceMapShift;
+
+        public RegisterCategory(String name) {
+            this(name, 0, 0);
+        }
+
+        public RegisterCategory(String name, int referenceMapOffset) {
+            this(name, referenceMapOffset, 0);
+        }
+
+        public RegisterCategory(String name, int referenceMapOffset, int referenceMapShift) {
+            this.name = name;
+            this.referenceMapOffset = referenceMapOffset;
+            this.referenceMapShift = referenceMapShift;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+
+        @Override
+        public int hashCode() {
+            return 23 + name.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof RegisterCategory) {
+                RegisterCategory that = (RegisterCategory) obj;
+                return this.referenceMapOffset == that.referenceMapOffset && this.referenceMapShift == that.referenceMapShift && this.name.equals(that.name);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Creates a {@link Register} instance.
+     *
+     * @param number unique identifier for the register
+     * @param encoding the target machine encoding for the register
+     * @param name the mnemonic name for the register
+     * @param registerCategory the register category
+     */
+    public Register(int number, int encoding, String name, RegisterCategory registerCategory) {
+        this.number = number;
+        this.name = name;
+        this.registerCategory = registerCategory;
+        this.encoding = encoding;
+    }
+
+    public RegisterCategory getRegisterCategory() {
+        return registerCategory;
+    }
+
+    /**
+     * Get the start index of this register in the {@link ReferenceMap}.
+     */
+    public int getReferenceMapIndex() {
+        return (encoding << registerCategory.referenceMapShift) + registerCategory.referenceMapOffset;
+    }
+
+    /**
+     * Gets this register as a {@linkplain RegisterValue value} with a specified kind.
+     *
+     * @param kind the specified kind
+     * @return the {@link RegisterValue}
+     */
+    public RegisterValue asValue(LIRKind kind) {
+        return new RegisterValue(kind, this);
+    }
+
+    /**
+     * Gets this register as a {@linkplain RegisterValue value} with no particular kind.
+     *
+     * @return a {@link RegisterValue} with {@link JavaKind#Illegal} kind.
+     */
+    public RegisterValue asValue() {
+        return asValue(LIRKind.Illegal);
+    }
+
+    /**
+     * Determines if this is a valid register.
+     *
+     * @return {@code true} iff this register is valid
+     */
+    public boolean isValid() {
+        return number >= 0;
+    }
+
+    /**
+     * Gets the maximum register {@linkplain #number number} in a given set of registers.
+     *
+     * @param registers the set of registers to process
+     * @return the maximum register number for any register in {@code registers}
+     */
+    public static int maxRegisterNumber(Register[] registers) {
+        int max = Integer.MIN_VALUE;
+        for (Register r : registers) {
+            if (r.number > max) {
+                max = r.number;
+            }
+        }
+        return max;
+    }
+
+    /**
+     * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
+     *
+     * @param registers the set of registers to process
+     * @return the maximum register encoding for any register in {@code registers}
+     */
+    public static int maxRegisterEncoding(Register[] registers) {
+        int max = Integer.MIN_VALUE;
+        for (Register r : registers) {
+            if (r.encoding > max) {
+                max = r.encoding;
+            }
+        }
+        return max;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public int compareTo(Register o) {
+        if (number < o.number) {
+            return -1;
+        }
+        if (number > o.number) {
+            return 1;
+        }
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return 17 + name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Register) {
+            Register other = (Register) obj;
+            if (number == other.number) {
+                assert name.equals(other.name);
+                assert encoding == other.encoding;
+                assert registerCategory.equals(other.registerCategory);
+                return true;
+            }
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterAttributes.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+import java.util.*;
+
+/**
+ * A collection of register attributes. The specific attribute values for a register may be local to
+ * a compilation context. For example, a {@link RegisterConfig} in use during a compilation will
+ * determine which registers are callee saved.
+ */
+public class RegisterAttributes {
+
+    private final boolean callerSave;
+    private final boolean calleeSave;
+    private final boolean allocatable;
+
+    public RegisterAttributes(boolean isCallerSave, boolean isCalleeSave, boolean isAllocatable) {
+        this.callerSave = isCallerSave;
+        this.calleeSave = isCalleeSave;
+        this.allocatable = isAllocatable;
+    }
+
+    public static final RegisterAttributes NONE = new RegisterAttributes(false, false, false);
+
+    /**
+     * Creates a map from register {@linkplain Register#number numbers} to register
+     * {@linkplain RegisterAttributes attributes} for a given register configuration and set of
+     * registers.
+     *
+     * @param registerConfig a register configuration
+     * @param registers a set of registers
+     * @return an array whose length is the max register number in {@code registers} plus 1. An
+     *         element at index i holds the attributes of the register whose number is i.
+     */
+    public static RegisterAttributes[] createMap(RegisterConfig registerConfig, Register[] registers) {
+        RegisterAttributes[] map = new RegisterAttributes[registers.length];
+        for (Register reg : registers) {
+            if (reg != null) {
+                Register[] csr = registerConfig.getCalleeSaveRegisters();
+                RegisterAttributes attr = new RegisterAttributes(Arrays.asList(registerConfig.getCallerSaveRegisters()).contains(reg), csr == null ? false : Arrays.asList(csr).contains(reg),
+                                Arrays.asList(registerConfig.getAllocatableRegisters()).contains(reg));
+                if (map.length <= reg.number) {
+                    map = Arrays.copyOf(map, reg.number + 1);
+                }
+                map[reg.number] = attr;
+            }
+        }
+        for (int i = 0; i < map.length; i++) {
+            if (map[i] == null) {
+                map[i] = NONE;
+            }
+        }
+        return map;
+    }
+
+    /**
+     * @return Denotes a register that is available for use by a register allocator.
+     */
+    public boolean isAllocatable() {
+        return allocatable;
+    }
+
+    /**
+     * @return Denotes a register whose value preservation (if required) across a call is the
+     *         responsibility of the callee.
+     */
+    public boolean isCalleeSave() {
+        return calleeSave;
+    }
+
+    /**
+     * @return Denotes a register whose value preservation (if required) across a call is the
+     *         responsibility of the caller.
+     */
+    public boolean isCallerSave() {
+        return callerSave;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+import jdk.vm.ci.code.CallingConvention.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical
+ * registers.
+ */
+public interface RegisterConfig {
+
+    /**
+     * Gets the register to be used for returning a value of a given kind.
+     */
+    Register getReturnRegister(JavaKind kind);
+
+    /**
+     * Gets the maximum allowed size of the frame.
+     */
+    default int getMaximumFrameSize() {
+        return Integer.MAX_VALUE;
+    }
+
+    /**
+     * Gets the register to which {@link Register#Frame} and {@link Register#CallerFrame} are bound.
+     */
+    Register getFrameRegister();
+
+    /**
+     * Gets the calling convention describing how arguments are passed.
+     *
+     * @param type the type of calling convention being requested
+     * @param returnType the return type (can be null for methods returning {@code void})
+     * @param parameterTypes the types of the arguments of the call
+     * @param target the target platform
+     * @param stackOnly ignore registers
+     */
+    CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly);
+
+    /**
+     * Gets the ordered set of registers that are can be used to pass parameters according to a
+     * given calling convention.
+     *
+     * @param type the type of calling convention
+     * @param kind specifies what kind of registers is being requested
+     * @return the ordered set of registers that may be used to pass parameters in a call conforming
+     *         to {@code type}
+     */
+    Register[] getCallingConventionRegisters(Type type, JavaKind kind);
+
+    /**
+     * Gets the set of all registers that might be used by the register allocator.
+     *
+     * To get the set of registers the register allocator is allowed to use see
+     * {@link RegisterAllocationConfig#getAllocatableRegisters()}
+     */
+    @SuppressWarnings("javadoc")
+    Register[] getAllocatableRegisters();
+
+    /**
+     * Filters a set of registers and returns only those that can be used by the register allocator
+     * for a value of a particular kind.
+     */
+    Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers);
+
+    /**
+     * Gets the registers whose values must be preserved by a method across any call it makes.
+     */
+    Register[] getCallerSaveRegisters();
+
+    /**
+     * Gets the registers whose values must be preserved by the callee.
+     */
+    Register[] getCalleeSaveRegisters();
+
+    /**
+     * Gets a map from register {@linkplain Register#number numbers} to register
+     * {@linkplain RegisterAttributes attributes} for this register configuration.
+     *
+     * @return an array where an element at index i holds the attributes of the register whose
+     *         number is i
+     */
+    RegisterAttributes[] getAttributesMap();
+
+    /**
+     * Gets the register corresponding to a runtime-defined role.
+     *
+     * @param id the identifier of a runtime-defined register role
+     * @return the register playing the role specified by {@code id}
+     */
+    Register getRegisterForRole(int id);
+
+    /**
+     * Determines if all {@link #getAllocatableRegisters() allocatable} registers are
+     * {@link #getCallerSaveRegisters() caller saved}.
+     */
+    boolean areAllAllocatableRegistersCallerSaved();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterSaveLayout.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013, 2014, 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 jdk.vm.ci.code;
+
+import java.util.*;
+
+/**
+ * A map from registers to frame slots. This can be used to describe where callee saved registers
+ * are saved in a callee's frame.
+ */
+public final class RegisterSaveLayout {
+
+    /**
+     * Keys.
+     */
+    private final Register[] registers;
+
+    /**
+     * Slot indexes relative to stack pointer.
+     */
+    private final int[] slots;
+
+    /**
+     * Creates a map from registers to frame slots.
+     *
+     * @param registers the keys in the map
+     * @param slots frame slot index for each register in {@code registers}
+     */
+    public RegisterSaveLayout(Register[] registers, int[] slots) {
+        assert registers.length == slots.length;
+        this.registers = registers;
+        this.slots = slots;
+        assert registersToSlots(false).size() == registers.length : "non-unique registers";
+        assert new HashSet<>(registersToSlots(false).values()).size() == slots.length : "non-unqiue slots";
+    }
+
+    /**
+     * Gets the frame slot index for a given register.
+     *
+     * @param register register to get the frame slot index for
+     * @return frame slot index
+     */
+    public int registerToSlot(Register register) {
+        for (int i = 0; i < registers.length; i++) {
+            if (register.equals(registers[i])) {
+                return slots[i];
+            }
+        }
+        throw new IllegalArgumentException(register + " not saved by this layout: " + this);
+    }
+
+    /**
+     * Gets this layout information as a {@link Map} from registers to slots.
+     */
+    public Map<Register, Integer> registersToSlots(boolean sorted) {
+        Map<Register, Integer> result;
+        if (sorted) {
+            result = new TreeMap<>();
+        } else {
+            result = new HashMap<>();
+        }
+        for (int i = 0; i < registers.length; i++) {
+            result.put(registers[i], slots[i]);
+        }
+        return result;
+    }
+
+    /**
+     * Gets this layout information as a {@link Map} from slots to registers.
+     */
+    public Map<Integer, Register> slotsToRegisters(boolean sorted) {
+        Map<Integer, Register> result;
+        if (sorted) {
+            result = new TreeMap<>();
+        } else {
+            result = new HashMap<>();
+        }
+        for (int i = 0; i < registers.length; i++) {
+            result.put(slots[i], registers[i]);
+        }
+        return result;
+    }
+
+    @Override
+    public int hashCode() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof RegisterSaveLayout) {
+            RegisterSaveLayout that = (RegisterSaveLayout) obj;
+            if (Arrays.equals(registers, that.registers) && Arrays.equals(slots, that.slots)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return registersToSlots(true).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance
+ * of {@link RegisterValue} for each ({@link Register}, {@link JavaKind}) pair. Use
+ * {@link Register#asValue(LIRKind)} to retrieve the canonical {@link RegisterValue} instance for a
+ * given (register,kind) pair.
+ */
+public final class RegisterValue extends AllocatableValue {
+
+    private final Register reg;
+
+    /**
+     * Should only be called from {@link Register#Register} to ensure canonicalization.
+     */
+    protected RegisterValue(LIRKind kind, Register register) {
+        super(kind);
+        this.reg = register;
+    }
+
+    @Override
+    public String toString() {
+        return getRegister().name + getKindSuffix();
+    }
+
+    /**
+     * @return the register that contains the value
+     */
+    public Register getRegister() {
+        return reg;
+    }
+
+    @Override
+    public int hashCode() {
+        return 29 * super.hashCode() + reg.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof RegisterValue) {
+            RegisterValue other = (RegisterValue) obj;
+            return super.equals(obj) && reg.equals(other.reg);
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SourceStackTrace.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.code;
+
+/**
+ * Class representing a exception with a stack trace of the currently processed position in the
+ * compiled Java program instead of the stack trace of the compiler. The exception of the compiler
+ * is saved as the cause of this exception.
+ */
+public abstract class SourceStackTrace extends BailoutException {
+    private static final long serialVersionUID = 2144811793442316776L;
+
+    public static SourceStackTrace create(Throwable cause, String format, StackTraceElement[] elements) {
+        return new SourceStackTrace(cause, format) {
+
+            private static final long serialVersionUID = 6279381376051787907L;
+
+            @Override
+            public final synchronized Throwable fillInStackTrace() {
+                assert elements != null;
+                setStackTrace(elements);
+                return this;
+            }
+        };
+    }
+
+    private SourceStackTrace(Throwable cause, String format) {
+        super(cause, format);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackLockValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.code;
+
+import static jdk.vm.ci.code.ValueUtil.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents lock information in the debug information.
+ */
+public final class StackLockValue implements JavaValue {
+
+    private JavaValue owner;
+    private StackSlotValue slot;
+    private final boolean eliminated;
+
+    public StackLockValue(JavaValue object, StackSlotValue slot, boolean eliminated) {
+        this.owner = object;
+        this.slot = slot;
+        this.eliminated = eliminated;
+    }
+
+    public JavaValue getOwner() {
+        return owner;
+    }
+
+    public void setOwner(JavaValue newOwner) {
+        this.owner = newOwner;
+    }
+
+    public Value getSlot() {
+        return slot;
+    }
+
+    public boolean isEliminated() {
+        return eliminated;
+    }
+
+    @Override
+    public String toString() {
+        return "monitor[" + owner + (slot != null ? ", " + slot : "") + (eliminated ? ", eliminated" : "") + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 43;
+        int result = super.hashCode();
+        result = prime * result + (eliminated ? 1231 : 1237);
+        result = prime * result + owner.hashCode();
+        result = prime * result + slot.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof StackLockValue) {
+            StackLockValue other = (StackLockValue) obj;
+            return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot);
+        }
+        return false;
+    }
+
+    public void setSlot(StackSlotValue stackSlot) {
+        assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot);
+        slot = stackSlot;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010, 2014, 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 jdk.vm.ci.code;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an
+ * incoming stack-based argument in a method's {@linkplain #isInCallerFrame() caller's frame}.
+ */
+public final class StackSlot extends StackSlotValue {
+
+    private final int offset;
+    private final boolean addFrameSize;
+
+    /**
+     * Gets a {@link StackSlot} instance representing a stack slot at a given index holding a value
+     * of a given kind.
+     *
+     * @param kind The kind of the value stored in the stack slot.
+     * @param offset The offset of the stack slot (in bytes)
+     * @param addFrameSize Specifies if the offset is relative to the stack pointer, or the
+     *            beginning of the frame (stack pointer + total frame size).
+     */
+    public static StackSlot get(LIRKind kind, int offset, boolean addFrameSize) {
+        assert addFrameSize || offset >= 0;
+        return new StackSlot(kind, offset, addFrameSize);
+    }
+
+    /**
+     * Private constructor to enforce use of {@link #get(LIRKind, int, boolean)} so that a cache can
+     * be used.
+     */
+    private StackSlot(LIRKind kind, int offset, boolean addFrameSize) {
+        super(kind);
+        this.offset = offset;
+        this.addFrameSize = addFrameSize;
+    }
+
+    /**
+     * Gets the offset of this stack slot, relative to the stack pointer.
+     *
+     * @return The offset of this slot (in bytes).
+     */
+    public int getOffset(int totalFrameSize) {
+        assert totalFrameSize > 0 || !addFrameSize;
+        int result = offset + (addFrameSize ? totalFrameSize : 0);
+        assert result >= 0;
+        return result;
+    }
+
+    public boolean isInCallerFrame() {
+        return addFrameSize && offset >= 0;
+    }
+
+    public int getRawOffset() {
+        return offset;
+    }
+
+    public boolean getRawAddFrameSize() {
+        return addFrameSize;
+    }
+
+    @Override
+    public String toString() {
+        if (!addFrameSize) {
+            return "out:" + offset + getKindSuffix();
+        } else if (offset >= 0) {
+            return "in:" + offset + getKindSuffix();
+        } else {
+            return "stack:" + (-offset) + getKindSuffix();
+        }
+    }
+
+    /**
+     * Gets this stack slot used to pass an argument from the perspective of a caller.
+     */
+    public StackSlot asOutArg() {
+        assert offset >= 0;
+        if (addFrameSize) {
+            return get(getLIRKind(), offset, false);
+        }
+        return this;
+    }
+
+    /**
+     * Gets this stack slot used to pass an argument from the perspective of a callee.
+     */
+    public StackSlot asInArg() {
+        assert offset >= 0;
+        if (!addFrameSize) {
+            return get(getLIRKind(), offset, true);
+        }
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 37;
+        int result = super.hashCode();
+        result = prime * result + (addFrameSize ? 1231 : 1237);
+        result = prime * result + offset;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof StackSlot) {
+            StackSlot other = (StackSlot) obj;
+            return super.equals(obj) && addFrameSize == other.addFrameSize && offset == other.offset;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlotValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.code;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Common base class for {@linkplain StackSlot real} and {@linkplain VirtualStackSlot virtual} stack
+ * slots.
+ */
+public abstract class StackSlotValue extends AllocatableValue {
+
+    public StackSlotValue(LIRKind lirKind) {
+        super(lirKind);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.code;
+
+import static jdk.vm.ci.meta.MetaUtil.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents the target machine for a compiler, including the CPU architecture, the size of
+ * pointers and references, alignment of stacks, caches, etc.
+ */
+public class TargetDescription {
+
+    public final Architecture arch;
+
+    /**
+     * Specifies if this is a multi-processor system.
+     */
+    public final boolean isMP;
+
+    /**
+     * Specifies if this target supports encoding objects inline in the machine code.
+     */
+    public final boolean inlineObjects;
+
+    /**
+     * The machine word size on this target.
+     */
+    public final int wordSize;
+
+    /**
+     * The kind to be used for representing raw pointers and CPU registers.
+     */
+    public final JavaKind wordKind;
+
+    /**
+     * The stack alignment requirement of the platform. For example, from Appendix D of <a
+     * href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures
+     * Optimization Reference Manual</a>:
+     *
+     * <pre>
+     *     "It is important to ensure that the stack frame is aligned to a
+     *      16-byte boundary upon function entry to keep local __m128 data,
+     *      parameters, and XMM register spill locations aligned throughout
+     *      a function invocation."
+     * </pre>
+     */
+    public final int stackAlignment;
+
+    /**
+     * Maximum constant displacement at which a memory access can no longer be an implicit null
+     * check.
+     */
+    public final int implicitNullCheckLimit;
+
+    public TargetDescription(Architecture arch, boolean isMP, int stackAlignment, int implicitNullCheckLimit, boolean inlineObjects) {
+        this.arch = arch;
+        this.isMP = isMP;
+        this.wordSize = arch.getWordSize();
+        this.wordKind = JavaKind.fromWordSize(wordSize);
+        this.stackAlignment = stackAlignment;
+        this.implicitNullCheckLimit = implicitNullCheckLimit;
+        this.inlineObjects = inlineObjects;
+    }
+
+    @Override
+    public final int hashCode() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TargetDescription) {
+            TargetDescription that = (TargetDescription) obj;
+            // @formatter:off
+            if (this.implicitNullCheckLimit == that.implicitNullCheckLimit &&
+                this.inlineObjects == that.inlineObjects &&
+                this.isMP == that.isMP &&
+                this.stackAlignment == that.stackAlignment &&
+                this.wordKind.equals(that.wordKind) &&
+                this.wordSize == that.wordSize &&
+                this.arch.equals(that.arch)) {
+                return true;
+            }
+            // @formatter:on
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return identityHashCodeString(this);
+    }
+
+    public int getSizeInBytes(PlatformKind kind) {
+        return kind.getSizeInBytes();
+    }
+
+    public LIRKind getLIRKind(JavaKind javaKind) {
+        PlatformKind platformKind = arch.getPlatformKind(javaKind);
+        if (javaKind.isObject()) {
+            return LIRKind.reference(platformKind);
+        } else {
+            return LIRKind.value(platformKind);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/UnsignedMath.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+import java.math.*;
+
+//JaCoCo Exclude
+
+/**
+ * Utilities for unsigned comparisons. All methods have correct, but slow, standard Java
+ * implementations so that they can be used with compilers not supporting the intrinsics.
+ */
+public class UnsignedMath {
+
+    private static final long MASK = 0xffffffffL;
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    public static boolean aboveThan(int a, int b) {
+        return (a & MASK) > (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    public static boolean aboveOrEqual(int a, int b) {
+        return (a & MASK) >= (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(int a, int b) {
+        return (a & MASK) < (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(int a, int b) {
+        return (a & MASK) <= (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    public static boolean aboveThan(long a, long b) {
+        return (a > b) ^ ((a < 0) != (b < 0));
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    public static boolean aboveOrEqual(long a, long b) {
+        return (a >= b) ^ ((a < 0) != (b < 0));
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(long a, long b) {
+        return (a < b) ^ ((a < 0) != (b < 0));
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(long a, long b) {
+        return (a <= b) ^ ((a < 0) != (b < 0));
+    }
+
+    /**
+     * Unsigned division for two numbers.
+     */
+    public static int divide(int a, int b) {
+        return (int) ((a & MASK) / (b & MASK));
+    }
+
+    /**
+     * Unsigned remainder for two numbers.
+     */
+    public static int remainder(int a, int b) {
+        return (int) ((a & MASK) % (b & MASK));
+    }
+
+    /**
+     * Unsigned division for two numbers.
+     */
+    public static long divide(long a, long b) {
+        return bi(a).divide(bi(b)).longValue();
+    }
+
+    /**
+     * Unsigned remainder for two numbers.
+     */
+    public static long remainder(long a, long b) {
+        return bi(a).remainder(bi(b)).longValue();
+    }
+
+    private static BigInteger bi(long unsigned) {
+        return unsigned >= 0 ? BigInteger.valueOf(unsigned) : BigInteger.valueOf(unsigned & 0x7fffffffffffffffL).setBit(63);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2012, 2015, 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 jdk.vm.ci.code;
+
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Utility class for working with the {@link Value} class and its subclasses.
+ */
+public final class ValueUtil {
+
+    public static boolean isIllegal(Value value) {
+        assert value != null;
+        return Value.ILLEGAL.equals(value);
+    }
+
+    public static boolean isIllegalJavaValue(JavaValue value) {
+        assert value != null;
+        return Value.ILLEGAL.equals(value);
+    }
+
+    public static boolean isLegal(Value value) {
+        return !isIllegal(value);
+    }
+
+    public static boolean isVirtualObject(JavaValue value) {
+        assert value != null;
+        return value instanceof VirtualObject;
+    }
+
+    public static VirtualObject asVirtualObject(JavaValue value) {
+        assert value != null;
+        return (VirtualObject) value;
+    }
+
+    public static boolean isConstantJavaValue(JavaValue value) {
+        assert value != null;
+        return value instanceof JavaConstant;
+    }
+
+    public static boolean isAllocatableValue(Value value) {
+        assert value != null;
+        return value instanceof AllocatableValue;
+    }
+
+    public static AllocatableValue asAllocatableValue(Value value) {
+        assert value != null;
+        return (AllocatableValue) value;
+    }
+
+    public static boolean isStackSlot(Value value) {
+        assert value != null;
+        return value instanceof StackSlot;
+    }
+
+    public static StackSlot asStackSlot(Value value) {
+        assert value != null;
+        return (StackSlot) value;
+    }
+
+    public static boolean isStackSlotValue(Value value) {
+        assert value != null;
+        return value instanceof StackSlotValue;
+    }
+
+    public static StackSlotValue asStackSlotValue(Value value) {
+        assert value != null;
+        return (StackSlotValue) value;
+    }
+
+    public static boolean isVirtualStackSlot(Value value) {
+        assert value != null;
+        return value instanceof VirtualStackSlot;
+    }
+
+    public static VirtualStackSlot asVirtualStackSlot(Value value) {
+        assert value != null;
+        return (VirtualStackSlot) value;
+    }
+
+    public static boolean isRegister(Value value) {
+        assert value != null;
+        return value instanceof RegisterValue;
+    }
+
+    public static Register asRegister(Value value) {
+        return asRegisterValue(value).getRegister();
+    }
+
+    public static RegisterValue asRegisterValue(Value value) {
+        assert value != null;
+        return (RegisterValue) value;
+    }
+
+    public static Register asRegister(Value value, PlatformKind kind) {
+        if (value.getPlatformKind() != kind) {
+            throw new InternalError("needed: " + kind + " got: " + value.getPlatformKind());
+        } else {
+            return asRegister(value);
+        }
+    }
+
+    public static boolean sameRegister(Value v1, Value v2) {
+        return isRegister(v1) && isRegister(v2) && asRegister(v1).equals(asRegister(v2));
+    }
+
+    public static boolean sameRegister(Value v1, Value v2, Value v3) {
+        return sameRegister(v1, v2) && sameRegister(v1, v3);
+    }
+
+    /**
+     * Checks if all the provided values are different physical registers. The parameters can be
+     * either {@link Register registers}, {@link Value values} or arrays of them. All values that
+     * are not {@link RegisterValue registers} are ignored.
+     */
+    public static boolean differentRegisters(Object... values) {
+        List<Register> registers = collectRegisters(values, new ArrayList<Register>());
+        for (int i = 1; i < registers.size(); i++) {
+            Register r1 = registers.get(i);
+            for (int j = 0; j < i; j++) {
+                Register r2 = registers.get(j);
+                if (r1.equals(r2)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private static List<Register> collectRegisters(Object[] values, List<Register> registers) {
+        for (Object o : values) {
+            if (o instanceof Register) {
+                registers.add((Register) o);
+            } else if (o instanceof Value) {
+                if (isRegister((Value) o)) {
+                    registers.add(asRegister((Value) o));
+                }
+            } else if (o instanceof Object[]) {
+                collectRegisters((Object[]) o, registers);
+            } else {
+                throw new IllegalArgumentException("Not a Register or Value: " + o);
+            }
+        }
+        return registers;
+    }
+
+    /**
+     * Subtract sets of registers (x - y).
+     *
+     * @param x a set of register to subtract from.
+     * @param y a set of registers to subtract.
+     * @return resulting set of registers (x - y).
+     */
+    public static Value[] subtractRegisters(Value[] x, Value[] y) {
+        ArrayList<Value> result = new ArrayList<>(x.length);
+        for (Value i : x) {
+            boolean append = true;
+            for (Value j : y) {
+                if (ValueUtil.sameRegister(i, j)) {
+                    append = false;
+                    break;
+                }
+            }
+            if (append) {
+                result.add(i);
+            }
+        }
+        Value[] resultArray = new Value[result.size()];
+        return result.toArray(resultArray);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2010, 2015, 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 jdk.vm.ci.code;
+
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * An instance of this class represents an object whose allocation was removed by escape analysis.
+ * The information stored in the {@link VirtualObject} is used during deoptimization to recreate the
+ * object.
+ */
+public final class VirtualObject implements JavaValue {
+
+    private final ResolvedJavaType type;
+    private JavaValue[] values;
+    private JavaKind[] slotKinds;
+    private final int id;
+
+    /**
+     * Creates a new {@link VirtualObject} for the given type, with the given fields. If
+     * {@code type} is an instance class then {@code values} provides the values for the fields
+     * returned by {@link ResolvedJavaType#getInstanceFields(boolean) getInstanceFields(true)}. If
+     * {@code type} is an array then the length of the values array determines the reallocated array
+     * length.
+     *
+     * @param type the type of the object whose allocation was removed during compilation. This can
+     *            be either an instance of an array type.
+     * @param id a unique id that identifies the object within the debug information for one
+     *            position in the compiled code.
+     * @return a new {@link VirtualObject} instance.
+     */
+    public static VirtualObject get(ResolvedJavaType type, int id) {
+        return new VirtualObject(type, id);
+    }
+
+    private VirtualObject(ResolvedJavaType type, int id) {
+        this.type = type;
+        this.id = id;
+    }
+
+    private static StringBuilder appendValue(StringBuilder buf, JavaValue value, Set<VirtualObject> visited) {
+        if (value instanceof VirtualObject) {
+            VirtualObject vo = (VirtualObject) value;
+            buf.append("vobject:").append(vo.type.toJavaName(false)).append(':').append(vo.id);
+            if (!visited.contains(vo)) {
+                visited.add(vo);
+                buf.append('{');
+                if (vo.values == null) {
+                    buf.append("<uninitialized>");
+                } else {
+                    if (vo.type.isArray()) {
+                        for (int i = 0; i < vo.values.length; i++) {
+                            if (i != 0) {
+                                buf.append(',');
+                            }
+                            buf.append(i).append('=');
+                            appendValue(buf, vo.values[i], visited);
+                        }
+                    } else {
+                        ResolvedJavaField[] fields = vo.type.getInstanceFields(true);
+                        assert fields.length == vo.values.length : vo.type + ", fields=" + Arrays.toString(fields) + ", values=" + Arrays.toString(vo.values);
+                        for (int i = 0; i < vo.values.length; i++) {
+                            if (i != 0) {
+                                buf.append(',');
+                            }
+                            buf.append(fields[i].getName()).append('=');
+                            appendValue(buf, vo.values[i], visited);
+                        }
+                    }
+                }
+                buf.append('}');
+            }
+        } else {
+            buf.append(value);
+        }
+        return buf;
+    }
+
+    @Override
+    public String toString() {
+        Set<VirtualObject> visited = Collections.newSetFromMap(new IdentityHashMap<VirtualObject, Boolean>());
+        return appendValue(new StringBuilder(), this, visited).toString();
+    }
+
+    /**
+     * Returns the type of the object whose allocation was removed during compilation. This can be
+     * either an instance of an array type.
+     */
+    public ResolvedJavaType getType() {
+        return type;
+    }
+
+    /**
+     * Returns an array containing all the values to be stored into the object when it is recreated.
+     */
+    public JavaValue[] getValues() {
+        return values;
+    }
+
+    /**
+     * Returns an array containing the Java kind of all values in the object.
+     */
+    public JavaKind[] getSlotKinds() {
+        return slotKinds;
+    }
+
+    /**
+     * Returns the unique id that identifies the object within the debug information for one
+     * position in the compiled code.
+     */
+    public int getId() {
+        return id;
+    }
+
+    private boolean checkValues() {
+        assert (values == null) == (slotKinds == null);
+        if (values != null) {
+            assert values.length == slotKinds.length;
+            if (!type.isArray()) {
+                ResolvedJavaField[] fields = type.getInstanceFields(true);
+                int fieldIndex = 0;
+                for (int i = 0; i < values.length; i++) {
+                    ResolvedJavaField field = fields[fieldIndex++];
+                    JavaKind valKind = slotKinds[i].getStackKind();
+                    if (field.getJavaKind() == JavaKind.Object) {
+                        assert valKind.isObject() : field + ": " + valKind + " != " + field.getJavaKind();
+                    } else {
+                        if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && field.getJavaKind() == JavaKind.Int) {
+                            assert fields[fieldIndex].getJavaKind() == JavaKind.Int;
+                            fieldIndex++;
+                        } else {
+                            assert valKind == field.getJavaKind().getStackKind() : field + ": " + valKind + " != " + field.getJavaKind();
+                        }
+                    }
+                }
+                assert fields.length == fieldIndex : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
+            } else {
+                JavaKind componentKind = type.getComponentType().getJavaKind().getStackKind();
+                if (componentKind == JavaKind.Object) {
+                    for (int i = 0; i < values.length; i++) {
+                        assert slotKinds[i].isObject() : slotKinds[i] + " != " + componentKind;
+                    }
+                } else {
+                    for (int i = 0; i < values.length; i++) {
+                        assert slotKinds[i] == componentKind || componentKind.getBitCount() >= slotKinds[i].getBitCount() ||
+                                        (componentKind == JavaKind.Int && slotKinds[i].getBitCount() >= JavaKind.Int.getBitCount()) : slotKinds[i] + " != " + componentKind;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Overwrites the current set of values with a new one.
+     *
+     * @param values an array containing all the values to be stored into the object when it is
+     *            recreated.
+     * @param slotKinds an array containing the Java kinds of the values.
+     */
+    public void setValues(JavaValue[] values, JavaKind[] slotKinds) {
+        this.values = values;
+        this.slotKinds = slotKinds;
+        assert checkValues();
+    }
+
+    @Override
+    public int hashCode() {
+        return 42 + type.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof VirtualObject) {
+            VirtualObject l = (VirtualObject) o;
+            if (!l.type.equals(type) || l.values.length != values.length) {
+                return false;
+            }
+            for (int i = 0; i < values.length; i++) {
+                /*
+                 * Virtual objects can form cycles. Calling equals() could therefore lead to
+                 * infinite recursion.
+                 */
+                if (!same(values[i], l.values[i])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean same(Object o1, Object o2) {
+        return o1 == o2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualStackSlot.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.code;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * {@link VirtualStackSlot}s are stack slots that are not yet fixed to specific frame offset. They
+ * are replaced by real {@link StackSlot}s with a fixed position in the frame before code emission.
+ */
+public abstract class VirtualStackSlot extends StackSlotValue {
+
+    private final int id;
+
+    public VirtualStackSlot(int id, LIRKind lirKind) {
+        super(lirKind);
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return "vstack:" + id + getKindSuffix();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + id;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        VirtualStackSlot other = (VirtualStackSlot) obj;
+        if (id != other.id) {
+            return false;
+        }
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR
+ * REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it 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 that defines the interface between a Java application that wants to install code and the
+ * runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider}
+ * interface. The method
+ * {@link jdk.vm.ci.code.CodeCacheProvider#addMethod(jdk.vm.ci.meta.ResolvedJavaMethod, CompilationResult, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
+ * can be used to install code for a given method.
+ */
+package jdk.vm.ci.code;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.code.stack;
+
+import jdk.vm.ci.meta.*;
+
+public interface InspectedFrame {
+
+    /**
+     * Returns the value of the local at the given index. Currently only works for object values.
+     * This value is a copy iff {@link #isVirtual(int)} is true.
+     */
+    Object getLocal(int index);
+
+    /**
+     * Returns whether the local at the given index is a virtual object, and therefore the object
+     * returned by {@link #getLocal(int)} is a copy.
+     */
+    boolean isVirtual(int index);
+
+    /**
+     * Returns true if the stack frame is a compiled stack frame and there are virtual objects
+     * anywhere in the current state of the compiled method. This can return true even if
+     * {@link #isVirtual(int)} return false for all locals.
+     */
+    boolean hasVirtualObjects();
+
+    /**
+     * This method will materialize all virtual objects, deoptimize the stack frame and make sure
+     * that subsequent execution of the deoptimized frame uses the materialized values.
+     */
+    void materializeVirtualObjects(boolean invalidateCode);
+
+    /**
+     * @return the current bytecode index
+     */
+    int getBytecodeIndex();
+
+    /**
+     * @return the current method
+     */
+    ResolvedJavaMethod getMethod();
+
+    /**
+     * Checks if the current method is equal to the given method. This is semantically equivalent to
+     * {@code method.equals(getMethod())}, but can be implemented more efficiently.
+     */
+    boolean isMethod(ResolvedJavaMethod method);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrameVisitor.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.code.stack;
+
+/**
+ * Callback interface for {@link StackIntrospection#iterateFrames}. Implementations of
+ * {@link #visitFrame} return null to indicate that frame iteration should continue and the next
+ * caller frame should be visited; and return any non-null value to indicate that frame iteration
+ * should stop.
+ */
+public interface InspectedFrameVisitor<T> {
+
+    T visitFrame(InspectedFrame frame);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/StackIntrospection.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.code.stack;
+
+import jdk.vm.ci.meta.*;
+
+public interface StackIntrospection {
+
+    /**
+     * Accesses the current stack, providing {@link InspectedFrame}s to the visitor that can be used
+     * to inspect the stack frames' contents. Iteration continues as long as
+     * {@link InspectedFrameVisitor#visitFrame}, which is invoked for every {@link InspectedFrame},
+     * returns null. Any non-null result of the visitor indicates that frame iteration should stop.
+     *
+     * @param initialMethods if this is non-{@code null}, then the stack trace will start at these
+     *            methods
+     * @param matchingMethods if this is non-{@code null}, then only matching stack frames are
+     *            returned
+     * @param initialSkip the number of matching methods to skip (including the initial method)
+     * @param visitor the visitor that is called for every matching method
+     * @return the last result returned by the visitor (which is non-null to indicate that iteration
+     *         should stop), or null if the whole stack was iterated.
+     */
+    <T> T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor<T> visitor);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2011, 2014, 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 jdk.vm.ci.common;
+
+import java.util.*;
+
+/**
+ * Indicates a condition in JVMCI related code that should never occur during normal operation.
+ */
+public class JVMCIError extends Error {
+
+    private static final long serialVersionUID = 531632331813456233L;
+    private final ArrayList<String> context = new ArrayList<>();
+
+    public static RuntimeException unimplemented() {
+        throw new JVMCIError("unimplemented");
+    }
+
+    public static RuntimeException unimplemented(String msg) {
+        throw new JVMCIError("unimplemented: %s", msg);
+    }
+
+    public static RuntimeException shouldNotReachHere() {
+        throw new JVMCIError("should not reach here");
+    }
+
+    public static RuntimeException shouldNotReachHere(String msg) {
+        throw new JVMCIError("should not reach here: %s", msg);
+    }
+
+    public static RuntimeException shouldNotReachHere(Throwable cause) {
+        throw new JVMCIError(cause);
+    }
+
+    /**
+     * Checks a given condition and throws a {@link JVMCIError} if it is false. Guarantees are
+     * stronger than assertions in that they are always checked. Error messages for guarantee
+     * violations should clearly indicate the nature of the problem as well as a suggested solution
+     * if possible.
+     *
+     * @param condition the condition to check
+     * @param msg the message that will be associated with the error, in
+     *            {@link String#format(String, Object...)} syntax
+     * @param args arguments to the format string
+     */
+    public static void guarantee(boolean condition, String msg, Object... args) {
+        if (!condition) {
+            throw new JVMCIError("failed guarantee: " + msg, args);
+        }
+    }
+
+    /**
+     * This constructor creates a {@link JVMCIError} with a given message.
+     *
+     * @param msg the message that will be associated with the error
+     */
+    public JVMCIError(String msg) {
+        super(msg);
+    }
+
+    /**
+     * This constructor creates a {@link JVMCIError} with a message assembled via
+     * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to
+     * always generate the same output.
+     *
+     * @param msg the message that will be associated with the error, in String.format syntax
+     * @param args parameters to String.format - parameters that implement {@link Iterable} will be
+     *            expanded into a [x, x, ...] representation.
+     */
+    public JVMCIError(String msg, Object... args) {
+        super(format(msg, args));
+    }
+
+    /**
+     * This constructor creates a {@link JVMCIError} for a given causing Throwable instance.
+     *
+     * @param cause the original exception that contains additional information on this error
+     */
+    public JVMCIError(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * This constructor creates a {@link JVMCIError} and adds all the
+     * {@linkplain #addContext(String) context} of another {@link JVMCIError}.
+     *
+     * @param e the original {@link JVMCIError}
+     */
+    public JVMCIError(JVMCIError e) {
+        super(e);
+        context.addAll(e.context);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append(super.toString());
+        for (String s : context) {
+            str.append("\n\tat ").append(s);
+        }
+        return str.toString();
+    }
+
+    private static String format(String msg, Object... args) {
+        if (args != null) {
+            // expand Iterable parameters into a list representation
+            for (int i = 0; i < args.length; i++) {
+                if (args[i] instanceof Iterable<?>) {
+                    ArrayList<Object> list = new ArrayList<>();
+                    for (Object o : (Iterable<?>) args[i]) {
+                        list.add(o);
+                    }
+                    args[i] = list.toString();
+                }
+            }
+        }
+        return String.format(Locale.ENGLISH, msg, args);
+    }
+
+    public JVMCIError addContext(String newContext) {
+        this.context.add(newContext);
+        return this;
+    }
+
+    public JVMCIError addContext(String name, Object obj) {
+        return addContext(format("%s: %s", name, obj));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/UnsafeUtil.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+package jdk.vm.ci.common;
+
+import sun.misc.Unsafe;
+
+/**
+ * Utilities for operating on raw memory with {@link Unsafe}.
+ */
+public class UnsafeUtil {
+
+    /**
+     * Copies the contents of a {@link String} to a native memory buffer as a {@code '\0'}
+     * terminated C string. The native memory buffer is allocated via
+     * {@link Unsafe#allocateMemory(long)}. The caller is responsible for releasing the buffer when
+     * it is no longer needed via {@link Unsafe#freeMemory(long)}.
+     *
+     * @return the native memory pointer of the C string created from {@code s}
+     */
+    public static long createCString(Unsafe unsafe, String s) {
+        return writeCString(unsafe, s, unsafe.allocateMemory(s.length() + 1));
+    }
+
+    /**
+     * Reads a {@code '\0'} terminated C string from native memory and converts it to a
+     * {@link String}.
+     *
+     * @return a Java string
+     */
+    public static String readCString(Unsafe unsafe, long address) {
+        if (address == 0) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0;; i++) {
+            char c = (char) unsafe.getByte(address + i);
+            if (c == 0) {
+                break;
+            }
+            sb.append(c);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Writes the contents of a {@link String} to a native memory buffer as a {@code '\0'}
+     * terminated C string. The caller is responsible for ensuring the buffer is at least
+     * {@code s.length() + 1} bytes long. The caller is also responsible for releasing the buffer
+     * when it is no longer.
+     *
+     * @return the value of {@code buf}
+     */
+    public static long writeCString(Unsafe unsafe, String s, long buf) {
+        int size = s.length();
+        for (int i = 0; i < size; i++) {
+            unsafe.putByte(buf + i, (byte) s.charAt(i));
+        }
+        unsafe.putByte(buf + size, (byte) '\0');
+        return buf;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.compiler/src/jdk/vm/ci/compiler/Compiler.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.compiler;
+
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.options.*;
+
+public interface Compiler {
+    int INVOCATION_ENTRY_BCI = -1;
+
+    @Option(help = "", type = OptionType.Debug) OptionValue<String> PrintFilter = new OptionValue<>(null);
+    @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintCompilation = new OptionValue<>(false);
+    @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintAfterCompilation = new OptionValue<>(false);
+    @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintBailout = new OptionValue<>(false);
+    @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> ExitVMOnBailout = new OptionValue<>(false);
+    @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> ExitVMOnException = new OptionValue<>(true);
+    @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintStackTraceOnException = new OptionValue<>(false);
+
+    /**
+     * Request the compilation of a method by this JVMCI compiler. The compiler should compile the
+     * method to machine code and install it in the code cache if the compilation is successful.
+     *
+     * @param method the method that should be compiled
+     * @param entryBCI the BCI at which to start compiling where -1 denotes a non-OSR compilation
+     *            request and all other values denote an OSR compilation request
+     * @param jvmciEnv pointer to native {@code JVMCIEnv} object
+     * @param id a unique identifier for this compilation
+     */
+    void compileMethod(ResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.compiler/src/jdk/vm/ci/compiler/CompilerFactory.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.compiler;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.runtime.*;
+
+/**
+ * Factory for a JVMCI compiler.
+ */
+public interface CompilerFactory {
+
+    /**
+     * Get the name of this compiler. The compiler will be selected when the jvmci.compiler system
+     * property is equal to this name.
+     */
+    String getCompilerName();
+
+    /**
+     * Initialize an {@link Architecture}. The compiler has the opportunity to extend the
+     * {@link Architecture} description with a custom subclass.
+     */
+    Architecture initializeArchitecture(Architecture arch);
+
+    /**
+     * Create a new instance of the {@link Compiler}.
+     */
+    Compiler createCompiler(JVMCIRuntime runtime);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.compiler/src/jdk/vm/ci/compiler/StartupEventListener.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.compiler;
+
+public interface StartupEventListener {
+
+    /**
+     * This method is called before any of the {@link CompilerFactory} methods.
+     */
+    void beforeJVMCIStartup();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012, 2015, 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 jdk.vm.ci.hotspot.amd64;
+
+import static jdk.vm.ci.inittimer.InitTimer.*;
+
+import java.util.*;
+
+import jdk.vm.ci.amd64.*;
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.compiler.*;
+import jdk.vm.ci.hotspot.*;
+import jdk.vm.ci.inittimer.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+import jdk.vm.ci.service.*;
+
+@ServiceProvider(HotSpotJVMCIBackendFactory.class)
+public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
+
+    protected EnumSet<AMD64.CPUFeature> computeFeatures(HotSpotVMConfig config) {
+        // Configure the feature set using the HotSpot flag settings.
+        EnumSet<AMD64.CPUFeature> features = EnumSet.noneOf(AMD64.CPUFeature.class);
+        if ((config.x86CPUFeatures & config.cpu3DNOWPREFETCH) != 0) {
+            features.add(AMD64.CPUFeature.AMD_3DNOW_PREFETCH);
+        }
+        assert config.useSSE >= 2 : "minimum config for x64";
+        features.add(AMD64.CPUFeature.SSE);
+        features.add(AMD64.CPUFeature.SSE2);
+        if ((config.x86CPUFeatures & config.cpuSSE3) != 0) {
+            features.add(AMD64.CPUFeature.SSE3);
+        }
+        if ((config.x86CPUFeatures & config.cpuSSSE3) != 0) {
+            features.add(AMD64.CPUFeature.SSSE3);
+        }
+        if ((config.x86CPUFeatures & config.cpuSSE4A) != 0) {
+            features.add(AMD64.CPUFeature.SSE4A);
+        }
+        if ((config.x86CPUFeatures & config.cpuSSE41) != 0) {
+            features.add(AMD64.CPUFeature.SSE4_1);
+        }
+        if ((config.x86CPUFeatures & config.cpuSSE42) != 0) {
+            features.add(AMD64.CPUFeature.SSE4_2);
+        }
+        if ((config.x86CPUFeatures & config.cpuPOPCNT) != 0) {
+            features.add(AMD64.CPUFeature.POPCNT);
+        }
+        if ((config.x86CPUFeatures & config.cpuLZCNT) != 0) {
+            features.add(AMD64.CPUFeature.LZCNT);
+        }
+        if ((config.x86CPUFeatures & config.cpuAVX) != 0) {
+            features.add(AMD64.CPUFeature.AVX);
+        }
+        if ((config.x86CPUFeatures & config.cpuAVX2) != 0) {
+            features.add(AMD64.CPUFeature.AVX2);
+        }
+        if ((config.x86CPUFeatures & config.cpuAES) != 0) {
+            features.add(AMD64.CPUFeature.AES);
+        }
+        if ((config.x86CPUFeatures & config.cpuERMS) != 0) {
+            features.add(AMD64.CPUFeature.ERMS);
+        }
+        if ((config.x86CPUFeatures & config.cpuBMI1) != 0) {
+            features.add(AMD64.CPUFeature.BMI1);
+        }
+        return features;
+    }
+
+    protected EnumSet<AMD64.Flag> computeFlags(HotSpotVMConfig config) {
+        EnumSet<AMD64.Flag> flags = EnumSet.noneOf(AMD64.Flag.class);
+        if (config.useCountLeadingZerosInstruction) {
+            flags.add(AMD64.Flag.UseCountLeadingZerosInstruction);
+        }
+        if (config.useCountTrailingZerosInstruction) {
+            flags.add(AMD64.Flag.UseCountTrailingZerosInstruction);
+        }
+        return flags;
+    }
+
+    protected TargetDescription createTarget(HotSpotVMConfig config, CompilerFactory compilerFactory) {
+        final int stackFrameAlignment = 16;
+        final int implicitNullCheckLimit = 4096;
+        final boolean inlineObjects = true;
+        Architecture arch = new AMD64(computeFeatures(config), computeFlags(config));
+        return new TargetDescription(compilerFactory.initializeArchitecture(arch), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+    }
+
+    protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntimeProvider runtime) {
+        return new HotSpotConstantReflectionProvider(runtime);
+    }
+
+    protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
+        return new AMD64HotSpotRegisterConfig(target.arch, runtime.getConfig());
+    }
+
+    protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
+        return new HotSpotCodeCacheProvider(runtime, runtime.getConfig(), target, regConfig);
+    }
+
+    protected HotSpotMetaAccessProvider createMetaAccess(HotSpotJVMCIRuntimeProvider runtime) {
+        return new HotSpotMetaAccessProvider(runtime);
+    }
+
+    @Override
+    public String getArchitecture() {
+        return "AMD64";
+    }
+
+    @Override
+    public String toString() {
+        return "JVMCIBackend:" + getArchitecture();
+    }
+
+    @SuppressWarnings("try")
+    public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host) {
+
+        assert host == null;
+        TargetDescription target = createTarget(runtime.getConfig(), compilerFactory);
+
+        RegisterConfig regConfig;
+        HotSpotCodeCacheProvider codeCache;
+        ConstantReflectionProvider constantReflection;
+        HotSpotMetaAccessProvider metaAccess;
+        try (InitTimer t = timer("create providers")) {
+            try (InitTimer rt = timer("create MetaAccess provider")) {
+                metaAccess = createMetaAccess(runtime);
+            }
+            try (InitTimer rt = timer("create RegisterConfig")) {
+                regConfig = createRegisterConfig(runtime, target);
+            }
+            try (InitTimer rt = timer("create CodeCache provider")) {
+                codeCache = createCodeCache(runtime, target, regConfig);
+            }
+            try (InitTimer rt = timer("create ConstantReflection provider")) {
+                constantReflection = createConstantReflection(runtime);
+            }
+        }
+        try (InitTimer rt = timer("instantiate backend")) {
+            return createBackend(metaAccess, codeCache, constantReflection);
+        }
+    }
+
+    protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection) {
+        return new JVMCIBackend(metaAccess, codeCache, constantReflection);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot.amd64;
+
+import static jdk.vm.ci.amd64.AMD64.*;
+
+import java.util.*;
+
+import jdk.vm.ci.amd64.*;
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.CallingConvention.*;
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.hotspot.*;
+import jdk.vm.ci.meta.*;
+
+public class AMD64HotSpotRegisterConfig implements RegisterConfig {
+
+    private final Architecture architecture;
+
+    private final Register[] allocatable;
+
+    private final int maxFrameSize;
+
+    /**
+     * The caller saved registers always include all parameter registers.
+     */
+    private final Register[] callerSaved;
+
+    private final boolean allAllocatableAreCallerSaved;
+
+    private final RegisterAttributes[] attributesMap;
+
+    public int getMaximumFrameSize() {
+        return maxFrameSize;
+    }
+
+    @Override
+    public Register[] getAllocatableRegisters() {
+        return allocatable.clone();
+    }
+
+    public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
+        ArrayList<Register> list = new ArrayList<>();
+        for (Register reg : registers) {
+            if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
+                list.add(reg);
+            }
+        }
+
+        Register[] ret = list.toArray(new Register[list.size()]);
+        return ret;
+    }
+
+    @Override
+    public RegisterAttributes[] getAttributesMap() {
+        return attributesMap.clone();
+    }
+
+    private final Register[] javaGeneralParameterRegisters;
+    private final Register[] nativeGeneralParameterRegisters;
+    private final Register[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7};
+
+    /*
+     * Some ABIs (e.g. Windows) require a so-called "home space", that is a save area on the stack
+     * to store the argument registers
+     */
+    private final boolean needsNativeStackHomeSpace;
+
+    private static Register[] initAllocatable(boolean reserveForHeapBase) {
+        Register[] registers = null;
+        // @formatter:off
+        if (reserveForHeapBase) {
+            registers = new Register[] {
+                        rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9,  r10, r11, /*r12,*/ r13, r14, /*r15, */
+                        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+                        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+                      };
+        } else {
+            registers = new Register[] {
+                        rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9,  r10, r11, r12, r13, r14, /*r15, */
+                        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+                        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+                      };
+        }
+       // @formatter:on
+        return registers;
+    }
+
+    public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
+        this(architecture, config, initAllocatable(config.useCompressedOops));
+        assert callerSaved.length >= allocatable.length;
+    }
+
+    public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
+        this.architecture = architecture;
+        this.maxFrameSize = config.maxFrameSize;
+
+        if (config.windowsOs) {
+            javaGeneralParameterRegisters = new Register[]{rdx, r8, r9, rdi, rsi, rcx};
+            nativeGeneralParameterRegisters = new Register[]{rcx, rdx, r8, r9};
+            this.needsNativeStackHomeSpace = true;
+        } else {
+            javaGeneralParameterRegisters = new Register[]{rsi, rdx, rcx, r8, r9, rdi};
+            nativeGeneralParameterRegisters = new Register[]{rdi, rsi, rdx, rcx, r8, r9};
+            this.needsNativeStackHomeSpace = false;
+        }
+
+        this.allocatable = allocatable.clone();
+        Set<Register> callerSaveSet = new HashSet<>();
+        Collections.addAll(callerSaveSet, allocatable);
+        Collections.addAll(callerSaveSet, xmmParameterRegisters);
+        Collections.addAll(callerSaveSet, javaGeneralParameterRegisters);
+        Collections.addAll(callerSaveSet, nativeGeneralParameterRegisters);
+        callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
+
+        allAllocatableAreCallerSaved = true;
+        attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters);
+    }
+
+    @Override
+    public Register[] getCallerSaveRegisters() {
+        return callerSaved;
+    }
+
+    public Register[] getCalleeSaveRegisters() {
+        return null;
+    }
+
+    @Override
+    public boolean areAllAllocatableRegistersCallerSaved() {
+        return allAllocatableAreCallerSaved;
+    }
+
+    @Override
+    public Register getRegisterForRole(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
+        if (type == Type.NativeCall) {
+            return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
+        }
+        // On x64, parameter locations are the same whether viewed
+        // from the caller or callee perspective
+        return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
+    }
+
+    public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
+        switch (kind) {
+            case Boolean:
+            case Byte:
+            case Short:
+            case Char:
+            case Int:
+            case Long:
+            case Object:
+                return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters;
+            case Float:
+            case Double:
+                return xmmParameterRegisters;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
+        AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
+
+        int currentGeneral = 0;
+        int currentXMM = 0;
+        int currentStackOffset = type == Type.NativeCall && needsNativeStackHomeSpace ? generalParameterRegisters.length * target.wordSize : 0;
+
+        for (int i = 0; i < parameterTypes.length; i++) {
+            final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
+
+            switch (kind) {
+                case Byte:
+                case Boolean:
+                case Short:
+                case Char:
+                case Int:
+                case Long:
+                case Object:
+                    if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
+                        Register register = generalParameterRegisters[currentGeneral++];
+                        locations[i] = register.asValue(target.getLIRKind(kind));
+                    }
+                    break;
+                case Float:
+                case Double:
+                    if (!stackOnly && currentXMM < xmmParameterRegisters.length) {
+                        Register register = xmmParameterRegisters[currentXMM++];
+                        locations[i] = register.asValue(target.getLIRKind(kind));
+                    }
+                    break;
+                default:
+                    throw JVMCIError.shouldNotReachHere();
+            }
+
+            if (locations[i] == null) {
+                LIRKind lirKind = target.getLIRKind(kind);
+                locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
+                currentStackOffset += Math.max(target.getSizeInBytes(lirKind.getPlatformKind()), target.wordSize);
+            }
+        }
+
+        JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
+        AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind()));
+        return new CallingConvention(currentStackOffset, returnLocation, locations);
+    }
+
+    @Override
+    public Register getReturnRegister(JavaKind kind) {
+        switch (kind) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
+            case Long:
+            case Object:
+                return rax;
+            case Float:
+            case Double:
+                return xmm0;
+            case Void:
+            case Illegal:
+                return null;
+            default:
+                throw new UnsupportedOperationException("no return register for type " + kind);
+        }
+    }
+
+    @Override
+    public Register getFrameRegister() {
+        return rsp;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, 2015, 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 jdk.vm.ci.hotspot.sparc;
+
+import static jdk.vm.ci.inittimer.InitTimer.*;
+
+import java.util.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.compiler.*;
+import jdk.vm.ci.hotspot.*;
+import jdk.vm.ci.inittimer.*;
+import jdk.vm.ci.runtime.*;
+import jdk.vm.ci.service.*;
+import jdk.vm.ci.sparc.*;
+import jdk.vm.ci.sparc.SPARC.CPUFeature;
+
+@ServiceProvider(HotSpotJVMCIBackendFactory.class)
+public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
+
+    protected TargetDescription createTarget(HotSpotVMConfig config, CompilerFactory compilerFactory) {
+        final int stackFrameAlignment = 16;
+        final int implicitNullCheckLimit = 4096;
+        final boolean inlineObjects = false;
+        Architecture arch = new SPARC(computeFeatures(config));
+        return new TargetDescription(compilerFactory.initializeArchitecture(arch), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+    }
+
+    protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
+        return new HotSpotCodeCacheProvider(runtime, runtime.getConfig(), target, regConfig);
+    }
+
+    protected EnumSet<CPUFeature> computeFeatures(HotSpotVMConfig config) {
+        EnumSet<CPUFeature> features = EnumSet.noneOf(CPUFeature.class);
+        if ((config.sparcFeatures & config.vis1Instructions) != 0) {
+            features.add(CPUFeature.VIS1);
+        }
+        if ((config.sparcFeatures & config.vis2Instructions) != 0) {
+            features.add(CPUFeature.VIS2);
+        }
+        if ((config.sparcFeatures & config.vis3Instructions) != 0) {
+            features.add(CPUFeature.VIS3);
+        }
+        if ((config.sparcFeatures & config.cbcondInstructions) != 0) {
+            features.add(CPUFeature.CBCOND);
+        }
+        if (config.useBlockZeroing) {
+            features.add(CPUFeature.BLOCK_ZEROING);
+        }
+        return features;
+    }
+
+    @Override
+    public String getArchitecture() {
+        return "SPARC";
+    }
+
+    @Override
+    public String toString() {
+        return "JVMCIBackend:" + getArchitecture();
+    }
+
+    @SuppressWarnings("try")
+    public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host) {
+        assert host == null;
+        TargetDescription target = createTarget(runtime.getConfig(), compilerFactory);
+
+        HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
+        RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target, runtime.getConfig());
+        HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig);
+        HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
+        try (InitTimer rt = timer("instantiate backend")) {
+            return createBackend(metaAccess, codeCache, constantReflection);
+        }
+    }
+
+    protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, HotSpotConstantReflectionProvider constantReflection) {
+        return new JVMCIBackend(metaAccess, codeCache, constantReflection);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.vm.ci.hotspot.sparc;
+
+import static jdk.vm.ci.sparc.SPARC.*;
+
+import java.util.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.CallingConvention.*;
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.hotspot.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.sparc.*;
+
+public class SPARCHotSpotRegisterConfig implements RegisterConfig {
+
+    private final Architecture architecture;
+
+    private final Register[] allocatable;
+
+    private final RegisterAttributes[] attributesMap;
+
+    @Override
+    public Register[] getAllocatableRegisters() {
+        return allocatable.clone();
+    }
+
+    public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
+        ArrayList<Register> list = new ArrayList<>();
+        for (Register reg : registers) {
+            if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
+                // Special treatment for double precision
+                // TODO: This is wasteful it uses only half of the registers as float.
+                if (kind == JavaKind.Double) {
+                    if (reg.getRegisterCategory().equals(FPUd)) {
+                        list.add(reg);
+                    }
+                } else if (kind == JavaKind.Float) {
+                    if (reg.getRegisterCategory().equals(FPUs)) {
+                        list.add(reg);
+                    }
+                } else {
+                    list.add(reg);
+                }
+            }
+        }
+
+        Register[] ret = list.toArray(new Register[list.size()]);
+        return ret;
+    }
+
+    @Override
+    public RegisterAttributes[] getAttributesMap() {
+        return attributesMap.clone();
+    }
+
+    private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
+    private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
+
+    private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
+    private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
+    // @formatter:off
+    private final Register[] callerSaveRegisters =
+                   {g1, g2, g3, g4, g5, g6, g7,
+                    o0, o1, o2, o3, o4, o5, o7,
+                    f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
+                    f8,  f9,  f10, f11, f12, f13, f14, f15,
+                    f16, f17, f18, f19, f20, f21, f22, f23,
+                    f24, f25, f26, f27, f28, f29, f30, f31,
+                    d32, d34, d36, d38, d40, d42, d44, d46,
+                    d48, d50, d52, d54, d56, d58, d60, d62};
+    // @formatter:on
+
+    /**
+     * Registers saved by the callee. This lists all L and I registers which are saved in the
+     * register window.
+     */
+    private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7};
+
+    private static Register[] initAllocatable(boolean reserveForHeapBase) {
+        Register[] registers = null;
+        if (reserveForHeapBase) {
+            // @formatter:off
+            registers = new Register[]{
+                        // TODO this is not complete
+                        // o7 cannot be used as register because it is always overwritten on call
+                        // and the current register handler would ignore this fact if the called
+                        // method still does not modify registers, in fact o7 is modified by the Call instruction
+                        // There would be some extra handlin necessary to be able to handle the o7 properly for local usage
+                        g1, g4, g5,
+                        o0, o1, o2, o3, o4, o5, /*o6,o7,*/
+                        l0, l1, l2, l3, l4, l5, l6, l7,
+                        i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
+                        //f0, f1, f2, f3, f4, f5, f6, f7,
+                        f8,  f9,  f10, f11, f12, f13, f14, f15,
+                        f16, f17, f18, f19, f20, f21, f22, f23,
+                        f24, f25, f26, f27, f28, f29, f30, f31,
+                        d32, d34, d36, d38, d40, d42, d44, d46,
+                        d48, d50, d52, d54, d56, d58, d60, d62
+            };
+            // @formatter:on
+        } else {
+            // @formatter:off
+            registers = new Register[]{
+                        // TODO this is not complete
+                        g1, g4, g5,
+                        o0, o1, o2, o3, o4, o5, /*o6, o7,*/
+                        l0, l1, l2, l3, l4, l5, l6, l7,
+                        i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
+//                        f0, f1, f2, f3, f4, f5, f6, f7
+                        f8,  f9,  f10, f11, f12, f13, f14, f15,
+                        f16, f17, f18, f19, f20, f21, f22, f23,
+                        f24, f25, f26, f27, f28, f29, f30, f31,
+                        d32, d34, d36, d38, d40, d42, d44, d46,
+                        d48, d50, d52, d54, d56, d58, d60, d62
+            };
+            // @formatter:on
+        }
+
+        return registers;
+    }
+
+    public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
+        this(target, initAllocatable(config.useCompressedOops));
+    }
+
+    public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
+        this.architecture = target.arch;
+        this.allocatable = allocatable.clone();
+        attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
+    }
+
+    @Override
+    public Register[] getCallerSaveRegisters() {
+        return callerSaveRegisters;
+    }
+
+    public Register[] getCalleeSaveRegisters() {
+        return calleeSaveRegisters;
+    }
+
+    @Override
+    public boolean areAllAllocatableRegistersCallerSaved() {
+        return false;
+    }
+
+    @Override
+    public Register getRegisterForRole(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
+        if (type == Type.JavaCall || type == Type.NativeCall) {
+            return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
+        }
+        if (type == Type.JavaCallee) {
+            return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
+        }
+        throw JVMCIError.shouldNotReachHere();
+    }
+
+    public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
+        if (architecture.canStoreValue(FPUs, kind) || architecture.canStoreValue(FPUd, kind)) {
+            return fpuParameterRegisters;
+        }
+        assert architecture.canStoreValue(CPU, kind);
+        return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
+    }
+
+    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
+        AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
+
+        int currentGeneral = 0;
+        int currentFloating = 0;
+        int currentStackOffset = 0;
+
+        for (int i = 0; i < parameterTypes.length; i++) {
+            final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
+
+            switch (kind) {
+                case Byte:
+                case Boolean:
+                case Short:
+                case Char:
+                case Int:
+                case Long:
+                case Object:
+                    if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
+                        Register register = generalParameterRegisters[currentGeneral++];
+                        locations[i] = register.asValue(target.getLIRKind(kind));
+                    }
+                    break;
+                case Double:
+                    if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
+                        if (currentFloating % 2 != 0) {
+                            // Make register number even to be a double reg
+                            currentFloating++;
+                        }
+                        Register register = fpuDoubleParameterRegisters[currentFloating];
+                        currentFloating += 2; // Only every second is a double register
+                        locations[i] = register.asValue(target.getLIRKind(kind));
+                    }
+                    break;
+                case Float:
+                    if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
+                        Register register = fpuParameterRegisters[currentFloating++];
+                        locations[i] = register.asValue(target.getLIRKind(kind));
+                    }
+                    break;
+                default:
+                    throw JVMCIError.shouldNotReachHere();
+            }
+
+            if (locations[i] == null) {
+                // Stack slot is always aligned to its size in bytes but minimum wordsize
+                int typeSize = SPARC.spillSlotSize(target, kind);
+                currentStackOffset = roundUp(currentStackOffset, typeSize);
+                int slotOffset = currentStackOffset + SPARC.REGISTER_SAFE_AREA_SIZE;
+                locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), slotOffset, !type.out);
+                currentStackOffset += typeSize;
+            }
+        }
+
+        JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
+        AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
+        // Space where callee may spill outgoing parameters o0...o5
+        int lowerOutgoingSpace = Math.min(locations.length, 6) * target.wordSize;
+        return new CallingConvention(currentStackOffset + lowerOutgoingSpace, returnLocation, locations);
+    }
+
+    private static int roundUp(int number, int mod) {
+        return ((number + mod - 1) / mod) * mod;
+    }
+
+    @Override
+    public Register getReturnRegister(JavaKind kind) {
+        return getReturnRegister(kind, Type.JavaCallee);
+    }
+
+    private static Register getReturnRegister(JavaKind kind, Type type) {
+        switch (kind) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
+            case Long:
+            case Object:
+                return type == Type.JavaCallee ? i0 : o0;
+            case Float:
+                return f0;
+            case Double:
+                return d0;
+            case Void:
+            case Illegal:
+                return null;
+            default:
+                throw new UnsupportedOperationException("no return register for type " + kind);
+        }
+    }
+
+    @Override
+    public Register getFrameRegister() {
+        return sp;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,574 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.inittimer.InitTimer.timer;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
+import jdk.vm.ci.inittimer.InitTimer;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.SpeculationLog;
+import sun.misc.Unsafe;
+
+/**
+ * Calls from Java into HotSpot. The behavior of all the methods in this class that take a native
+ * pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not
+ * denote a valid native object.
+ */
+public final class CompilerToVM {
+    /**
+     * Initializes the native part of the JVMCI runtime.
+     */
+    private static native void registerNatives();
+
+    static {
+        initialize();
+    }
+
+    @SuppressWarnings("try")
+    private static void initialize() {
+        try (InitTimer t = timer("CompilerToVM.registerNatives")) {
+            registerNatives();
+        }
+    }
+
+    /**
+     * Copies the original bytecode of {@code method} into a new byte array and returns it.
+     *
+     * @return a new byte array containing the original bytecode of {@code method}
+     */
+    native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Gets the number of entries in {@code method}'s exception handler table or 0 if it has not
+     * exception handler table.
+     */
+    native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Gets the address of the first entry in {@code method}'s exception handler table.
+     *
+     * Each entry is a native object described by these fields:
+     *
+     * <ul>
+     * <li>{@link HotSpotVMConfig#exceptionTableElementSize}</li>
+     * <li>{@link HotSpotVMConfig#exceptionTableElementStartPcOffset}</li>
+     * <li>{@link HotSpotVMConfig#exceptionTableElementEndPcOffset}</li>
+     * <li>{@link HotSpotVMConfig#exceptionTableElementHandlerPcOffset}</li>
+     * <li>{@link HotSpotVMConfig#exceptionTableElementCatchTypeIndexOffset}
+     * </ul>
+     *
+     * @return 0 if {@code method} has no exception handlers (i.e.
+     *         {@code getExceptionTableLength(method) == 0})
+     */
+    native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Determines if {@code method} can be inlined. A method may not be inlinable for a number of
+     * reasons such as:
+     * <ul>
+     * <li>a CompileOracle directive may prevent inlining or compilation of methods</li>
+     * <li>the method may have a bytecode breakpoint set</li>
+     * <li>the method may have other bytecode features that require special handling by the VM</li>
+     * </ul>
+     */
+    native boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Determines if {@code method} should be inlined at any cost. This could be because:
+     * <ul>
+     * <li>a CompileOracle directive may forces inlining of this methods</li>
+     * <li>an annotation forces inlining of this method</li>
+     * </ul>
+     */
+    native boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}.
+     *
+     * @param method the method on which to base the search
+     * @param actualHolderType the best known type of receiver
+     * @return the method result or 0 is there is no unique concrete method for {@code method}
+     */
+    native HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl actualHolderType, HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Gets the implementor for the interface class {@code type}.
+     *
+     * @return the implementor if there is a single implementor, 0 if there is no implementor, or
+     *         {@code type} itself if there is more than one implementor
+     */
+    native HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type);
+
+    /**
+     * Determines if {@code method} is ignored by security stack walks.
+     */
+    native boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Converts a name to a type.
+     *
+     * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
+     * @param accessingClass the context of resolution (must not be null)
+     * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will
+     *            either return a {@link ResolvedJavaType} or throw an exception
+     * @return the type for {@code name} or 0 if resolution failed and {@code resolve == false}
+     * @throws LinkageError if {@code resolve == true} and the resolution failed
+     */
+    native HotSpotResolvedObjectTypeImpl lookupType(String name, Class<?> accessingClass, boolean resolve);
+
+    /**
+     * Resolves the entry at index {@code cpi} in {@code constantPool} to an object.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote one of the following
+     * entry types: {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError},
+     * {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}.
+     */
+    native Object resolveConstantInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the
+     * constant pool cache first.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote a
+     * {@code JVM_CONSTANT_String} entry.
+     */
+    native Object resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Gets the {@code JVM_CONSTANT_NameAndType} index from the entry at index {@code cpi} in
+     * {@code constantPool}.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a
+     * {@code JVM_CONSTANT_NameAndType} index.
+     */
+    native int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Gets the name of the {@code JVM_CONSTANT_NameAndType} entry referenced by another entry
+     * denoted by {@code which} in {@code constantPool}.
+     *
+     * The behavior of this method is undefined if {@code which} does not denote a entry that
+     * references a {@code JVM_CONSTANT_NameAndType} entry.
+     */
+    native String lookupNameInPool(HotSpotConstantPool constantPool, int which);
+
+    /**
+     * Gets the signature of the {@code JVM_CONSTANT_NameAndType} entry referenced by another entry
+     * denoted by {@code which} in {@code constantPool}.
+     *
+     * The behavior of this method is undefined if {@code which} does not denote a entry that
+     * references a {@code JVM_CONSTANT_NameAndType} entry.
+     */
+    native String lookupSignatureInPool(HotSpotConstantPool constantPool, int which);
+
+    /**
+     * Gets the {@code JVM_CONSTANT_Class} index from the entry at index {@code cpi} in
+     * {@code constantPool}.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a
+     * {@code JVM_CONSTANT_Class} index.
+     */
+    native int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Looks up a class denoted by the {@code JVM_CONSTANT_Class} entry at index {@code cpi} in
+     * {@code constantPool}. This method does not perform any resolution.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote a
+     * {@code JVM_CONSTANT_Class} entry.
+     *
+     * @return the resolved class entry or a String otherwise
+     */
+    native Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Looks up a method denoted by the entry at index {@code cpi} in {@code constantPool}. This
+     * method does not perform any resolution.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
+     * a method.
+     *
+     * @param opcode the opcode of the instruction for which the lookup is being performed or
+     *            {@code -1}. If non-negative, then resolution checks specific to the bytecode it
+     *            denotes are performed if the method is already resolved. Should any of these
+     *            checks fail, 0 is returned.
+     * @return the resolved method entry, 0 otherwise
+     */
+    native HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool, int cpi, byte opcode);
+
+    /**
+     * Ensures that the type referenced by the specified {@code JVM_CONSTANT_InvokeDynamic} entry at
+     * index {@code cpi} in {@code constantPool} is loaded and initialized.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote a
+     * {@code JVM_CONSTANT_InvokeDynamic} entry.
+     */
+    native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Ensures that the type referenced by the entry for a <a
+     * href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
+     * polymorphic</a> method at index {@code cpi} in {@code constantPool} is loaded and
+     * initialized.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
+     * a signature polymorphic method.
+     */
+    native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Gets the resolved type denoted by the entry at index {@code cpi} in {@code constantPool}.
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
+     * a class.
+     *
+     * @throws LinkageError if resolution failed
+     */
+    native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError;
+
+    /**
+     * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry at index {@code cpi} in
+     * {@code constantPool}. The values returned in {@code info} are:
+     *
+     * <pre>
+     *     [(int) flags,   // only valid if field is resolved
+     *      (int) offset]  // only valid if field is resolved
+     * </pre>
+     *
+     * The behavior of this method is undefined if {@code cpi} does not denote a
+     * {@code JVM_CONSTANT_Field} entry.
+     *
+     * @param info an array in which the details of the field are returned
+     * @return the type defining the field if resolution is successful, 0 otherwise
+     */
+    native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int cpi, byte opcode, long[] info);
+
+    /**
+     * Converts {@code cpci} from an index into the cache for {@code constantPool} to an index
+     * directly into {@code constantPool}.
+     *
+     * The behavior of this method is undefined if {@code ccpi} is an invalid constant pool cache
+     * index.
+     */
+    native int constantPoolRemapInstructionOperandFromCache(HotSpotConstantPool constantPool, int cpci);
+
+    /**
+     * Gets the appendix object (if any) associated with the entry at index {@code cpi} in
+     * {@code constantPool}.
+     */
+    native Object lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi);
+
+    /**
+     * Installs the result of a compilation into the code cache.
+     *
+     * @param target the target where this code should be installed
+     * @param compiledCode the result of a compilation
+     * @param code the details of the installed CodeBlob are written to this object
+     * @return the outcome of the installation which will be one of
+     *         {@link HotSpotVMConfig#codeInstallResultOk},
+     *         {@link HotSpotVMConfig#codeInstallResultCacheFull},
+     *         {@link HotSpotVMConfig#codeInstallResultCodeTooLarge},
+     *         {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
+     *         {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
+     */
+    public native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog);
+
+    public native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData);
+
+    /**
+     * Notifies the VM of statistics for a completed compilation.
+     *
+     * @param id the identifier of the compilation
+     * @param method the method compiled
+     * @param osr specifies if the compilation was for on-stack-replacement
+     * @param processedBytecodes the number of bytecodes processed during the compilation, including
+     *            the bytecodes of all inlined methods
+     * @param time the amount time spent compiling {@code method}
+     * @param timeUnitsPerSecond the granularity of the units for the {@code time} value
+     * @param installedCode the nmethod installed as a result of the compilation
+     */
+    public synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethodImpl method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
+                    InstalledCode installedCode);
+
+    /**
+     * Resets all compilation statistics.
+     */
+    public native void resetCompilationStatistics();
+
+    /**
+     * Initializes the fields of {@code config}.
+     */
+    native long initializeConfiguration();
+
+    /**
+     * Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic
+     * type {@code exactReceiver}. This resolution process only searches "up" the class hierarchy of
+     * {@code exactReceiver}.
+     *
+     * @param caller the caller or context type used to perform access checks
+     * @return the link-time resolved method (might be abstract) or {@code 0} if it can not be
+     *         linked
+     */
+    native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller);
+
+    /**
+     * Gets the static initializer of {@code type}.
+     *
+     * @return 0 if {@code type} has no static initializer
+     */
+    native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type);
+
+    /**
+     * Determines if {@code type} or any of its currently loaded subclasses overrides
+     * {@code Object.finalize()}.
+     */
+    native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type);
+
+    /**
+     * Gets the method corresponding to {@code holder} and slot number {@code slot} (i.e.
+     * {@link Method#slot} or {@link Constructor#slot}).
+     */
+    native HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(Class<?> holder, int slot);
+
+    /**
+     * Gets the maximum absolute offset of a PC relative call to {@code address} from any position
+     * in the code cache.
+     *
+     * @param address an address that may be called from any code in the code cache
+     * @return -1 if {@code address == 0}
+     */
+    public native long getMaxCallTargetOffset(long address);
+
+    /**
+     * Gets a textual disassembly of {@code codeBlob}.
+     *
+     * @return a non-zero length string containing a disassembly of {@code codeBlob} or null if
+     *         {@code codeBlob} could not be disassembled for some reason
+     */
+    // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
+    public synchronized native String disassembleCodeBlob(long codeBlob);
+
+    /**
+     * Gets a stack trace element for {@code method} at bytecode index {@code bci}.
+     */
+    native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci);
+
+    /**
+     * Executes some {@code installedCode} with arguments {@code args}.
+     *
+     * @return the result of executing {@code installedCode}
+     * @throws InvalidInstalledCodeException if {@code installedCode} has been invalidated
+     */
+    native Object executeInstalledCode(Object[] args, InstalledCode installedCode) throws InvalidInstalledCodeException;
+
+    /**
+     * Gets the line number table for {@code method}. The line number table is encoded as (bci,
+     * source line number) pairs.
+     *
+     * @return the line number table for {@code method} or null if it doesn't have one
+     */
+    native long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Gets the number of entries in the local variable table for {@code method}.
+     *
+     * @return the number of entries in the local variable table for {@code method}
+     */
+    native int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Gets the address of the first entry in the local variable table for {@code method}.
+     *
+     * Each entry is a native object described by these fields:
+     *
+     * <ul>
+     * <li>{@link HotSpotVMConfig#localVariableTableElementSize}</li>
+     * <li>{@link HotSpotVMConfig#localVariableTableElementLengthOffset}</li>
+     * <li>{@link HotSpotVMConfig#localVariableTableElementNameCpIndexOffset}</li>
+     * <li>{@link HotSpotVMConfig#localVariableTableElementDescriptorCpIndexOffset}</li>
+     * <li>{@link HotSpotVMConfig#localVariableTableElementSignatureCpIndexOffset}
+     * <li>{@link HotSpotVMConfig#localVariableTableElementSlotOffset}
+     * <li>{@link HotSpotVMConfig#localVariableTableElementStartBciOffset}
+     * </ul>
+     *
+     * @return 0 if {@code method} does not have a local variable table
+     */
+    native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Reads an object pointer within a VM data structure. That is, any {@link HotSpotVMField} whose
+     * {@link HotSpotVMField#type() type} is {@code "oop"} (e.g.,
+     * {@code ArrayKlass::_component_mirror}, {@code Klass::_java_mirror},
+     * {@code JavaThread::_threadObj}).
+     *
+     * Note that {@link Unsafe#getObject(Object, long)} cannot be used for this since it does a
+     * {@code narrowOop} read if the VM is using compressed oops whereas oops within VM data
+     * structures are (currently) always uncompressed.
+     *
+     * @param address address of an oop field within a VM data structure
+     */
+    native Object readUncompressedOop(long address);
+
+    /**
+     * Determines if {@code method} should not be inlined or compiled.
+     */
+    native void doNotInlineOrCompile(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Invalidates the profiling information for {@code method} and (re)initializes it such that
+     * profiling restarts upon its next invocation.
+     */
+    native void reprofile(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
+     * raised the next time {@code installedCode} is executed.
+     */
+    public native void invalidateInstalledCode(InstalledCode installedCode);
+
+    /**
+     * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
+     */
+    public native long[] collectCounters();
+
+    /**
+     * Determines if {@code metaspaceMethodData} is mature.
+     */
+    native boolean isMature(long metaspaceMethodData);
+
+    /**
+     * Generate a unique id to identify the result of the compile.
+     */
+    native int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI);
+
+    /**
+     * Determines if {@code method} has OSR compiled code identified by {@code entryBCI} for
+     * compilation level {@code level}.
+     */
+    native boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level);
+
+    /**
+     * Gets the value of {@code metaspaceSymbol} as a String.
+     */
+    native String getSymbol(long metaspaceSymbol);
+
+    /**
+     * Looks for the next Java stack frame matching an entry in {@code methods}.
+     *
+     * @param frame the starting point of the search, where {@code null} refers to the topmost frame
+     * @param methods the methods to look for, where {@code null} means that any frame is returned
+     * @return the frame, or {@code null} if the end of the stack was reached during the search
+     */
+    public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, HotSpotResolvedJavaMethodImpl[] methods, int initialSkip);
+
+    /**
+     * Materializes all virtual objects within {@code stackFrame} updates its locals.
+     *
+     * @param invalidate if {@code true}, the compiled method for the stack frame will be
+     *            invalidated.
+     */
+    native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
+
+    /**
+     * Gets the v-table index for interface method {@code method} in the receiver {@code type} or
+     * {@link HotSpotVMConfig#invalidVtableIndex} if {@code method} is not in {@code type}'s
+     * v-table.
+     *
+     * @throws InternalError if {@code type} is an interface or {@code method} is not held by an
+     *             interface or class represented by {@code type} is not initialized
+     */
+    native int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Determines if debug info should also be emitted at non-safepoint locations.
+     */
+    public native boolean shouldDebugNonSafepoints();
+
+    /**
+     * Writes {@code length} bytes from {@code bytes} starting at offset {@code offset} to the
+     * HotSpot's log stream.
+     *
+     * @exception NullPointerException if <code>bytes</code> is <code>null</code>.
+     * @exception IndexOutOfBoundsException if copying would cause access of data outside array
+     *                bounds.
+     */
+    public native void writeDebugOutput(byte[] bytes, int offset, int length);
+
+    /**
+     * Flush HotSpot's log stream.
+     */
+    public native void flushDebugOutput();
+
+    /**
+     * Read a value representing a metaspace Method* and return the
+     * {@link HotSpotResolvedJavaMethodImpl} wrapping it. This method does no checking that the
+     * location actually contains a valid Method*. If the {@code base} object is a
+     * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
+     * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
+     * and used as the base. Otherwise the object itself is used as the base.
+     *
+     * @param base an object to read from or null
+     * @param displacement
+     * @return null or the resolved method for this location
+     */
+    native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
+
+    /**
+     * Read a value representing a metaspace ConstantPool* and return the
+     * {@link HotSpotConstantPool} wrapping it. This method does no checking that the location
+     * actually contains a valid ConstantPool*. If the {@code base} object is a
+     * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
+     * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
+     * and used as the base. Otherwise the object itself is used as the base.
+     *
+     * @param base an object to read from or null
+     * @param displacement
+     * @return null or the resolved method for this location
+     */
+    native HotSpotConstantPool getConstantPool(Object base, long displacement);
+
+    /**
+     * Read a value representing a metaspace Klass* and return the
+     * {@link HotSpotResolvedObjectTypeImpl} wrapping it. The method does no checking that the
+     * location actually contains a valid Klass*. If the {@code base} object is a
+     * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
+     * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
+     * and used as the base. Otherwise the object itself is used as the base.
+     *
+     * @param base an object to read from or null
+     * @param displacement
+     * @param compressed true if the location contains a compressed Klass*
+     * @return null or the resolved method for this location
+     */
+    native HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base, long displacement, boolean compressed);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.*;
+
+import java.lang.reflect.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.CompilationResult.*;
+import jdk.vm.ci.code.DataSection.*;
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * HotSpot implementation of {@link CodeCacheProvider}.
+ */
+public class HotSpotCodeCacheProvider implements CodeCacheProvider {
+
+    protected final HotSpotJVMCIRuntimeProvider runtime;
+    public final HotSpotVMConfig config;
+    protected final TargetDescription target;
+    protected final RegisterConfig regConfig;
+
+    public HotSpotCodeCacheProvider(HotSpotJVMCIRuntimeProvider runtime, HotSpotVMConfig config, TargetDescription target, RegisterConfig regConfig) {
+        this.runtime = runtime;
+        this.config = config;
+        this.target = target;
+        this.regConfig = regConfig;
+    }
+
+    @Override
+    public String getMarkName(Mark mark) {
+        int markId = (int) mark.id;
+        Field[] fields = runtime.getConfig().getClass().getDeclaredFields();
+        for (Field f : fields) {
+            if (f.getName().startsWith("MARKID_")) {
+                f.setAccessible(true);
+                try {
+                    if (f.getInt(runtime.getConfig()) == markId) {
+                        return f.getName();
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return CodeCacheProvider.super.getMarkName(mark);
+    }
+
+    /**
+     * Decodes a call target to a mnemonic if possible.
+     */
+    @Override
+    public String getTargetName(Call call) {
+        Field[] fields = runtime.getConfig().getClass().getDeclaredFields();
+        for (Field f : fields) {
+            if (f.getName().endsWith("Stub")) {
+                f.setAccessible(true);
+                try {
+                    Object address = f.get(runtime.getConfig());
+                    if (address.equals(call.target)) {
+                        return f.getName() + ":0x" + Long.toHexString((Long) address);
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return CodeCacheProvider.super.getTargetName(call);
+    }
+
+    @Override
+    public RegisterConfig getRegisterConfig() {
+        return regConfig;
+    }
+
+    @Override
+    public int getMinimumOutgoingSize() {
+        return runtime.getConfig().runtimeCallStackSize;
+    }
+
+    public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) {
+        HotSpotJVMCIRuntime.runtime().notifyInstall(this, installedCode, compResult);
+        return installedCode;
+    }
+
+    private InstalledCode installCode(CompilationResult compResult, HotSpotCompiledNmethod compiledCode, InstalledCode installedCode, SpeculationLog log) {
+        int result = runtime.getCompilerToVM().installCode(target, compiledCode, installedCode, log);
+        if (result != config.codeInstallResultOk) {
+            String msg = compiledCode.getInstallationFailureMessage();
+            String resultDesc = config.getCodeInstallResultDescription(result);
+            if (msg != null) {
+                msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
+            } else {
+                msg = String.format("Code installation failed: %s", resultDesc);
+            }
+            if (result == config.codeInstallResultDependenciesInvalid) {
+                throw new AssertionError(resultDesc + " " + msg);
+            }
+            throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg);
+        }
+        return logOrDump(installedCode, compResult);
+    }
+
+    public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv, boolean isDefault) {
+        if (compResult.getId() == -1) {
+            compResult.setId(method.allocateCompileId(compResult.getEntryBCI()));
+        }
+        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
+        HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(method, compResult, jvmciEnv);
+        return installCode(compResult, compiledCode, installedCode, method.getSpeculationLog());
+    }
+
+    @Override
+    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode predefinedInstalledCode) {
+        HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
+        if (compResult.getId() == -1) {
+            compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI()));
+        }
+        InstalledCode installedCode = predefinedInstalledCode;
+        if (installedCode == null) {
+            HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false);
+            installedCode = code;
+        }
+        HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(hotspotMethod, compResult);
+        return installCode(compResult, compiledCode, installedCode, log);
+    }
+
+    @Override
+    public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) {
+        HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
+        return installMethod(hotspotMethod, compResult, 0L, true);
+    }
+
+    public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
+        HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
+        if (compResult.getId() == -1) {
+            compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI()));
+        }
+        HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true);
+        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compResult);
+        CompilerToVM vm = runtime.getCompilerToVM();
+        int result = vm.installCode(target, compiled, code, null);
+        if (result != runtime.getConfig().codeInstallResultOk) {
+            return null;
+        }
+        return code;
+    }
+
+    public boolean needsDataPatch(JavaConstant constant) {
+        return constant instanceof HotSpotMetaspaceConstant;
+    }
+
+    private Data createSingleDataItem(Constant constant) {
+        int size;
+        DataBuilder builder;
+        if (constant instanceof VMConstant) {
+            VMConstant vmConstant = (VMConstant) constant;
+            boolean compressed;
+            long raw;
+            if (constant instanceof HotSpotObjectConstant) {
+                HotSpotObjectConstant c = (HotSpotObjectConstant) vmConstant;
+                compressed = c.isCompressed();
+                raw = 0xDEADDEADDEADDEADL;
+            } else if (constant instanceof HotSpotMetaspaceConstant) {
+                HotSpotMetaspaceConstant meta = (HotSpotMetaspaceConstant) constant;
+                compressed = meta.isCompressed();
+                raw = meta.rawValue();
+            } else {
+                throw new JVMCIError(String.valueOf(constant));
+            }
+
+            size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind);
+            if (size == 4) {
+                builder = (buffer, patch) -> {
+                    patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
+                    buffer.putInt((int) raw);
+                };
+            } else {
+                assert size == 8;
+                builder = (buffer, patch) -> {
+                    patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
+                    buffer.putLong(raw);
+                };
+            }
+        } else if (JavaConstant.isNull(constant)) {
+            boolean compressed = COMPRESSED_NULL.equals(constant);
+            size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind);
+            builder = DataBuilder.zero(size);
+        } else if (constant instanceof SerializableConstant) {
+            SerializableConstant s = (SerializableConstant) constant;
+            size = s.getSerializedSize();
+            builder = DataBuilder.serializable(s);
+        } else {
+            throw new JVMCIError(String.valueOf(constant));
+        }
+
+        return new Data(size, size, builder);
+    }
+
+    public Data createDataItem(Constant... constants) {
+        assert constants.length > 0;
+        if (constants.length == 1) {
+            return createSingleDataItem(constants[0]);
+        } else {
+            DataBuilder[] builders = new DataBuilder[constants.length];
+            int size = 0;
+            int alignment = 1;
+            for (int i = 0; i < constants.length; i++) {
+                Data data = createSingleDataItem(constants[i]);
+
+                assert size % data.getAlignment() == 0 : "invalid alignment in packed constants";
+                alignment = DataSection.lcm(alignment, data.getAlignment());
+
+                builders[i] = data.getBuilder();
+                size += data.getSize();
+            }
+            DataBuilder ret = (buffer, patches) -> {
+                for (DataBuilder b : builders) {
+                    b.emit(buffer, patches);
+                }
+            };
+            return new Data(alignment, size, ret);
+        }
+    }
+
+    @Override
+    public TargetDescription getTarget() {
+        return target;
+    }
+
+    public String disassemble(InstalledCode code) {
+        if (code.isValid()) {
+            long codeBlob = code.getAddress();
+            return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob);
+        }
+        return null;
+    }
+
+    public SpeculationLog createSpeculationLog() {
+        return new HotSpotSpeculationLog();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import java.nio.*;
+import java.util.*;
+import java.util.stream.*;
+import java.util.stream.Stream.Builder;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.CompilationResult.CodeAnnotation;
+import jdk.vm.ci.code.CompilationResult.CodeComment;
+import jdk.vm.ci.code.CompilationResult.DataPatch;
+import jdk.vm.ci.code.CompilationResult.ExceptionHandler;
+import jdk.vm.ci.code.CompilationResult.Infopoint;
+import jdk.vm.ci.code.CompilationResult.JumpTable;
+import jdk.vm.ci.code.CompilationResult.Mark;
+import jdk.vm.ci.code.CompilationResult.Site;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Assumptions.Assumption;
+
+/**
+ * A {@link CompilationResult} with additional HotSpot-specific information required for installing
+ * the code in HotSpot's code cache.
+ */
+public abstract class HotSpotCompiledCode {
+
+    public final String name;
+    public final Site[] sites;
+    public final ExceptionHandler[] exceptionHandlers;
+    public final Comment[] comments;
+    public final Assumption[] assumptions;
+
+    public final byte[] targetCode;
+    public final int targetCodeSize;
+
+    public final byte[] dataSection;
+    public final int dataSectionAlignment;
+    public final DataPatch[] dataSectionPatches;
+    public final boolean isImmutablePIC;
+
+    public final int totalFrameSize;
+    public final int customStackAreaOffset;
+
+    /**
+     * The list of the methods whose bytecodes were used as input to the compilation. If
+     * {@code null}, then the compilation did not record method dependencies. Otherwise, the first
+     * element of this array is the root method of the compilation.
+     */
+    public final ResolvedJavaMethod[] methods;
+
+    public static class Comment {
+
+        public final String text;
+        public final int pcOffset;
+
+        public Comment(int pcOffset, String text) {
+            this.text = text;
+            this.pcOffset = pcOffset;
+        }
+    }
+
+    public HotSpotCompiledCode(CompilationResult compResult) {
+        name = compResult.getName();
+        sites = getSortedSites(compResult);
+        if (compResult.getExceptionHandlers().isEmpty()) {
+            exceptionHandlers = null;
+        } else {
+            exceptionHandlers = compResult.getExceptionHandlers().toArray(new ExceptionHandler[compResult.getExceptionHandlers().size()]);
+        }
+        List<CodeAnnotation> annotations = compResult.getAnnotations();
+        comments = new Comment[annotations.size()];
+        if (!annotations.isEmpty()) {
+            for (int i = 0; i < comments.length; i++) {
+                CodeAnnotation annotation = annotations.get(i);
+                String text;
+                if (annotation instanceof CodeComment) {
+                    CodeComment codeComment = (CodeComment) annotation;
+                    text = codeComment.value;
+                } else if (annotation instanceof JumpTable) {
+                    JumpTable jumpTable = (JumpTable) annotation;
+                    text = "JumpTable [" + jumpTable.low + " .. " + jumpTable.high + "]";
+                } else {
+                    text = annotation.toString();
+                }
+                comments[i] = new Comment(annotation.position, text);
+            }
+        }
+        assumptions = compResult.getAssumptions();
+        assert validateFrames();
+
+        targetCode = compResult.getTargetCode();
+        targetCodeSize = compResult.getTargetCodeSize();
+
+        DataSection data = compResult.getDataSection();
+        if (!data.isFinalized()) {
+            data.finalizeLayout();
+        }
+        dataSection = new byte[data.getSectionSize()];
+
+        ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());
+        Builder<DataPatch> patchBuilder = Stream.builder();
+        data.buildDataSection(buffer, patchBuilder);
+
+        dataSectionAlignment = data.getSectionAlignment();
+        dataSectionPatches = patchBuilder.build().toArray(len -> new DataPatch[len]);
+
+        isImmutablePIC = compResult.isImmutablePIC();
+
+        totalFrameSize = compResult.getTotalFrameSize();
+        customStackAreaOffset = compResult.getCustomStackAreaOffset();
+
+        methods = compResult.getMethods();
+    }
+
+    /**
+     * Ensure that all the frames passed into HotSpot are properly formatted with an empty or
+     * illegal slot following double word slots.
+     */
+    private boolean validateFrames() {
+        for (Site site : sites) {
+            if (site instanceof Infopoint) {
+                Infopoint info = (Infopoint) site;
+                if (info.debugInfo != null) {
+                    BytecodeFrame frame = info.debugInfo.frame();
+                    assert frame == null || frame.validateFormat();
+                }
+            }
+        }
+        return true;
+    }
+
+    static class SiteComparator implements Comparator<Site> {
+
+        public int compare(Site s1, Site s2) {
+            if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) {
+                return s1 instanceof Mark ? -1 : 1;
+            }
+            return s1.pcOffset - s2.pcOffset;
+        }
+    }
+
+    private static Site[] getSortedSites(CompilationResult target) {
+        List<?>[] lists = new List<?>[]{target.getInfopoints(), target.getDataPatches(), target.getMarks()};
+        int count = 0;
+        for (List<?> list : lists) {
+            count += list.size();
+        }
+        Site[] result = new Site[count];
+        int pos = 0;
+        for (List<?> list : lists) {
+            for (Object elem : list) {
+                result[pos++] = (Site) elem;
+            }
+        }
+        Arrays.sort(result, new SiteComparator());
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 2014, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.inittimer.*;
+
+/**
+ * {@link HotSpotCompiledCode} destined for installation as an nmethod.
+ */
+public final class HotSpotCompiledNmethod extends HotSpotCompiledCode {
+
+    public final HotSpotResolvedJavaMethod method;
+    public final int entryBCI;
+    public final int id;
+    public final long jvmciEnv;
+    public final boolean hasUnsafeAccess;
+
+    /**
+     * May be set by VM if code installation fails. It will describe in more detail why installation
+     * failed (e.g., exactly which dependency failed).
+     */
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage;
+
+    public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) {
+        this(method, compResult, 0L);
+    }
+
+    public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv) {
+        super(compResult);
+        this.method = method;
+        this.entryBCI = compResult.getEntryBCI();
+        this.id = compResult.getId();
+        this.jvmciEnv = jvmciEnv;
+        this.hasUnsafeAccess = compResult.hasUnsafeAccess();
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + id + ":" + method.format("%H.%n(%p)%r@") + entryBCI + "]";
+    }
+
+    public String getInstallationFailureMessage() {
+        return installationFailureMessage;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * The compressed representation of the {@link JavaConstant#NULL_POINTER null constant}.
+ */
+public final class HotSpotCompressedNullConstant implements JavaConstant, HotSpotConstant {
+
+    public static final JavaConstant COMPRESSED_NULL = new HotSpotCompressedNullConstant();
+
+    private HotSpotCompressedNullConstant() {
+    }
+
+    public JavaKind getJavaKind() {
+        return JavaKind.Object;
+    }
+
+    @Override
+    public boolean isNull() {
+        return true;
+    }
+
+    @Override
+    public boolean isCompressed() {
+        return true;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return true;
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int asInt() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public boolean asBoolean() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public long asLong() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public float asFloat() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public double asDouble() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public String toString() {
+        return JavaConstant.toString(this);
+    }
+
+    @Override
+    public String toValueString() {
+        return "null";
+    }
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o instanceof HotSpotCompressedNullConstant;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Marker interface for hotspot specific constants.
+ */
+public interface HotSpotConstant extends Constant {
+
+    boolean isCompressed();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,716 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import java.lang.invoke.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Implementation of {@link ConstantPool} for HotSpot.
+ */
+public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
+
+    /**
+     * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.
+     */
+    public static class Bytecodes {
+        public static final int LDC = 18; // 0x12
+        public static final int LDC_W = 19; // 0x13
+        public static final int LDC2_W = 20; // 0x14
+        public static final int GETSTATIC = 178; // 0xB2
+        public static final int PUTSTATIC = 179; // 0xB3
+        public static final int GETFIELD = 180; // 0xB4
+        public static final int PUTFIELD = 181; // 0xB5
+        public static final int INVOKEVIRTUAL = 182; // 0xB6
+        public static final int INVOKESPECIAL = 183; // 0xB7
+        public static final int INVOKESTATIC = 184; // 0xB8
+        public static final int INVOKEINTERFACE = 185; // 0xB9
+        public static final int INVOKEDYNAMIC = 186; // 0xBA
+        public static final int NEW = 187; // 0xBB
+        public static final int NEWARRAY = 188; // 0xBC
+        public static final int ANEWARRAY = 189; // 0xBD
+        public static final int CHECKCAST = 192; // 0xC0
+        public static final int INSTANCEOF = 193; // 0xC1
+        public static final int MULTIANEWARRAY = 197; // 0xC5
+
+        static boolean isInvoke(int opcode) {
+            switch (opcode) {
+                case INVOKEVIRTUAL:
+                case INVOKESPECIAL:
+                case INVOKESTATIC:
+                case INVOKEINTERFACE:
+                case INVOKEDYNAMIC:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+        /**
+         * See: {@code Rewriter::maybe_rewrite_invokehandle}.
+         */
+        static boolean isInvokeHandleAlias(int opcode) {
+            switch (opcode) {
+                case INVOKEVIRTUAL:
+                case INVOKESPECIAL:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    }
+
+    /**
+     * Enum of all {@code JVM_CONSTANT} constants used in the VM. This includes the public and
+     * internal ones.
+     */
+    private enum JVM_CONSTANT {
+        // @formatter:off
+        Utf8(config().jvmConstantUtf8),
+        Integer(config().jvmConstantInteger),
+        Long(config().jvmConstantLong),
+        Float(config().jvmConstantFloat),
+        Double(config().jvmConstantDouble),
+        Class(config().jvmConstantClass),
+        UnresolvedClass(config().jvmConstantUnresolvedClass),
+        UnresolvedClassInError(config().jvmConstantUnresolvedClassInError),
+        String(config().jvmConstantString),
+        Fieldref(config().jvmConstantFieldref),
+        MethodRef(config().jvmConstantMethodref),
+        InterfaceMethodref(config().jvmConstantInterfaceMethodref),
+        NameAndType(config().jvmConstantNameAndType),
+        MethodHandle(config().jvmConstantMethodHandle),
+        MethodHandleInError(config().jvmConstantMethodHandleInError),
+        MethodType(config().jvmConstantMethodType),
+        MethodTypeInError(config().jvmConstantMethodTypeInError),
+        InvokeDynamic(config().jvmConstantInvokeDynamic);
+        // @formatter:on
+
+        private final int tag;
+
+        private static final int ExternalMax = config().jvmConstantExternalMax;
+        private static final int InternalMin = config().jvmConstantInternalMin;
+        private static final int InternalMax = config().jvmConstantInternalMax;
+
+        private JVM_CONSTANT(int tag) {
+            this.tag = tag;
+        }
+
+        private static HotSpotVMConfig config() {
+            return runtime().getConfig();
+        }
+
+        /**
+         * Maps JVM_CONSTANT tags to {@link JVM_CONSTANT} values. Using a separate class for lazy
+         * initialization.
+         */
+        static class TagValueMap {
+            private static final JVM_CONSTANT[] table = new JVM_CONSTANT[ExternalMax + 1 + (InternalMax - InternalMin) + 1];
+
+            static {
+                assert InternalMin > ExternalMax;
+                for (JVM_CONSTANT e : values()) {
+                    table[indexOf(e.tag)] = e;
+                }
+            }
+
+            private static int indexOf(int tag) {
+                if (tag >= InternalMin) {
+                    return tag - InternalMin + ExternalMax + 1;
+                } else {
+                    assert tag <= ExternalMax;
+                }
+                return tag;
+            }
+
+            static JVM_CONSTANT get(int tag) {
+                JVM_CONSTANT res = table[indexOf(tag)];
+                if (res != null) {
+                    return res;
+                }
+                throw new JVMCIError("Unknown JVM_CONSTANT tag %s", tag);
+            }
+        }
+
+        public static JVM_CONSTANT getEnum(int tag) {
+            return TagValueMap.get(tag);
+        }
+    }
+
+    private static class LookupTypeCacheElement {
+        int lastCpi = Integer.MIN_VALUE;
+        JavaType javaType;
+
+        public LookupTypeCacheElement(int lastCpi, JavaType javaType) {
+            super();
+            this.lastCpi = lastCpi;
+            this.javaType = javaType;
+        }
+    }
+
+    /**
+     * Reference to the C++ ConstantPool object.
+     */
+    private final long metaspaceConstantPool;
+    private volatile LookupTypeCacheElement lastLookupType;
+
+    /**
+     * Gets the JVMCI mirror from a HotSpot constant pool.The VM is responsible for ensuring that
+     * the ConstantPool is kept alive for the duration of this call and the
+     * {@link HotSpotJVMCIMetaAccessContext} keeps it alive after that.
+     *
+     * Called from the VM.
+     *
+     * @param metaspaceConstantPool a metaspace ConstantPool object
+     * @return the {@link HotSpotConstantPool} corresponding to {@code metaspaceConstantPool}
+     */
+    @SuppressWarnings("unused")
+    private static HotSpotConstantPool fromMetaspace(long metaspaceConstantPool) {
+        return new HotSpotConstantPool(metaspaceConstantPool);
+    }
+
+    private HotSpotConstantPool(long metaspaceConstantPool) {
+        this.metaspaceConstantPool = metaspaceConstantPool;
+    }
+
+    /**
+     * Gets the holder for this constant pool as {@link HotSpotResolvedObjectTypeImpl}.
+     *
+     * @return holder for this constant pool
+     */
+    private HotSpotResolvedObjectType getHolder() {
+        return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().constantPoolHolderOffset, false);
+    }
+
+    /**
+     * Converts a raw index from the bytecodes to a constant pool index by adding a
+     * {@link HotSpotVMConfig#constantPoolCpCacheIndexTag constant}.
+     *
+     * @param rawIndex index from the bytecode
+     * @param opcode bytecode to convert the index for
+     * @return constant pool index
+     */
+    private static int rawIndexToConstantPoolIndex(int rawIndex, int opcode) {
+        int index;
+        if (opcode == Bytecodes.INVOKEDYNAMIC) {
+            index = rawIndex;
+            // See: ConstantPool::is_invokedynamic_index
+            assert index < 0 : "not an invokedynamic constant pool index " + index;
+        } else {
+            assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE ||
+                            opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode;
+            index = rawIndex + runtime().getConfig().constantPoolCpCacheIndexTag;
+        }
+        return index;
+    }
+
+    /**
+     * Decode a constant pool cache index to a constant pool index.
+     *
+     * See {@code ConstantPool::decode_cpcache_index}.
+     *
+     * @param index constant pool cache index
+     * @return decoded index
+     */
+    private static int decodeConstantPoolCacheIndex(int index) {
+        if (isInvokedynamicIndex(index)) {
+            return decodeInvokedynamicIndex(index);
+        } else {
+            return index - runtime().getConfig().constantPoolCpCacheIndexTag;
+        }
+    }
+
+    /**
+     * See {@code ConstantPool::is_invokedynamic_index}.
+     */
+    private static boolean isInvokedynamicIndex(int index) {
+        return index < 0;
+    }
+
+    /**
+     * See {@code ConstantPool::decode_invokedynamic_index}.
+     */
+    private static int decodeInvokedynamicIndex(int i) {
+        assert isInvokedynamicIndex(i) : i;
+        return ~i;
+    }
+
+    public long getMetaspaceConstantPool() {
+        return metaspaceConstantPool;
+    }
+
+    public long getMetaspacePointer() {
+        return getMetaspaceConstantPool();
+    }
+
+    /**
+     * Gets the constant pool tag at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return constant pool tag
+     */
+    private JVM_CONSTANT getTagAt(int index) {
+        assertBounds(index);
+        HotSpotVMConfig config = runtime().getConfig();
+        final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset);
+        final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
+        if (tag == 0) {
+            return null;
+        }
+        return JVM_CONSTANT.getEnum(tag);
+    }
+
+    /**
+     * Gets the constant pool entry at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return constant pool entry
+     */
+    private long getEntryAt(int index) {
+        assertBounds(index);
+        return UNSAFE.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+    }
+
+    /**
+     * Gets the integer constant pool entry at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return integer constant pool entry at index
+     */
+    private int getIntAt(int index) {
+        assertTag(index, JVM_CONSTANT.Integer);
+        return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+    }
+
+    /**
+     * Gets the long constant pool entry at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return long constant pool entry
+     */
+    private long getLongAt(int index) {
+        assertTag(index, JVM_CONSTANT.Long);
+        return UNSAFE.getLong(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+    }
+
+    /**
+     * Gets the float constant pool entry at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return float constant pool entry
+     */
+    private float getFloatAt(int index) {
+        assertTag(index, JVM_CONSTANT.Float);
+        return UNSAFE.getFloat(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+    }
+
+    /**
+     * Gets the double constant pool entry at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return float constant pool entry
+     */
+    private double getDoubleAt(int index) {
+        assertTag(index, JVM_CONSTANT.Double);
+        return UNSAFE.getDouble(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+    }
+
+    /**
+     * Gets the {@code JVM_CONSTANT_NameAndType} constant pool entry at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return {@code JVM_CONSTANT_NameAndType} constant pool entry
+     */
+    private int getNameAndTypeAt(int index) {
+        assertTag(index, JVM_CONSTANT.NameAndType);
+        return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+    }
+
+    /**
+     * Gets the {@code JVM_CONSTANT_NameAndType} reference index constant pool entry at index
+     * {@code index}.
+     *
+     * @param index constant pool index
+     * @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry
+     */
+    private int getNameAndTypeRefIndexAt(int index) {
+        return runtime().getCompilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
+    }
+
+    /**
+     * Gets the name of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by another
+     * entry denoted by {@code which}.
+     *
+     * @param which constant pool index or constant pool cache index
+     * @return name as {@link String}
+     */
+    private String getNameOf(int which) {
+        return runtime().getCompilerToVM().lookupNameInPool(this, which);
+    }
+
+    /**
+     * Gets the name reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry at
+     * index {@code index}.
+     *
+     * @param index constant pool index
+     * @return name reference index
+     */
+    private int getNameRefIndexAt(int index) {
+        final int refIndex = getNameAndTypeAt(index);
+        // name ref index is in the low 16-bits.
+        return refIndex & 0xFFFF;
+    }
+
+    /**
+     * Gets the signature of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by
+     * another entry denoted by {@code which}.
+     *
+     * @param which constant pool index or constant pool cache index
+     * @return signature as {@link String}
+     */
+    private String getSignatureOf(int which) {
+        return runtime().getCompilerToVM().lookupSignatureInPool(this, which);
+    }
+
+    /**
+     * Gets the signature reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry
+     * at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return signature reference index
+     */
+    private int getSignatureRefIndexAt(int index) {
+        final int refIndex = getNameAndTypeAt(index);
+        // signature ref index is in the high 16-bits.
+        return refIndex >>> 16;
+    }
+
+    /**
+     * Gets the klass reference index constant pool entry at index {@code index}.
+     *
+     * @param index constant pool index
+     * @return klass reference index
+     */
+    private int getKlassRefIndexAt(int index) {
+        return runtime().getCompilerToVM().lookupKlassRefIndexInPool(this, index);
+    }
+
+    /**
+     * Gets the uncached klass reference index constant pool entry at index {@code index}. See:
+     * {@code ConstantPool::uncached_klass_ref_index_at}.
+     *
+     * @param index constant pool index
+     * @return klass reference index
+     */
+    private int getUncachedKlassRefIndexAt(int index, JVM_CONSTANT tag) {
+        int resultIndex;
+        if (tag == JVM_CONSTANT.MethodRef || tag == JVM_CONSTANT.Fieldref || tag == JVM_CONSTANT.InterfaceMethodref) {
+            assertTagIsFieldOrMethod(index);
+            final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+            // klass ref index is in the low 16-bits.
+            resultIndex = refIndex & 0xFFFF;
+        } else {
+            resultIndex = index;
+        }
+
+        // Read the tag only once because it could change between multiple reads.
+        final JVM_CONSTANT klassTag = getTagAt(resultIndex);
+        assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError : klassTag;
+
+        return resultIndex;
+    }
+
+    /**
+     * Asserts that the constant pool index {@code index} is in the bounds of the constant pool.
+     *
+     * @param index constant pool index
+     */
+    private void assertBounds(int index) {
+        assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
+    }
+
+    /**
+     * Asserts that the constant pool tag at index {@code index} is equal to {@code tag}.
+     *
+     * @param index constant pool index
+     * @param tag expected tag
+     */
+    private void assertTag(int index, JVM_CONSTANT tag) {
+        final JVM_CONSTANT tagAt = getTagAt(index);
+        assert tagAt == tag : "constant pool tag at index " + index + " is " + tagAt + " but expected " + tag;
+    }
+
+    /**
+     * Asserts that the constant pool tag at index {@code index} is a {@link JVM_CONSTANT#Fieldref},
+     * or a {@link JVM_CONSTANT#MethodRef}, or a {@link JVM_CONSTANT#InterfaceMethodref}.
+     *
+     * @param index constant pool index
+     */
+    private void assertTagIsFieldOrMethod(int index) {
+        final JVM_CONSTANT tagAt = getTagAt(index);
+        assert tagAt == JVM_CONSTANT.Fieldref || tagAt == JVM_CONSTANT.MethodRef || tagAt == JVM_CONSTANT.InterfaceMethodref : tagAt;
+    }
+
+    @Override
+    public int length() {
+        return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolLengthOffset);
+    }
+
+    @Override
+    public Object lookupConstant(int cpi) {
+        assert cpi != 0;
+        final JVM_CONSTANT tag = getTagAt(cpi);
+        switch (tag) {
+            case Integer:
+                return JavaConstant.forInt(getIntAt(cpi));
+            case Long:
+                return JavaConstant.forLong(getLongAt(cpi));
+            case Float:
+                return JavaConstant.forFloat(getFloatAt(cpi));
+            case Double:
+                return JavaConstant.forDouble(getDoubleAt(cpi));
+            case Class:
+            case UnresolvedClass:
+            case UnresolvedClassInError:
+                final int opcode = -1;  // opcode is not used
+                return lookupType(cpi, opcode);
+            case String:
+                /*
+                 * Normally, we would expect a String here, but anonymous classes can have
+                 * "pseudo strings" (arbitrary live objects) patched into a String entry. Such
+                 * entries do not have a symbol in the constant pool slot.
+                 */
+                Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
+                return HotSpotObjectConstantImpl.forObject(string);
+            case MethodHandle:
+            case MethodHandleInError:
+            case MethodType:
+            case MethodTypeInError:
+                Object obj = runtime().getCompilerToVM().resolveConstantInPool(this, cpi);
+                return HotSpotObjectConstantImpl.forObject(obj);
+            default:
+                throw new JVMCIError("Unknown constant pool tag %s", tag);
+        }
+    }
+
+    @Override
+    public String lookupUtf8(int cpi) {
+        assertTag(cpi, JVM_CONSTANT.Utf8);
+        return runtime().getCompilerToVM().getSymbol(getEntryAt(cpi));
+    }
+
+    @Override
+    public Signature lookupSignature(int cpi) {
+        return new HotSpotSignature(runtime(), lookupUtf8(cpi));
+    }
+
+    @Override
+    public JavaConstant lookupAppendix(int cpi, int opcode) {
+        assert Bytecodes.isInvoke(opcode);
+        final int index = rawIndexToConstantPoolIndex(cpi, opcode);
+        Object appendix = runtime().getCompilerToVM().lookupAppendixInPool(this, index);
+        if (appendix == null) {
+            return null;
+        } else {
+            return HotSpotObjectConstantImpl.forObject(appendix);
+        }
+    }
+
+    /**
+     * Gets a {@link JavaType} corresponding a given resolved or unresolved type.
+     *
+     * @param type either a ResolvedJavaType or a String naming a unresolved type.
+     */
+    private static JavaType getJavaType(final Object type) {
+        if (type instanceof String) {
+            String name = (String) type;
+            return HotSpotUnresolvedJavaType.create(runtime(), "L" + name + ";");
+        } else {
+            return (JavaType) type;
+        }
+    }
+
+    @Override
+    public JavaMethod lookupMethod(int cpi, int opcode) {
+        final int index = rawIndexToConstantPoolIndex(cpi, opcode);
+        final HotSpotResolvedJavaMethod method = runtime().getCompilerToVM().lookupMethodInPool(this, index, (byte) opcode);
+        if (method != null) {
+            return method;
+        } else {
+            // Get the method's name and signature.
+            String name = getNameOf(index);
+            HotSpotSignature signature = new HotSpotSignature(runtime(), getSignatureOf(index));
+            if (opcode == Bytecodes.INVOKEDYNAMIC) {
+                HotSpotResolvedObjectType holder = HotSpotResolvedObjectTypeImpl.fromObjectClass(MethodHandle.class);
+                return new HotSpotMethodUnresolved(name, signature, holder);
+            } else {
+                final int klassIndex = getKlassRefIndexAt(index);
+                final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, klassIndex);
+                JavaType holder = getJavaType(type);
+                return new HotSpotMethodUnresolved(name, signature, holder);
+            }
+        }
+    }
+
+    @Override
+    public JavaType lookupType(int cpi, int opcode) {
+        final LookupTypeCacheElement elem = this.lastLookupType;
+        if (elem != null && elem.lastCpi == cpi) {
+            return elem.javaType;
+        } else {
+            final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, cpi);
+            JavaType result = getJavaType(type);
+            if (result instanceof ResolvedJavaType) {
+                this.lastLookupType = new LookupTypeCacheElement(cpi, result);
+            }
+            return result;
+        }
+    }
+
+    @Override
+    public JavaField lookupField(int cpi, int opcode) {
+        final int index = rawIndexToConstantPoolIndex(cpi, opcode);
+        final int nameAndTypeIndex = getNameAndTypeRefIndexAt(index);
+        final int nameIndex = getNameRefIndexAt(nameAndTypeIndex);
+        String name = lookupUtf8(nameIndex);
+        final int typeIndex = getSignatureRefIndexAt(nameAndTypeIndex);
+        String typeName = lookupUtf8(typeIndex);
+        JavaType type = runtime().lookupType(typeName, getHolder(), false);
+
+        final int holderIndex = getKlassRefIndexAt(index);
+        JavaType holder = lookupType(holderIndex, opcode);
+
+        if (holder instanceof HotSpotResolvedObjectTypeImpl) {
+            long[] info = new long[2];
+            HotSpotResolvedObjectTypeImpl resolvedHolder;
+            try {
+                resolvedHolder = runtime().getCompilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
+            } catch (Throwable t) {
+                /*
+                 * If there was an exception resolving the field we give up and return an unresolved
+                 * field.
+                 */
+                return new HotSpotUnresolvedField(holder, name, type);
+            }
+            final int flags = (int) info[0];
+            final long offset = info[1];
+            HotSpotResolvedJavaField result = resolvedHolder.createField(name, type, offset, flags);
+            return result;
+        } else {
+            return new HotSpotUnresolvedField(holder, name, type);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("fallthrough")
+    public void loadReferencedType(int cpi, int opcode) {
+        int index;
+        switch (opcode) {
+            case Bytecodes.CHECKCAST:
+            case Bytecodes.INSTANCEOF:
+            case Bytecodes.NEW:
+            case Bytecodes.ANEWARRAY:
+            case Bytecodes.MULTIANEWARRAY:
+            case Bytecodes.LDC:
+            case Bytecodes.LDC_W:
+            case Bytecodes.LDC2_W:
+                index = cpi;
+                break;
+            case Bytecodes.INVOKEDYNAMIC: {
+                // invokedynamic instructions point to a constant pool cache entry.
+                index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag;
+                index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
+                break;
+            }
+            case Bytecodes.GETSTATIC:
+            case Bytecodes.PUTSTATIC:
+            case Bytecodes.GETFIELD:
+            case Bytecodes.PUTFIELD:
+            case Bytecodes.INVOKEVIRTUAL:
+            case Bytecodes.INVOKESPECIAL:
+            case Bytecodes.INVOKESTATIC:
+            case Bytecodes.INVOKEINTERFACE: {
+                // invoke and field instructions point to a constant pool cache entry.
+                index = rawIndexToConstantPoolIndex(cpi, opcode);
+                index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
+                break;
+            }
+            default:
+                throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode);
+        }
+
+        final JVM_CONSTANT tag = getTagAt(index);
+        if (tag == null) {
+            assert getTagAt(index - 1) == JVM_CONSTANT.Double || getTagAt(index - 1) == JVM_CONSTANT.Long;
+            return;
+        }
+        switch (tag) {
+            case MethodRef:
+            case Fieldref:
+            case InterfaceMethodref:
+            case Class:
+            case UnresolvedClass:
+            case UnresolvedClassInError:
+                index = getUncachedKlassRefIndexAt(index, tag);
+                final HotSpotResolvedObjectTypeImpl type = runtime().getCompilerToVM().resolveTypeInPool(this, index);
+                Class<?> klass = type.mirror();
+                if (!klass.isPrimitive() && !klass.isArray()) {
+                    UNSAFE.ensureClassInitialized(klass);
+                }
+                switch (tag) {
+                    case MethodRef:
+                        if (Bytecodes.isInvokeHandleAlias(opcode)) {
+                            final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode);
+                            if (isInvokeHandle(methodRefCacheIndex, type)) {
+                                runtime().getCompilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
+                            }
+                        }
+                }
+                break;
+            case InvokeDynamic:
+                if (isInvokedynamicIndex(cpi)) {
+                    runtime().getCompilerToVM().resolveInvokeDynamicInPool(this, cpi);
+                }
+                break;
+            default:
+                // nothing
+                break;
+        }
+    }
+
+    private boolean isInvokeHandle(int methodRefCacheIndex, HotSpotResolvedObjectTypeImpl klass) {
+        assertTag(runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
+        return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameOf(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess());
+    }
+
+    @Override
+    public String toString() {
+        HotSpotResolvedObjectType holder = getHolder();
+        return "HotSpotConstantPool<" + holder.toJavaName() + ">";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider.Options.*;
+
+import java.lang.reflect.*;
+
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.options.*;
+
+/**
+ * HotSpot implementation of {@link ConstantReflectionProvider}.
+ */
+public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider, HotSpotProxified {
+
+    static class Options {
+        //@formatter:off
+        @Option(help = "Constant fold final fields with default values.", type = OptionType.Debug)
+        public static final OptionValue<Boolean> TrustFinalDefaultFields = new OptionValue<>(true);
+        //@formatter:on
+    }
+
+    protected final HotSpotJVMCIRuntimeProvider runtime;
+    protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
+    protected final HotSpotMemoryAccessProviderImpl memoryAccess;
+
+    public HotSpotConstantReflectionProvider(HotSpotJVMCIRuntimeProvider runtime) {
+        this.runtime = runtime;
+        this.methodHandleAccess = new HotSpotMethodHandleAccessProvider(this);
+        this.memoryAccess = new HotSpotMemoryAccessProviderImpl(runtime);
+    }
+
+    public MethodHandleAccessProvider getMethodHandleAccess() {
+        return methodHandleAccess;
+    }
+
+    @Override
+    public MemoryAccessProvider getMemoryAccessProvider() {
+        return memoryAccess;
+    }
+
+    @Override
+    public boolean isEmbeddable(Constant constant) {
+        return true;
+    }
+
+    @Override
+    public Boolean constantEquals(Constant x, Constant y) {
+        if (x == y) {
+            return true;
+        } else if (x instanceof HotSpotObjectConstantImpl) {
+            return y instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) x).object() == ((HotSpotObjectConstantImpl) y).object();
+        } else {
+            return x.equals(y);
+        }
+    }
+
+    @Override
+    public Integer readArrayLength(JavaConstant array) {
+        if (array.getJavaKind() != JavaKind.Object || array.isNull()) {
+            return null;
+        }
+
+        Object arrayObject = ((HotSpotObjectConstantImpl) array).object();
+        if (!arrayObject.getClass().isArray()) {
+            return null;
+        }
+        return Array.getLength(arrayObject);
+    }
+
+    public JavaConstant readConstantArrayElement(JavaConstant array, int index) {
+        if (array instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) array).getStableDimension() > 0) {
+            JavaConstant element = readArrayElement(array, index);
+            if (element != null && (((HotSpotObjectConstantImpl) array).isDefaultStable() || !element.isDefaultForKind())) {
+                return element;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Try to convert {@code offset} into an an index into {@code array}.
+     *
+     * @return the computed index or -1 if the offset isn't within the array
+     */
+    private int indexForOffset(JavaConstant array, long offset) {
+        if (array.getJavaKind() != JavaKind.Object || array.isNull()) {
+            return -1;
+        }
+        Class<?> componentType = ((HotSpotObjectConstantImpl) array).object().getClass().getComponentType();
+        JavaKind kind = runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(componentType).getJavaKind();
+        int arraybase = runtime.getArrayBaseOffset(kind);
+        int scale = runtime.getArrayIndexScale(kind);
+        if (offset < arraybase) {
+            return -1;
+        }
+        long index = offset - arraybase;
+        if (index % scale != 0) {
+            return -1;
+        }
+        long result = index / scale;
+        if (result >= Integer.MAX_VALUE) {
+            return -1;
+        }
+        return (int) result;
+    }
+
+    public JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset) {
+        if (array instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) array).getStableDimension() > 0) {
+            return readConstantArrayElement(array, indexForOffset(array, offset));
+        }
+        return null;
+    }
+
+    @Override
+    public JavaConstant readArrayElement(JavaConstant array, int index) {
+        if (array.getJavaKind() != JavaKind.Object || array.isNull()) {
+            return null;
+        }
+        Object a = ((HotSpotObjectConstantImpl) array).object();
+
+        if (index < 0 || index >= Array.getLength(a)) {
+            return null;
+        }
+
+        if (a instanceof Object[]) {
+            Object element = ((Object[]) a)[index];
+            if (((HotSpotObjectConstantImpl) array).getStableDimension() > 1) {
+                return HotSpotObjectConstantImpl.forStableArray(element, ((HotSpotObjectConstantImpl) array).getStableDimension() - 1, ((HotSpotObjectConstantImpl) array).isDefaultStable());
+            } else {
+                return HotSpotObjectConstantImpl.forObject(element);
+            }
+        } else {
+            return JavaConstant.forBoxedPrimitive(Array.get(a, index));
+        }
+    }
+
+    /**
+     * Check if the constant is a boxed value that is guaranteed to be cached by the platform.
+     * Otherwise the generated code might be the only reference to the boxed value and since object
+     * references from nmethods are weak this can cause GC problems.
+     *
+     * @param source
+     * @return true if the box is cached
+     */
+    private static boolean isBoxCached(JavaConstant source) {
+        switch (source.getJavaKind()) {
+            case Boolean:
+                return true;
+            case Char:
+                return source.asInt() <= 127;
+            case Byte:
+            case Short:
+            case Int:
+                return source.asInt() >= -128 && source.asInt() <= 127;
+            case Long:
+                return source.asLong() >= -128 && source.asLong() <= 127;
+            case Float:
+            case Double:
+                return false;
+            default:
+                throw new IllegalArgumentException("unexpected kind " + source.getJavaKind());
+        }
+    }
+
+    @Override
+    public JavaConstant boxPrimitive(JavaConstant source) {
+        if (!source.getJavaKind().isPrimitive() || !isBoxCached(source)) {
+            return null;
+        }
+        return HotSpotObjectConstantImpl.forObject(source.asBoxedPrimitive());
+    }
+
+    @Override
+    public JavaConstant unboxPrimitive(JavaConstant source) {
+        if (!source.getJavaKind().isObject()) {
+            return null;
+        }
+        if (source.isNull()) {
+            return null;
+        }
+        return JavaConstant.forBoxedPrimitive(((HotSpotObjectConstantImpl) source).object());
+    }
+
+    public JavaConstant forString(String value) {
+        return HotSpotObjectConstantImpl.forObject(value);
+    }
+
+    @Override
+    public ResolvedJavaType asJavaType(Constant constant) {
+        if (constant instanceof HotSpotObjectConstant) {
+            Object obj = ((HotSpotObjectConstantImpl) constant).object();
+            if (obj instanceof Class) {
+                return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType((Class<?>) obj);
+            }
+        }
+        if (constant instanceof HotSpotMetaspaceConstant) {
+            Object obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant);
+            if (obj instanceof HotSpotResolvedObjectTypeImpl) {
+                return (ResolvedJavaType) obj;
+            }
+        }
+        return null;
+    }
+
+    private static final String SystemClassName = "Ljava/lang/System;";
+
+    /**
+     * Determines if a static field is constant for the purpose of
+     * {@link #readConstantFieldValue(JavaField, JavaConstant)}.
+     */
+    protected boolean isStaticFieldConstant(HotSpotResolvedJavaField staticField) {
+        if (staticField.isFinal() || staticField.isStable()) {
+            ResolvedJavaType holder = staticField.getDeclaringClass();
+            if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determines if a value read from a {@code final} instance field is considered constant. The
+     * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
+     * not the {@link JavaConstant#isDefaultForKind default value} for its kind or if
+     * {@link Options#TrustFinalDefaultFields} is true.
+     *
+     * @param value a value read from a {@code final} instance field
+     * @param receiverClass the {@link Object#getClass() class} of object from which the
+     *            {@code value} was read
+     */
+    protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
+        return !value.isDefaultForKind() || TrustFinalDefaultFields.getValue();
+    }
+
+    /**
+     * Determines if a value read from a {@link Stable} instance field is considered constant. The
+     * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
+     * not the {@link JavaConstant#isDefaultForKind default value} for its kind.
+     *
+     * @param value a value read from a {@link Stable} field
+     * @param receiverClass the {@link Object#getClass() class} of object from which the
+     *            {@code value} was read
+     */
+    protected boolean isStableInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
+        return !value.isDefaultForKind();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The {@code value} field in {@link OptionValue} is considered constant if the type of
+     * {@code receiver} is (assignable to) {@link StableOptionValue}.
+     */
+    public JavaConstant readConstantFieldValue(JavaField field, JavaConstant receiver) {
+        HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
+
+        if (hotspotField.isStatic()) {
+            if (isStaticFieldConstant(hotspotField)) {
+                JavaConstant value = readFieldValue(field, receiver);
+                if (hotspotField.isFinal() || !value.isDefaultForKind()) {
+                    return value;
+                }
+            }
+        } else {
+            /*
+             * for non-static final fields, we must assume that they are only initialized if they
+             * have a non-default value.
+             */
+            Object object = receiver.isNull() ? null : ((HotSpotObjectConstantImpl) receiver).object();
+
+            // Canonicalization may attempt to process an unsafe read before
+            // processing a guard (e.g. a null check or a type check) for this read
+            // so we need to check the object being read
+            if (object != null) {
+                if (hotspotField.isFinal()) {
+                    if (hotspotField.isInObject(object)) {
+                        JavaConstant value = readFieldValue(field, receiver);
+                        if (isFinalInstanceFieldValueConstant(value, object.getClass())) {
+                            return value;
+                        }
+                    }
+                } else if (hotspotField.isStable()) {
+                    if (hotspotField.isInObject(object)) {
+                        JavaConstant value = readFieldValue(field, receiver);
+                        if (isStableInstanceFieldValueConstant(value, object.getClass())) {
+                            return value;
+                        }
+                    }
+                } else {
+                    Class<?> clazz = object.getClass();
+                    if (StableOptionValue.class.isAssignableFrom(clazz)) {
+                        if (hotspotField.isInObject(object) && hotspotField.getName().equals("value")) {
+                            StableOptionValue<?> option = (StableOptionValue<?>) object;
+                            return HotSpotObjectConstantImpl.forObject(option.getValue());
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public JavaConstant readFieldValue(JavaField field, JavaConstant receiver) {
+        HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
+        if (!hotspotField.isStable()) {
+            return readNonStableFieldValue(field, receiver);
+        } else {
+            return readStableFieldValue(field, receiver, false);
+        }
+    }
+
+    private JavaConstant readNonStableFieldValue(JavaField field, JavaConstant receiver) {
+        HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
+        if (hotspotField.isStatic()) {
+            HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
+            if (holder.isInitialized()) {
+                return memoryAccess.readUnsafeConstant(hotspotField.getJavaKind(), HotSpotObjectConstantImpl.forObject(holder.mirror()), hotspotField.offset());
+            }
+        } else {
+            if (receiver.isNonNull() && hotspotField.isInObject(((HotSpotObjectConstantImpl) receiver).object())) {
+                return memoryAccess.readUnsafeConstant(hotspotField.getJavaKind(), receiver, hotspotField.offset());
+            }
+        }
+        return null;
+    }
+
+    public JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable) {
+        JavaConstant fieldValue = readNonStableFieldValue(field, receiver);
+        if (fieldValue.isNonNull()) {
+            JavaType declaredType = field.getType();
+            if (declaredType.getComponentType() != null) {
+                int stableDimension = getArrayDimension(declaredType);
+                return HotSpotObjectConstantImpl.forStableArray(((HotSpotObjectConstantImpl) fieldValue).object(), stableDimension, isDefaultStable);
+            }
+        }
+        return fieldValue;
+    }
+
+    private static int getArrayDimension(JavaType type) {
+        int dimensions = 0;
+        JavaType componentType = type;
+        while ((componentType = componentType.getComponentType()) != null) {
+            dimensions++;
+        }
+        return dimensions;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotForeignCallTarget.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+public class HotSpotForeignCallTarget {
+
+    /**
+     * The entry point address of this call's target.
+     */
+    protected long address;
+
+    public HotSpotForeignCallTarget(long address) {
+        this.address = address;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.inittimer.SuppressFBWarnings;
+import sun.misc.Unsafe;
+
+/**
+ * Implementation of {@link InstalledCode} for HotSpot.
+ */
+public abstract class HotSpotInstalledCode extends InstalledCode {
+
+    /**
+     * Total size of the code blob.
+     */
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int size;
+
+    /**
+     * Start address of the code.
+     */
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private long codeStart;
+
+    /**
+     * Size of the code.
+     */
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int codeSize;
+
+    public HotSpotInstalledCode(String name) {
+        super(name);
+    }
+
+    /**
+     * @return the total size of this code blob
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * @return a copy of this code blob if it is {@linkplain #isValid() valid}, null otherwise.
+     */
+    public byte[] getBlob() {
+        if (!isValid()) {
+            return null;
+        }
+        byte[] blob = new byte[size];
+        UNSAFE.copyMemory(null, getAddress(), blob, Unsafe.ARRAY_BYTE_BASE_OFFSET, size);
+        return blob;
+    }
+
+    @Override
+    public abstract String toString();
+
+    @Override
+    public long getStart() {
+        return codeStart;
+    }
+
+    @Override
+    public long getCodeSize() {
+        return codeSize;
+    }
+
+    @Override
+    public byte[] getCode() {
+        if (!isValid()) {
+            return null;
+        }
+        byte[] code = new byte[codeSize];
+        UNSAFE.copyMemory(null, codeStart, code, Unsafe.ARRAY_BYTE_BASE_OFFSET, codeSize);
+        return code;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.compiler.*;
+import jdk.vm.ci.runtime.*;
+
+public interface HotSpotJVMCIBackendFactory {
+
+    JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host);
+
+    /**
+     * Gets the CPU architecture of this backend.
+     */
+    String getArchitecture();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.compiler.*;
+import jdk.vm.ci.compiler.Compiler;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+import jdk.vm.ci.service.*;
+
+final class HotSpotJVMCICompilerConfig {
+
+    private static class DummyCompilerFactory implements CompilerFactory, Compiler {
+
+        public void compileMethod(ResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
+            throw new JVMCIError("no JVMCI compiler selected");
+        }
+
+        public String getCompilerName() {
+            return "<none>";
+        }
+
+        public Architecture initializeArchitecture(Architecture arch) {
+            return arch;
+        }
+
+        public Compiler createCompiler(JVMCIRuntime runtime) {
+            return this;
+        }
+    }
+
+    private static CompilerFactory compilerFactory;
+
+    /**
+     * Selects the system compiler.
+     *
+     * Called from VM. This method has an object return type to allow it to be called with a VM
+     * utility function used to call other static initialization methods.
+     */
+    static Boolean selectCompiler(String compilerName) {
+        assert compilerFactory == null;
+        for (CompilerFactory factory : Services.load(CompilerFactory.class)) {
+            if (factory.getCompilerName().equals(compilerName)) {
+                compilerFactory = factory;
+                return Boolean.TRUE;
+            }
+        }
+
+        throw new JVMCIError("JVMCI compiler '%s' not found", compilerName);
+    }
+
+    static CompilerFactory getCompilerFactory() {
+        if (compilerFactory == null) {
+            compilerFactory = new DummyCompilerFactory();
+        }
+        return compilerFactory;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+import java.lang.ref.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * This class manages the set of metadata roots that must be scanned during garbage collection.
+ * Because of class redefinition Method* and ConstantPool* can be freed if they don't appear to be
+ * in use so they must be tracked when there are live references to them from Java.
+ *
+ * The general theory of operation is that all {@link MetaspaceWrapperObject}s are created by
+ * calling into the VM which calls back out to actually create the wrapper instance. During the call
+ * the VM keeps the metadata reference alive through the use of metadata handles. Once the call
+ * completes the wrapper object is registered here and will be scanned during metadata scanning. The
+ * weakness of the reference to the wrapper object allows them to be reclaimed when they are no
+ * longer used.
+ *
+ */
+public class HotSpotJVMCIMetaAccessContext implements JVMCIMetaAccessContext {
+
+    /**
+     * The set of currently live contexts used for tracking of live metadata. Examined from the VM
+     * during garbage collection.
+     */
+    private static WeakReference<?>[] allContexts = new WeakReference<?>[0];
+
+    /**
+     * This is a chunked list of metadata roots. It can be read from VM native code so it's been
+     * marked volatile to ensure the order of updates are respected.
+     */
+    private volatile Object[] metadataRoots;
+
+    private ChunkedList<WeakReference<MetaspaceWrapperObject>> list = new ChunkedList<>();
+
+    /**
+     * The number of weak references freed since the last time the list was shrunk.
+     */
+    private int freed;
+
+    /**
+     * The {@link ReferenceQueue} tracking the weak references created by this context.
+     */
+    private final ReferenceQueue<MetaspaceWrapperObject> queue = new ReferenceQueue<>();
+
+    static synchronized void add(HotSpotJVMCIMetaAccessContext context) {
+        for (int i = 0; i < allContexts.length; i++) {
+            if (allContexts[i] == null || allContexts[i].get() == null) {
+                allContexts[i] = new WeakReference<>(context);
+                return;
+            }
+        }
+        int index = allContexts.length;
+        allContexts = Arrays.copyOf(allContexts, index + 2);
+        allContexts[index] = new WeakReference<>(context);
+    }
+
+    HotSpotJVMCIMetaAccessContext() {
+        add(this);
+    }
+
+    /**
+     * Periodically trim the list of tracked metadata. A new list is created to replace the old to
+     * avoid concurrent scanning issues.
+     */
+    private void clean() {
+        Reference<?> ref = queue.poll();
+        if (ref == null) {
+            return;
+        }
+        while (ref != null) {
+            freed++;
+            ref = queue.poll();
+        }
+        if (freed > list.size() / 2) {
+            ChunkedList<WeakReference<MetaspaceWrapperObject>> newList = new ChunkedList<>();
+            for (WeakReference<MetaspaceWrapperObject> element : list) {
+                /*
+                 * The referent could become null anywhere in here but it doesn't matter. It will
+                 * get cleaned up next time.
+                 */
+                if (element != null && element.get() != null) {
+                    newList.add(element);
+                }
+            }
+            list = newList;
+            metadataRoots = list.getHead();
+            freed = 0;
+        }
+    }
+
+    /**
+     * Add a {@link MetaspaceWrapperObject} to tracked by the GC. It's assumed that the caller is
+     * responsible for keeping the reference alive for the duration of the call. Once registration
+     * is complete then the VM will ensure it's kept alive.
+     *
+     * @param metaspaceObject
+     */
+
+    public synchronized void add(MetaspaceWrapperObject metaspaceObject) {
+        clean();
+        list.add(new WeakReference<>(metaspaceObject, queue));
+        if (list.getHead() != metadataRoots) {
+            /*
+             * The list enlarged so update the head.
+             */
+            metadataRoots = list.getHead();
+        }
+    }
+
+    protected ResolvedJavaType createClass(Class<?> javaClass) {
+        if (javaClass.isPrimitive()) {
+            JavaKind kind = JavaKind.fromJavaClass(javaClass);
+            return new HotSpotResolvedPrimitiveType(kind);
+        } else {
+            return new HotSpotResolvedObjectTypeImpl(javaClass, this);
+        }
+    }
+
+    private final Map<Class<?>, WeakReference<ResolvedJavaType>> typeMap = new WeakHashMap<>();
+
+    @Override
+    public synchronized ResolvedJavaType fromClass(Class<?> javaClass) {
+        WeakReference<ResolvedJavaType> typeRef = typeMap.get(javaClass);
+        ResolvedJavaType type = typeRef != null ? typeRef.get() : null;
+        if (type == null) {
+            type = createClass(javaClass);
+            typeMap.put(javaClass, new WeakReference<>(type));
+        }
+        return type;
+    }
+
+    /**
+     * A very simple append only chunked list implementation.
+     */
+    static class ChunkedList<T> implements Iterable<T> {
+        private static final int CHUNK_SIZE = 32;
+
+        private static final int NEXT_CHUNK_INDEX = CHUNK_SIZE - 1;
+
+        private Object[] head;
+        private int index;
+        private int size;
+
+        ChunkedList() {
+            head = new Object[CHUNK_SIZE];
+            index = 0;
+        }
+
+        void add(T element) {
+            if (index == NEXT_CHUNK_INDEX) {
+                Object[] newHead = new Object[CHUNK_SIZE];
+                newHead[index] = head;
+                head = newHead;
+                index = 0;
+            }
+            head[index++] = element;
+            size++;
+        }
+
+        Object[] getHead() {
+            return head;
+        }
+
+        public Iterator<T> iterator() {
+            return new ChunkIterator<>();
+        }
+
+        int size() {
+            return size;
+        }
+
+        class ChunkIterator<V> implements Iterator<V> {
+
+            ChunkIterator() {
+                currentChunk = head;
+                currentIndex = -1;
+                findNext();
+            }
+
+            Object[] currentChunk;
+            int currentIndex;
+            V next;
+
+            @SuppressWarnings("unchecked")
+            V findNext() {
+                V result;
+                do {
+                    currentIndex++;
+                    if (currentIndex == NEXT_CHUNK_INDEX) {
+                        currentChunk = (Object[]) currentChunk[currentIndex];
+                        currentIndex = 0;
+                        if (currentChunk == null) {
+                            return null;
+                        }
+                    }
+                    result = (V) currentChunk[currentIndex];
+                } while (result == null);
+                return result;
+            }
+
+            public boolean hasNext() {
+                return next != null;
+            }
+
+            public V next() {
+                V result = next;
+                next = findNext();
+                return result;
+            }
+
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.inittimer.InitTimer.*;
+
+import java.util.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.compiler.*;
+import jdk.vm.ci.compiler.Compiler;
+import jdk.vm.ci.inittimer.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+import jdk.vm.ci.service.*;
+
+//JaCoCo Exclude
+
+public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
+
+    /**
+     * The proper initialization of this class is complex because it's tangled up with the
+     * initialization of the JVMCI and really should only ever be triggered through
+     * {@link JVMCI#getRuntime}. However since {@link #runtime} can also be called directly it
+     * should also trigger proper initialization. To ensure proper ordering, the static initializer
+     * of this class initializes {@link JVMCI} and then access to {@link DelayedInit#instance}
+     * triggers the final initialization of the {@link HotSpotJVMCIRuntime}.
+     */
+    static {
+        JVMCI.initialize();
+    }
+
+    @SuppressWarnings("try")
+    static class DelayedInit {
+        private static final HotSpotJVMCIRuntime instance;
+
+        static {
+            try (InitTimer t0 = timer("HotSpotJVMCIRuntime.<clinit>")) {
+                try (InitTimer t = timer("StartupEventListener.beforeJVMCIStartup")) {
+                    for (StartupEventListener l : Services.load(StartupEventListener.class)) {
+                        l.beforeJVMCIStartup();
+                    }
+                }
+
+                try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
+                    instance = new HotSpotJVMCIRuntime();
+                }
+
+                try (InitTimer t = timer("HotSpotJVMCIRuntime.completeInitialization")) {
+                    instance.completeInitialization();
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the singleton {@link HotSpotJVMCIRuntime} object.
+     */
+    public static HotSpotJVMCIRuntime runtime() {
+        assert DelayedInit.instance != null;
+        return DelayedInit.instance;
+    }
+
+    /**
+     * Do deferred initialization.
+     */
+    public void completeInitialization() {
+        compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
+        for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
+            vmEventListener.completeInitialization(this);
+        }
+    }
+
+    public static HotSpotJVMCIBackendFactory findFactory(String architecture) {
+        for (HotSpotJVMCIBackendFactory factory : Services.load(HotSpotJVMCIBackendFactory.class)) {
+            if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
+                return factory;
+            }
+        }
+
+        throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture);
+    }
+
+    /**
+     * Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend.
+     */
+    public static JavaKind getHostWordKind() {
+        return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordKind;
+    }
+
+    protected final CompilerToVM compilerToVm;
+
+    protected final HotSpotVMConfig config;
+    private final JVMCIBackend hostBackend;
+
+    private Compiler compiler;
+    protected final JVMCIMetaAccessContext metaAccessContext;
+
+    private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
+
+    private final Iterable<HotSpotVMEventListener> vmEventListeners;
+
+    @SuppressWarnings("try")
+    private HotSpotJVMCIRuntime() {
+        compilerToVm = new CompilerToVM();
+        try (InitTimer t = timer("HotSpotVMConfig<init>")) {
+            config = new HotSpotVMConfig(compilerToVm);
+        }
+
+        String hostArchitecture = config.getHostArchitectureName();
+
+        HotSpotJVMCIBackendFactory factory;
+        try (InitTimer t = timer("find factory:", hostArchitecture)) {
+            factory = findFactory(hostArchitecture);
+        }
+
+        CompilerFactory compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
+
+        try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) {
+            hostBackend = registerBackend(factory.createJVMCIBackend(this, compilerFactory, null));
+        }
+
+        vmEventListeners = Services.load(HotSpotVMEventListener.class);
+
+        JVMCIMetaAccessContext context = null;
+        for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
+            context = vmEventListener.createMetaAccessContext(this);
+            if (context != null) {
+                break;
+            }
+        }
+        if (context == null) {
+            context = new HotSpotJVMCIMetaAccessContext();
+        }
+        metaAccessContext = context;
+    }
+
+    private JVMCIBackend registerBackend(JVMCIBackend backend) {
+        Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
+        JVMCIBackend oldValue = backends.put(arch, backend);
+        assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName();
+        return backend;
+    }
+
+    public ResolvedJavaType fromClass(Class<?> javaClass) {
+        return metaAccessContext.fromClass(javaClass);
+    }
+
+    public HotSpotVMConfig getConfig() {
+        return config;
+    }
+
+    public CompilerToVM getCompilerToVM() {
+        return compilerToVm;
+    }
+
+    public JVMCIMetaAccessContext getMetaAccessContext() {
+        return metaAccessContext;
+    }
+
+    public Compiler getCompiler() {
+        return compiler;
+    }
+
+    public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) {
+        Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class");
+        // If the name represents a primitive type we can short-circuit the lookup.
+        if (name.length() == 1) {
+            JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
+            return fromClass(kind.toJavaClass());
+        }
+
+        // Resolve non-primitive types in the VM.
+        HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType;
+        final HotSpotResolvedObjectTypeImpl klass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve);
+
+        if (klass == null) {
+            assert resolve == false;
+            return HotSpotUnresolvedJavaType.create(this, name);
+        }
+        return klass;
+    }
+
+    public JVMCIBackend getHostJVMCIBackend() {
+        return hostBackend;
+    }
+
+    public <T extends Architecture> JVMCIBackend getJVMCIBackend(Class<T> arch) {
+        assert arch != Architecture.class;
+        return backends.get(arch);
+    }
+
+    public Map<Class<? extends Architecture>, JVMCIBackend> getBackends() {
+        return Collections.unmodifiableMap(backends);
+    }
+
+    /**
+     * Called from the VM.
+     */
+    @SuppressWarnings({"unused"})
+    private void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
+        compiler.compileMethod(method, entryBCI, jvmciEnv, id);
+    }
+
+    /**
+     * Shuts down the runtime.
+     *
+     * Called from the VM.
+     */
+    @SuppressWarnings({"unused"})
+    private void shutdown() throws Exception {
+        for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
+            vmEventListener.notifyShutdown();
+        }
+    }
+
+    /**
+     * Notify on successful install into the CodeCache.
+     *
+     * @param hotSpotCodeCacheProvider
+     * @param installedCode
+     * @param compResult
+     */
+    void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompilationResult compResult) {
+        for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
+            vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compResult);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntimeProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.compiler.Compiler;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+import sun.misc.*;
+
+//JaCoCo Exclude
+
+/**
+ * Configuration information for the HotSpot JVMCI runtime.
+ */
+public interface HotSpotJVMCIRuntimeProvider extends JVMCIRuntime {
+
+    HotSpotVMConfig getConfig();
+
+    CompilerToVM getCompilerToVM();
+
+    Compiler getCompiler();
+
+    /**
+     * Converts a name to a Java type. This method attempts to resolve {@code name} to a
+     * {@link ResolvedJavaType}.
+     *
+     * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
+     * @param accessingType the context of resolution which must be non-null
+     * @param resolve specifies whether resolution failure results in an unresolved type being
+     *            return or a {@link LinkageError} being thrown
+     * @return a Java type for {@code name} which is guaranteed to be of type
+     *         {@link ResolvedJavaType} if {@code resolve == true}
+     * @throws LinkageError if {@code resolve == true} and the resolution failed
+     * @throws NullPointerException if {@code accessingClass} is {@code null}
+     */
+    JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve);
+
+    /**
+     * Gets the JVMCI mirror for a {@link Class} object.
+     *
+     * @return the {@link ResolvedJavaType} corresponding to {@code javaClass}
+     */
+    ResolvedJavaType fromClass(Class<?> clazz);
+
+    JVMCIMetaAccessContext getMetaAccessContext();
+
+    /**
+     * The offset from the origin of an array to the first element.
+     *
+     * @return the offset in bytes
+     */
+    default int getArrayBaseOffset(JavaKind kind) {
+        switch (kind) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_BASE_OFFSET;
+            case Char:
+                return Unsafe.ARRAY_CHAR_BASE_OFFSET;
+            case Short:
+                return Unsafe.ARRAY_SHORT_BASE_OFFSET;
+            case Int:
+                return Unsafe.ARRAY_INT_BASE_OFFSET;
+            case Long:
+                return Unsafe.ARRAY_LONG_BASE_OFFSET;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+            default:
+                throw new JVMCIError("%s", kind);
+        }
+    }
+
+    /**
+     * The scale used for the index when accessing elements of an array of this kind.
+     *
+     * @return the scale in order to convert the index into a byte offset
+     */
+    default int getArrayIndexScale(JavaKind kind) {
+        switch (kind) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_INDEX_SCALE;
+            case Char:
+                return Unsafe.ARRAY_CHAR_INDEX_SCALE;
+            case Short:
+                return Unsafe.ARRAY_SHORT_INDEX_SCALE;
+            case Int:
+                return Unsafe.ARRAY_INT_INDEX_SCALE;
+            case Long:
+                return Unsafe.ARRAY_LONG_INDEX_SCALE;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+            default:
+                throw new JVMCIError("%s", kind);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJavaType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Common base class for all HotSpot {@link JavaType} implementations.
+ */
+public abstract class HotSpotJavaType implements JavaType {
+
+    private final String name;
+
+    public HotSpotJavaType(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public final String getName() {
+        return name;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * HotSpot specific extension of {@link MemoryAccessProvider}.
+ */
+public interface HotSpotMemoryAccessProvider extends MemoryAccessProvider {
+
+    JavaConstant readNarrowOopConstant(Constant base, long displacement, CompressEncoding encoding);
+
+    Constant readKlassPointerConstant(Constant base, long displacement);
+
+    Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding);
+
+    Constant readMethodPointerConstant(Constant base, long displacement);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.PrimitiveConstant;
+
+/**
+ * HotSpot implementation of {@link MemoryAccessProvider}.
+ */
+public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
+
+    protected final HotSpotJVMCIRuntimeProvider runtime;
+
+    public HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntimeProvider runtime) {
+        this.runtime = runtime;
+    }
+
+    private static Object asObject(Constant base) {
+        if (base instanceof HotSpotObjectConstantImpl) {
+            return ((HotSpotObjectConstantImpl) base).object();
+        } else {
+            return null;
+        }
+    }
+
+    private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
+        if (base instanceof HotSpotMetaspaceConstant) {
+            Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
+            if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
+                if (displacement == runtime.getConfig().classMirrorOffset) {
+                    // Klass::_java_mirror is valid for all Klass* values
+                    return true;
+                }
+            } else {
+                throw new JVMCIError("%s", metaspaceObject);
+            }
+        }
+        return false;
+    }
+
+    private static long asRawPointer(Constant base) {
+        if (base instanceof HotSpotMetaspaceConstant) {
+            return ((HotSpotMetaspaceConstant) base).rawValue();
+        } else if (base instanceof PrimitiveConstant) {
+            PrimitiveConstant prim = (PrimitiveConstant) base;
+            if (prim.getJavaKind().isNumericInteger()) {
+                return prim.asLong();
+            }
+        }
+        throw new JVMCIError("%s", base);
+    }
+
+    private static long readRawValue(Constant baseConstant, long displacement, int bits) {
+        Object base = asObject(baseConstant);
+        if (base != null) {
+            switch (bits) {
+                case 8:
+                    return UNSAFE.getByte(base, displacement);
+                case 16:
+                    return UNSAFE.getShort(base, displacement);
+                case 32:
+                    return UNSAFE.getInt(base, displacement);
+                case 64:
+                    return UNSAFE.getLong(base, displacement);
+                default:
+                    throw new JVMCIError("%d", bits);
+            }
+        } else {
+            long pointer = asRawPointer(baseConstant);
+            switch (bits) {
+                case 8:
+                    return UNSAFE.getByte(pointer + displacement);
+                case 16:
+                    return UNSAFE.getShort(pointer + displacement);
+                case 32:
+                    return UNSAFE.getInt(pointer + displacement);
+                case 64:
+                    return UNSAFE.getLong(pointer + displacement);
+                default:
+                    throw new JVMCIError("%d", bits);
+            }
+        }
+    }
+
+    private boolean verifyReadRawObject(Object expected, Constant base, long displacement, boolean compressed) {
+        if (compressed == runtime.getConfig().useCompressedOops) {
+            Object obj = asObject(base);
+            if (obj != null) {
+                assert expected == UNSAFE.getObject(obj, displacement) : "readUnsafeOop doesn't agree with unsafe.getObject";
+            }
+        }
+        if (base instanceof HotSpotMetaspaceConstant) {
+            Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
+            if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
+                if (displacement == runtime.getConfig().classMirrorOffset) {
+                    assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
+                }
+            }
+        }
+        return true;
+    }
+
+    private Object readRawObject(Constant baseConstant, long initialDisplacement, boolean compressed) {
+        long displacement = initialDisplacement;
+
+        Object ret;
+        Object base = asObject(baseConstant);
+        if (base == null) {
+            assert !compressed;
+            displacement += asRawPointer(baseConstant);
+            ret = runtime.getCompilerToVM().readUncompressedOop(displacement);
+        } else {
+            assert runtime.getConfig().useCompressedOops == compressed;
+            ret = UNSAFE.getObject(base, displacement);
+        }
+        assert verifyReadRawObject(ret, baseConstant, initialDisplacement, compressed);
+        return ret;
+    }
+
+    @Override
+    public JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant baseConstant, long displacement) {
+        if (kind == JavaKind.Object) {
+            Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops);
+            return HotSpotObjectConstantImpl.forObject(o);
+        } else {
+            return readPrimitiveConstant(kind, baseConstant, displacement, kind.getByteCount() * 8);
+        }
+    }
+
+    @Override
+    public JavaConstant readPrimitiveConstant(JavaKind kind, Constant baseConstant, long initialDisplacement, int bits) {
+        try {
+            long rawValue = readRawValue(baseConstant, initialDisplacement, bits);
+            switch (kind) {
+                case Boolean:
+                    return JavaConstant.forBoolean(rawValue != 0);
+                case Byte:
+                    return JavaConstant.forByte((byte) rawValue);
+                case Char:
+                    return JavaConstant.forChar((char) rawValue);
+                case Short:
+                    return JavaConstant.forShort((short) rawValue);
+                case Int:
+                    return JavaConstant.forInt((int) rawValue);
+                case Long:
+                    return JavaConstant.forLong(rawValue);
+                case Float:
+                    return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue));
+                case Double:
+                    return JavaConstant.forDouble(Double.longBitsToDouble(rawValue));
+                default:
+                    throw new JVMCIError("Unsupported kind: %s", kind);
+            }
+        } catch (NullPointerException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public JavaConstant readObjectConstant(Constant base, long displacement) {
+        if (!isValidObjectFieldDisplacement(base, displacement)) {
+            return null;
+        }
+        return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false));
+    }
+
+    @Override
+    public JavaConstant readNarrowOopConstant(Constant base, long displacement, CompressEncoding encoding) {
+        assert encoding.equals(runtime.getConfig().getOopEncoding()) : "unexpected oop encoding: " + encoding + " != " + runtime.getConfig().getOopEncoding();
+        return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
+    }
+
+    private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) {
+        assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass();
+        Object baseObject = (base instanceof HotSpotMetaspaceConstantImpl) ? ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType() : ((HotSpotObjectConstantImpl) base).object();
+        return runtime.getCompilerToVM().getResolvedJavaType(baseObject, displacement, compressed);
+    }
+
+    @Override
+    public Constant readKlassPointerConstant(Constant base, long displacement) {
+        HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false);
+        if (klass == null) {
+            return JavaConstant.NULL_POINTER;
+        }
+        TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, klass.getMetaspaceKlass(), klass, false);
+    }
+
+    @Override
+    public Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding) {
+        HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, true);
+        if (klass == null) {
+            return HotSpotCompressedNullConstant.COMPRESSED_NULL;
+        }
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Int, encoding.compress(klass.getMetaspaceKlass()), klass, true);
+    }
+
+    @Override
+    public Constant readMethodPointerConstant(Constant base, long displacement) {
+        TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
+        assert (base instanceof HotSpotObjectConstantImpl);
+        Object baseObject = ((HotSpotObjectConstantImpl) base).object();
+        HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, method.getMetaspaceMethod(), method, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import java.lang.reflect.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+
+// JaCoCo Exclude
+
+/**
+ * HotSpot implementation of {@link MetaAccessProvider}.
+ */
+public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotProxified {
+
+    protected final HotSpotJVMCIRuntimeProvider runtime;
+
+    public HotSpotMetaAccessProvider(HotSpotJVMCIRuntimeProvider runtime) {
+        this.runtime = runtime;
+    }
+
+    public ResolvedJavaType lookupJavaType(Class<?> clazz) {
+        if (clazz == null) {
+            throw new IllegalArgumentException("Class parameter was null");
+        }
+        return runtime.fromClass(clazz);
+    }
+
+    public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) {
+        if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) {
+            return null;
+        }
+        return ((HotSpotObjectConstant) constant).getType();
+    }
+
+    public Signature parseMethodDescriptor(String signature) {
+        return new HotSpotSignature(runtime, signature);
+    }
+
+    /**
+     * {@link Field} object of {@link Method#slot}.
+     */
+    private Field reflectionMethodSlot = getReflectionSlotField(Method.class);
+
+    /**
+     * {@link Field} object of {@link Constructor#slot}.
+     */
+    private Field reflectionConstructorSlot = getReflectionSlotField(Constructor.class);
+
+    private static Field getReflectionSlotField(Class<?> reflectionClass) {
+        try {
+            Field field = reflectionClass.getDeclaredField("slot");
+            field.setAccessible(true);
+            return field;
+        } catch (NoSuchFieldException | SecurityException e) {
+            throw new JVMCIError(e);
+        }
+    }
+
+    public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) {
+        try {
+            Class<?> holder = reflectionMethod.getDeclaringClass();
+            Field slotField = reflectionMethod instanceof Constructor ? reflectionConstructorSlot : reflectionMethodSlot;
+            final int slot = slotField.getInt(reflectionMethod);
+            return runtime.getCompilerToVM().getResolvedJavaMethodAtSlot(holder, slot);
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new JVMCIError(e);
+        }
+    }
+
+    public ResolvedJavaField lookupJavaField(Field reflectionField) {
+        String name = reflectionField.getName();
+        Class<?> fieldHolder = reflectionField.getDeclaringClass();
+        Class<?> fieldType = reflectionField.getType();
+        // java.lang.reflect.Field's modifiers should be enough here since VM internal modifier bits
+        // are not used (yet).
+        final int modifiers = reflectionField.getModifiers();
+        final long offset = Modifier.isStatic(modifiers) ? UNSAFE.staticFieldOffset(reflectionField) : UNSAFE.objectFieldOffset(reflectionField);
+
+        HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder);
+        JavaType type = runtime.fromClass(fieldType);
+
+        if (offset != -1) {
+            HotSpotResolvedObjectType resolved = holder;
+            return resolved.createField(name, type, offset, modifiers);
+        } else {
+            throw new JVMCIError("unresolved field %s", reflectionField);
+        }
+    }
+
+    private static int intMaskRight(int n) {
+        assert n <= 32;
+        return n == 32 ? -1 : (1 << n) - 1;
+    }
+
+    @Override
+    public JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId) {
+        HotSpotVMConfig config = runtime.getConfig();
+        int actionValue = convertDeoptAction(action);
+        int reasonValue = convertDeoptReason(reason);
+        int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits);
+        JavaConstant c = JavaConstant.forInt(~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift)));
+        assert c.asInt() < 0;
+        return c;
+    }
+
+    public DeoptimizationReason decodeDeoptReason(JavaConstant constant) {
+        HotSpotVMConfig config = runtime.getConfig();
+        int reasonValue = ((~constant.asInt()) >> config.deoptimizationReasonShift) & intMaskRight(config.deoptimizationReasonBits);
+        DeoptimizationReason reason = convertDeoptReason(reasonValue);
+        return reason;
+    }
+
+    public DeoptimizationAction decodeDeoptAction(JavaConstant constant) {
+        HotSpotVMConfig config = runtime.getConfig();
+        int actionValue = ((~constant.asInt()) >> config.deoptimizationActionShift) & intMaskRight(config.deoptimizationActionBits);
+        DeoptimizationAction action = convertDeoptAction(actionValue);
+        return action;
+    }
+
+    public int decodeDebugId(JavaConstant constant) {
+        HotSpotVMConfig config = runtime.getConfig();
+        return ((~constant.asInt()) >> config.deoptimizationDebugIdShift) & intMaskRight(config.deoptimizationDebugIdBits);
+    }
+
+    public int convertDeoptAction(DeoptimizationAction action) {
+        HotSpotVMConfig config = runtime.getConfig();
+        switch (action) {
+            case None:
+                return config.deoptActionNone;
+            case RecompileIfTooManyDeopts:
+                return config.deoptActionMaybeRecompile;
+            case InvalidateReprofile:
+                return config.deoptActionReinterpret;
+            case InvalidateRecompile:
+                return config.deoptActionMakeNotEntrant;
+            case InvalidateStopCompiling:
+                return config.deoptActionMakeNotCompilable;
+            default:
+                throw new JVMCIError("%s", action);
+        }
+    }
+
+    public DeoptimizationAction convertDeoptAction(int action) {
+        HotSpotVMConfig config = runtime.getConfig();
+        if (action == config.deoptActionNone) {
+            return DeoptimizationAction.None;
+        }
+        if (action == config.deoptActionMaybeRecompile) {
+            return DeoptimizationAction.RecompileIfTooManyDeopts;
+        }
+        if (action == config.deoptActionReinterpret) {
+            return DeoptimizationAction.InvalidateReprofile;
+        }
+        if (action == config.deoptActionMakeNotEntrant) {
+            return DeoptimizationAction.InvalidateRecompile;
+        }
+        if (action == config.deoptActionMakeNotCompilable) {
+            return DeoptimizationAction.InvalidateStopCompiling;
+        }
+        throw new JVMCIError("%d", action);
+    }
+
+    public int convertDeoptReason(DeoptimizationReason reason) {
+        HotSpotVMConfig config = runtime.getConfig();
+        switch (reason) {
+            case None:
+                return config.deoptReasonNone;
+            case NullCheckException:
+                return config.deoptReasonNullCheck;
+            case BoundsCheckException:
+                return config.deoptReasonRangeCheck;
+            case ClassCastException:
+                return config.deoptReasonClassCheck;
+            case ArrayStoreException:
+                return config.deoptReasonArrayCheck;
+            case UnreachedCode:
+                return config.deoptReasonUnreached0;
+            case TypeCheckedInliningViolated:
+                return config.deoptReasonTypeCheckInlining;
+            case OptimizedTypeCheckViolated:
+                return config.deoptReasonOptimizedTypeCheck;
+            case NotCompiledExceptionHandler:
+                return config.deoptReasonNotCompiledExceptionHandler;
+            case Unresolved:
+                return config.deoptReasonUnresolved;
+            case JavaSubroutineMismatch:
+                return config.deoptReasonJsrMismatch;
+            case ArithmeticException:
+                return config.deoptReasonDiv0Check;
+            case RuntimeConstraint:
+                return config.deoptReasonConstraint;
+            case LoopLimitCheck:
+                return config.deoptReasonLoopLimitCheck;
+            case Aliasing:
+                return config.deoptReasonAliasing;
+            case TransferToInterpreter:
+                return config.deoptReasonTransferToInterpreter;
+            default:
+                throw new JVMCIError("%s", reason);
+        }
+    }
+
+    public DeoptimizationReason convertDeoptReason(int reason) {
+        HotSpotVMConfig config = runtime.getConfig();
+        if (reason == config.deoptReasonNone) {
+            return DeoptimizationReason.None;
+        }
+        if (reason == config.deoptReasonNullCheck) {
+            return DeoptimizationReason.NullCheckException;
+        }
+        if (reason == config.deoptReasonRangeCheck) {
+            return DeoptimizationReason.BoundsCheckException;
+        }
+        if (reason == config.deoptReasonClassCheck) {
+            return DeoptimizationReason.ClassCastException;
+        }
+        if (reason == config.deoptReasonArrayCheck) {
+            return DeoptimizationReason.ArrayStoreException;
+        }
+        if (reason == config.deoptReasonUnreached0) {
+            return DeoptimizationReason.UnreachedCode;
+        }
+        if (reason == config.deoptReasonTypeCheckInlining) {
+            return DeoptimizationReason.TypeCheckedInliningViolated;
+        }
+        if (reason == config.deoptReasonOptimizedTypeCheck) {
+            return DeoptimizationReason.OptimizedTypeCheckViolated;
+        }
+        if (reason == config.deoptReasonNotCompiledExceptionHandler) {
+            return DeoptimizationReason.NotCompiledExceptionHandler;
+        }
+        if (reason == config.deoptReasonUnresolved) {
+            return DeoptimizationReason.Unresolved;
+        }
+        if (reason == config.deoptReasonJsrMismatch) {
+            return DeoptimizationReason.JavaSubroutineMismatch;
+        }
+        if (reason == config.deoptReasonDiv0Check) {
+            return DeoptimizationReason.ArithmeticException;
+        }
+        if (reason == config.deoptReasonConstraint) {
+            return DeoptimizationReason.RuntimeConstraint;
+        }
+        if (reason == config.deoptReasonLoopLimitCheck) {
+            return DeoptimizationReason.LoopLimitCheck;
+        }
+        if (reason == config.deoptReasonAliasing) {
+            return DeoptimizationReason.Aliasing;
+        }
+        if (reason == config.deoptReasonTransferToInterpreter) {
+            return DeoptimizationReason.TransferToInterpreter;
+        }
+        throw new JVMCIError("%x", reason);
+    }
+
+    @Override
+    public long getMemorySize(JavaConstant constant) {
+        if (constant.getJavaKind() == JavaKind.Object) {
+            HotSpotResolvedObjectType lookupJavaType = lookupJavaType(constant);
+
+            if (lookupJavaType == null) {
+                return 0;
+            } else {
+                if (lookupJavaType.isArray()) {
+                    // TODO(tw): Add compressed pointer support.
+                    int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
+                    ResolvedJavaType elementType = lookupJavaType.getComponentType();
+                    JavaKind elementKind = elementType.getJavaKind();
+                    final int headerSize = runtime.getArrayBaseOffset(elementKind);
+                    TargetDescription target = runtime.getHostJVMCIBackend().getTarget();
+                    int sizeOfElement = target.getSizeInBytes(elementKind);
+                    int alignment = target.wordSize;
+                    int log2ElementSize = CodeUtil.log2(sizeOfElement);
+                    return computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
+                }
+                return lookupJavaType.instanceSize();
+            }
+        } else {
+            return constant.getJavaKind().getByteCount();
+        }
+    }
+
+    /**
+     * Computes the size of the memory chunk allocated for an array. This size accounts for the
+     * array header size, body size and any padding after the last element to satisfy object
+     * alignment requirements.
+     *
+     * @param length the number of elements in the array
+     * @param alignment the object alignment requirement
+     * @param headerSize the size of the array header
+     * @param log2ElementSize log2 of the size of an element in the array
+     */
+    public static int computeArrayAllocationSize(int length, int alignment, int headerSize, int log2ElementSize) {
+        int size = (length << log2ElementSize) + headerSize + (alignment - 1);
+        int mask = ~(alignment - 1);
+        return size & mask;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.hotspot;
+
+public class HotSpotMetaData {
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] pcDescBytes;
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] scopesDescBytes;
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] relocBytes;
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] exceptionBytes;
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] oopMaps;
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private String[] metadata;
+
+    public byte[] pcDescBytes() {
+        return pcDescBytes != null ? pcDescBytes : new byte[0];
+    }
+
+    public byte[] scopesDescBytes() {
+        return scopesDescBytes != null ? scopesDescBytes : new byte[0];
+    }
+
+    public byte[] relocBytes() {
+        return relocBytes != null ? relocBytes : new byte[0];
+    }
+
+    public byte[] exceptionBytes() {
+        return exceptionBytes != null ? exceptionBytes : new byte[0];
+    }
+
+    public byte[] oopMaps() {
+        return oopMaps != null ? oopMaps : new byte[0];
+    }
+
+    public String[] metadataEntries() {
+        return metadata != null ? metadata : new String[0];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
+import jdk.vm.ci.meta.*;
+
+public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant {
+
+    Constant compress(CompressEncoding encoding);
+
+    Constant uncompress(CompressEncoding encoding);
+
+    HotSpotResolvedObjectType asResolvedJavaType();
+
+    HotSpotResolvedJavaMethod asResolvedJavaMethod();
+
+    long rawValue();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.hotspot;
+
+import java.util.*;
+
+import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
+import jdk.vm.ci.meta.*;
+
+public final class HotSpotMetaspaceConstantImpl extends PrimitiveConstant implements HotSpotMetaspaceConstant, VMConstant, HotSpotProxified {
+
+    static HotSpotMetaspaceConstantImpl forMetaspaceObject(JavaKind kind, long primitive, Object metaspaceObject, boolean compressed) {
+        return new HotSpotMetaspaceConstantImpl(kind, primitive, metaspaceObject, compressed);
+    }
+
+    static Object getMetaspaceObject(Constant constant) {
+        return ((HotSpotMetaspaceConstantImpl) constant).metaspaceObject;
+    }
+
+    private final Object metaspaceObject;
+    private final boolean compressed;
+
+    private HotSpotMetaspaceConstantImpl(JavaKind kind, long primitive, Object metaspaceObject, boolean compressed) {
+        super(kind, primitive);
+        this.metaspaceObject = metaspaceObject;
+        this.compressed = compressed;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ System.identityHashCode(metaspaceObject);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this || (o instanceof HotSpotMetaspaceConstantImpl && super.equals(o) && Objects.equals(metaspaceObject, ((HotSpotMetaspaceConstantImpl) o).metaspaceObject));
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "{" + metaspaceObject + (compressed ? ";compressed}" : "}");
+    }
+
+    public boolean isCompressed() {
+        return compressed;
+    }
+
+    public JavaConstant compress(CompressEncoding encoding) {
+        assert !isCompressed();
+        HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Int, encoding.compress(asLong()), metaspaceObject, true);
+        assert res.isCompressed();
+        return res;
+    }
+
+    public JavaConstant uncompress(CompressEncoding encoding) {
+        assert isCompressed();
+        HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Long, encoding.uncompress(asInt()), metaspaceObject, false);
+        assert !res.isCompressed();
+        return res;
+    }
+
+    public HotSpotResolvedObjectType asResolvedJavaType() {
+        if (metaspaceObject instanceof HotSpotResolvedObjectType) {
+            return (HotSpotResolvedObjectType) metaspaceObject;
+        }
+        return null;
+    }
+
+    public HotSpotResolvedJavaMethod asResolvedJavaMethod() {
+        if (metaspaceObject instanceof HotSpotResolvedJavaMethod) {
+            return (HotSpotResolvedJavaMethod) metaspaceObject;
+        }
+        return null;
+    }
+
+    public long rawValue() {
+        return asLong();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import static java.util.FormattableFlags.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+public abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{
+
+    public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
+        if (flags == 0 && width < 0) {
+            return s;
+        }
+        StringBuilder sb = new StringBuilder(s);
+
+        // apply width and justification
+        int len = sb.length();
+        if (len < width) {
+            for (int i = 0; i < width - len; i++) {
+                if ((flags & LEFT_JUSTIFY) == LEFT_JUSTIFY) {
+                    sb.append(' ');
+                } else {
+                    sb.insert(0, ' ');
+                }
+            }
+        }
+
+        String res = sb.toString();
+        if ((flags & UPPERCASE) == UPPERCASE) {
+            res = res.toUpperCase();
+        }
+        return res;
+    }
+
+    protected String name;
+
+    /**
+     * Controls whether {@link #toString()} includes the qualified or simple name of the class in
+     * which the method is declared.
+     */
+    public static final boolean FULLY_QUALIFIED_METHOD_NAME = false;
+
+    protected HotSpotMethod(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public final String getName() {
+        return name;
+    }
+
+    @Override
+    public final String toString() {
+        char h = FULLY_QUALIFIED_METHOD_NAME ? 'H' : 'h';
+        String suffix = this instanceof ResolvedJavaMethod ? "" : ", unresolved";
+        String fmt = String.format("HotSpotMethod<%%%c.%%n(%%p)%s>", h, suffix);
+        return format(fmt);
+    }
+
+    public void formatTo(Formatter formatter, int flags, int width, int precision) {
+        String base = (flags & ALTERNATE) == ALTERNATE ? getName() : toString();
+        formatter.format(applyFormattingFlagsAndWidth(base, flags & ~ALTERNATE, width));
+    }
+
+    public JavaMethod asJavaMethod() {
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,864 @@
+/*
+ * 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.
+ */
+package jdk.vm.ci.hotspot;
+
+import static java.lang.String.*;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import java.util.*;
+
+import jdk.vm.ci.hotspot.HotSpotMethodDataAccessor.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaMethodProfile.*;
+import jdk.vm.ci.meta.JavaTypeProfile.*;
+import sun.misc.*;
+
+/**
+ * Access to a HotSpot MethodData structure (defined in methodData.hpp).
+ */
+public final class HotSpotMethodData {
+
+    private static final HotSpotVMConfig config = runtime().getConfig();
+    private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(TriState.FALSE);
+    private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(TriState.UNKNOWN);
+
+    // sorted by tag
+    // @formatter:off
+    private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {
+        null,
+        new BitData(),
+        new CounterData(),
+        new JumpData(),
+        new TypeCheckData(),
+        new VirtualCallData(),
+        new RetData(),
+        new BranchData(),
+        new MultiBranchData(),
+        new ArgInfoData(),
+        null, // call_type_data_tag
+        null, // virtual_call_type_data_tag
+        null, // parameters_type_data_tag
+        null, // speculative_trap_data_tag
+    };
+    // @formatter:on
+
+    /**
+     * Reference to the C++ MethodData object.
+     */
+    private final long metaspaceMethodData;
+    @SuppressWarnings("unused") private final HotSpotResolvedJavaMethodImpl method;
+
+    public HotSpotMethodData(long metaspaceMethodData, HotSpotResolvedJavaMethodImpl method) {
+        this.metaspaceMethodData = metaspaceMethodData;
+        this.method = method;
+    }
+
+    /**
+     * @return value of the MethodData::_data_size field
+     */
+    private int normalDataSize() {
+        return UNSAFE.getInt(metaspaceMethodData + config.methodDataDataSize);
+    }
+
+    /**
+     * Returns the size of the extra data records. This method does the same calculation as
+     * MethodData::extra_data_size().
+     *
+     * @return size of extra data records
+     */
+    private int extraDataSize() {
+        final int extraDataBase = config.methodDataOopDataOffset + normalDataSize();
+        final int extraDataLimit = UNSAFE.getInt(metaspaceMethodData + config.methodDataSize);
+        return extraDataLimit - extraDataBase;
+    }
+
+    public boolean hasNormalData() {
+        return normalDataSize() > 0;
+    }
+
+    public boolean hasExtraData() {
+        return extraDataSize() > 0;
+    }
+
+    public int getExtraDataBeginOffset() {
+        return normalDataSize();
+    }
+
+    public boolean isWithin(int position) {
+        return position >= 0 && position < normalDataSize() + extraDataSize();
+    }
+
+    public int getDeoptimizationCount(DeoptimizationReason reason) {
+        HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess();
+        int reasonIndex = metaAccess.convertDeoptReason(reason);
+        return UNSAFE.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF;
+    }
+
+    public int getOSRDeoptimizationCount(DeoptimizationReason reason) {
+        HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) runtime().getHostJVMCIBackend().getMetaAccess();
+        int reasonIndex = metaAccess.convertDeoptReason(reason);
+        return UNSAFE.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + config.deoptReasonOSROffset + reasonIndex) & 0xFF;
+    }
+
+    public HotSpotMethodDataAccessor getNormalData(int position) {
+        if (position >= normalDataSize()) {
+            return null;
+        }
+
+        HotSpotMethodDataAccessor result = getData(position);
+        assert result != null : "NO_DATA tag is not allowed";
+        return result;
+    }
+
+    public HotSpotMethodDataAccessor getExtraData(int position) {
+        if (position >= normalDataSize() + extraDataSize()) {
+            return null;
+        }
+        HotSpotMethodDataAccessor data = getData(position);
+        if (data != null) {
+            return data;
+        }
+        return data;
+    }
+
+    public static HotSpotMethodDataAccessor getNoDataAccessor(boolean exceptionPossiblyNotRecorded) {
+        if (exceptionPossiblyNotRecorded) {
+            return NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR;
+        } else {
+            return NO_DATA_NO_EXCEPTION_ACCESSOR;
+        }
+    }
+
+    private HotSpotMethodDataAccessor getData(int position) {
+        assert position >= 0 : "out of bounds";
+        final Tag tag = AbstractMethodData.readTag(this, position);
+        HotSpotMethodDataAccessor accessor = PROFILE_DATA_ACCESSORS[tag.getValue()];
+        assert accessor == null || accessor.getTag() == tag : "wrong data accessor " + accessor + " for tag " + tag;
+        return accessor;
+    }
+
+    private int readUnsignedByte(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return UNSAFE.getByte(metaspaceMethodData + fullOffsetInBytes) & 0xFF;
+    }
+
+    private int readUnsignedShort(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return UNSAFE.getShort(metaspaceMethodData + fullOffsetInBytes) & 0xFFFF;
+    }
+
+    /**
+     * Since the values are stored in cells (platform words) this method uses
+     * {@link Unsafe#getAddress} to read the right value on both little and big endian machines.
+     */
+    private long readUnsignedInt(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return UNSAFE.getAddress(metaspaceMethodData + fullOffsetInBytes) & 0xFFFFFFFFL;
+    }
+
+    private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) {
+        long value = readUnsignedInt(position, offsetInBytes);
+        return truncateLongToInt(value);
+    }
+
+    /**
+     * Since the values are stored in cells (platform words) this method uses
+     * {@link Unsafe#getAddress} to read the right value on both little and big endian machines.
+     */
+    private int readInt(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return (int) UNSAFE.getAddress(metaspaceMethodData + fullOffsetInBytes);
+    }
+
+    private HotSpotResolvedJavaMethod readMethod(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return runtime().compilerToVm.getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes);
+    }
+
+    private HotSpotResolvedObjectTypeImpl readKlass(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return runtime().compilerToVm.getResolvedJavaType(null, metaspaceMethodData + fullOffsetInBytes, false);
+    }
+
+    private static int truncateLongToInt(long value) {
+        return value > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) value;
+    }
+
+    private static int computeFullOffset(int position, int offsetInBytes) {
+        return config.methodDataOopDataOffset + position + offsetInBytes;
+    }
+
+    private static int cellIndexToOffset(int cells) {
+        return config.dataLayoutHeaderSize + cellsToBytes(cells);
+    }
+
+    private static int cellsToBytes(int cells) {
+        return cells * config.dataLayoutCellSize;
+    }
+
+    /**
+     * Returns whether profiling ran long enough that the profile information is mature. Other
+     * informational data will still be valid even if the profile isn't mature.
+     */
+    public boolean isProfileMature() {
+        return runtime().getCompilerToVM().isMature(metaspaceMethodData);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        String nl = String.format("%n");
+        String nlIndent = String.format("%n%38s", "");
+        if (hasNormalData()) {
+            int pos = 0;
+            HotSpotMethodDataAccessor data;
+            while ((data = getNormalData(pos)) != null) {
+                if (pos != 0) {
+                    sb.append(nl);
+                }
+                int bci = data.getBCI(this, pos);
+                sb.append(String.format("%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName()));
+                sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent));
+                pos = pos + data.getSize(this, pos);
+            }
+        }
+
+        if (hasExtraData()) {
+            int pos = getExtraDataBeginOffset();
+            HotSpotMethodDataAccessor data;
+            while ((data = getExtraData(pos)) != null) {
+                if (pos == getExtraDataBeginOffset()) {
+                    sb.append(nl).append("--- Extra data:");
+                }
+                int bci = data.getBCI(this, pos);
+                sb.append(String.format("%n%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName()));
+                sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent));
+                pos = pos + data.getSize(this, pos);
+            }
+
+        }
+        return sb.toString();
+    }
+
+    private abstract static class AbstractMethodData implements HotSpotMethodDataAccessor {
+
+        /**
+         * Corresponds to {@code exception_seen_flag}.
+         */
+        private static final int EXCEPTIONS_MASK = 0x2;
+
+        private final Tag tag;
+        private final int staticSize;
+
+        protected AbstractMethodData(Tag tag, int staticSize) {
+            this.tag = tag;
+            this.staticSize = staticSize;
+        }
+
+        public Tag getTag() {
+            return tag;
+        }
+
+        public static Tag readTag(HotSpotMethodData data, int position) {
+            final int tag = data.readUnsignedByte(position, config.dataLayoutTagOffset);
+            return Tag.getEnum(tag);
+        }
+
+        @Override
+        public int getBCI(HotSpotMethodData data, int position) {
+            return data.readUnsignedShort(position, config.dataLayoutBCIOffset);
+        }
+
+        @Override
+        public int getSize(HotSpotMethodData data, int position) {
+            return staticSize + getDynamicSize(data, position);
+        }
+
+        @Override
+        public TriState getExceptionSeen(HotSpotMethodData data, int position) {
+            return TriState.get((getFlags(data, position) & EXCEPTIONS_MASK) != 0);
+        }
+
+        @Override
+        public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
+            return null;
+        }
+
+        @Override
+        public JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) {
+            return null;
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        @Override
+        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
+            return null;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        @Override
+        public TriState getNullSeen(HotSpotMethodData data, int position) {
+            return TriState.UNKNOWN;
+        }
+
+        protected int getFlags(HotSpotMethodData data, int position) {
+            return data.readUnsignedByte(position, config.dataLayoutFlagsOffset);
+        }
+
+        /**
+         * @param data
+         * @param position
+         */
+        protected int getDynamicSize(HotSpotMethodData data, int position) {
+            return 0;
+        }
+
+        public abstract StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos);
+    }
+
+    private static class NoMethodData extends AbstractMethodData {
+
+        private static final int NO_DATA_SIZE = cellIndexToOffset(0);
+
+        private final TriState exceptionSeen;
+
+        protected NoMethodData(TriState exceptionSeen) {
+            super(Tag.No, NO_DATA_SIZE);
+            this.exceptionSeen = exceptionSeen;
+        }
+
+        @Override
+        public int getBCI(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        @Override
+        public TriState getExceptionSeen(HotSpotMethodData data, int position) {
+            return exceptionSeen;
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            return sb;
+        }
+    }
+
+    private static class BitData extends AbstractMethodData {
+
+        private static final int BIT_DATA_SIZE = cellIndexToOffset(0);
+        private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01;
+
+        private BitData() {
+            super(Tag.BitData, BIT_DATA_SIZE);
+        }
+
+        protected BitData(Tag tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public TriState getNullSeen(HotSpotMethodData data, int position) {
+            return TriState.get((getFlags(data, position) & BIT_DATA_NULL_SEEN_FLAG) != 0);
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            return sb.append(format("exception_seen(%s)", getExceptionSeen(data, pos)));
+        }
+    }
+
+    private static class CounterData extends BitData {
+
+        private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
+        private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0);
+
+        public CounterData() {
+            super(Tag.CounterData, COUNTER_DATA_SIZE);
+        }
+
+        protected CounterData(Tag tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return getCounterValue(data, position);
+        }
+
+        protected int getCounterValue(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, COUNTER_DATA_COUNT_OFFSET);
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            return sb.append(format("count(%d) null_seen(%s) exception_seen(%s)", getCounterValue(data, pos), getNullSeen(data, pos), getExceptionSeen(data, pos)));
+        }
+    }
+
+    private static class JumpData extends AbstractMethodData {
+
+        private static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
+        protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(0);
+        protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1);
+
+        public JumpData() {
+            super(Tag.JumpData, JUMP_DATA_SIZE);
+        }
+
+        protected JumpData(Tag tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            return getExecutionCount(data, position) != 0 ? 1 : 0;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, TAKEN_COUNT_OFFSET);
+        }
+
+        public int getTakenDisplacement(HotSpotMethodData data, int position) {
+            return data.readInt(position, TAKEN_DISPLACEMENT_OFFSET);
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            return sb.append(format("taken(%d) displacement(%d)", getExecutionCount(data, pos), getTakenDisplacement(data, pos)));
+        }
+    }
+
+    static class RawItemProfile<T> {
+        final int entries;
+        final T[] items;
+        final long[] counts;
+        final long totalCount;
+
+        public RawItemProfile(int entries, T[] items, long[] counts, long totalCount) {
+            this.entries = entries;
+            this.items = items;
+            this.counts = counts;
+            this.totalCount = totalCount;
+        }
+    }
+
+    private abstract static class AbstractTypeData extends CounterData {
+
+        protected static final int TYPE_DATA_ROW_SIZE = cellsToBytes(2);
+
+        protected static final int NONPROFILED_COUNT_OFFSET = cellIndexToOffset(1);
+        protected static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(2);
+        protected static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(3);
+
+        protected AbstractTypeData(Tag tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
+            return createTypeProfile(getNullSeen(data, position), getRawTypeProfile(data, position));
+        }
+
+        private RawItemProfile<ResolvedJavaType> getRawTypeProfile(HotSpotMethodData data, int position) {
+            int typeProfileWidth = config.typeProfileWidth;
+
+            ResolvedJavaType[] types = new ResolvedJavaType[typeProfileWidth];
+            long[] counts = new long[typeProfileWidth];
+            long totalCount = 0;
+            int entries = 0;
+
+            outer: for (int i = 0; i < typeProfileWidth; i++) {
+                HotSpotResolvedObjectTypeImpl receiverKlass = data.readKlass(position, getTypeOffset(i));
+                if (receiverKlass != null) {
+                    HotSpotResolvedObjectTypeImpl klass = receiverKlass;
+                    long count = data.readUnsignedInt(position, getTypeCountOffset(i));
+                    /*
+                     * Because of races in the profile collection machinery it's possible for a
+                     * class to appear multiple times so merge them to make the profile look
+                     * rational.
+                     */
+                    for (int j = 0; j < entries; j++) {
+                        if (types[j].equals(klass)) {
+                            totalCount += count;
+                            counts[j] += count;
+                            continue outer;
+                        }
+                    }
+                    types[entries] = klass;
+                    totalCount += count;
+                    counts[entries] = count;
+                    entries++;
+                }
+            }
+
+            totalCount += getTypesNotRecordedExecutionCount(data, position);
+            return new RawItemProfile<>(entries, types, counts, totalCount);
+        }
+
+        protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position);
+
+        private static JavaTypeProfile createTypeProfile(TriState nullSeen, RawItemProfile<ResolvedJavaType> profile) {
+            if (profile.entries <= 0 || profile.totalCount <= 0) {
+                return null;
+            }
+
+            ProfiledType[] ptypes = new ProfiledType[profile.entries];
+            double totalProbability = 0.0;
+            for (int i = 0; i < profile.entries; i++) {
+                double p = profile.counts[i];
+                p = p / profile.totalCount;
+                totalProbability += p;
+                ptypes[i] = new ProfiledType(profile.items[i], p);
+            }
+
+            Arrays.sort(ptypes);
+
+            double notRecordedTypeProbability = profile.entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability));
+            assert notRecordedTypeProbability == 0 || profile.entries == config.typeProfileWidth;
+            return new JavaTypeProfile(nullSeen, notRecordedTypeProbability, ptypes);
+        }
+
+        private static int getTypeOffset(int row) {
+            return TYPE_DATA_FIRST_TYPE_OFFSET + row * TYPE_DATA_ROW_SIZE;
+        }
+
+        protected static int getTypeCountOffset(int row) {
+            return TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + row * TYPE_DATA_ROW_SIZE;
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            RawItemProfile<ResolvedJavaType> profile = getRawTypeProfile(data, pos);
+            TriState nullSeen = getNullSeen(data, pos);
+            TriState exceptionSeen = getExceptionSeen(data, pos);
+            sb.append(format("count(%d) null_seen(%s) exception_seen(%s) nonprofiled_count(%d) entries(%d)", getCounterValue(data, pos), nullSeen, exceptionSeen,
+                            getTypesNotRecordedExecutionCount(data, pos), profile.entries));
+            for (int i = 0; i < profile.entries; i++) {
+                long count = profile.counts[i];
+                sb.append(format("%n  %s (%d, %4.2f)", profile.items[i].toJavaName(), count, (double) count / profile.totalCount));
+            }
+            return sb;
+        }
+    }
+
+    private static class TypeCheckData extends AbstractTypeData {
+
+        private static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+
+        public TypeCheckData() {
+            super(Tag.ReceiverTypeData, TYPE_CHECK_DATA_SIZE);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        @Override
+        protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, NONPROFILED_COUNT_OFFSET);
+        }
+    }
+
+    private static class VirtualCallData extends AbstractTypeData {
+
+        private static final int VIRTUAL_CALL_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * (config.typeProfileWidth + config.methodProfileWidth);
+        private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET = TYPE_DATA_FIRST_TYPE_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+        private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET = TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+
+        public VirtualCallData() {
+            super(Tag.VirtualCallData, VIRTUAL_CALL_DATA_SIZE);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            final int typeProfileWidth = config.typeProfileWidth;
+
+            long total = 0;
+            for (int i = 0; i < typeProfileWidth; i++) {
+                total += data.readUnsignedInt(position, getTypeCountOffset(i));
+            }
+
+            total += getCounterValue(data, position);
+            return truncateLongToInt(total);
+        }
+
+        @Override
+        protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) {
+            return getCounterValue(data, position);
+        }
+
+        private static long getMethodsNotRecordedExecutionCount(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, NONPROFILED_COUNT_OFFSET);
+        }
+
+        @Override
+        public JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) {
+            return createMethodProfile(getRawMethodProfile(data, position));
+        }
+
+        private static RawItemProfile<ResolvedJavaMethod> getRawMethodProfile(HotSpotMethodData data, int position) {
+            int profileWidth = config.methodProfileWidth;
+
+            ResolvedJavaMethod[] methods = new ResolvedJavaMethod[profileWidth];
+            long[] counts = new long[profileWidth];
+            long totalCount = 0;
+            int entries = 0;
+
+            for (int i = 0; i < profileWidth; i++) {
+                HotSpotResolvedJavaMethod method = data.readMethod(position, getMethodOffset(i));
+                if (method != null) {
+                    methods[entries] = method;
+                    long count = data.readUnsignedInt(position, getMethodCountOffset(i));
+                    totalCount += count;
+                    counts[entries] = count;
+
+                    entries++;
+                }
+            }
+
+            totalCount += getMethodsNotRecordedExecutionCount(data, position);
+            return new RawItemProfile<>(entries, methods, counts, totalCount);
+        }
+
+        private static JavaMethodProfile createMethodProfile(RawItemProfile<ResolvedJavaMethod> profile) {
+            if (profile.entries <= 0 || profile.totalCount <= 0) {
+                return null;
+            }
+
+            ProfiledMethod[] pmethods = new ProfiledMethod[profile.entries];
+            double totalProbability = 0.0;
+            for (int i = 0; i < profile.entries; i++) {
+                double p = profile.counts[i];
+                p = p / profile.totalCount;
+                totalProbability += p;
+                pmethods[i] = new ProfiledMethod(profile.items[i], p);
+            }
+
+            Arrays.sort(pmethods);
+
+            double notRecordedMethodProbability = profile.entries < config.methodProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability));
+            assert notRecordedMethodProbability == 0 || profile.entries == config.methodProfileWidth;
+            return new JavaMethodProfile(notRecordedMethodProbability, pmethods);
+        }
+
+        private static int getMethodOffset(int row) {
+            return VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET + row * TYPE_DATA_ROW_SIZE;
+        }
+
+        private static int getMethodCountOffset(int row) {
+            return VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET + row * TYPE_DATA_ROW_SIZE;
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            RawItemProfile<ResolvedJavaMethod> profile = getRawMethodProfile(data, pos);
+            super.appendTo(sb.append(format("exception_seen(%s) ", getExceptionSeen(data, pos))), data, pos).append(format("%nmethod_entries(%d)", profile.entries));
+            for (int i = 0; i < profile.entries; i++) {
+                long count = profile.counts[i];
+                sb.append(format("%n  %s (%d, %4.2f)", profile.items[i].format("%H.%n(%p)"), count, (double) count / profile.totalCount));
+            }
+            return sb;
+        }
+    }
+
+    private static class RetData extends CounterData {
+
+        private static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
+        private static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth;
+
+        public RetData() {
+            super(Tag.RetData, RET_DATA_SIZE);
+        }
+    }
+
+    private static class BranchData extends JumpData {
+
+        private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
+        private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2);
+
+        public BranchData() {
+            super(Tag.BranchData, BRANCH_DATA_SIZE);
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            long takenCount = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET);
+            long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
+            long total = takenCount + notTakenCount;
+
+            return total <= 0 ? -1 : takenCount / (double) total;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            long count = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET) + data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
+            return truncateLongToInt(count);
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            long taken = data.readUnsignedInt(pos, TAKEN_COUNT_OFFSET);
+            long notTaken = data.readUnsignedInt(pos, NOT_TAKEN_COUNT_OFFSET);
+            double takenProbability = getBranchTakenProbability(data, pos);
+            return sb.append(format("taken(%d, %4.2f) not_taken(%d, %4.2f) displacement(%d)", taken, takenProbability, notTaken, 1.0D - takenProbability, getTakenDisplacement(data, pos)));
+        }
+    }
+
+    private static class ArrayData extends AbstractMethodData {
+
+        private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(0);
+        protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(1);
+
+        public ArrayData(Tag tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        protected int getDynamicSize(HotSpotMethodData data, int position) {
+            return cellsToBytes(getLength(data, position));
+        }
+
+        protected static int getLength(HotSpotMethodData data, int position) {
+            return data.readInt(position, ARRAY_DATA_LENGTH_OFFSET);
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            return sb.append(format("length(%d)", getLength(data, pos)));
+        }
+    }
+
+    private static class MultiBranchData extends ArrayData {
+
+        private static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
+        private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = 2;
+        private static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
+        private static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
+        private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
+
+        public MultiBranchData() {
+            super(Tag.MultiBranchData, MULTI_BRANCH_DATA_SIZE);
+        }
+
+        @Override
+        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
+            int arrayLength = getLength(data, position);
+            assert arrayLength > 0 : "switch must have at least the default case";
+            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
+
+            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
+            long totalCount = 0;
+            double[] result = new double[length];
+
+            // default case is first in HotSpot but last for the compiler
+            long count = readCount(data, position, 0);
+            totalCount += count;
+            result[length - 1] = count;
+
+            for (int i = 1; i < length; i++) {
+                count = readCount(data, position, i);
+                totalCount += count;
+                result[i - 1] = count;
+            }
+
+            if (totalCount <= 0) {
+                return null;
+            } else {
+                for (int i = 0; i < length; i++) {
+                    result[i] = result[i] / totalCount;
+                }
+                return result;
+            }
+        }
+
+        private static long readCount(HotSpotMethodData data, int position, int i) {
+            int offset;
+            long count;
+            offset = getCountOffset(i);
+            count = data.readUnsignedInt(position, offset);
+            return count;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            int arrayLength = getLength(data, position);
+            assert arrayLength > 0 : "switch must have at least the default case";
+            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
+
+            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
+            long totalCount = 0;
+            for (int i = 0; i < length; i++) {
+                int offset = getCountOffset(i);
+                totalCount += data.readUnsignedInt(position, offset);
+            }
+
+            return truncateLongToInt(totalCount);
+        }
+
+        private static int getCountOffset(int index) {
+            return MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
+        }
+
+        private static int getDisplacementOffset(int index) {
+            return MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
+        }
+
+        @Override
+        public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+            int entries = getLength(data, pos) / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
+            sb.append(format("entries(%d)", entries));
+            for (int i = 0; i < entries; i++) {
+                sb.append(format("%n  %d: count(%d) displacement(%d)", i, data.readUnsignedInt(pos, getCountOffset(i)), data.readUnsignedInt(pos, getDisplacementOffset(i))));
+            }
+            return sb;
+        }
+    }
+
+    private static class ArgInfoData extends ArrayData {
+
+        private static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1);
+
+        public ArgInfoData() {
+            super(Tag.ArgInfoData, ARG_INFO_DATA_SIZE);
+        }
+    }
+
+    public void setCompiledIRSize(int size) {
+        UNSAFE.putInt(metaspaceMethodData + config.methodDataIRSizeOffset, size);
+    }
+
+    public int getCompiledIRSize() {
+        return UNSAFE.getInt(metaspaceMethodData + config.methodDataIRSizeOffset);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Interface for accessor objects that encapsulate the logic for accessing the different kinds of
+ * data in a HotSpot methodDataOop. This interface is similar to the interface {@link ProfilingInfo}
+ * , but most methods require a MethodDataObject and the exact position within the methodData.
+ */
+public interface HotSpotMethodDataAccessor {
+
+    /**
+     * {@code DataLayout} tag values.
+     */
+    enum Tag {
+        No(config().dataLayoutNoTag),
+        BitData(config().dataLayoutBitDataTag),
+        CounterData(config().dataLayoutCounterDataTag),
+        JumpData(config().dataLayoutJumpDataTag),
+        ReceiverTypeData(config().dataLayoutReceiverTypeDataTag),
+        VirtualCallData(config().dataLayoutVirtualCallDataTag),
+        RetData(config().dataLayoutRetDataTag),
+        BranchData(config().dataLayoutBranchDataTag),
+        MultiBranchData(config().dataLayoutMultiBranchDataTag),
+        ArgInfoData(config().dataLayoutArgInfoDataTag),
+        CallTypeData(config().dataLayoutCallTypeDataTag),
+        VirtualCallTypeData(config().dataLayoutVirtualCallTypeDataTag),
+        ParametersTypeData(config().dataLayoutParametersTypeDataTag),
+        SpeculativeTrapData(config().dataLayoutSpeculativeTrapDataTag);
+
+        private final int value;
+
+        private Tag(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+
+        private static HotSpotVMConfig config() {
+            return runtime().getConfig();
+        }
+
+        public static Tag getEnum(int value) {
+            Tag result = values()[value];
+            assert value == result.value;
+            return result;
+        }
+    }
+
+    /**
+     * Returns the {@link Tag} stored in the LayoutData header.
+     *
+     * @return tag stored in the LayoutData header
+     */
+    Tag getTag();
+
+    /**
+     * Returns the BCI stored in the LayoutData header.
+     *
+     * @return An integer &ge; 0 and &le; Short.MAX_VALUE, or -1 if not supported.
+     */
+    int getBCI(HotSpotMethodData data, int position);
+
+    /**
+     * Computes the size for the specific data at the given position.
+     *
+     * @return An integer &gt; 0.
+     */
+    int getSize(HotSpotMethodData data, int position);
+
+    JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position);
+
+    JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position);
+
+    double getBranchTakenProbability(HotSpotMethodData data, int position);
+
+    double[] getSwitchProbabilities(HotSpotMethodData data, int position);
+
+    TriState getExceptionSeen(HotSpotMethodData data, int position);
+
+    TriState getNullSeen(HotSpotMethodData data, int position);
+
+    int getExecutionCount(HotSpotMethodData data, int position);
+
+    StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+
+public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider, HotSpotProxified {
+
+    private final ConstantReflectionProvider constantReflection;
+
+    public HotSpotMethodHandleAccessProvider(ConstantReflectionProvider constantReflection) {
+        this.constantReflection = constantReflection;
+    }
+
+    /**
+     * Lazy initialization to break class initialization cycle. Field and method lookup is only
+     * possible after the {@link HotSpotJVMCIRuntime} is fully initialized.
+     */
+    static class LazyInitialization {
+        static final ResolvedJavaField methodHandleFormField;
+        static final ResolvedJavaField lambdaFormVmentryField;
+        static final ResolvedJavaMethod lambdaFormCompileToBytecodeMethod;
+        static final HotSpotResolvedJavaField memberNameVmtargetField;
+
+        /**
+         * Search for an instance field with the given name in a class.
+         *
+         * @param className name of the class to search in
+         * @param fieldName name of the field to be searched
+         * @return resolved java field
+         * @throws ClassNotFoundException
+         */
+        private static ResolvedJavaField findFieldInClass(String className, String fieldName) throws ClassNotFoundException {
+            Class<?> clazz = Class.forName(className);
+            ResolvedJavaType type = runtime().fromClass(clazz);
+            ResolvedJavaField[] fields = type.getInstanceFields(false);
+            for (ResolvedJavaField field : fields) {
+                if (field.getName().equals(fieldName)) {
+                    return field;
+                }
+            }
+            return null;
+        }
+
+        private static ResolvedJavaMethod findMethodInClass(String className, String methodName) throws ClassNotFoundException {
+            Class<?> clazz = Class.forName(className);
+            HotSpotResolvedObjectTypeImpl type = fromObjectClass(clazz);
+            ResolvedJavaMethod result = null;
+            for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
+                if (method.getName().equals(methodName)) {
+                    assert result == null : "more than one method found: " + className + "." + methodName;
+                    result = method;
+                }
+            }
+            assert result != null : "method not found: " + className + "." + methodName;
+            return result;
+        }
+
+        static {
+            try {
+                methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form");
+                lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry");
+                lambdaFormCompileToBytecodeMethod = findMethodInClass("java.lang.invoke.LambdaForm", "compileToBytecode");
+                memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass("java.lang.invoke.MemberName", "vmtarget");
+            } catch (Throwable ex) {
+                throw new JVMCIError(ex);
+            }
+        }
+    }
+
+    @Override
+    public IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method) {
+        int intrinsicId = ((HotSpotResolvedJavaMethodImpl) method).intrinsicId();
+        if (intrinsicId != 0) {
+            return getMethodHandleIntrinsic(intrinsicId);
+        }
+        return null;
+    }
+
+    public static IntrinsicMethod getMethodHandleIntrinsic(int intrinsicId) {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (intrinsicId == config.vmIntrinsicInvokeBasic) {
+            return IntrinsicMethod.INVOKE_BASIC;
+        } else if (intrinsicId == config.vmIntrinsicLinkToInterface) {
+            return IntrinsicMethod.LINK_TO_INTERFACE;
+        } else if (intrinsicId == config.vmIntrinsicLinkToSpecial) {
+            return IntrinsicMethod.LINK_TO_SPECIAL;
+        } else if (intrinsicId == config.vmIntrinsicLinkToStatic) {
+            return IntrinsicMethod.LINK_TO_STATIC;
+        } else if (intrinsicId == config.vmIntrinsicLinkToVirtual) {
+            return IntrinsicMethod.LINK_TO_VIRTUAL;
+        }
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveInvokeBasicTarget(JavaConstant methodHandle, boolean forceBytecodeGeneration) {
+        if (methodHandle.isNull()) {
+            return null;
+        }
+
+        /* Load non-public field: LambdaForm MethodHandle.form */
+        JavaConstant lambdaForm = constantReflection.readFieldValue(LazyInitialization.methodHandleFormField, methodHandle);
+        if (lambdaForm.isNull()) {
+            return null;
+        }
+
+        JavaConstant memberName;
+        if (forceBytecodeGeneration) {
+            /* Invoke non-public method: MemberName LambdaForm.compileToBytecode() */
+            memberName = LazyInitialization.lambdaFormCompileToBytecodeMethod.invoke(lambdaForm, new JavaConstant[0]);
+        } else {
+            /* Load non-public field: MemberName LambdaForm.vmentry */
+            memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
+        }
+        return getTargetMethod(memberName);
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName) {
+        return getTargetMethod(memberName);
+    }
+
+    /**
+     * Returns the {@link ResolvedJavaMethod} for the vmtarget of a java.lang.invoke.MemberName.
+     */
+    private static ResolvedJavaMethod getTargetMethod(JavaConstant memberName) {
+        if (memberName.isNull()) {
+            return null;
+        }
+
+        Object object = ((HotSpotObjectConstantImpl) memberName).object();
+        /* Read the ResolvedJavaMethod from the injected field MemberName.vmtarget */
+        return runtime().compilerToVm.getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodUnresolved.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Implementation of {@link JavaMethod} for unresolved HotSpot methods.
+ */
+public final class HotSpotMethodUnresolved extends HotSpotMethod {
+
+    private final Signature signature;
+    protected JavaType holder;
+
+    public HotSpotMethodUnresolved(String name, Signature signature, JavaType holder) {
+        super(name);
+        this.holder = holder;
+        this.signature = signature;
+    }
+
+    @Override
+    public Signature getSignature() {
+        return signature;
+    }
+
+    @Override
+    public JavaType getDeclaringClass() {
+        return holder;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || !(obj instanceof HotSpotMethodUnresolved)) {
+            return false;
+        }
+        HotSpotMethodUnresolved that = (HotSpotMethodUnresolved) obj;
+        return this.name.equals(that.name) && this.signature.equals(that.signature) && this.holder.equals(that.holder);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a
+ * weak reference to an instance of this class. This is necessary to keep the nmethod from being
+ * unloaded while the associated {@link HotSpotNmethod} instance is alive.
+ * <p>
+ * Note that there is no (current) way for the reference from an nmethod to a {@link HotSpotNmethod}
+ * instance to be anything but weak. This is due to the fact that HotSpot does not treat nmethods as
+ * strong GC roots.
+ */
+public class HotSpotNmethod extends HotSpotInstalledCode {
+
+    /**
+     * This (indirect) Method* reference is safe since class redefinition preserves all methods
+     * associated with nmethods in the code cache.
+     */
+    private final HotSpotResolvedJavaMethod method;
+
+    private final boolean isDefault;
+    private final boolean isExternal;
+
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault) {
+        this(method, name, isDefault, false);
+    }
+
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault, boolean isExternal) {
+        super(name);
+        this.method = method;
+        this.isDefault = isDefault;
+        this.isExternal = isExternal;
+    }
+
+    public boolean isDefault() {
+        return isDefault;
+    }
+
+    public boolean isExternal() {
+        return isExternal;
+    }
+
+    public ResolvedJavaMethod getMethod() {
+        return method;
+    }
+
+    @Override
+    public void invalidate() {
+        runtime().getCompilerToVM().invalidateInstalledCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("InstalledNmethod[method=%s, codeBlob=0x%x, isDefault=%b, name=%s]", method, getAddress(), isDefault, name);
+    }
+
+    protected boolean checkThreeObjectArgs() {
+        assert method.getSignature().getParameterCount(!method.isStatic()) == 3;
+        assert method.getSignature().getParameterKind(0) == JavaKind.Object;
+        assert method.getSignature().getParameterKind(1) == JavaKind.Object;
+        assert !method.isStatic() || method.getSignature().getParameterKind(2) == JavaKind.Object;
+        return true;
+    }
+
+    private boolean checkArgs(Object... args) {
+        JavaType[] sig = method.toParameterTypes();
+        assert args.length == sig.length : method.format("%H.%n(%p): expected ") + sig.length + " args, got " + args.length;
+        for (int i = 0; i < sig.length; i++) {
+            Object arg = args[i];
+            if (arg == null) {
+                assert sig[i].getJavaKind() == JavaKind.Object : method.format("%H.%n(%p): expected arg ") + i + " to be Object, not " + sig[i];
+            } else if (sig[i].getJavaKind() != JavaKind.Object) {
+                assert sig[i].getJavaKind().toBoxedJavaClass() == arg.getClass() : method.format("%H.%n(%p): expected arg ") + i + " to be " + sig[i] + ", not " + arg.getClass();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
+        assert checkArgs(args);
+        assert !isExternal();
+        return runtime().getCompilerToVM().executeInstalledCode(args, this);
+    }
+
+    @Override
+    public long getStart() {
+        return isValid() ? super.getStart() : 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.hotspot;
+
+import java.lang.invoke.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a constant non-{@code null} object reference, within the compiler and across the
+ * compiler/runtime interface.
+ */
+public interface HotSpotObjectConstant extends JavaConstant, HotSpotConstant, VMConstant {
+
+    JavaConstant compress();
+
+    JavaConstant uncompress();
+
+    /**
+     * Gets the resolved Java type of the object represented by this constant.
+     */
+    HotSpotResolvedObjectType getType();
+
+    /**
+     * Gets the result of {@link Class#getClassLoader()} for the {@link Class} object represented by
+     * this constant.
+     *
+     * @return {@code null} if this constant does not represent a {@link Class} object
+     */
+    JavaConstant getClassLoader();
+
+    /**
+     * Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object
+     * represented by this constant.
+     */
+    int getIdentityHashCode();
+
+    /**
+     * Gets the result of {@link Class#getComponentType()} for the {@link Class} object represented
+     * by this constant.
+     *
+     * @return {@code null} if this constant does not represent a {@link Class} object
+     */
+    JavaConstant getComponentType();
+
+    /**
+     * Gets the result of {@link Class#getSuperclass()} for the {@link Class} object represented by
+     * this constant.
+     *
+     * @return {@code null} if this constant does not represent a {@link Class} object
+     */
+    JavaConstant getSuperclass();
+
+    /**
+     * Gets the result of {@link CallSite#getTarget()} for the {@link CallSite} object represented
+     * by this constant.
+     *
+     * @param assumptions used to register an assumption that the {@link CallSite}'s target does not
+     *            change
+     * @return {@code null} if this constant does not represent a {@link CallSite} object
+     */
+    JavaConstant getCallSiteTarget(Assumptions assumptions);
+
+    /**
+     * Determines if this constant represents an {@linkplain String#intern() interned} string.
+     */
+    boolean isInternedString();
+
+    /**
+     * Gets the object represented by this constant represents if it is of a given type.
+     *
+     * @param type the expected type of the object represented by this constant. If the object is
+     *            required to be of this type, then wrap the call to this method in
+     *            {@link Objects#requireNonNull(Object)}.
+     * @return the object value represented by this constant if it is an
+     *         {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise
+     *         {@code null}
+     */
+    <T> T asObject(Class<T> type);
+
+    /**
+     * Gets the object represented by this constant represents if it is of a given type.
+     *
+     * @param type the expected type of the object represented by this constant. If the object is
+     *            required to be of this type, then wrap the call to this method in
+     *            {@link Objects#requireNonNull(Object)}.
+     * @return the object value represented by this constant if it is an
+     *         {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise
+     *         {@code null}
+     */
+    Object asObject(ResolvedJavaType type);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
+
+import java.lang.invoke.*;
+
+import jdk.vm.ci.inittimer.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a constant non-{@code null} object reference, within the compiler and across the
+ * compiler/runtime interface.
+ */
+public final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
+
+    public static JavaConstant forObject(Object object) {
+        return forObject(object, false);
+    }
+
+    static JavaConstant forObject(Object object, boolean compressed) {
+        if (object == null) {
+            return compressed ? HotSpotCompressedNullConstant.COMPRESSED_NULL : JavaConstant.NULL_POINTER;
+        } else {
+            return new HotSpotObjectConstantImpl(object, compressed);
+        }
+    }
+
+    static JavaConstant forStableArray(Object object, int stableDimension, boolean isDefaultStable) {
+        if (object == null) {
+            return JavaConstant.NULL_POINTER;
+        } else {
+            assert object.getClass().isArray();
+            return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable);
+        }
+    }
+
+    public static JavaConstant forBoxedValue(JavaKind kind, Object value) {
+        if (kind == JavaKind.Object) {
+            return HotSpotObjectConstantImpl.forObject(value);
+        } else {
+            return JavaConstant.forBoxedPrimitive(value);
+        }
+    }
+
+    static Object asBoxedValue(Constant constant) {
+        if (JavaConstant.isNull(constant)) {
+            return null;
+        } else if (constant instanceof HotSpotObjectConstantImpl) {
+            return ((HotSpotObjectConstantImpl) constant).object;
+        } else {
+            return ((JavaConstant) constant).asBoxedPrimitive();
+        }
+    }
+
+    private final Object object;
+    private final boolean compressed;
+    private final byte stableDimension;
+    private final boolean isDefaultStable;
+
+    private HotSpotObjectConstantImpl(Object object, boolean compressed, int stableDimension, boolean isDefaultStable) {
+        this.object = object;
+        this.compressed = compressed;
+        this.stableDimension = (byte) stableDimension;
+        this.isDefaultStable = isDefaultStable;
+        assert object != null;
+        assert stableDimension == 0 || (object != null && object.getClass().isArray());
+        assert stableDimension >= 0 && stableDimension <= 255;
+        assert !isDefaultStable || stableDimension > 0;
+    }
+
+    private HotSpotObjectConstantImpl(Object object, boolean compressed) {
+        this(object, compressed, 0, false);
+    }
+
+    @Override
+    public JavaKind getJavaKind() {
+        return JavaKind.Object;
+    }
+
+    /**
+     * Package-private accessor for the object represented by this constant.
+     */
+    Object object() {
+        return object;
+    }
+
+    /**
+     * Determines if the object represented by this constant is {@link Object#equals(Object) equal}
+     * to a given object.
+     */
+    public boolean isEqualTo(Object obj) {
+        return object.equals(obj);
+    }
+
+    /**
+     * Gets the class of the object represented by this constant.
+     */
+    public Class<?> getObjectClass() {
+        return object.getClass();
+    }
+
+    public boolean isCompressed() {
+        return compressed;
+    }
+
+    public JavaConstant compress() {
+        assert !compressed;
+        return new HotSpotObjectConstantImpl(object, true, stableDimension, isDefaultStable);
+    }
+
+    public JavaConstant uncompress() {
+        assert compressed;
+        return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable);
+    }
+
+    public HotSpotResolvedObjectType getType() {
+        return fromObjectClass(object.getClass());
+    }
+
+    public JavaConstant getClassLoader() {
+        if (object instanceof Class) {
+            /*
+             * This is an intrinsic for getClassLoader0, which occurs after any security checks. We
+             * can't call that directly so just call getClassLoader.
+             */
+            return HotSpotObjectConstantImpl.forObject(((Class<?>) object).getClassLoader());
+        }
+        return null;
+    }
+
+    public int getIdentityHashCode() {
+        return System.identityHashCode(object);
+    }
+
+    public JavaConstant getComponentType() {
+        if (object instanceof Class) {
+            return HotSpotObjectConstantImpl.forObject(((Class<?>) object).getComponentType());
+        }
+        return null;
+    }
+
+    public JavaConstant getSuperclass() {
+        if (object instanceof Class) {
+            return HotSpotObjectConstantImpl.forObject(((Class<?>) object).getSuperclass());
+        }
+        return null;
+    }
+
+    public JavaConstant getCallSiteTarget(Assumptions assumptions) {
+        if (object instanceof CallSite) {
+            CallSite callSite = (CallSite) object;
+            MethodHandle target = callSite.getTarget();
+            if (!(callSite instanceof ConstantCallSite)) {
+                if (assumptions == null) {
+                    return null;
+                }
+                assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target));
+            }
+            return HotSpotObjectConstantImpl.forObject(target);
+        }
+        return null;
+    }
+
+    @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want")
+    public boolean isInternedString() {
+        if (object instanceof String) {
+            String s = (String) object;
+            return s.intern() == s;
+        }
+        return false;
+    }
+
+    public <T> T asObject(Class<T> type) {
+        if (type.isInstance(object)) {
+            return type.cast(object);
+        }
+        return null;
+    }
+
+    public Object asObject(ResolvedJavaType type) {
+        if (type.isInstance(this)) {
+            return object;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isNull() {
+        return false;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return false;
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int asInt() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public boolean asBoolean() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public long asLong() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public float asFloat() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public double asDouble() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(object);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        } else if (o instanceof HotSpotObjectConstantImpl) {
+            HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o;
+            return object == other.object && compressed == other.compressed && stableDimension == other.stableDimension && isDefaultStable == other.isDefaultStable;
+        }
+        return false;
+    }
+
+    @Override
+    public String toValueString() {
+        if (object instanceof String) {
+            return "\"" + (String) object + "\"";
+        } else {
+            return JavaKind.Object.format(object);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return (compressed ? "NarrowOop" : getJavaKind().getJavaName()) + "[" + JavaKind.Object.format(object) + "]";
+    }
+
+    /**
+     * Number of stable dimensions if this constant is a stable array.
+     */
+    public int getStableDimension() {
+        return stableDimension & 0xff;
+    }
+
+    /**
+     * Returns {@code true} if this is a stable array constant and its elements should be considered
+     * as stable regardless of whether they are default values.
+     */
+    public boolean isDefaultStable() {
+        return isDefaultStable;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotOopMap.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+public class HotSpotOopMap {
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int offset;
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int count;
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] data;
+
+    public byte[] data() {
+        return data;
+    }
+
+    public int count() {
+        return count;
+    }
+
+    public int offset() {
+        return offset;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified {
+
+    // private static final DebugMetric metricInsufficentSpace =
+    // Debug.metric("InsufficientSpaceForProfilingData");
+
+    private final HotSpotMethodData methodData;
+    private final HotSpotResolvedJavaMethod method;
+
+    private boolean isMature;
+    private int position;
+    private int hintPosition;
+    private int hintBCI;
+    private HotSpotMethodDataAccessor dataAccessor;
+
+    private boolean includeNormal;
+    private boolean includeOSR;
+
+    public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) {
+        this.methodData = methodData;
+        this.method = method;
+        this.includeNormal = includeNormal;
+        this.includeOSR = includeOSR;
+        this.isMature = methodData.isProfileMature();
+        hintPosition = 0;
+        hintBCI = -1;
+    }
+
+    @Override
+    public int getCodeSize() {
+        return method.getCodeSize();
+    }
+
+    @Override
+    public JavaTypeProfile getTypeProfile(int bci) {
+        if (!isMature) {
+            return null;
+        }
+        findBCI(bci, false);
+        return dataAccessor.getTypeProfile(methodData, position);
+    }
+
+    @Override
+    public JavaMethodProfile getMethodProfile(int bci) {
+        if (!isMature) {
+            return null;
+        }
+        findBCI(bci, false);
+        return dataAccessor.getMethodProfile(methodData, position);
+    }
+
+    @Override
+    public double getBranchTakenProbability(int bci) {
+        if (!isMature) {
+            return -1;
+        }
+        findBCI(bci, false);
+        return dataAccessor.getBranchTakenProbability(methodData, position);
+    }
+
+    @Override
+    public double[] getSwitchProbabilities(int bci) {
+        if (!isMature) {
+            return null;
+        }
+        findBCI(bci, false);
+        return dataAccessor.getSwitchProbabilities(methodData, position);
+    }
+
+    @Override
+    public TriState getExceptionSeen(int bci) {
+        findBCI(bci, true);
+        return dataAccessor.getExceptionSeen(methodData, position);
+    }
+
+    @Override
+    public TriState getNullSeen(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getNullSeen(methodData, position);
+    }
+
+    @Override
+    public int getExecutionCount(int bci) {
+        if (!isMature) {
+            return -1;
+        }
+        findBCI(bci, false);
+        return dataAccessor.getExecutionCount(methodData, position);
+    }
+
+    @Override
+    public int getDeoptimizationCount(DeoptimizationReason reason) {
+        int count = 0;
+        if (includeNormal) {
+            count += methodData.getDeoptimizationCount(reason);
+        }
+        if (includeOSR) {
+            count += methodData.getOSRDeoptimizationCount(reason);
+        }
+        return count;
+    }
+
+    private void findBCI(int targetBCI, boolean searchExtraData) {
+        assert targetBCI >= 0 : "invalid BCI";
+
+        if (methodData.hasNormalData()) {
+            int currentPosition = targetBCI < hintBCI ? 0 : hintPosition;
+            HotSpotMethodDataAccessor currentAccessor;
+            while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) {
+                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
+                if (currentBCI == targetBCI) {
+                    normalDataFound(currentAccessor, currentPosition, currentBCI);
+                    return;
+                } else if (currentBCI > targetBCI) {
+                    break;
+                }
+                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
+            }
+        }
+
+        boolean exceptionPossiblyNotRecorded = false;
+        if (searchExtraData && methodData.hasExtraData()) {
+            int currentPosition = methodData.getExtraDataBeginOffset();
+            HotSpotMethodDataAccessor currentAccessor;
+            while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) {
+                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
+                if (currentBCI == targetBCI) {
+                    extraDataFound(currentAccessor, currentPosition);
+                    return;
+                }
+                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
+            }
+
+            if (!methodData.isWithin(currentPosition)) {
+                exceptionPossiblyNotRecorded = true;
+                // metricInsufficentSpace.increment();
+            }
+        }
+
+        noDataFound(exceptionPossiblyNotRecorded);
+    }
+
+    private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) {
+        setCurrentData(data, pos);
+        this.hintPosition = position;
+        this.hintBCI = bci;
+    }
+
+    private void extraDataFound(HotSpotMethodDataAccessor data, int pos) {
+        setCurrentData(data, pos);
+    }
+
+    private void noDataFound(boolean exceptionPossiblyNotRecorded) {
+        HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded);
+        setCurrentData(accessor, -1);
+    }
+
+    private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) {
+        this.dataAccessor = dataAccessor;
+        this.position = position;
+    }
+
+    @Override
+    public boolean isMature() {
+        return isMature;
+    }
+
+    public void ignoreMature() {
+        isMature = true;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">";
+    }
+
+    @Override
+    public void setMature() {
+        isMature = true;
+    }
+
+    /**
+     * {@code MethodData::_jvmci_ir_size} (currently) supports at most one JVMCI compiler IR type
+     * which will be determined by the first JVMCI compiler that calls
+     * {@link #setCompilerIRSize(Class, int)}.
+     */
+    private static volatile Class<?> supportedCompilerIRType;
+
+    @Override
+    public boolean setCompilerIRSize(Class<?> irType, int size) {
+        if (supportedCompilerIRType == null) {
+            synchronized (HotSpotProfilingInfo.class) {
+                if (supportedCompilerIRType == null) {
+                    supportedCompilerIRType = irType;
+                }
+            }
+        }
+        if (supportedCompilerIRType != irType) {
+            return false;
+        }
+        methodData.setCompiledIRSize(size);
+        return true;
+    }
+
+    @Override
+    public int getCompilerIRSize(Class<?> irType) {
+        if (irType == supportedCompilerIRType) {
+            return methodData.getCompiledIRSize();
+        }
+        return -1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProxified.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot;
+
+/**
+ * Marker interface for classes whose values are proxied during replay compilation capture.
+ */
+public interface HotSpotProxified {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.hotspot;
+
+import java.util.*;
+
+import jdk.vm.ci.code.*;
+
+public final class HotSpotReferenceMap extends ReferenceMap {
+
+    final Location[] objects;
+    final Location[] derivedBase;
+    final int[] sizeInBytes;
+    final int maxRegisterSize;
+
+    public HotSpotReferenceMap(Location[] objects, Location[] derivedBase, int[] sizeInBytes, int maxRegisterSize) {
+        this.objects = objects;
+        this.derivedBase = derivedBase;
+        this.sizeInBytes = sizeInBytes;
+        this.maxRegisterSize = maxRegisterSize;
+    }
+
+    @Override
+    public int hashCode() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof HotSpotReferenceMap) {
+            HotSpotReferenceMap that = (HotSpotReferenceMap) obj;
+            if (Arrays.equals(objects, that.objects)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return Arrays.toString(objects);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, 2014, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a field in a HotSpot type.
+ */
+public interface HotSpotResolvedJavaField extends ResolvedJavaField {
+
+    /**
+     * Determines if a given object contains this field.
+     *
+     * @return true iff this is a non-static field and its declaring class is assignable from
+     *         {@code object}'s class
+     */
+    boolean isInObject(Object object);
+
+    int offset();
+
+    /**
+     * Checks if this field has the {@link Stable} annotation.
+     *
+     * @return true if field has {@link Stable} annotation, false otherwise
+     */
+    boolean isStable();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2011, 2014, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.HotSpotResolvedJavaFieldImpl.Options.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.options.*;
+
+/**
+ * Represents a field in a HotSpot type.
+ */
+public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
+
+    static class Options {
+        //@formatter:off
+        @Option(help = "Mark well-known stable fields as such.", type = OptionType.Debug)
+        public static final OptionValue<Boolean> ImplicitStableValues = new OptionValue<>(true);
+        //@formatter:on
+    }
+
+    private final HotSpotResolvedObjectTypeImpl holder;
+    private final String name;
+    private JavaType type;
+    private final int offset;
+
+    /**
+     * This value contains all flags as stored in the VM including internal ones.
+     */
+    private final int modifiers;
+    private final LocationIdentity locationIdentity = new FieldLocationIdentity(this);
+
+    public static class FieldLocationIdentity extends LocationIdentity {
+        HotSpotResolvedJavaField inner;
+
+        public FieldLocationIdentity(HotSpotResolvedJavaFieldImpl inner) {
+            this.inner = inner;
+        }
+
+        @Override
+        public boolean isImmutable() {
+            return false;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof FieldLocationIdentity) {
+                FieldLocationIdentity fieldLocationIdentity = (FieldLocationIdentity) obj;
+                return inner.equals(fieldLocationIdentity.inner);
+
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return inner.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return inner.getName();
+        }
+    }
+
+    public HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
+        this.holder = holder;
+        this.name = name;
+        this.type = type;
+        assert offset != -1;
+        assert offset == (int) offset : "offset larger than int";
+        this.offset = (int) offset;
+        this.modifiers = modifiers;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof HotSpotResolvedJavaField) {
+            HotSpotResolvedJavaFieldImpl that = (HotSpotResolvedJavaFieldImpl) obj;
+            if (that.offset != this.offset || that.isStatic() != this.isStatic()) {
+                return false;
+            } else if (this.holder.equals(that.holder)) {
+                assert this.name.equals(that.name) && this.type.equals(that.type);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public int getModifiers() {
+        return modifiers & ModifiersProvider.jvmFieldModifiers();
+    }
+
+    @Override
+    public boolean isInternal() {
+        return (modifiers & runtime().getConfig().jvmAccFieldInternal) != 0;
+    }
+
+    /**
+     * Determines if a given object contains this field.
+     *
+     * @return true iff this is a non-static field and its declaring class is assignable from
+     *         {@code object}'s class
+     */
+    public boolean isInObject(Object object) {
+        if (isStatic()) {
+            return false;
+        }
+        return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectTypeImpl.fromObjectClass(object.getClass()));
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
+        return holder;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public JavaType getType() {
+        // Pull field into local variable to prevent a race causing
+        // a ClassCastException below
+        JavaType currentType = type;
+        if (currentType instanceof HotSpotUnresolvedJavaType) {
+            // Don't allow unresolved types to hang around forever
+            HotSpotUnresolvedJavaType unresolvedType = (HotSpotUnresolvedJavaType) currentType;
+            ResolvedJavaType resolved = unresolvedType.reresolve(holder);
+            if (resolved != null) {
+                type = resolved;
+            }
+        }
+        return type;
+    }
+
+    public int offset() {
+        return offset;
+    }
+
+    @Override
+    public String toString() {
+        return format("HotSpotField<%H.%n %t:") + offset + ">";
+    }
+
+    @Override
+    public boolean isSynthetic() {
+        return (runtime().getConfig().syntheticFlag & modifiers) != 0;
+    }
+
+    /**
+     * Checks if this field has the {@link Stable} annotation.
+     *
+     * @return true if field has {@link Stable} annotation, false otherwise
+     */
+    public boolean isStable() {
+        if ((runtime().getConfig().jvmAccFieldStable & modifiers) != 0) {
+            return true;
+        }
+        assert getAnnotation(Stable.class) == null;
+        if (ImplicitStableValues.getValue() && isImplicitStableField()) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Annotation[] getAnnotations() {
+        Field javaField = toJava();
+        if (javaField != null) {
+            return javaField.getAnnotations();
+        }
+        return new Annotation[0];
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        Field javaField = toJava();
+        if (javaField != null) {
+            return javaField.getAnnotation(annotationClass);
+        }
+        return null;
+    }
+
+    private Field toJavaCache;
+
+    private Field toJava() {
+        if (toJavaCache != null) {
+            return toJavaCache;
+        }
+
+        if (isInternal()) {
+            return null;
+        }
+        try {
+            return toJavaCache = holder.mirror().getDeclaredField(name);
+        } catch (NoSuchFieldException | NoClassDefFoundError e) {
+            return null;
+        }
+    }
+
+    private boolean isArray() {
+        JavaType fieldType = getType();
+        return fieldType instanceof ResolvedJavaType && ((ResolvedJavaType) fieldType).isArray();
+    }
+
+    private boolean isImplicitStableField() {
+        if (isSynthetic()) {
+            if (isSyntheticImplicitStableField()) {
+                return true;
+            }
+        } else if (isWellKnownImplicitStableField()) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isSyntheticImplicitStableField() {
+        assert this.isSynthetic();
+        if (isStatic() && isArray()) {
+            if (isFinal() && name.equals("$VALUES") || name.equals("ENUM$VALUES")) {
+                // generated int[] field for EnumClass::values()
+                return true;
+            } else if (name.startsWith("$SwitchMap$") || name.startsWith("$SWITCH_TABLE$")) {
+                // javac and ecj generate a static field in an inner class for a switch on an enum
+                // named $SwitchMap$p$k$g$EnumClass and $SWITCH_TABLE$p$k$g$EnumClass, respectively
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isWellKnownImplicitStableField() {
+        return WellKnownImplicitStableField.test(this);
+    }
+
+    static class WellKnownImplicitStableField {
+        /**
+         * @return {@code true} if the field is a well-known stable field.
+         */
+        public static boolean test(HotSpotResolvedJavaField field) {
+            return field.equals(STRING_VALUE_FIELD);
+        }
+
+        private static final ResolvedJavaField STRING_VALUE_FIELD;
+        static {
+            try {
+                MetaAccessProvider metaAccess = runtime().getHostJVMCIBackend().getMetaAccess();
+                STRING_VALUE_FIELD = metaAccess.lookupJavaField(String.class.getDeclaredField("value"));
+            } catch (SecurityException | NoSuchFieldException e) {
+                throw new JVMCIError(e);
+            }
+        }
+    }
+
+    public LocationIdentity getLocationIdentity() {
+        return locationIdentity;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011, 2014, 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 jdk.vm.ci.hotspot;
+
+import java.lang.reflect.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Implementation of {@link JavaMethod} for resolved HotSpot methods.
+ */
+public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod {
+
+    /**
+     * Returns true if this method has a {@code CallerSensitive} annotation.
+     *
+     * @return true if CallerSensitive annotation present, false otherwise
+     */
+    boolean isCallerSensitive();
+
+    HotSpotResolvedObjectType getDeclaringClass();
+
+    /**
+     * Returns true if this method has a {@code ForceInline} annotation.
+     *
+     * @return true if ForceInline annotation present, false otherwise
+     */
+    boolean isForceInline();
+
+    /**
+     * Returns true if this method has a {@code DontInline} annotation.
+     *
+     * @return true if DontInline annotation present, false otherwise
+     */
+    boolean isDontInline();
+
+    /**
+     * Manually adds a DontInline annotation to this method.
+     */
+    void setNotInlineable();
+
+    /**
+     * Returns true if this method is one of the special methods that is ignored by security stack
+     * walks.
+     *
+     * @return true if special method ignored by security stack walks, false otherwise
+     */
+    boolean ignoredBySecurityStackWalk();
+
+    ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver);
+
+    /**
+     * Returns whether this method has compiled code.
+     *
+     * @return true if this method has compiled code, false otherwise
+     */
+    boolean hasCompiledCode();
+
+    /**
+     * @param level
+     * @return true if the currently installed code was generated at {@code level}.
+     */
+    boolean hasCompiledCodeAtLevel(int level);
+
+    default boolean isDefault() {
+        if (isConstructor()) {
+            return false;
+        }
+        // Copied from java.lang.Method.isDefault()
+        int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC;
+        return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface();
+    }
+
+    /**
+     * Returns the offset of this method into the v-table. The method must have a v-table entry as
+     * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is
+     * thrown.
+     *
+     * @return the offset of this method into the v-table
+     */
+    int vtableEntryOffset(ResolvedJavaType resolved);
+
+    int intrinsicId();
+
+    /**
+     * Allocates a compile id for this method by asking the VM for one.
+     *
+     * @param entryBCI entry bci
+     * @return compile id
+     */
+    int allocateCompileId(int entryBCI);
+
+    boolean hasCodeAtLevel(int entryBCI, int level);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,726 @@
+/*
+ * Copyright (c) 2011, 2014, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.Options.*;
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.options.*;
+
+/**
+ * Implementation of {@link JavaMethod} for resolved HotSpot methods.
+ */
+public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
+
+    public static class Options {
+        // @formatter:off
+        @Option(help = "", type = OptionType.Debug)
+        public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
+        // @formatter:on
+    }
+
+    /**
+     * Reference to metaspace Method object.
+     */
+    private final long metaspaceMethod;
+
+    private final HotSpotResolvedObjectTypeImpl holder;
+    private final HotSpotConstantPool constantPool;
+    private final HotSpotSignature signature;
+    private HotSpotMethodData methodData;
+    private byte[] code;
+    private Member toJavaCache;
+
+    /**
+     * Gets the holder of a HotSpot metaspace method native object.
+     *
+     * @param metaspaceMethod a metaspace Method object
+     * @return the {@link ResolvedJavaType} corresponding to the holder of the
+     *         {@code metaspaceMethod}
+     */
+    private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
+        HotSpotVMConfig config = runtime().getConfig();
+        final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset);
+        final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
+        return runtime().getCompilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
+    }
+
+    /**
+     * Gets the JVMCI mirror from a HotSpot method. The VM is responsible for ensuring that the
+     * Method* is kept alive for the duration of this call and the
+     * {@link HotSpotJVMCIMetaAccessContext} keeps it alive after that.
+     *
+     * Called from the VM.
+     *
+     * @param metaspaceMethod a metaspace Method object
+     * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod}
+     */
+    @SuppressWarnings("unused")
+    private static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceMethod) {
+        HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceMethod);
+        return holder.createMethod(metaspaceMethod);
+    }
+
+    HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceMethod) {
+        // It would be too much work to get the method name here so we fill it in later.
+        super(null);
+        this.metaspaceMethod = metaspaceMethod;
+        this.holder = holder;
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final long constMethod = getConstMethod();
+
+        /*
+         * Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for
+         * signature-polymorphic method handle methods) have their own constant pool instead of the
+         * one from their holder.
+         */
+        final long metaspaceConstantPool = UNSAFE.getAddress(constMethod + config.constMethodConstantsOffset);
+        if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
+            this.constantPool = holder.getConstantPool();
+        } else {
+            this.constantPool = runtime().getCompilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
+        }
+
+        final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);
+        this.name = constantPool.lookupUtf8(nameIndex);
+
+        final int signatureIndex = UNSAFE.getChar(constMethod + config.constMethodSignatureIndexOffset);
+        this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex);
+    }
+
+    /**
+     * Returns a pointer to this method's constant method data structure (
+     * {@code Method::_constMethod}). This pointer isn't wrapped since it should be safe to use it
+     * within the context of this HotSpotResolvedJavaMethodImpl since the Method* and ConstMethod*
+     * are kept alive as a pair.
+     *
+     * @return pointer to this method's ConstMethod
+     */
+    private long getConstMethod() {
+        assert metaspaceMethod != 0;
+        return UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodConstMethodOffset);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof HotSpotResolvedJavaMethodImpl) {
+            HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj;
+            return that.metaspaceMethod == metaspaceMethod;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) metaspaceMethod;
+    }
+
+    /**
+     * Returns this method's flags ({@code Method::_flags}).
+     *
+     * @return flags of this method
+     */
+    private int getFlags() {
+        return UNSAFE.getByte(metaspaceMethod + runtime().getConfig().methodFlagsOffset);
+    }
+
+    /**
+     * Returns this method's constant method flags ({@code ConstMethod::_flags}).
+     *
+     * @return flags of this method's ConstMethod
+     */
+    private int getConstMethodFlags() {
+        return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodFlagsOffset);
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
+        return holder;
+    }
+
+    /**
+     * Gets the address of the C++ Method object for this method.
+     */
+    public JavaConstant getMetaspaceMethodConstant() {
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false);
+    }
+
+    public long getMetaspaceMethod() {
+        return metaspaceMethod;
+    }
+
+    public long getMetaspacePointer() {
+        return getMetaspaceMethod();
+    }
+
+    @Override
+    public JavaConstant getEncoding() {
+        return getMetaspaceMethodConstant();
+    }
+
+    /**
+     * Gets the complete set of modifiers for this method which includes the JVM specification
+     * modifiers as well as the HotSpot internal modifiers.
+     */
+    public int getAllModifiers() {
+        return UNSAFE.getInt(metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset);
+    }
+
+    @Override
+    public int getModifiers() {
+        return getAllModifiers() & ModifiersProvider.jvmMethodModifiers();
+    }
+
+    @Override
+    public boolean canBeStaticallyBound() {
+        return (isFinal() || isPrivate() || isStatic() || holder.isLeaf()) && isConcrete();
+    }
+
+    @Override
+    public byte[] getCode() {
+        if (getCodeSize() == 0) {
+            return null;
+        }
+        if (code == null && holder.isLinked()) {
+            code = runtime().getCompilerToVM().getBytecode(this);
+            assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length;
+        }
+        return code;
+    }
+
+    @Override
+    public int getCodeSize() {
+        return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodCodeSizeOffset);
+    }
+
+    @Override
+    public ExceptionHandler[] getExceptionHandlers() {
+        final boolean hasExceptionTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasExceptionTable) != 0;
+        if (!hasExceptionTable) {
+            return new ExceptionHandler[0];
+        }
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final int exceptionTableLength = runtime().getCompilerToVM().getExceptionTableLength(this);
+        ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
+        long exceptionTableElement = runtime().getCompilerToVM().getExceptionTableStart(this);
+
+        for (int i = 0; i < exceptionTableLength; i++) {
+            final int startPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset);
+            final int endPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementEndPcOffset);
+            final int handlerPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementHandlerPcOffset);
+            int catchTypeIndex = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementCatchTypeIndexOffset);
+
+            JavaType catchType;
+            if (catchTypeIndex == 0) {
+                catchType = null;
+            } else {
+                final int opcode = -1;  // opcode is not used
+                catchType = constantPool.lookupType(catchTypeIndex, opcode);
+
+                // Check for Throwable which catches everything.
+                if (catchType instanceof HotSpotResolvedObjectTypeImpl) {
+                    HotSpotResolvedObjectTypeImpl resolvedType = (HotSpotResolvedObjectTypeImpl) catchType;
+                    if (resolvedType.mirror() == Throwable.class) {
+                        catchTypeIndex = 0;
+                        catchType = null;
+                    }
+                }
+            }
+            handlers[i] = new ExceptionHandler(startPc, endPc, handlerPc, catchTypeIndex, catchType);
+
+            // Go to the next ExceptionTableElement
+            exceptionTableElement += config.exceptionTableElementSize;
+        }
+
+        return handlers;
+    }
+
+    /**
+     * Returns true if this method has a {@code CallerSensitive} annotation.
+     *
+     * @return true if CallerSensitive annotation present, false otherwise
+     */
+    public boolean isCallerSensitive() {
+        return (getFlags() & runtime().getConfig().methodFlagsCallerSensitive) != 0;
+    }
+
+    /**
+     * Returns true if this method has a {@code ForceInline} annotation.
+     *
+     * @return true if ForceInline annotation present, false otherwise
+     */
+    public boolean isForceInline() {
+        return (getFlags() & runtime().getConfig().methodFlagsForceInline) != 0;
+    }
+
+    /**
+     * Returns true if this method has a {@code DontInline} annotation.
+     *
+     * @return true if DontInline annotation present, false otherwise
+     */
+    public boolean isDontInline() {
+        return (getFlags() & runtime().getConfig().methodFlagsDontInline) != 0;
+    }
+
+    /**
+     * Manually adds a DontInline annotation to this method.
+     */
+    public void setNotInlineable() {
+        runtime().getCompilerToVM().doNotInlineOrCompile(this);
+    }
+
+    /**
+     * Returns true if this method is one of the special methods that is ignored by security stack
+     * walks.
+     *
+     * @return true if special method ignored by security stack walks, false otherwise
+     */
+    public boolean ignoredBySecurityStackWalk() {
+        return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(this);
+    }
+
+    @Override
+    public boolean isClassInitializer() {
+        return "<clinit>".equals(name) && isStatic();
+    }
+
+    @Override
+    public boolean isConstructor() {
+        return "<init>".equals(name) && !isStatic();
+    }
+
+    @Override
+    public int getMaxLocals() {
+        if (isAbstract() || isNative()) {
+            return 0;
+        }
+        HotSpotVMConfig config = runtime().getConfig();
+        return UNSAFE.getChar(getConstMethod() + config.methodMaxLocalsOffset);
+    }
+
+    @Override
+    public int getMaxStackSize() {
+        if (isAbstract() || isNative()) {
+            return 0;
+        }
+        HotSpotVMConfig config = runtime().getConfig();
+        return config.extraStackEntries + UNSAFE.getChar(getConstMethod() + config.constMethodMaxStackOffset);
+    }
+
+    @Override
+    public StackTraceElement asStackTraceElement(int bci) {
+        if (bci < 0 || bci >= getCodeSize()) {
+            // HotSpot code can only construct stack trace elements for valid bcis
+            StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(this, 0);
+            return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
+        }
+        return runtime().getCompilerToVM().getStackTraceElement(this, bci);
+    }
+
+    public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
+        if (receiver.isInterface()) {
+            // Cannot trust interfaces. Because of:
+            // interface I { void foo(); }
+            // class A { public void foo() {} }
+            // class B extends A implements I { }
+            // class C extends B { public void foo() { } }
+            // class D extends B { }
+            // Would lead to identify C.foo() as the unique concrete method for I.foo() without
+            // seeing A.foo().
+            return null;
+        }
+        return runtime().getCompilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
+    }
+
+    @Override
+    public HotSpotSignature getSignature() {
+        return signature;
+    }
+
+    /**
+     * Gets the value of {@code Method::_code}.
+     *
+     * @return the value of {@code Method::_code}
+     */
+    private long getCompiledCode() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return UNSAFE.getAddress(metaspaceMethod + config.methodCodeOffset);
+    }
+
+    /**
+     * Returns whether this method has compiled code.
+     *
+     * @return true if this method has compiled code, false otherwise
+     */
+    public boolean hasCompiledCode() {
+        return getCompiledCode() != 0L;
+    }
+
+    /**
+     * @param level
+     * @return true if the currently installed code was generated at {@code level}.
+     */
+    public boolean hasCompiledCodeAtLevel(int level) {
+        long compiledCode = getCompiledCode();
+        if (compiledCode != 0) {
+            return UNSAFE.getInt(compiledCode + runtime().getConfig().nmethodCompLevelOffset) == level;
+        }
+        return false;
+    }
+
+    private static final String TraceMethodDataFilter = System.getProperty("jvmci.traceMethodDataFilter");
+
+    @Override
+    public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
+        ProfilingInfo info;
+
+        if (UseProfilingInformation.getValue() && methodData == null) {
+            long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodDataOffset);
+            if (metaspaceMethodData != 0) {
+                methodData = new HotSpotMethodData(metaspaceMethodData, this);
+                if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
+                    System.out.println("Raw method data for " + this.format("%H.%n(%p)") + ":");
+                    System.out.println(methodData.toString());
+                }
+            }
+        }
+
+        if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) {
+            // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in
+            // case of a deoptimization.
+            info = DefaultProfilingInfo.get(TriState.FALSE);
+        } else {
+            info = new HotSpotProfilingInfo(methodData, this, includeNormal, includeOSR);
+        }
+        return info;
+    }
+
+    @Override
+    public void reprofile() {
+        runtime().getCompilerToVM().reprofile(this);
+    }
+
+    @Override
+    public ConstantPool getConstantPool() {
+        return constantPool;
+    }
+
+    @Override
+    public Annotation[][] getParameterAnnotations() {
+        if (isConstructor()) {
+            Constructor<?> javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getParameterAnnotations();
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getParameterAnnotations();
+    }
+
+    @Override
+    public Annotation[] getAnnotations() {
+        if (isConstructor()) {
+            Constructor<?> javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? new Annotation[0] : javaConstructor.getAnnotations();
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        if (isConstructor()) {
+            Constructor<?> javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass);
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
+    }
+
+    public boolean isDefault() {
+        if (isConstructor()) {
+            return false;
+        }
+        // Copied from java.lang.Method.isDefault()
+        int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC;
+        return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface();
+    }
+
+    @Override
+    public Type[] getGenericParameterTypes() {
+        if (isConstructor()) {
+            Constructor<?> javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes();
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
+    }
+
+    public Class<?>[] signatureToTypes() {
+        Signature sig = getSignature();
+        int count = sig.getParameterCount(false);
+        Class<?>[] result = new Class<?>[count];
+        for (int i = 0; i < result.length; ++i) {
+            JavaType parameterType = sig.getParameterType(i, holder);
+            HotSpotResolvedJavaType resolvedParameterType = (HotSpotResolvedJavaType) parameterType.resolve(holder);
+            result[i] = resolvedParameterType.mirror();
+        }
+        return result;
+    }
+
+    private Method toJava() {
+        if (toJavaCache != null) {
+            return (Method) toJavaCache;
+        }
+        try {
+            Method result = holder.mirror().getDeclaredMethod(name, signatureToTypes());
+            toJavaCache = result;
+            return result;
+        } catch (NoSuchMethodException | NoClassDefFoundError e) {
+            return null;
+        }
+    }
+
+    private Constructor<?> toJavaConstructor() {
+        if (toJavaCache != null) {
+            return (Constructor<?>) toJavaCache;
+        }
+        try {
+            Constructor<?> result = holder.mirror().getDeclaredConstructor(signatureToTypes());
+            toJavaCache = result;
+            return result;
+        } catch (NoSuchMethodException | NoClassDefFoundError e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean canBeInlined() {
+        if (isDontInline()) {
+            return false;
+        }
+        return runtime().getCompilerToVM().canInlineMethod(this);
+    }
+
+    @Override
+    public boolean shouldBeInlined() {
+        if (isForceInline()) {
+            return true;
+        }
+        return runtime().getCompilerToVM().shouldInlineMethod(this);
+    }
+
+    @Override
+    public LineNumberTable getLineNumberTable() {
+        final boolean hasLineNumberTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLineNumberTable) != 0;
+        if (!hasLineNumberTable) {
+            return null;
+        }
+
+        long[] values = runtime().getCompilerToVM().getLineNumberTable(this);
+        if (values == null || values.length == 0) {
+            // Empty table so treat is as non-existent
+            return null;
+        }
+        assert values.length % 2 == 0;
+        int[] bci = new int[values.length / 2];
+        int[] line = new int[values.length / 2];
+
+        for (int i = 0; i < values.length / 2; i++) {
+            bci[i] = (int) values[i * 2];
+            line[i] = (int) values[i * 2 + 1];
+        }
+
+        return new LineNumberTableImpl(line, bci);
+    }
+
+    @Override
+    public LocalVariableTable getLocalVariableTable() {
+        final boolean hasLocalVariableTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLocalVariableTable) != 0;
+        if (!hasLocalVariableTable) {
+            return null;
+        }
+
+        HotSpotVMConfig config = runtime().getConfig();
+        long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(this);
+        final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(this);
+        Local[] locals = new Local[localVariableTableLength];
+
+        for (int i = 0; i < localVariableTableLength; i++) {
+            final int startBci = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementStartBciOffset);
+            final int endBci = startBci + UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementLengthOffset);
+            final int nameCpIndex = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementNameCpIndexOffset);
+            final int typeCpIndex = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementDescriptorCpIndexOffset);
+            final int slot = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementSlotOffset);
+
+            String localName = getConstantPool().lookupUtf8(nameCpIndex);
+            String localType = getConstantPool().lookupUtf8(typeCpIndex);
+
+            locals[i] = new LocalImpl(localName, runtime().lookupType(localType, holder, false), startBci, endBci, slot);
+
+            // Go to the next LocalVariableTableElement
+            localVariableTableElement += config.localVariableTableElementSize;
+        }
+
+        return new LocalVariableTableImpl(locals);
+    }
+
+    /**
+     * Returns the offset of this method into the v-table. The method must have a v-table entry as
+     * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is
+     * thrown.
+     *
+     * @return the offset of this method into the v-table
+     */
+    public int vtableEntryOffset(ResolvedJavaType resolved) {
+        if (!isInVirtualMethodTable(resolved)) {
+            throw new JVMCIError("%s does not have a vtable entry in type %s", this, resolved);
+        }
+        HotSpotVMConfig config = runtime().getConfig();
+        final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
+        return config.instanceKlassVtableStartOffset() + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
+    }
+
+    @Override
+    public boolean isInVirtualMethodTable(ResolvedJavaType resolved) {
+        if (resolved instanceof HotSpotResolvedObjectTypeImpl) {
+            HotSpotResolvedObjectTypeImpl hotspotResolved = (HotSpotResolvedObjectTypeImpl) resolved;
+            int vtableIndex = getVtableIndex(hotspotResolved);
+            return vtableIndex >= 0 && vtableIndex < hotspotResolved.getVtableLength();
+        }
+        return false;
+    }
+
+    private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) {
+        if (!holder.isLinked()) {
+            return runtime().getConfig().invalidVtableIndex;
+        }
+        if (holder.isInterface()) {
+            if (resolved.isInterface()) {
+                return runtime().getConfig().invalidVtableIndex;
+            }
+            return getVtableIndexForInterfaceMethod(resolved);
+        }
+        return getVtableIndex();
+    }
+
+    /**
+     * Returns this method's virtual table index.
+     *
+     * @return virtual table index
+     */
+    private int getVtableIndex() {
+        assert!holder.isInterface();
+        HotSpotVMConfig config = runtime().getConfig();
+        int result = UNSAFE.getInt(metaspaceMethod + config.methodVtableIndexOffset);
+        assert result >= config.nonvirtualVtableIndex : "must be linked";
+        return result;
+    }
+
+    private int getVtableIndexForInterfaceMethod(ResolvedJavaType resolved) {
+        HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved;
+        return runtime().getCompilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this);
+    }
+
+    /**
+     * The {@link SpeculationLog} for methods compiled by JVMCI hang off this per-declaring-type
+     * {@link ClassValue}. The raw Method* value is safe to use as a key in the map as a) it is
+     * never moves and b) we never read from it.
+     * <p>
+     * One implication is that we will preserve {@link SpeculationLog}s for methods that have been
+     * redefined via class redefinition. It's tempting to periodically flush such logs but we cannot
+     * read the JVM_ACC_IS_OBSOLETE bit (or anything else) via the raw pointer as obsoleted methods
+     * are subject to clean up and deletion (see InstanceKlass::purge_previous_versions_internal).
+     */
+    private static final ClassValue<Map<Long, SpeculationLog>> SpeculationLogs = new ClassValue<Map<Long, SpeculationLog>>() {
+        @Override
+        protected Map<Long, SpeculationLog> computeValue(java.lang.Class<?> type) {
+            return new HashMap<>(4);
+        }
+    };
+
+    public SpeculationLog getSpeculationLog() {
+        Map<Long, SpeculationLog> map = SpeculationLogs.get(holder.mirror());
+        synchronized (map) {
+            SpeculationLog log = map.get(this.metaspaceMethod);
+            if (log == null) {
+                log = new HotSpotSpeculationLog();
+                map.put(metaspaceMethod, log);
+            }
+            return log;
+        }
+    }
+
+    public int intrinsicId() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
+    }
+
+    @Override
+    public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) {
+        assert!isConstructor();
+        Method javaMethod = toJava();
+        javaMethod.setAccessible(true);
+
+        Object[] objArguments = new Object[arguments.length];
+        for (int i = 0; i < arguments.length; i++) {
+            objArguments[i] = HotSpotObjectConstantImpl.asBoxedValue(arguments[i]);
+        }
+        Object objReceiver = receiver != null && !receiver.isNull() ? ((HotSpotObjectConstantImpl) receiver).object() : null;
+
+        try {
+            Object objResult = javaMethod.invoke(objReceiver, objArguments);
+            return javaMethod.getReturnType() == void.class ? null : HotSpotObjectConstantImpl.forBoxedValue(getSignature().getReturnKind(), objResult);
+
+        } catch (IllegalAccessException | InvocationTargetException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+
+    /**
+     * Allocates a compile id for this method by asking the VM for one.
+     *
+     * @param entryBCI entry bci
+     * @return compile id
+     */
+    public int allocateCompileId(int entryBCI) {
+        return runtime().getCompilerToVM().allocateCompileId(this, entryBCI);
+    }
+
+    public boolean hasCodeAtLevel(int entryBCI, int level) {
+        if (entryBCI == runtime().getConfig().invocationEntryBci) {
+            return hasCompiledCodeAtLevel(level);
+        }
+        return runtime().getCompilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {
+
+    public HotSpotResolvedJavaType(String name) {
+        super(name);
+    }
+
+    public abstract Class<?> mirror();
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (!(obj instanceof HotSpotResolvedJavaType)) {
+            return false;
+        }
+        HotSpotResolvedJavaType that = (HotSpotResolvedJavaType) obj;
+        return this.mirror().equals(that.mirror());
+    }
+
+    @Override
+    public final int hashCode() {
+        return getName().hashCode();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Assumptions.*;
+
+/**
+ * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
+ */
+public interface HotSpotResolvedObjectType extends ResolvedJavaType {
+
+    HotSpotResolvedObjectType getArrayClass();
+
+    ResolvedJavaType getComponentType();
+
+    AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype();
+
+    HotSpotResolvedObjectType getSuperclass();
+
+    HotSpotResolvedObjectType[] getInterfaces();
+
+    HotSpotResolvedObjectType getSupertype();
+
+    HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType);
+
+    HotSpotResolvedObjectType asExactType();
+
+    default boolean isPrimitive() {
+        return false;
+    }
+
+    default JavaKind getJavaKind() {
+        return JavaKind.Object;
+    }
+
+    ConstantPool getConstantPool();
+
+    /**
+     * Gets the instance size of this type. If an instance of this type cannot be fast path
+     * allocated, then the returned value is negative (its absolute value gives the size). Must not
+     * be called if this is an array or interface type.
+     */
+    int instanceSize();
+
+    int getVtableLength();
+
+    @Override
+    AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method);
+
+    /**
+     * Performs a fast-path check that this type is resolved in the context of a given accessing
+     * class. A negative result does not mean this type is not resolved with respect to
+     * {@code accessingClass}. That can only be determined by
+     * {@linkplain HotSpotJVMCIRuntime#lookupType(String, HotSpotResolvedObjectType, boolean)
+     * re-resolving} the type.
+     */
+    boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass);
+
+    /**
+     * Gets the metaspace Klass boxed in a {@link JavaConstant}.
+     */
+    Constant klass();
+
+    boolean isPrimaryType();
+
+    int superCheckOffset();
+
+    long prototypeMarkWord();
+
+    int layoutHelper();
+
+    HotSpotResolvedObjectType getEnclosingType();
+
+    ResolvedJavaMethod getClassInitializer();
+
+    ResolvedJavaField createField(String name, JavaType type, long offset, int modifiers);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,889 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static java.util.Objects.*;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.nio.*;
+import java.util.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Assumptions.*;
+
+/**
+ * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
+ */
+public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
+
+    /**
+     * The Java class this type represents.
+     */
+    private final Class<?> javaClass;
+    private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
+    private HashMap<Long, HotSpotResolvedJavaMethodImpl> methodCache;
+    private HotSpotResolvedJavaField[] instanceFields;
+    private HotSpotResolvedObjectTypeImpl[] interfaces;
+    private HotSpotConstantPool constantPool;
+    final HotSpotJVMCIMetaAccessContext context;
+    private HotSpotResolvedObjectType arrayOfType;
+
+    /**
+     * Gets the JVMCI mirror for a {@link Class} object.
+     *
+     * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
+     */
+    public static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
+        return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(javaClass);
+    }
+
+    /**
+     * Gets the JVMCI mirror from a HotSpot type. Since {@link Class} is already a proxy for the
+     * underlying Klass*, it is used instead of the raw Klass*.
+     *
+     * Called from the VM.
+     *
+     * @param javaClass a {@link Class} object
+     * @return the {@link ResolvedJavaType} corresponding to {@code javaClass}
+     */
+    @SuppressWarnings("unused")
+    private static HotSpotResolvedObjectTypeImpl fromMetaspace(Class<?> javaClass) {
+        return fromObjectClass(javaClass);
+    }
+
+    /**
+     * Creates the JVMCI mirror for a {@link Class} object.
+     *
+     * <p>
+     * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
+     * {@link Class} type. Use {@link #fromObjectClass(Class)} or {@link #fromMetaspace(Class)}
+     * instead.
+     * </p>
+     *
+     * @param javaClass the Class to create the mirror for
+     * @param context
+     */
+    HotSpotResolvedObjectTypeImpl(Class<?> javaClass, HotSpotJVMCIMetaAccessContext context) {
+        super(getSignatureName(javaClass));
+        this.javaClass = javaClass;
+        this.context = context;
+        assert getName().charAt(0) != '[' || isArray() : getName();
+    }
+
+    /**
+     * Returns the name of this type as it would appear in a signature.
+     */
+    private static String getSignatureName(Class<?> javaClass) {
+        if (javaClass.isArray()) {
+            return javaClass.getName().replace('.', '/');
+        }
+        return "L" + javaClass.getName().replace('.', '/') + ";";
+    }
+
+    /**
+     * Gets the metaspace Klass for this type.
+     */
+    public long getMetaspaceKlass() {
+        if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
+            return UNSAFE.getLong(javaClass, (long) runtime().getConfig().klassOffset);
+        }
+        return UNSAFE.getInt(javaClass, (long) runtime().getConfig().klassOffset) & 0xFFFFFFFFL;
+    }
+
+    public long getMetaspacePointer() {
+        return getMetaspaceKlass();
+    }
+
+    @Override
+    public int getModifiers() {
+        if (isArray()) {
+            return (getElementalType().getModifiers() & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) | Modifier.FINAL | Modifier.ABSTRACT;
+        } else {
+            return getAccessFlags() & ModifiersProvider.jvmClassModifiers();
+        }
+    }
+
+    public int getAccessFlags() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
+    }
+
+    @Override
+    public HotSpotResolvedObjectType getArrayClass() {
+        if (arrayOfType == null) {
+            arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
+        }
+        return arrayOfType;
+    }
+
+    @Override
+    public ResolvedJavaType getComponentType() {
+        Class<?> javaComponentType = mirror().getComponentType();
+        return javaComponentType == null ? null : runtime().fromClass(javaComponentType);
+    }
+
+    @Override
+    public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (isArray()) {
+            return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
+        } else if (isInterface()) {
+            HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
+            /*
+             * If the implementor field contains itself that indicates that the interface has more
+             * than one implementors (see: InstanceKlass::add_implementor).
+             */
+            if (implementor == null || implementor.equals(this)) {
+                return null;
+            }
+
+            assert !implementor.isInterface();
+            if (implementor.isAbstract() || !implementor.isLeafClass()) {
+                AssumptionResult<ResolvedJavaType> leafConcreteSubtype = implementor.findLeafConcreteSubtype();
+                if (leafConcreteSubtype != null) {
+                    assert !leafConcreteSubtype.getResult().equals(implementor);
+                    AssumptionResult<ResolvedJavaType> newResult = new AssumptionResult<>(leafConcreteSubtype.getResult(), new ConcreteSubtype(this, implementor));
+                    // Accumulate leaf assumptions and return the combined result.
+                    newResult.add(leafConcreteSubtype);
+                    return newResult;
+                }
+                return null;
+            }
+
+            return new AssumptionResult<>(implementor, new LeafType(implementor), new ConcreteSubtype(this, implementor));
+        } else {
+            HotSpotResolvedObjectTypeImpl type = this;
+            while (type.isAbstract()) {
+                HotSpotResolvedObjectTypeImpl subklass = type.getSubklass();
+                if (subklass == null || UNSAFE.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) {
+                    return null;
+                }
+                type = subklass;
+            }
+            if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
+                return null;
+            }
+            if (this.isAbstract()) {
+                return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
+            } else {
+                assert this.equals(type);
+                return new AssumptionResult<>(type, new LeafType(type));
+            }
+        }
+    }
+
+    /**
+     * Returns if type {@code type} is a leaf class. This is the case if the
+     * {@code Klass::_subklass} field of the underlying class is zero.
+     *
+     * @return true if the type is a leaf class
+     */
+    private boolean isLeafClass() {
+        return getSubklass() == null;
+    }
+
+    /**
+     * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given
+     * type {@code type}.
+     *
+     * @return value of the subklass field as metaspace klass pointer
+     */
+    private HotSpotResolvedObjectTypeImpl getSubklass() {
+        return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().subklassOffset, false);
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getSuperclass() {
+        Class<?> javaSuperclass = mirror().getSuperclass();
+        return javaSuperclass == null ? null : fromObjectClass(javaSuperclass);
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl[] getInterfaces() {
+        if (interfaces == null) {
+            Class<?>[] javaInterfaces = mirror().getInterfaces();
+            HotSpotResolvedObjectTypeImpl[] result = new HotSpotResolvedObjectTypeImpl[javaInterfaces.length];
+            for (int i = 0; i < javaInterfaces.length; i++) {
+                result[i] = fromObjectClass(javaInterfaces[i]);
+            }
+            interfaces = result;
+        }
+        return interfaces;
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getSingleImplementor() {
+        if (!isInterface()) {
+            throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this);
+        }
+        return runtime().getCompilerToVM().getImplementor(this);
+    }
+
+    public HotSpotResolvedObjectTypeImpl getSupertype() {
+        if (isArray()) {
+            ResolvedJavaType componentType = getComponentType();
+            if (mirror() == Object[].class || componentType.isPrimitive()) {
+                return fromObjectClass(Object.class);
+            }
+            return (HotSpotResolvedObjectTypeImpl) ((HotSpotResolvedObjectTypeImpl) componentType).getSupertype().getArrayClass();
+        }
+        if (isInterface()) {
+            return fromObjectClass(Object.class);
+        }
+        return getSuperclass();
+    }
+
+    @Override
+    public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) {
+        if (otherType.isPrimitive()) {
+            return null;
+        } else {
+            HotSpotResolvedObjectTypeImpl t1 = this;
+            HotSpotResolvedObjectTypeImpl t2 = (HotSpotResolvedObjectTypeImpl) otherType;
+            while (true) {
+                if (t1.isAssignableFrom(t2)) {
+                    return t1;
+                }
+                if (t2.isAssignableFrom(t1)) {
+                    return t2;
+                }
+                t1 = t1.getSupertype();
+                t2 = t2.getSupertype();
+            }
+        }
+    }
+
+    @Override
+    public HotSpotResolvedObjectType asExactType() {
+        return isLeaf() ? this : null;
+    }
+
+    @Override
+    public JavaConstant getJavaClass() {
+        return HotSpotObjectConstantImpl.forObject(mirror());
+    }
+
+    @Override
+    public JavaConstant getObjectHub() {
+        return klass();
+    }
+
+    @Override
+    public AssumptionResult<Boolean> hasFinalizableSubclass() {
+        assert !isArray();
+        if (!runtime().getCompilerToVM().hasFinalizableSubclass(this)) {
+            return new AssumptionResult<>(false, new NoFinalizableSubclass(this));
+        }
+        return new AssumptionResult<>(true);
+    }
+
+    @Override
+    public boolean hasFinalizer() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return false;
+    }
+
+    @Override
+    public boolean isArray() {
+        return mirror().isArray();
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized;
+    }
+
+    @Override
+    public boolean isLinked() {
+        return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked;
+    }
+
+    /**
+     * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace
+     * klass.
+     *
+     * @return state field value of this type
+     */
+    private int getInitState() {
+        assert !isArray() : "_init_state only exists in InstanceKlass";
+        return UNSAFE.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF;
+    }
+
+    @Override
+    public void initialize() {
+        if (!isInitialized()) {
+            UNSAFE.ensureClassInitialized(mirror());
+            assert isInitialized();
+        }
+    }
+
+    @Override
+    public boolean isInstance(JavaConstant obj) {
+        if (obj.getJavaKind() == JavaKind.Object && !obj.isNull()) {
+            return mirror().isInstance(((HotSpotObjectConstantImpl) obj).object());
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isInstanceClass() {
+        return !isArray() && !isInterface();
+    }
+
+    @Override
+    public boolean isInterface() {
+        return mirror().isInterface();
+    }
+
+    @Override
+    public boolean isAssignableFrom(ResolvedJavaType other) {
+        assert other != null;
+        if (other instanceof HotSpotResolvedObjectTypeImpl) {
+            HotSpotResolvedObjectTypeImpl otherType = (HotSpotResolvedObjectTypeImpl) other;
+            return mirror().isAssignableFrom(otherType.mirror());
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isJavaLangObject() {
+        return javaClass.equals(Object.class);
+    }
+
+    @Override
+    public JavaKind getJavaKind() {
+        return JavaKind.Object;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
+        ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType);
+        if (resolvedMethod == null || resolvedMethod.isAbstract()) {
+            return null;
+        }
+        return resolvedMethod;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
+        assert !callerType.isArray();
+        if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic()) {
+            return method;
+        }
+        if (!method.getDeclaringClass().isAssignableFrom(this)) {
+            return null;
+        }
+        HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
+        HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType;
+        return runtime().getCompilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
+    }
+
+    public HotSpotConstantPool getConstantPool() {
+        if (constantPool == null) {
+            constantPool = runtime().getCompilerToVM().getConstantPool(this, runtime().getConfig().instanceKlassConstantsOffset);
+        }
+        return constantPool;
+    }
+
+    /**
+     * Gets the instance size of this type. If an instance of this type cannot be fast path
+     * allocated, then the returned value is negative (its absolute value gives the size). Must not
+     * be called if this is an array or interface type.
+     */
+    public int instanceSize() {
+        assert !isArray();
+        assert !isInterface();
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final int layoutHelper = layoutHelper();
+        assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance";
+
+        // See: Klass::layout_helper_size_in_bytes
+        int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit;
+
+        // See: Klass::layout_helper_needs_slow_path
+        boolean needsSlowPath = (layoutHelper & config.klassLayoutHelperInstanceSlowPathBit) != 0;
+
+        return needsSlowPath ? -size : size;
+    }
+
+    public int layoutHelper() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return UNSAFE.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset);
+    }
+
+    synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
+        HotSpotResolvedJavaMethodImpl method = null;
+        if (methodCache == null) {
+            methodCache = new HashMap<>(8);
+        } else {
+            method = methodCache.get(metaspaceMethod);
+        }
+        if (method == null) {
+            method = new HotSpotResolvedJavaMethodImpl(this, metaspaceMethod);
+            methodCache.put(metaspaceMethod, method);
+            context.add(method);
+        }
+        return method;
+    }
+
+    public int getVtableLength() {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (isInterface() || isArray()) {
+            /* Everything has the core vtable of java.lang.Object */
+            return config.baseVtableLength();
+        }
+        int result = UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
+        assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize;
+        return result;
+    }
+
+    public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
+        HotSpotResolvedJavaField result = null;
+
+        final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers();
+
+        final long id = offset + ((long) flags << 32);
+
+        // Must cache the fields, because the local load elimination only works if the
+        // objects from two field lookups are identical.
+        if (fieldCache == null) {
+            fieldCache = new HashMap<>(8);
+        } else {
+            result = fieldCache.get(id);
+        }
+
+        if (result == null) {
+            result = new HotSpotResolvedJavaFieldImpl(this, fieldName, type, offset, rawFlags);
+            fieldCache.put(id, result);
+        } else {
+            assert result.getName().equals(fieldName);
+            // assert result.getType().equals(type);
+            assert result.offset() == offset;
+            assert result.getModifiers() == flags;
+        }
+
+        return result;
+    }
+
+    @Override
+    public AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method) {
+        HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method;
+        HotSpotResolvedObjectType declaredHolder = hmethod.getDeclaringClass();
+        /*
+         * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared
+         * holder, usually because of phis, so make sure that the type is related to the declared
+         * type before using it for lookup. Unlinked types should also be ignored because we can't
+         * resolve the proper method to invoke. Generally unlinked types in invokes should result in
+         * a deopt instead since they can't really be used if they aren't linked yet.
+         */
+        if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) {
+            ResolvedJavaMethod result = hmethod.uniqueConcreteMethod(declaredHolder);
+            if (result != null) {
+                return new AssumptionResult<>(result, new ConcreteMethod(method, declaredHolder, result));
+            }
+            return null;
+        }
+        /*
+         * The holder may be a subtype of the declaredHolder so make sure to resolve the method to
+         * the correct method for the subtype.
+         */
+        HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this);
+        if (resolvedMethod == null) {
+            // The type isn't known to implement the method.
+            return null;
+        }
+
+        ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this);
+        if (result != null) {
+            return new AssumptionResult<>(result, new ConcreteMethod(method, this, result));
+        }
+        return null;
+    }
+
+    /**
+     * This class represents the field information for one field contained in the fields array of an
+     * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class.
+     */
+    private class FieldInfo {
+        /**
+         * Native pointer into the array of Java shorts.
+         */
+        private final long metaspaceData;
+
+        /**
+         * Creates a field info for the field in the fields array at index {@code index}.
+         *
+         * @param index index to the fields array
+         */
+        public FieldInfo(int index) {
+            HotSpotVMConfig config = runtime().getConfig();
+            // Get Klass::_fields
+            final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
+            assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
+            metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index;
+        }
+
+        private int getAccessFlags() {
+            return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset);
+        }
+
+        private int getNameIndex() {
+            return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset);
+        }
+
+        private int getSignatureIndex() {
+            return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset);
+        }
+
+        public int getOffset() {
+            HotSpotVMConfig config = runtime().getConfig();
+            final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
+            final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
+            final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
+            return offset;
+        }
+
+        /**
+         * Helper method to read an entry (slot) from the field array. Currently field info is laid
+         * on top an array of Java shorts.
+         */
+        private int readFieldSlot(int index) {
+            return UNSAFE.getChar(metaspaceData + Short.BYTES * index);
+        }
+
+        /**
+         * Returns the name of this field as a {@link String}. If the field is an internal field the
+         * name index is pointing into the vmSymbols table.
+         */
+        public String getName() {
+            final int nameIndex = getNameIndex();
+            return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : getConstantPool().lookupUtf8(nameIndex);
+        }
+
+        /**
+         * Returns the signature of this field as {@link String}. If the field is an internal field
+         * the signature index is pointing into the vmSymbols table.
+         */
+        public String getSignature() {
+            final int signatureIndex = getSignatureIndex();
+            return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : getConstantPool().lookupUtf8(signatureIndex);
+        }
+
+        public JavaType getType() {
+            String signature = getSignature();
+            return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false);
+        }
+
+        private boolean isInternal() {
+            return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0;
+        }
+
+        public boolean isStatic() {
+            return Modifier.isStatic(getAccessFlags());
+        }
+
+        public boolean hasGenericSignature() {
+            return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0;
+        }
+    }
+
+    private static class OffsetComparator implements java.util.Comparator<HotSpotResolvedJavaField> {
+        @Override
+        public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) {
+            return o1.offset() - o2.offset();
+        }
+    }
+
+    @Override
+    public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
+        if (instanceFields == null) {
+            if (isArray() || isInterface()) {
+                instanceFields = new HotSpotResolvedJavaField[0];
+            } else {
+                final int fieldCount = getFieldCount();
+                ArrayList<HotSpotResolvedJavaField> fieldsArray = new ArrayList<>(fieldCount);
+
+                for (int i = 0; i < fieldCount; i++) {
+                    FieldInfo field = new FieldInfo(i);
+
+                    // We are only interested in instance fields.
+                    if (!field.isStatic()) {
+                        HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags());
+                        fieldsArray.add(resolvedJavaField);
+                    }
+                }
+
+                fieldsArray.sort(new OffsetComparator());
+
+                HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]);
+
+                if (mirror() != Object.class) {
+                    HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true);
+                    HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length);
+                    System.arraycopy(myFields, 0, fields, superFields.length, myFields.length);
+                    instanceFields = fields;
+                } else {
+                    assert myFields.length == 0 : "java.lang.Object has fields!";
+                    instanceFields = myFields;
+                }
+
+            }
+        }
+        if (!includeSuperclasses) {
+            int myFieldsStart = 0;
+            while (myFieldsStart < instanceFields.length && !instanceFields[myFieldsStart].getDeclaringClass().equals(this)) {
+                myFieldsStart++;
+            }
+            if (myFieldsStart == 0) {
+                return instanceFields;
+            }
+            if (myFieldsStart == instanceFields.length) {
+                return new HotSpotResolvedJavaField[0];
+            }
+            return Arrays.copyOfRange(instanceFields, myFieldsStart, instanceFields.length);
+        }
+        return instanceFields;
+    }
+
+    @Override
+    public ResolvedJavaField[] getStaticFields() {
+        if (isArray()) {
+            return new HotSpotResolvedJavaField[0];
+        } else {
+            final int fieldCount = getFieldCount();
+            ArrayList<HotSpotResolvedJavaField> fieldsArray = new ArrayList<>(fieldCount);
+
+            for (int i = 0; i < fieldCount; i++) {
+                FieldInfo field = new FieldInfo(i);
+
+                // We are only interested in static fields.
+                if (field.isStatic()) {
+                    HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags());
+                    fieldsArray.add(resolvedJavaField);
+                }
+            }
+
+            fieldsArray.sort(new OffsetComparator());
+            return fieldsArray.toArray(new HotSpotResolvedJavaField[fieldsArray.size()]);
+        }
+    }
+
+    /**
+     * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array
+     * by walking the array and discounting the generic signature slots at the end of the array.
+     *
+     * <p>
+     * See {@code FieldStreamBase::init_generic_signature_start_slot}
+     */
+    private int getFieldCount() {
+        HotSpotVMConfig config = runtime().getConfig();
+        final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
+        int metaspaceFieldsLength = UNSAFE.getInt(metaspaceFields + config.arrayU1LengthOffset);
+        int fieldCount = 0;
+
+        for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) {
+            FieldInfo field = new FieldInfo(index);
+            if (field.hasGenericSignature()) {
+                metaspaceFieldsLength--;
+            }
+            fieldCount++;
+        }
+        return fieldCount;
+    }
+
+    @Override
+    public Class<?> mirror() {
+        return javaClass;
+    }
+
+    @Override
+    public String getSourceFileName() {
+        HotSpotVMConfig config = runtime().getConfig();
+        final int sourceFileNameIndex = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset);
+        if (sourceFileNameIndex == 0) {
+            return null;
+        }
+        return getConstantPool().lookupUtf8(sourceFileNameIndex);
+    }
+
+    @Override
+    public Annotation[] getAnnotations() {
+        return mirror().getAnnotations();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return mirror().getAnnotation(annotationClass);
+    }
+
+    /**
+     * Performs a fast-path check that this type is resolved in the context of a given accessing
+     * class. A negative result does not mean this type is not resolved with respect to
+     * {@code accessingClass}. That can only be determined by
+     * {@linkplain HotSpotJVMCIRuntime#lookupType(String, HotSpotResolvedObjectType, boolean)
+     * re-resolving} the type.
+     */
+    public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) {
+        assert accessingClass != null;
+        ResolvedJavaType elementType = getElementalType();
+        if (elementType.isPrimitive()) {
+            // Primitive type resolution is context free.
+            return true;
+        }
+        if (elementType.getName().startsWith("Ljava/")) {
+            // Classes in a java.* package can only be defined by the
+            // boot class loader. This is enforced by ClassLoader.preDefineClass()
+            assert mirror().getClassLoader() == null;
+            return true;
+        }
+        ClassLoader thisCl = mirror().getClassLoader();
+        ClassLoader accessingClassCl = ((HotSpotResolvedObjectTypeImpl) accessingClass).mirror().getClassLoader();
+        return thisCl == accessingClassCl;
+    }
+
+    @Override
+    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+        if (isDefinitelyResolvedWithRespectTo(requireNonNull(accessingClass))) {
+            return this;
+        }
+        HotSpotResolvedObjectTypeImpl accessingType = (HotSpotResolvedObjectTypeImpl) accessingClass;
+        return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true);
+    }
+
+    /**
+     * Gets the metaspace Klass boxed in a {@link JavaConstant}.
+     */
+    public JavaConstant klass() {
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime().getHostJVMCIBackend().getTarget().wordKind, getMetaspaceKlass(), this, false);
+    }
+
+    public boolean isPrimaryType() {
+        return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset();
+    }
+
+    public int superCheckOffset() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return UNSAFE.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset);
+    }
+
+    public long prototypeMarkWord() {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (isArray()) {
+            return config.arrayPrototypeMarkWord();
+        } else {
+            return UNSAFE.getAddress(getMetaspaceKlass() + config.prototypeMarkWordOffset);
+        }
+    }
+
+    @Override
+    public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedEntryKind) {
+        ResolvedJavaField[] declaredFields = getInstanceFields(true);
+        for (ResolvedJavaField field : declaredFields) {
+            HotSpotResolvedJavaField resolvedField = (HotSpotResolvedJavaField) field;
+            long resolvedFieldOffset = resolvedField.offset();
+            // @formatter:off
+            if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN  &&
+                            expectedEntryKind.isPrimitive() &&
+                            !expectedEntryKind.equals(JavaKind.Void) &&
+                            resolvedField.getJavaKind().isPrimitive()) {
+                resolvedFieldOffset +=
+                                resolvedField.getJavaKind().getByteCount() -
+                                Math.min(resolvedField.getJavaKind().getByteCount(), 4 + expectedEntryKind.getByteCount());
+            }
+            if (resolvedFieldOffset == offset) {
+                return field;
+            }
+            // @formatter:on
+        }
+        return null;
+    }
+
+    @Override
+    public URL getClassFilePath() {
+        Class<?> cls = mirror();
+        return cls.getResource(MetaUtil.getSimpleName(cls, true).replace('.', '$') + ".class");
+    }
+
+    @Override
+    public boolean isLocal() {
+        return mirror().isLocalClass();
+    }
+
+    @Override
+    public boolean isMember() {
+        return mirror().isMemberClass();
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getEnclosingType() {
+        final Class<?> encl = mirror().getEnclosingClass();
+        return encl == null ? null : fromObjectClass(encl);
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredConstructors() {
+        Constructor<?>[] constructors = mirror().getDeclaredConstructors();
+        ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
+        for (int i = 0; i < constructors.length; i++) {
+            result[i] = runtime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod(constructors[i]);
+            assert result[i].isConstructor();
+        }
+        return result;
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredMethods() {
+        Method[] methods = mirror().getDeclaredMethods();
+        ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length];
+        for (int i = 0; i < methods.length; i++) {
+            result[i] = runtime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod(methods[i]);
+            assert !result[i].isConstructor();
+        }
+        return result;
+    }
+
+    public ResolvedJavaMethod getClassInitializer() {
+        return runtime().getCompilerToVM().getClassInitializer(this);
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotType<" + getName() + ", resolved>";
+    }
+
+    @Override
+    public boolean isTrustedInterfaceType() {
+        return TrustedInterface.class.isAssignableFrom(mirror());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static java.util.Objects.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.net.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Assumptions.AssumptionResult;
+
+/**
+ * Implementation of {@link JavaType} for primitive HotSpot types.
+ */
+public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType implements HotSpotProxified {
+
+    private final JavaKind kind;
+
+    /**
+     * Creates the JVMCI mirror for a primitive {@link JavaKind}.
+     *
+     * <p>
+     * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
+     * {@link Class} type. Use {@link HotSpotJVMCIRuntimeProvider#fromClass(Class)} instead.
+     * </p>
+     *
+     * @param kind the Kind to create the mirror for
+     */
+    public HotSpotResolvedPrimitiveType(JavaKind kind) {
+        super(String.valueOf(Character.toUpperCase(kind.getTypeChar())));
+        this.kind = kind;
+        assert mirror().isPrimitive() : mirror() + " not a primitive type";
+    }
+
+    @Override
+    public int getModifiers() {
+        return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getArrayClass() {
+        if (kind == JavaKind.Void) {
+            return null;
+        }
+        Class<?> javaArrayMirror = Array.newInstance(mirror(), 0).getClass();
+        return HotSpotResolvedObjectTypeImpl.fromObjectClass(javaArrayMirror);
+    }
+
+    public ResolvedJavaType getElementalType() {
+        return this;
+    }
+
+    @Override
+    public ResolvedJavaType getComponentType() {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaType asExactType() {
+        return this;
+    }
+
+    @Override
+    public ResolvedJavaType getSuperclass() {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaType[] getInterfaces() {
+        return new ResolvedJavaType[0];
+    }
+
+    @Override
+    public ResolvedJavaType getSingleImplementor() {
+        throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this);
+    }
+
+    @Override
+    public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) {
+        return null;
+    }
+
+    @Override
+    public JavaConstant getObjectHub() {
+        throw JVMCIError.unimplemented();
+    }
+
+    @Override
+    public JavaConstant getJavaClass() {
+        throw JVMCIError.unimplemented();
+    }
+
+    @Override
+    public AssumptionResult<Boolean> hasFinalizableSubclass() {
+        return new AssumptionResult<>(false);
+    }
+
+    @Override
+    public boolean hasFinalizer() {
+        return false;
+    }
+
+    @Override
+    public boolean isArray() {
+        return false;
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return true;
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return true;
+    }
+
+    public boolean isLinked() {
+        return true;
+    }
+
+    @Override
+    public boolean isInstance(JavaConstant obj) {
+        return false;
+    }
+
+    @Override
+    public boolean isInstanceClass() {
+        return false;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return false;
+    }
+
+    @Override
+    public boolean isAssignableFrom(ResolvedJavaType other) {
+        assert other != null;
+        return other.equals(this);
+    }
+
+    @Override
+    public JavaKind getJavaKind() {
+        return kind;
+    }
+
+    @Override
+    public boolean isJavaLangObject() {
+        return false;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotResolvedPrimitiveType<" + kind + ">";
+    }
+
+    @Override
+    public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
+        return new AssumptionResult<>(this);
+    }
+
+    @Override
+    public AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method) {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
+        return new ResolvedJavaField[0];
+    }
+
+    @Override
+    public ResolvedJavaField[] getStaticFields() {
+        return new ResolvedJavaField[0];
+    }
+
+    @Override
+    public Annotation[] getAnnotations() {
+        return new Annotation[0];
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+        requireNonNull(accessingClass);
+        return this;
+    }
+
+    @Override
+    public void initialize() {
+    }
+
+    @Override
+    public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedType) {
+        return null;
+    }
+
+    @Override
+    public String getSourceFileName() {
+        throw JVMCIError.unimplemented();
+    }
+
+    @Override
+    public Class<?> mirror() {
+        return kind.toJavaClass();
+    }
+
+    @Override
+    public URL getClassFilePath() {
+        return null;
+    }
+
+    @Override
+    public boolean isLocal() {
+        return false;
+    }
+
+    @Override
+    public boolean isMember() {
+        return false;
+    }
+
+    @Override
+    public ResolvedJavaType getEnclosingType() {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredConstructors() {
+        return new ResolvedJavaMethod[0];
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredMethods() {
+        return new ResolvedJavaMethod[0];
+    }
+
+    @Override
+    public ResolvedJavaMethod getClassInitializer() {
+        return null;
+    }
+
+    @Override
+    public boolean isTrustedInterfaceType() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+public final class HotSpotSentinelConstant extends Value implements JavaConstant, VMConstant {
+
+    public HotSpotSentinelConstant(JavaKind kind) {
+        super(LIRKind.reference(kind));
+    }
+
+    public JavaKind getJavaKind() {
+        return (JavaKind) getLIRKind().getPlatformKind();
+    }
+
+    @Override
+    public boolean isNull() {
+        return true;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return true;
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int asInt() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public boolean asBoolean() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public long asLong() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public float asFloat() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public double asDouble() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public String toString() {
+        return JavaConstant.toString(this);
+    }
+
+    @Override
+    public String toValueString() {
+        return "sentinel";
+    }
+
+    @Override
+    public int hashCode() {
+        return 13;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o instanceof HotSpotSentinelConstant;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import java.util.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents a method signature.
+ */
+public class HotSpotSignature implements Signature {
+
+    private final List<String> parameters = new ArrayList<>();
+    private final String returnType;
+    private final String originalString;
+    private ResolvedJavaType[] parameterTypes;
+    private ResolvedJavaType returnTypeCache;
+    private final HotSpotJVMCIRuntimeProvider runtime;
+
+    public HotSpotSignature(HotSpotJVMCIRuntimeProvider runtime, String signature) {
+        this.runtime = runtime;
+        assert signature.length() > 0;
+        this.originalString = signature;
+
+        if (signature.charAt(0) == '(') {
+            int cur = 1;
+            while (cur < signature.length() && signature.charAt(cur) != ')') {
+                int nextCur = parseSignature(signature, cur);
+                parameters.add(signature.substring(cur, nextCur));
+                cur = nextCur;
+            }
+
+            cur++;
+            int nextCur = parseSignature(signature, cur);
+            returnType = signature.substring(cur, nextCur);
+            assert nextCur == signature.length();
+        } else {
+            returnType = null;
+        }
+    }
+
+    public HotSpotSignature(HotSpotJVMCIRuntimeProvider runtime, ResolvedJavaType returnType, ResolvedJavaType... parameterTypes) {
+        this.runtime = runtime;
+        this.parameterTypes = parameterTypes.clone();
+        this.returnTypeCache = returnType;
+        this.returnType = returnType.getName();
+        StringBuilder sb = new StringBuilder("(");
+        for (JavaType type : parameterTypes) {
+            parameters.add(type.getName());
+            sb.append(type.getName());
+        }
+        sb.append(")").append(returnType.getName());
+        this.originalString = sb.toString();
+        assert new HotSpotSignature(runtime, originalString).equals(this);
+    }
+
+    private static int parseSignature(String signature, int start) {
+        int cur = start;
+        char first;
+        do {
+            first = signature.charAt(cur++);
+        } while (first == '[');
+
+        switch (first) {
+            case 'L':
+                while (signature.charAt(cur) != ';') {
+                    cur++;
+                }
+                cur++;
+                break;
+            case 'V':
+            case 'I':
+            case 'B':
+            case 'C':
+            case 'D':
+            case 'F':
+            case 'J':
+            case 'S':
+            case 'Z':
+                break;
+            default:
+                throw new JVMCIError("Invalid character at index %d in signature: %s", cur, signature);
+        }
+        return cur;
+    }
+
+    @Override
+    public int getParameterCount(boolean withReceiver) {
+        return parameters.size() + (withReceiver ? 1 : 0);
+    }
+
+    @Override
+    public JavaKind getParameterKind(int index) {
+        return JavaKind.fromTypeString(parameters.get(index));
+    }
+
+    private static boolean checkValidCache(ResolvedJavaType type, ResolvedJavaType accessingClass) {
+        assert accessingClass != null;
+        if (type == null) {
+            return false;
+        } else if (type instanceof HotSpotResolvedObjectTypeImpl) {
+            return ((HotSpotResolvedObjectTypeImpl) type).isDefinitelyResolvedWithRespectTo(accessingClass);
+        }
+        return true;
+    }
+
+    private static JavaType getUnresolvedOrPrimitiveType(HotSpotJVMCIRuntimeProvider runtime, String name) {
+        if (name.length() == 1) {
+            JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
+            return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(kind.toJavaClass());
+        }
+        return new HotSpotUnresolvedJavaType(name, runtime);
+    }
+
+    @Override
+    public JavaType getParameterType(int index, ResolvedJavaType accessingClass) {
+        if (accessingClass == null) {
+            // Caller doesn't care about resolution context so return an unresolved
+            // or primitive type (primitive type resolution is context free)
+            return getUnresolvedOrPrimitiveType(runtime, parameters.get(index));
+        }
+        if (parameterTypes == null) {
+            parameterTypes = new ResolvedJavaType[parameters.size()];
+        }
+
+        ResolvedJavaType type = parameterTypes[index];
+        if (!checkValidCache(type, accessingClass)) {
+            JavaType result = runtime.lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false);
+            if (result instanceof ResolvedJavaType) {
+                type = (ResolvedJavaType) result;
+                parameterTypes[index] = type;
+            } else {
+                return result;
+            }
+        }
+        return type;
+    }
+
+    @Override
+    public String toMethodDescriptor() {
+        assert originalString.equals(Signature.super.toMethodDescriptor());
+        return originalString;
+    }
+
+    @Override
+    public JavaKind getReturnKind() {
+        return JavaKind.fromTypeString(returnType);
+    }
+
+    @Override
+    public JavaType getReturnType(ResolvedJavaType accessingClass) {
+        if (accessingClass == null) {
+            // Caller doesn't care about resolution context so return an unresolved
+            // or primitive type (primitive type resolution is context free)
+            return getUnresolvedOrPrimitiveType(runtime, returnType);
+        }
+        if (!checkValidCache(returnTypeCache, accessingClass)) {
+            JavaType result = runtime.lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false);
+            if (result instanceof ResolvedJavaType) {
+                returnTypeCache = (ResolvedJavaType) result;
+            } else {
+                return result;
+            }
+        }
+        return returnTypeCache;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotSignature<" + originalString + ">";
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof HotSpotSignature) {
+            HotSpotSignature other = (HotSpotSignature) obj;
+            if (other.originalString.equals(originalString)) {
+                assert other.parameters.equals(parameters);
+                assert other.returnType.equals(returnType);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return originalString.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+public class HotSpotSpeculationLog extends SpeculationLog {
+
+    @Override
+    public JavaConstant speculate(Object reason) {
+        addSpeculation(reason);
+        return HotSpotObjectConstantImpl.forObject(reason);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot;
+
+import java.util.*;
+
+import jdk.vm.ci.code.stack.*;
+import jdk.vm.ci.meta.*;
+
+public class HotSpotStackFrameReference implements InspectedFrame {
+
+    private CompilerToVM compilerToVM;
+
+    // information used to find the stack frame
+    private long stackPointer;
+    private int frameNumber;
+
+    // information about the stack frame's contents
+    private int bci;
+    private HotSpotResolvedJavaMethod method;
+    private Object[] locals;
+    private boolean[] localIsVirtual;
+
+    public long getStackPointer() {
+        return stackPointer;
+    }
+
+    public int getFrameNumber() {
+        return frameNumber;
+    }
+
+    @Override
+    public Object getLocal(int index) {
+        return locals[index];
+    }
+
+    @Override
+    public boolean isVirtual(int index) {
+        return localIsVirtual == null ? false : localIsVirtual[index];
+    }
+
+    @Override
+    public void materializeVirtualObjects(boolean invalidateCode) {
+        compilerToVM.materializeVirtualObjects(this, invalidateCode);
+    }
+
+    @Override
+    public int getBytecodeIndex() {
+        return bci;
+    }
+
+    @Override
+    public ResolvedJavaMethod getMethod() {
+        return method;
+    }
+
+    @Override
+    public boolean isMethod(ResolvedJavaMethod otherMethod) {
+        return method.equals(otherMethod);
+    }
+
+    @Override
+    public boolean hasVirtualObjects() {
+        return localIsVirtual != null;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotStackFrameReference [stackPointer=" + stackPointer + ", frameNumber=" + frameNumber + ", bci=" + bci + ", method=" + getMethod() + ", locals=" + Arrays.toString(locals) +
+                        ", localIsVirtual=" + Arrays.toString(localIsVirtual) + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotUnresolvedField.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * A implementation of {@link JavaField} for an unresolved field.
+ */
+public class HotSpotUnresolvedField implements JavaField {
+
+    private final String name;
+    private final JavaType holder;
+    private final JavaType type;
+
+    public HotSpotUnresolvedField(JavaType holder, String name, JavaType type) {
+        this.name = name;
+        this.type = type;
+        this.holder = holder;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public JavaType getType() {
+        return type;
+    }
+
+    public JavaType getDeclaringClass() {
+        return holder;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || !(obj instanceof HotSpotUnresolvedField)) {
+            return false;
+        }
+        HotSpotUnresolvedField that = (HotSpotUnresolvedField) obj;
+        return this.holder.equals(that.holder) && this.name.equals(that.name) && this.type.equals(that.type);
+    }
+
+    /**
+     * Converts this compiler interface field to a string.
+     */
+    @Override
+    public String toString() {
+        return format("HotSpotField<%H.%n %t, unresolved>");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotUnresolvedJavaType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Implementation of {@link JavaType} for unresolved HotSpot classes.
+ */
+public class HotSpotUnresolvedJavaType extends HotSpotJavaType {
+
+    private final HotSpotJVMCIRuntimeProvider runtime;
+
+    public HotSpotUnresolvedJavaType(String name, HotSpotJVMCIRuntimeProvider runtime) {
+        super(name);
+        assert name.charAt(0) == '[' || name.charAt(name.length() - 1) == ';' : name;
+        this.runtime = runtime;
+    }
+
+    /**
+     * Creates an unresolved type for a valid {@link JavaType#getName() type name}.
+     */
+    public static HotSpotUnresolvedJavaType create(HotSpotJVMCIRuntimeProvider runtime, String name) {
+        return new HotSpotUnresolvedJavaType(name, runtime);
+    }
+
+    @Override
+    public JavaType getComponentType() {
+        assert getName().charAt(0) == '[' : "no array class" + getName();
+        return new HotSpotUnresolvedJavaType(getName().substring(1), runtime);
+    }
+
+    @Override
+    public JavaType getArrayClass() {
+        return new HotSpotUnresolvedJavaType('[' + getName(), runtime);
+    }
+
+    @Override
+    public JavaKind getJavaKind() {
+        return JavaKind.Object;
+    }
+
+    @Override
+    public int hashCode() {
+        return getName().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || !(obj instanceof HotSpotUnresolvedJavaType)) {
+            return false;
+        }
+        HotSpotUnresolvedJavaType that = (HotSpotUnresolvedJavaType) obj;
+        return this.getName().equals(that.getName());
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotType<" + getName() + ", unresolved>";
+    }
+
+    @Override
+    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+        return (ResolvedJavaType) runtime.lookupType(getName(), (HotSpotResolvedObjectType) accessingClass, true);
+    }
+
+    /**
+     * Try to find a loaded version of this class.
+     *
+     * @param accessingClass
+     * @return the resolved class or null.
+     */
+    ResolvedJavaType reresolve(HotSpotResolvedObjectType accessingClass) {
+        JavaType type = runtime.lookupType(getName(), accessingClass, false);
+        if (type instanceof ResolvedJavaType) {
+            return (ResolvedJavaType) type;
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1771 @@
+/*
+ * Copyright (c) 2011, 2015, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.common.UnsafeUtil.readCString;
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import sun.misc.*;
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.hotspotvmconfig.*;
+
+//JaCoCo Exclude
+
+/**
+ * Used to access native configuration details.
+ *
+ * All non-static, public fields in this class are so that they can be compiled as constants.
+ */
+public class HotSpotVMConfig {
+
+    /**
+     * Maximum allowed size of allocated area for a frame.
+     */
+    public final int maxFrameSize = 16 * 1024;
+
+    public HotSpotVMConfig(CompilerToVM compilerToVm) {
+        // Get raw pointer to the array that contains all gHotSpotVM values.
+        final long gHotSpotVMData = compilerToVm.initializeConfiguration();
+        assert gHotSpotVMData != 0;
+
+        // Make FindBugs happy.
+        gHotSpotVMStructs = 0;
+        gHotSpotVMTypes = 0;
+        gHotSpotVMIntConstants = 0;
+        gHotSpotVMLongConstants = 0;
+        gHotSpotVMAddresses = 0;
+
+        // Initialize the gHotSpotVM fields.
+        for (Field f : HotSpotVMConfig.class.getDeclaredFields()) {
+            if (f.isAnnotationPresent(HotSpotVMData.class)) {
+                HotSpotVMData annotation = f.getAnnotation(HotSpotVMData.class);
+                final int index = annotation.index();
+                final long value = UNSAFE.getAddress(gHotSpotVMData + Unsafe.ADDRESS_SIZE * index);
+                try {
+                    f.setLong(this, value);
+                } catch (IllegalAccessException e) {
+                    throw new JVMCIError("index " + index, e);
+                }
+            }
+        }
+
+        // Quick sanity check.
+        assert gHotSpotVMStructs != 0;
+        assert gHotSpotVMTypes != 0;
+        assert gHotSpotVMIntConstants != 0;
+        assert gHotSpotVMLongConstants != 0;
+        assert gHotSpotVMAddresses != 0;
+
+        initialize();
+
+        oopEncoding = new CompressEncoding(narrowOopBase, narrowOopShift, logMinObjAlignment());
+        klassEncoding = new CompressEncoding(narrowKlassBase, narrowKlassShift, logKlassAlignment);
+
+        final long barrierSetAddress = UNSAFE.getAddress(universeCollectedHeap + collectedHeapBarrierSetOffset);
+        final int kind = UNSAFE.getInt(barrierSetAddress + barrierSetFakeRttiOffset + fakeRttiConcreteTagOffset);
+        if ((kind == barrierSetCardTableModRef) || (kind == barrierSetCardTableForRS) || (kind == barrierSetCardTableExtension) || (kind == barrierSetG1SATBCT) || (kind == barrierSetG1SATBCTLogging)) {
+            final long base = UNSAFE.getAddress(barrierSetAddress + cardTableModRefBSByteMapBaseOffset);
+            assert base != 0 : "unexpected byte_map_base: " + base;
+            cardtableStartAddress = base;
+            cardtableShift = cardTableModRefBSCardShift;
+        } else if (kind == barrierSetModRef) {
+            // No post barriers
+            cardtableStartAddress = 0;
+            cardtableShift = 0;
+        } else {
+            cardtableStartAddress = -1;
+            cardtableShift = -1;
+        }
+
+        // Now handle all HotSpotVMManual fields.
+        inlineCacheMissStub = inlineCacheMissBlob + UNSAFE.getInt(inlineCacheMissBlob + codeBlobCodeOffsetOffset);
+        handleWrongMethodStub = wrongMethodBlob + UNSAFE.getInt(wrongMethodBlob + codeBlobCodeOffsetOffset);
+        handleDeoptStub = deoptBlob + UNSAFE.getInt(deoptBlob + codeBlobCodeOffsetOffset) + UNSAFE.getInt(deoptBlob + deoptimizationBlobUnpackOffsetOffset);
+        uncommonTrapStub = deoptBlob + UNSAFE.getInt(deoptBlob + codeBlobCodeOffsetOffset) + UNSAFE.getInt(deoptBlob + deoptimizationBlobUncommonTrapOffsetOffset);
+
+        assert check();
+        assert HotSpotVMConfigVerifier.check();
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName();
+    }
+
+    /**
+     * Initialize fields by reading their values from vmStructs.
+     */
+    private void initialize() {
+        // Fill the VM fields hash map.
+        HashMap<String, VMFields.Field> vmFields = new HashMap<>();
+        for (VMFields.Field e : new VMFields(gHotSpotVMStructs)) {
+            vmFields.put(e.getName(), e);
+        }
+
+        // Fill the VM types hash map.
+        HashMap<String, VMTypes.Type> vmTypes = new HashMap<>();
+        for (VMTypes.Type e : new VMTypes(gHotSpotVMTypes)) {
+            vmTypes.put(e.getTypeName(), e);
+        }
+
+        // Fill the VM constants hash map.
+        HashMap<String, AbstractConstant> vmConstants = new HashMap<>();
+        for (AbstractConstant e : new VMIntConstants(gHotSpotVMIntConstants)) {
+            vmConstants.put(e.getName(), e);
+        }
+        for (AbstractConstant e : new VMAddresses(gHotSpotVMLongConstants)) {
+            vmConstants.put(e.getName(), e);
+        }
+
+        // Fill the VM addresses hash map.
+        HashMap<String, VMAddresses.Address> vmAddresses = new HashMap<>();
+        for (VMAddresses.Address e : new VMAddresses(gHotSpotVMAddresses)) {
+            vmAddresses.put(e.getName(), e);
+        }
+
+        // Fill the flags hash map.
+        HashMap<String, Flags.Flag> flags = new HashMap<>();
+        for (Flags.Flag e : new Flags(vmFields, vmTypes)) {
+            flags.put(e.getName(), e);
+        }
+
+        String osName = getHostOSName();
+        String osArch = getHostArchitectureName();
+
+        for (Field f : HotSpotVMConfig.class.getDeclaredFields()) {
+            if (f.isAnnotationPresent(HotSpotVMField.class)) {
+                HotSpotVMField annotation = f.getAnnotation(HotSpotVMField.class);
+                String name = annotation.name();
+                String type = annotation.type();
+                VMFields.Field entry = vmFields.get(name);
+                if (entry == null) {
+                    if (!isRequired(osArch, annotation.archs())) {
+                        continue;
+                    }
+                    throw new JVMCIError(f.getName() + ": expected VM field not found: " + name);
+                }
+
+                // Make sure the native type is still the type we expect.
+                if (!type.isEmpty()) {
+                    if (!type.equals(entry.getTypeString())) {
+                        throw new JVMCIError(f.getName() + ": compiler expects type " + type + " but VM field " + name + " is of type " + entry.getTypeString());
+                    }
+                }
+
+                switch (annotation.get()) {
+                    case OFFSET:
+                        setField(f, entry.getOffset());
+                        break;
+                    case ADDRESS:
+                        setField(f, entry.getAddress());
+                        break;
+                    case VALUE:
+                        setField(f, entry.getValue());
+                        break;
+                    default:
+                        throw new JVMCIError(f.getName() + ": unknown kind: " + annotation.get());
+                }
+            } else if (f.isAnnotationPresent(HotSpotVMType.class)) {
+                HotSpotVMType annotation = f.getAnnotation(HotSpotVMType.class);
+                String name = annotation.name();
+                VMTypes.Type entry = vmTypes.get(name);
+                if (entry == null) {
+                    throw new JVMCIError(f.getName() + ": expected VM type not found: " + name);
+                }
+                switch (annotation.get()) {
+                    case SIZE:
+                        setField(f, entry.getSize());
+                        break;
+                    default:
+                        throw new JVMCIError(f.getName() + ": unknown kind: " + annotation.get());
+                }
+            } else if (f.isAnnotationPresent(HotSpotVMConstant.class)) {
+                HotSpotVMConstant annotation = f.getAnnotation(HotSpotVMConstant.class);
+                String name = annotation.name();
+                AbstractConstant entry = vmConstants.get(name);
+                if (entry == null) {
+                    if (!isRequired(osArch, annotation.archs())) {
+                        continue;
+                    }
+                    throw new JVMCIError(f.getName() + ": expected VM constant not found: " + name);
+                }
+                setField(f, entry.getValue());
+            } else if (f.isAnnotationPresent(HotSpotVMAddress.class)) {
+                HotSpotVMAddress annotation = f.getAnnotation(HotSpotVMAddress.class);
+                String name = annotation.name();
+                VMAddresses.Address entry = vmAddresses.get(name);
+                if (entry == null) {
+                    if (!isRequired(osName, annotation.os())) {
+                        continue;
+                    }
+                    throw new JVMCIError(f.getName() + ": expected VM address not found: " + name);
+                }
+                setField(f, entry.getValue());
+            } else if (f.isAnnotationPresent(HotSpotVMFlag.class)) {
+                HotSpotVMFlag annotation = f.getAnnotation(HotSpotVMFlag.class);
+                String name = annotation.name();
+                Flags.Flag entry = flags.get(name);
+                if (entry == null) {
+                    if (annotation.optional() || !isRequired(osArch, annotation.archs())) {
+                        continue;
+                    }
+                    throw new JVMCIError(f.getName() + ": expected VM flag not found: " + name);
+
+                }
+                setField(f, entry.getValue());
+            }
+        }
+    }
+
+    private final CompressEncoding oopEncoding;
+    private final CompressEncoding klassEncoding;
+
+    public CompressEncoding getOopEncoding() {
+        return oopEncoding;
+    }
+
+    public CompressEncoding getKlassEncoding() {
+        return klassEncoding;
+    }
+
+    private void setField(Field field, Object value) {
+        try {
+            Class<?> fieldType = field.getType();
+            if (fieldType == boolean.class) {
+                if (value instanceof String) {
+                    field.setBoolean(this, Boolean.valueOf((String) value));
+                } else if (value instanceof Boolean) {
+                    field.setBoolean(this, (boolean) value);
+                } else if (value instanceof Long) {
+                    field.setBoolean(this, ((long) value) != 0);
+                } else {
+                    throw new JVMCIError(value.getClass().getSimpleName());
+                }
+            } else if (fieldType == byte.class) {
+                if (value instanceof Long) {
+                    field.setByte(this, (byte) (long) value);
+                } else {
+                    throw new JVMCIError(value.getClass().getSimpleName());
+                }
+            } else if (fieldType == int.class) {
+                if (value instanceof Integer) {
+                    field.setInt(this, (int) value);
+                } else if (value instanceof Long) {
+                    field.setInt(this, (int) (long) value);
+                } else {
+                    throw new JVMCIError(value.getClass().getSimpleName());
+                }
+            } else if (fieldType == long.class) {
+                field.setLong(this, (long) value);
+            } else {
+                throw new JVMCIError(field.toString());
+            }
+        } catch (IllegalAccessException e) {
+            throw new JVMCIError("%s: %s", field, e);
+        }
+    }
+
+    /**
+     * Gets the host operating system name.
+     */
+    private static String getHostOSName() {
+        String osName = System.getProperty("os.name");
+        switch (osName) {
+            case "Linux":
+                osName = "linux";
+                break;
+            case "SunOS":
+                osName = "solaris";
+                break;
+            case "Mac OS X":
+                osName = "bsd";
+                break;
+            default:
+                // Of course Windows is different...
+                if (osName.startsWith("Windows")) {
+                    osName = "windows";
+                } else {
+                    throw new JVMCIError("Unexpected OS name: " + osName);
+                }
+        }
+        return osName;
+    }
+
+    /**
+     * Gets the host architecture name for the purpose of finding the corresponding
+     * {@linkplain HotSpotJVMCIBackendFactory backend}.
+     */
+    public String getHostArchitectureName() {
+        String arch = System.getProperty("os.arch");
+        switch (arch) {
+            case "x86_64":
+                arch = "amd64";
+                break;
+            case "sparcv9":
+                arch = "sparc";
+                break;
+        }
+        return arch;
+    }
+
+    /**
+     * Determines if the current specification is included in a given set of specifications.
+     *
+     * @param current
+     * @param specification specifies a set of specifications, e.g. architectures or operating
+     *            systems. A zero length value implies all.
+     */
+    private static boolean isRequired(String current, String[] specification) {
+        if (specification.length == 0) {
+            return true;
+        }
+        for (String arch : specification) {
+            if (arch.equals(current)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * VMStructEntry (see {@code vmStructs.hpp}).
+     */
+    @HotSpotVMData(index = 0) @Stable private long gHotSpotVMStructs;
+    @HotSpotVMData(index = 1) @Stable private long gHotSpotVMStructEntryTypeNameOffset;
+    @HotSpotVMData(index = 2) @Stable private long gHotSpotVMStructEntryFieldNameOffset;
+    @HotSpotVMData(index = 3) @Stable private long gHotSpotVMStructEntryTypeStringOffset;
+    @HotSpotVMData(index = 4) @Stable private long gHotSpotVMStructEntryIsStaticOffset;
+    @HotSpotVMData(index = 5) @Stable private long gHotSpotVMStructEntryOffsetOffset;
+    @HotSpotVMData(index = 6) @Stable private long gHotSpotVMStructEntryAddressOffset;
+    @HotSpotVMData(index = 7) @Stable private long gHotSpotVMStructEntryArrayStride;
+
+    final class VMFields implements Iterable<VMFields.Field> {
+
+        private final long address;
+
+        public VMFields(long address) {
+            this.address = address;
+        }
+
+        public Iterator<VMFields.Field> iterator() {
+            return new Iterator<VMFields.Field>() {
+
+                private int index = 0;
+
+                private Field current() {
+                    return new Field(address + gHotSpotVMStructEntryArrayStride * index);
+                }
+
+                /**
+                 * The last entry is identified by a NULL fieldName.
+                 */
+                public boolean hasNext() {
+                    Field entry = current();
+                    return entry.getFieldName() != null;
+                }
+
+                public Field next() {
+                    Field entry = current();
+                    index++;
+                    return entry;
+                }
+            };
+        }
+
+        final class Field {
+
+            private final long entryAddress;
+
+            Field(long address) {
+                this.entryAddress = address;
+            }
+
+            public String getTypeName() {
+                long typeNameAddress = UNSAFE.getAddress(entryAddress + gHotSpotVMStructEntryTypeNameOffset);
+                return readCString(UNSAFE, typeNameAddress);
+            }
+
+            public String getFieldName() {
+                long fieldNameAddress = UNSAFE.getAddress(entryAddress + gHotSpotVMStructEntryFieldNameOffset);
+                return readCString(UNSAFE, fieldNameAddress);
+            }
+
+            public String getTypeString() {
+                long typeStringAddress = UNSAFE.getAddress(entryAddress + gHotSpotVMStructEntryTypeStringOffset);
+                return readCString(UNSAFE, typeStringAddress);
+            }
+
+            public boolean isStatic() {
+                return UNSAFE.getInt(entryAddress + gHotSpotVMStructEntryIsStaticOffset) != 0;
+            }
+
+            public long getOffset() {
+                return UNSAFE.getLong(entryAddress + gHotSpotVMStructEntryOffsetOffset);
+            }
+
+            public long getAddress() {
+                return UNSAFE.getAddress(entryAddress + gHotSpotVMStructEntryAddressOffset);
+            }
+
+            public String getName() {
+                String typeName = getTypeName();
+                String fieldName = getFieldName();
+                return typeName + "::" + fieldName;
+            }
+
+            public long getValue() {
+                String type = getTypeString();
+                switch (type) {
+                    case "bool":
+                        return UNSAFE.getByte(getAddress());
+                    case "int":
+                        return UNSAFE.getInt(getAddress());
+                    case "uint64_t":
+                        return UNSAFE.getLong(getAddress());
+                    case "address":
+                    case "intptr_t":
+                    case "uintptr_t":
+                        return UNSAFE.getAddress(getAddress());
+                    default:
+                        // All foo* types are addresses.
+                        if (type.endsWith("*")) {
+                            return UNSAFE.getAddress(getAddress());
+                        }
+                        throw new JVMCIError(type);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Field[typeName=%s, fieldName=%s, typeString=%s, isStatic=%b, offset=%d, address=0x%x]", getTypeName(), getFieldName(), getTypeString(), isStatic(), getOffset(),
+                                getAddress());
+            }
+        }
+    }
+
+    /**
+     * VMTypeEntry (see vmStructs.hpp).
+     */
+    @HotSpotVMData(index = 8) @Stable private long gHotSpotVMTypes;
+    @HotSpotVMData(index = 9) @Stable private long gHotSpotVMTypeEntryTypeNameOffset;
+    @HotSpotVMData(index = 10) @Stable private long gHotSpotVMTypeEntrySuperclassNameOffset;
+    @HotSpotVMData(index = 11) @Stable private long gHotSpotVMTypeEntryIsOopTypeOffset;
+    @HotSpotVMData(index = 12) @Stable private long gHotSpotVMTypeEntryIsIntegerTypeOffset;
+    @HotSpotVMData(index = 13) @Stable private long gHotSpotVMTypeEntryIsUnsignedOffset;
+    @HotSpotVMData(index = 14) @Stable private long gHotSpotVMTypeEntrySizeOffset;
+    @HotSpotVMData(index = 15) @Stable private long gHotSpotVMTypeEntryArrayStride;
+
+    final class VMTypes implements Iterable<VMTypes.Type> {
+
+        private final long address;
+
+        public VMTypes(long address) {
+            this.address = address;
+        }
+
+        public Iterator<VMTypes.Type> iterator() {
+            return new Iterator<VMTypes.Type>() {
+
+                private int index = 0;
+
+                private Type current() {
+                    return new Type(address + gHotSpotVMTypeEntryArrayStride * index);
+                }
+
+                /**
+                 * The last entry is identified by a NULL type name.
+                 */
+                public boolean hasNext() {
+                    Type entry = current();
+                    return entry.getTypeName() != null;
+                }
+
+                public Type next() {
+                    Type entry = current();
+                    index++;
+                    return entry;
+                }
+            };
+        }
+
+        final class Type {
+
+            private final long entryAddress;
+
+            Type(long address) {
+                this.entryAddress = address;
+            }
+
+            public String getTypeName() {
+                long typeNameAddress = UNSAFE.getAddress(entryAddress + gHotSpotVMTypeEntryTypeNameOffset);
+                return readCString(UNSAFE, typeNameAddress);
+            }
+
+            public String getSuperclassName() {
+                long superclassNameAddress = UNSAFE.getAddress(entryAddress + gHotSpotVMTypeEntrySuperclassNameOffset);
+                return readCString(UNSAFE, superclassNameAddress);
+            }
+
+            public boolean isOopType() {
+                return UNSAFE.getInt(entryAddress + gHotSpotVMTypeEntryIsOopTypeOffset) != 0;
+            }
+
+            public boolean isIntegerType() {
+                return UNSAFE.getInt(entryAddress + gHotSpotVMTypeEntryIsIntegerTypeOffset) != 0;
+            }
+
+            public boolean isUnsigned() {
+                return UNSAFE.getInt(entryAddress + gHotSpotVMTypeEntryIsUnsignedOffset) != 0;
+            }
+
+            public long getSize() {
+                return UNSAFE.getLong(entryAddress + gHotSpotVMTypeEntrySizeOffset);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Type[typeName=%s, superclassName=%s, isOopType=%b, isIntegerType=%b, isUnsigned=%b, size=%d]", getTypeName(), getSuperclassName(), isOopType(), isIntegerType(),
+                                isUnsigned(), getSize());
+            }
+        }
+    }
+
+    public abstract class AbstractConstant {
+
+        protected final long address;
+        protected final long nameOffset;
+        protected final long valueOffset;
+
+        AbstractConstant(long address, long nameOffset, long valueOffset) {
+            this.address = address;
+            this.nameOffset = nameOffset;
+            this.valueOffset = valueOffset;
+        }
+
+        public String getName() {
+            long nameAddress = UNSAFE.getAddress(address + nameOffset);
+            return readCString(UNSAFE, nameAddress);
+        }
+
+        public abstract long getValue();
+    }
+
+    /**
+     * VMIntConstantEntry (see vmStructs.hpp).
+     */
+    @HotSpotVMData(index = 16) @Stable private long gHotSpotVMIntConstants;
+    @HotSpotVMData(index = 17) @Stable private long gHotSpotVMIntConstantEntryNameOffset;
+    @HotSpotVMData(index = 18) @Stable private long gHotSpotVMIntConstantEntryValueOffset;
+    @HotSpotVMData(index = 19) @Stable private long gHotSpotVMIntConstantEntryArrayStride;
+
+    final class VMIntConstants implements Iterable<VMIntConstants.Constant> {
+
+        private final long address;
+
+        public VMIntConstants(long address) {
+            this.address = address;
+        }
+
+        public Iterator<VMIntConstants.Constant> iterator() {
+            return new Iterator<VMIntConstants.Constant>() {
+
+                private int index = 0;
+
+                private Constant current() {
+                    return new Constant(address + gHotSpotVMIntConstantEntryArrayStride * index);
+                }
+
+                /**
+                 * The last entry is identified by a NULL name.
+                 */
+                public boolean hasNext() {
+                    Constant entry = current();
+                    return entry.getName() != null;
+                }
+
+                public Constant next() {
+                    Constant entry = current();
+                    index++;
+                    return entry;
+                }
+            };
+        }
+
+        final class Constant extends AbstractConstant {
+
+            Constant(long address) {
+                super(address, gHotSpotVMIntConstantEntryNameOffset, gHotSpotVMIntConstantEntryValueOffset);
+            }
+
+            @Override
+            public long getValue() {
+                return UNSAFE.getInt(address + valueOffset);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("IntConstant[name=%s, value=%d (0x%x)]", getName(), getValue(), getValue());
+            }
+        }
+    }
+
+    /**
+     * VMLongConstantEntry (see vmStructs.hpp).
+     */
+    @HotSpotVMData(index = 20) @Stable private long gHotSpotVMLongConstants;
+    @HotSpotVMData(index = 21) @Stable private long gHotSpotVMLongConstantEntryNameOffset;
+    @HotSpotVMData(index = 22) @Stable private long gHotSpotVMLongConstantEntryValueOffset;
+    @HotSpotVMData(index = 23) @Stable private long gHotSpotVMLongConstantEntryArrayStride;
+
+    final class VMLongConstants implements Iterable<VMLongConstants.Constant> {
+
+        private final long address;
+
+        public VMLongConstants(long address) {
+            this.address = address;
+        }
+
+        public Iterator<VMLongConstants.Constant> iterator() {
+            return new Iterator<VMLongConstants.Constant>() {
+
+                private int index = 0;
+
+                private Constant currentEntry() {
+                    return new Constant(address + gHotSpotVMLongConstantEntryArrayStride * index);
+                }
+
+                /**
+                 * The last entry is identified by a NULL name.
+                 */
+                public boolean hasNext() {
+                    Constant entry = currentEntry();
+                    return entry.getName() != null;
+                }
+
+                public Constant next() {
+                    Constant entry = currentEntry();
+                    index++;
+                    return entry;
+                }
+            };
+        }
+
+        final class Constant extends AbstractConstant {
+
+            Constant(long address) {
+                super(address, gHotSpotVMLongConstantEntryNameOffset, gHotSpotVMLongConstantEntryValueOffset);
+            }
+
+            @Override
+            public long getValue() {
+                return UNSAFE.getLong(address + valueOffset);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("LongConstant[name=%s, value=%d (0x%x)]", getName(), getValue(), getValue());
+            }
+        }
+    }
+
+    /**
+     * VMAddressEntry (see vmStructs.hpp).
+     */
+    @HotSpotVMData(index = 24) @Stable private long gHotSpotVMAddresses;
+    @HotSpotVMData(index = 25) @Stable private long gHotSpotVMAddressEntryNameOffset;
+    @HotSpotVMData(index = 26) @Stable private long gHotSpotVMAddressEntryValueOffset;
+    @HotSpotVMData(index = 27) @Stable private long gHotSpotVMAddressEntryArrayStride;
+
+    final class VMAddresses implements Iterable<VMAddresses.Address> {
+
+        private final long address;
+
+        public VMAddresses(long address) {
+            this.address = address;
+        }
+
+        public Iterator<VMAddresses.Address> iterator() {
+            return new Iterator<VMAddresses.Address>() {
+
+                private int index = 0;
+
+                private Address currentEntry() {
+                    return new Address(address + gHotSpotVMAddressEntryArrayStride * index);
+                }
+
+                /**
+                 * The last entry is identified by a NULL name.
+                 */
+                public boolean hasNext() {
+                    Address entry = currentEntry();
+                    return entry.getName() != null;
+                }
+
+                public Address next() {
+                    Address entry = currentEntry();
+                    index++;
+                    return entry;
+                }
+            };
+        }
+
+        final class Address extends AbstractConstant {
+
+            Address(long address) {
+                super(address, gHotSpotVMAddressEntryNameOffset, gHotSpotVMAddressEntryValueOffset);
+            }
+
+            @Override
+            public long getValue() {
+                return UNSAFE.getLong(address + valueOffset);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Address[name=%s, value=%d (0x%x)]", getName(), getValue(), getValue());
+            }
+        }
+    }
+
+    final class Flags implements Iterable<Flags.Flag> {
+
+        private final long address;
+        private final long entrySize;
+        private final long typeOffset;
+        private final long nameOffset;
+        private final long addrOffset;
+
+        public Flags(HashMap<String, VMFields.Field> vmStructs, HashMap<String, VMTypes.Type> vmTypes) {
+            address = vmStructs.get("Flag::flags").getValue();
+            entrySize = vmTypes.get("Flag").getSize();
+            typeOffset = vmStructs.get("Flag::_type").getOffset();
+            nameOffset = vmStructs.get("Flag::_name").getOffset();
+            addrOffset = vmStructs.get("Flag::_addr").getOffset();
+
+            assert vmTypes.get("bool").getSize() == Byte.BYTES;
+            assert vmTypes.get("intx").getSize() == Long.BYTES;
+            assert vmTypes.get("uintx").getSize() == Long.BYTES;
+        }
+
+        public Iterator<Flags.Flag> iterator() {
+            return new Iterator<Flags.Flag>() {
+
+                private int index = 0;
+
+                private Flag current() {
+                    return new Flag(address + entrySize * index);
+                }
+
+                /**
+                 * The last entry is identified by a NULL name.
+                 */
+                public boolean hasNext() {
+                    Flag entry = current();
+                    return entry.getName() != null;
+                }
+
+                public Flag next() {
+                    Flag entry = current();
+                    index++;
+                    return entry;
+                }
+            };
+        }
+
+        final class Flag {
+
+            private final long entryAddress;
+
+            Flag(long address) {
+                this.entryAddress = address;
+            }
+
+            public String getType() {
+                long typeAddress = UNSAFE.getAddress(entryAddress + typeOffset);
+                return readCString(UNSAFE, typeAddress);
+            }
+
+            public String getName() {
+                long nameAddress = UNSAFE.getAddress(entryAddress + nameOffset);
+                return readCString(UNSAFE, nameAddress);
+            }
+
+            public long getAddr() {
+                return UNSAFE.getAddress(entryAddress + addrOffset);
+            }
+
+            public Object getValue() {
+                switch (getType()) {
+                    case "bool":
+                        return Boolean.valueOf(UNSAFE.getByte(getAddr()) != 0);
+                    case "intx":
+                    case "uintx":
+                    case "uint64_t":
+                        return Long.valueOf(UNSAFE.getLong(getAddr()));
+                    case "double":
+                        return Double.valueOf(UNSAFE.getDouble(getAddr()));
+                    case "ccstr":
+                    case "ccstrlist":
+                        return readCString(UNSAFE, getAddr());
+                    default:
+                        throw new JVMCIError(getType());
+                }
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Flag[type=%s, name=%s, value=%s]", getType(), getName(), getValue());
+            }
+        }
+    }
+
+    @HotSpotVMConstant(name = "ASSERT") @Stable public boolean cAssertions;
+    public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
+
+    @HotSpotVMFlag(name = "CodeEntryAlignment") @Stable public int codeEntryAlignment;
+    @HotSpotVMFlag(name = "VerifyOops") @Stable public boolean verifyOops;
+    @HotSpotVMFlag(name = "CITime") @Stable public boolean ciTime;
+    @HotSpotVMFlag(name = "CITimeEach") @Stable public boolean ciTimeEach;
+    @HotSpotVMFlag(name = "CompileTheWorldStartAt", optional = true) @Stable public int compileTheWorldStartAt;
+    @HotSpotVMFlag(name = "CompileTheWorldStopAt", optional = true) @Stable public int compileTheWorldStopAt;
+    @HotSpotVMFlag(name = "DontCompileHugeMethods") @Stable public boolean dontCompileHugeMethods;
+    @HotSpotVMFlag(name = "HugeMethodLimit") @Stable public int hugeMethodLimit;
+    @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining;
+    @HotSpotVMFlag(name = "JVMCIUseFastLocking") @Stable public boolean useFastLocking;
+    @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable;
+    @HotSpotVMFlag(name = "CodeCacheSegmentSize") @Stable public int codeSegmentSize;
+
+    @HotSpotVMFlag(name = "UseTLAB") @Stable public boolean useTLAB;
+    @HotSpotVMFlag(name = "UseBiasedLocking") @Stable public boolean useBiasedLocking;
+    @HotSpotVMFlag(name = "UsePopCountInstruction") @Stable public boolean usePopCountInstruction;
+    @HotSpotVMFlag(name = "UseCountLeadingZerosInstruction", archs = {"amd64"}) @Stable public boolean useCountLeadingZerosInstruction;
+    @HotSpotVMFlag(name = "UseCountTrailingZerosInstruction", archs = {"amd64"}) @Stable public boolean useCountTrailingZerosInstruction;
+    @HotSpotVMFlag(name = "UseAESIntrinsics") @Stable public boolean useAESIntrinsics;
+    @HotSpotVMFlag(name = "UseCRC32Intrinsics") @Stable public boolean useCRC32Intrinsics;
+    @HotSpotVMFlag(name = "UseG1GC") @Stable public boolean useG1GC;
+    @HotSpotVMFlag(name = "UseConcMarkSweepGC") @Stable public boolean useCMSGC;
+
+    @HotSpotVMFlag(name = "AllocatePrefetchStyle") @Stable public int allocatePrefetchStyle;
+    @HotSpotVMFlag(name = "AllocatePrefetchInstr") @Stable public int allocatePrefetchInstr;
+    @HotSpotVMFlag(name = "AllocatePrefetchLines") @Stable public int allocatePrefetchLines;
+    @HotSpotVMFlag(name = "AllocateInstancePrefetchLines") @Stable public int allocateInstancePrefetchLines;
+    @HotSpotVMFlag(name = "AllocatePrefetchStepSize") @Stable public int allocatePrefetchStepSize;
+    @HotSpotVMFlag(name = "AllocatePrefetchDistance") @Stable public int allocatePrefetchDistance;
+
+    @HotSpotVMFlag(name = "FlightRecorder", optional = true) @Stable public boolean flightRecorder;
+
+    @HotSpotVMField(name = "Universe::_collectedHeap", type = "CollectedHeap*", get = HotSpotVMField.Type.VALUE) @Stable private long universeCollectedHeap;
+    @HotSpotVMField(name = "CollectedHeap::_total_collections", type = "unsigned int", get = HotSpotVMField.Type.OFFSET) @Stable private int collectedHeapTotalCollectionsOffset;
+
+    public long gcTotalCollectionsAddress() {
+        return universeCollectedHeap + collectedHeapTotalCollectionsOffset;
+    }
+
+    @HotSpotVMFlag(name = "ReduceInitialCardMarks") @Stable public boolean useDeferredInitBarriers;
+
+    // Compressed Oops related values.
+    @HotSpotVMFlag(name = "UseCompressedOops") @Stable public boolean useCompressedOops;
+    @HotSpotVMFlag(name = "UseCompressedClassPointers") @Stable public boolean useCompressedClassPointers;
+
+    @HotSpotVMField(name = "Universe::_narrow_oop._base", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long narrowOopBase;
+    @HotSpotVMField(name = "Universe::_narrow_oop._shift", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int narrowOopShift;
+    @HotSpotVMFlag(name = "ObjectAlignmentInBytes") @Stable public int objectAlignment;
+
+    public final int minObjAlignment() {
+        return objectAlignment / heapWordSize;
+    }
+
+    public final int logMinObjAlignment() {
+        return (int) (Math.log(objectAlignment) / Math.log(2));
+    }
+
+    @HotSpotVMType(name = "narrowKlass", get = HotSpotVMType.Type.SIZE) @Stable public int narrowKlassSize;
+    @HotSpotVMField(name = "Universe::_narrow_klass._base", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long narrowKlassBase;
+    @HotSpotVMField(name = "Universe::_narrow_klass._shift", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int narrowKlassShift;
+    @HotSpotVMConstant(name = "LogKlassAlignmentInBytes") @Stable public int logKlassAlignment;
+
+    // CPU capabilities
+    @HotSpotVMFlag(name = "UseSSE") @Stable public int useSSE;
+    @HotSpotVMFlag(name = "UseAVX", archs = {"amd64"}) @Stable public int useAVX;
+
+    @HotSpotVMField(name = "Abstract_VM_Version::_reserve_for_allocation_prefetch", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int abstractVmVersionReserveForAllocationPrefetch;
+
+    // X86 specific values
+    @HotSpotVMField(name = "VM_Version::_cpuFeatures", type = "uint64_t", get = HotSpotVMField.Type.VALUE, archs = {"amd64"}) @Stable public long x86CPUFeatures;
+    @HotSpotVMConstant(name = "VM_Version::CPU_CX8", archs = {"amd64"}) @Stable public long cpuCX8;
+    @HotSpotVMConstant(name = "VM_Version::CPU_CMOV", archs = {"amd64"}) @Stable public long cpuCMOV;
+    @HotSpotVMConstant(name = "VM_Version::CPU_FXSR", archs = {"amd64"}) @Stable public long cpuFXSR;
+    @HotSpotVMConstant(name = "VM_Version::CPU_HT", archs = {"amd64"}) @Stable public long cpuHT;
+    @HotSpotVMConstant(name = "VM_Version::CPU_MMX", archs = {"amd64"}) @Stable public long cpuMMX;
+    @HotSpotVMConstant(name = "VM_Version::CPU_3DNOW_PREFETCH", archs = {"amd64"}) @Stable public long cpu3DNOWPREFETCH;
+    @HotSpotVMConstant(name = "VM_Version::CPU_SSE", archs = {"amd64"}) @Stable public long cpuSSE;
+    @HotSpotVMConstant(name = "VM_Version::CPU_SSE2", archs = {"amd64"}) @Stable public long cpuSSE2;
+    @HotSpotVMConstant(name = "VM_Version::CPU_SSE3", archs = {"amd64"}) @Stable public long cpuSSE3;
+    @HotSpotVMConstant(name = "VM_Version::CPU_SSSE3", archs = {"amd64"}) @Stable public long cpuSSSE3;
+    @HotSpotVMConstant(name = "VM_Version::CPU_SSE4A", archs = {"amd64"}) @Stable public long cpuSSE4A;
+    @HotSpotVMConstant(name = "VM_Version::CPU_SSE4_1", archs = {"amd64"}) @Stable public long cpuSSE41;
+    @HotSpotVMConstant(name = "VM_Version::CPU_SSE4_2", archs = {"amd64"}) @Stable public long cpuSSE42;
+    @HotSpotVMConstant(name = "VM_Version::CPU_POPCNT", archs = {"amd64"}) @Stable public long cpuPOPCNT;
+    @HotSpotVMConstant(name = "VM_Version::CPU_LZCNT", archs = {"amd64"}) @Stable public long cpuLZCNT;
+    @HotSpotVMConstant(name = "VM_Version::CPU_TSC", archs = {"amd64"}) @Stable public long cpuTSC;
+    @HotSpotVMConstant(name = "VM_Version::CPU_TSCINV", archs = {"amd64"}) @Stable public long cpuTSCINV;
+    @HotSpotVMConstant(name = "VM_Version::CPU_AVX", archs = {"amd64"}) @Stable public long cpuAVX;
+    @HotSpotVMConstant(name = "VM_Version::CPU_AVX2", archs = {"amd64"}) @Stable public long cpuAVX2;
+    @HotSpotVMConstant(name = "VM_Version::CPU_AES", archs = {"amd64"}) @Stable public long cpuAES;
+    @HotSpotVMConstant(name = "VM_Version::CPU_ERMS", archs = {"amd64"}) @Stable public long cpuERMS;
+    @HotSpotVMConstant(name = "VM_Version::CPU_CLMUL", archs = {"amd64"}) @Stable public long cpuCLMUL;
+    @HotSpotVMConstant(name = "VM_Version::CPU_BMI1", archs = {"amd64"}) @Stable public long cpuBMI1;
+
+    // SPARC specific values
+    @HotSpotVMField(name = "VM_Version::_features", type = "int", get = HotSpotVMField.Type.VALUE, archs = {"sparc"}) @Stable public int sparcFeatures;
+    @HotSpotVMConstant(name = "VM_Version::vis3_instructions_m", archs = {"sparc"}) @Stable public int vis3Instructions;
+    @HotSpotVMConstant(name = "VM_Version::vis2_instructions_m", archs = {"sparc"}) @Stable public int vis2Instructions;
+    @HotSpotVMConstant(name = "VM_Version::vis1_instructions_m", archs = {"sparc"}) @Stable public int vis1Instructions;
+    @HotSpotVMConstant(name = "VM_Version::cbcond_instructions_m", archs = {"sparc"}) @Stable public int cbcondInstructions;
+    @HotSpotVMFlag(name = "UseBlockZeroing", archs = {"sparc"}) @Stable public boolean useBlockZeroing;
+    @HotSpotVMFlag(name = "BlockZeroingLowLimit", archs = {"sparc"}) @Stable public int blockZeroingLowLimit;
+
+    // offsets, ...
+    @HotSpotVMFlag(name = "StackShadowPages") @Stable public int stackShadowPages;
+    @HotSpotVMFlag(name = "UseStackBanging") @Stable public boolean useStackBanging;
+    @HotSpotVMConstant(name = "STACK_BIAS") @Stable public int stackBias;
+
+    @HotSpotVMField(name = "oopDesc::_mark", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int markOffset;
+    @HotSpotVMField(name = "oopDesc::_metadata._klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int hubOffset;
+
+    @HotSpotVMField(name = "Klass::_prototype_header", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int prototypeMarkWordOffset;
+    @HotSpotVMField(name = "Klass::_subklass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int subklassOffset;
+    @HotSpotVMField(name = "Klass::_next_sibling", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int nextSiblingOffset;
+    @HotSpotVMField(name = "Klass::_super_check_offset", type = "juint", get = HotSpotVMField.Type.OFFSET) @Stable public int superCheckOffsetOffset;
+    @HotSpotVMField(name = "Klass::_secondary_super_cache", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySuperCacheOffset;
+    @HotSpotVMField(name = "Klass::_secondary_supers", type = "Array<Klass*>*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySupersOffset;
+
+    /**
+     * The offset of the _java_mirror field (of type {@link Class}) in a Klass.
+     */
+    @HotSpotVMField(name = "Klass::_java_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int classMirrorOffset;
+
+    @HotSpotVMField(name = "Klass::_super", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSuperKlassOffset;
+    @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset;
+    @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset;
+    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset;
+
+    @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue;
+    @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue;
+
+    /**
+     * This filters out the bit that differentiates a type array from an object array.
+     */
+    public int layoutHelperElementTypePrimitiveInPlace() {
+        return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift;
+    }
+
+    /**
+     * Bit pattern in the klass layout helper that can be used to identify arrays.
+     */
+    public final int arrayKlassLayoutHelperIdentifier = 0x80000000;
+
+    @HotSpotVMType(name = "vtableEntry", get = HotSpotVMType.Type.SIZE) @Stable public int vtableEntrySize;
+    @HotSpotVMField(name = "vtableEntry::_method", type = "Method*", get = HotSpotVMField.Type.OFFSET) @Stable public int vtableEntryMethodOffset;
+
+    @HotSpotVMType(name = "InstanceKlass", get = HotSpotVMType.Type.SIZE) @Stable public int instanceKlassSize;
+    @HotSpotVMField(name = "InstanceKlass::_source_file_name_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassSourceFileNameIndexOffset;
+    @HotSpotVMField(name = "InstanceKlass::_init_state", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassInitStateOffset;
+    @HotSpotVMField(name = "InstanceKlass::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset;
+    @HotSpotVMField(name = "InstanceKlass::_fields", type = "Array<u2>*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassFieldsOffset;
+    @HotSpotVMField(name = "InstanceKlass::_vtable_len", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassVtableLengthOffset;
+
+    @HotSpotVMConstant(name = "InstanceKlass::linked") @Stable public int instanceKlassStateLinked;
+    @HotSpotVMConstant(name = "InstanceKlass::fully_initialized") @Stable public int instanceKlassStateFullyInitialized;
+
+    /**
+     * See {@code InstanceKlass::vtable_start_offset()}.
+     */
+    public final int instanceKlassVtableStartOffset() {
+        return roundUp(instanceKlassSize, heapWordSize);
+    }
+
+    // TODO use CodeUtil method once it's moved from NumUtil
+    private static int roundUp(int number, int mod) {
+        return ((number + mod - 1) / mod) * mod;
+    }
+
+    @HotSpotVMType(name = "arrayOopDesc", get = HotSpotVMType.Type.SIZE) @Stable public int arrayOopDescSize;
+
+    /**
+     * The offset of the array length word in an array object's header.
+     *
+     * See {@code arrayOopDesc::length_offset_in_bytes()}.
+     */
+    public final int arrayOopDescLengthOffset() {
+        return useCompressedClassPointers ? hubOffset + narrowKlassSize : arrayOopDescSize;
+    }
+
+    @HotSpotVMField(name = "Array<int>::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1LengthOffset;
+    @HotSpotVMField(name = "Array<u1>::_data", type = "", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1DataOffset;
+    @HotSpotVMField(name = "Array<u2>::_data", type = "", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU2DataOffset;
+    @HotSpotVMField(name = "Array<Klass*>::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset;
+    @HotSpotVMField(name = "Array<Klass*>::_data[0]", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayBaseOffset;
+
+    @HotSpotVMField(name = "ObjArrayKlass::_element_klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayClassElementOffset;
+
+    @HotSpotVMConstant(name = "FieldInfo::access_flags_offset") @Stable public int fieldInfoAccessFlagsOffset;
+    @HotSpotVMConstant(name = "FieldInfo::name_index_offset") @Stable public int fieldInfoNameIndexOffset;
+    @HotSpotVMConstant(name = "FieldInfo::signature_index_offset") @Stable public int fieldInfoSignatureIndexOffset;
+    @HotSpotVMConstant(name = "FieldInfo::initval_index_offset") @Stable public int fieldInfoInitvalIndexOffset;
+    @HotSpotVMConstant(name = "FieldInfo::low_packed_offset") @Stable public int fieldInfoLowPackedOffset;
+    @HotSpotVMConstant(name = "FieldInfo::high_packed_offset") @Stable public int fieldInfoHighPackedOffset;
+    @HotSpotVMConstant(name = "FieldInfo::field_slots") @Stable public int fieldInfoFieldSlots;
+
+    @HotSpotVMConstant(name = "FIELDINFO_TAG_SIZE") @Stable public int fieldInfoTagSize;
+
+    @HotSpotVMConstant(name = "JVM_ACC_FIELD_INTERNAL") @Stable public int jvmAccFieldInternal;
+    @HotSpotVMConstant(name = "JVM_ACC_FIELD_STABLE") @Stable public int jvmAccFieldStable;
+    @HotSpotVMConstant(name = "JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE") @Stable public int jvmAccFieldHasGenericSignature;
+    @HotSpotVMConstant(name = "JVM_ACC_WRITTEN_FLAGS") @Stable public int jvmAccWrittenFlags;
+
+    @HotSpotVMField(name = "Thread::_tlab", type = "ThreadLocalAllocBuffer", get = HotSpotVMField.Type.OFFSET) @Stable public int threadTlabOffset;
+
+    @HotSpotVMField(name = "JavaThread::_anchor", type = "JavaFrameAnchor", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadAnchorOffset;
+    @HotSpotVMField(name = "JavaThread::_threadObj", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectOffset;
+    @HotSpotVMField(name = "JavaThread::_osthread", type = "OSThread*", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadOffset;
+    @HotSpotVMField(name = "JavaThread::_dirty_card_queue", type = "DirtyCardQueue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadDirtyCardQueueOffset;
+    @HotSpotVMField(name = "JavaThread::_is_method_handle_return", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int threadIsMethodHandleReturnOffset;
+    @HotSpotVMField(name = "JavaThread::_satb_mark_queue", type = "ObjPtrQueue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadSatbMarkQueueOffset;
+    @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
+    @HotSpotVMField(name = "JavaThread::_jvmci_counters", type = "jlong*", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciCountersThreadOffset;
+
+    /**
+     * An invalid value for {@link #rtldDefault}.
+     */
+    public static final long INVALID_RTLD_DEFAULT_HANDLE = 0xDEADFACE;
+
+    /**
+     * Address of the library lookup routine. The C signature of this routine is:
+     *
+     * <pre>
+     *     void* (const char *filename, char *ebuf, int ebuflen)
+     * </pre>
+     */
+    @HotSpotVMAddress(name = "os::dll_load") @Stable public long dllLoad;
+
+    /**
+     * Address of the library lookup routine. The C signature of this routine is:
+     *
+     * <pre>
+     *     void* (void* handle, const char* name)
+     * </pre>
+     */
+    @HotSpotVMAddress(name = "os::dll_lookup") @Stable public long dllLookup;
+
+    /**
+     * A pseudo-handle which when used as the first argument to {@link #dllLookup} means lookup will
+     * return the first occurrence of the desired symbol using the default library search order. If
+     * this field is {@value #INVALID_RTLD_DEFAULT_HANDLE}, then this capability is not supported on
+     * the current platform.
+     */
+    @HotSpotVMAddress(name = "RTLD_DEFAULT", os = {"bsd", "linux"}) @Stable public long rtldDefault = INVALID_RTLD_DEFAULT_HANDLE;
+
+    /**
+     * This field is used to pass exception objects into and out of the runtime system during
+     * exception handling for compiled code.
+     */
+    @HotSpotVMField(name = "JavaThread::_exception_oop", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadExceptionOopOffset;
+    @HotSpotVMField(name = "JavaThread::_exception_pc", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int threadExceptionPcOffset;
+    @HotSpotVMField(name = "ThreadShadow::_pending_exception", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingExceptionOffset;
+
+    @HotSpotVMField(name = "JavaThread::_pending_deoptimization", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingDeoptimizationOffset;
+    @HotSpotVMField(name = "JavaThread::_pending_failed_speculation", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingFailedSpeculationOffset;
+    @HotSpotVMField(name = "JavaThread::_pending_transfer_to_interpreter", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingTransferToInterpreterOffset;
+
+    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_sp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaSpOffset;
+    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_pc", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaPcOffset;
+    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_fp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET, archs = {"amd64"}) @Stable private int javaFrameAnchorLastJavaFpOffset;
+    @HotSpotVMField(name = "JavaFrameAnchor::_flags", type = "int", get = HotSpotVMField.Type.OFFSET, archs = {"sparc"}) @Stable private int javaFrameAnchorFlagsOffset;
+
+    public int threadLastJavaSpOffset() {
+        return javaThreadAnchorOffset + javaFrameAnchorLastJavaSpOffset;
+    }
+
+    public int threadLastJavaPcOffset() {
+        return javaThreadAnchorOffset + javaFrameAnchorLastJavaPcOffset;
+    }
+
+    /**
+     * This value is only valid on AMD64.
+     */
+    public int threadLastJavaFpOffset() {
+        // TODO add an assert for AMD64
+        return javaThreadAnchorOffset + javaFrameAnchorLastJavaFpOffset;
+    }
+
+    /**
+     * This value is only valid on SPARC.
+     */
+    public int threadJavaFrameAnchorFlagsOffset() {
+        // TODO add an assert for SPARC
+        return javaThreadAnchorOffset + javaFrameAnchorFlagsOffset;
+    }
+
+    // These are only valid on AMD64.
+    @HotSpotVMConstant(name = "frame::arg_reg_save_area_bytes", archs = {"amd64"}) @Stable public int runtimeCallStackSize;
+    @HotSpotVMConstant(name = "frame::interpreter_frame_sender_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameSenderSpOffset;
+    @HotSpotVMConstant(name = "frame::interpreter_frame_last_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameLastSpOffset;
+
+    @HotSpotVMField(name = "PtrQueue::_active", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueActiveOffset;
+    @HotSpotVMField(name = "PtrQueue::_buf", type = "void**", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueBufferOffset;
+    @HotSpotVMField(name = "PtrQueue::_index", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueIndexOffset;
+
+    @HotSpotVMField(name = "OSThread::_interrupted", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadInterruptedOffset;
+
+    @HotSpotVMConstant(name = "markOopDesc::unlocked_value") @Stable public int unlockedMask;
+    @HotSpotVMConstant(name = "markOopDesc::biased_lock_mask_in_place") @Stable public int biasedLockMaskInPlace;
+    @HotSpotVMConstant(name = "markOopDesc::age_mask_in_place") @Stable public int ageMaskInPlace;
+    @HotSpotVMConstant(name = "markOopDesc::epoch_mask_in_place") @Stable public int epochMaskInPlace;
+
+    @HotSpotVMConstant(name = "markOopDesc::hash_shift") @Stable public long markOopDescHashShift;
+    @HotSpotVMConstant(name = "markOopDesc::hash_mask") @Stable public long markOopDescHashMask;
+    @HotSpotVMConstant(name = "markOopDesc::hash_mask_in_place") @Stable public long markOopDescHashMaskInPlace;
+
+    @HotSpotVMConstant(name = "markOopDesc::biased_lock_pattern") @Stable public int biasedLockPattern;
+    @HotSpotVMConstant(name = "markOopDesc::no_hash_in_place") @Stable public int markWordNoHashInPlace;
+    @HotSpotVMConstant(name = "markOopDesc::no_lock_in_place") @Stable public int markWordNoLockInPlace;
+
+    /**
+     * See {@code markOopDesc::prototype()}.
+     */
+    public long arrayPrototypeMarkWord() {
+        return markWordNoHashInPlace | markWordNoLockInPlace;
+    }
+
+    /**
+     * See {@code markOopDesc::copy_set_hash()}.
+     */
+    public long tlabIntArrayMarkWord() {
+        long tmp = arrayPrototypeMarkWord() & (~markOopDescHashMaskInPlace);
+        tmp |= ((0x2 & markOopDescHashMask) << markOopDescHashShift);
+        return tmp;
+    }
+
+    /**
+     * Mark word right shift to get identity hash code.
+     */
+    @HotSpotVMConstant(name = "markOopDesc::hash_shift") @Stable public int identityHashCodeShift;
+
+    /**
+     * Identity hash code value when uninitialized.
+     */
+    @HotSpotVMConstant(name = "markOopDesc::no_hash") @Stable public int uninitializedIdentityHashCodeValue;
+
+    @HotSpotVMField(name = "Method::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int methodAccessFlagsOffset;
+    @HotSpotVMField(name = "Method::_constMethod", type = "ConstMethod*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodConstMethodOffset;
+    @HotSpotVMField(name = "Method::_intrinsic_id", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int methodIntrinsicIdOffset;
+    @HotSpotVMField(name = "Method::_flags", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodFlagsOffset;
+    @HotSpotVMField(name = "Method::_vtable_index", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodVtableIndexOffset;
+
+    @HotSpotVMConstant(name = "Method::_jfr_towrite") @Stable public int methodFlagsJfrTowrite;
+    @HotSpotVMConstant(name = "Method::_caller_sensitive") @Stable public int methodFlagsCallerSensitive;
+    @HotSpotVMConstant(name = "Method::_force_inline") @Stable public int methodFlagsForceInline;
+    @HotSpotVMConstant(name = "Method::_dont_inline") @Stable public int methodFlagsDontInline;
+    @HotSpotVMConstant(name = "Method::_hidden") @Stable public int methodFlagsHidden;
+    @HotSpotVMConstant(name = "Method::nonvirtual_vtable_index") @Stable public int nonvirtualVtableIndex;
+    @HotSpotVMConstant(name = "Method::invalid_vtable_index") @Stable public int invalidVtableIndex;
+
+    @HotSpotVMConstant(name = "InvocationEntryBci") @Stable public int invocationEntryBci;
+
+    @HotSpotVMField(name = "JVMCIEnv::_task", type = "CompileTask*", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciEnvTaskOffset;
+    @HotSpotVMField(name = "JVMCIEnv::_jvmti_can_hotswap_or_post_breakpoint", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciEnvJvmtiCanHotswapOrPostBreakpointOffset;
+    @HotSpotVMField(name = "CompileTask::_num_inlined_bytecodes", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int compileTaskNumInlinedBytecodesOffset;
+
+    /**
+     * See {@code Method::extra_stack_entries()}.
+     */
+    @HotSpotVMConstant(name = "Method::extra_stack_entries_for_jsr292") @Stable public int extraStackEntries;
+
+    @HotSpotVMField(name = "ConstMethod::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodConstantsOffset;
+    @HotSpotVMField(name = "ConstMethod::_flags", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodFlagsOffset;
+    @HotSpotVMField(name = "ConstMethod::_code_size", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodCodeSizeOffset;
+    @HotSpotVMField(name = "ConstMethod::_name_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodNameIndexOffset;
+    @HotSpotVMField(name = "ConstMethod::_signature_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodSignatureIndexOffset;
+    @HotSpotVMField(name = "ConstMethod::_max_stack", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodMaxStackOffset;
+    @HotSpotVMField(name = "ConstMethod::_max_locals", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int methodMaxLocalsOffset;
+
+    @HotSpotVMConstant(name = "ConstMethod::_has_linenumber_table") @Stable public int constMethodHasLineNumberTable;
+    @HotSpotVMConstant(name = "ConstMethod::_has_localvariable_table") @Stable public int constMethodHasLocalVariableTable;
+    @HotSpotVMConstant(name = "ConstMethod::_has_exception_table") @Stable public int constMethodHasExceptionTable;
+
+    @HotSpotVMType(name = "ExceptionTableElement", get = HotSpotVMType.Type.SIZE) @Stable public int exceptionTableElementSize;
+    @HotSpotVMField(name = "ExceptionTableElement::start_pc", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int exceptionTableElementStartPcOffset;
+    @HotSpotVMField(name = "ExceptionTableElement::end_pc", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int exceptionTableElementEndPcOffset;
+    @HotSpotVMField(name = "ExceptionTableElement::handler_pc", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int exceptionTableElementHandlerPcOffset;
+    @HotSpotVMField(name = "ExceptionTableElement::catch_type_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int exceptionTableElementCatchTypeIndexOffset;
+
+    @HotSpotVMType(name = "LocalVariableTableElement", get = HotSpotVMType.Type.SIZE) @Stable public int localVariableTableElementSize;
+    @HotSpotVMField(name = "LocalVariableTableElement::start_bci", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int localVariableTableElementStartBciOffset;
+    @HotSpotVMField(name = "LocalVariableTableElement::length", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int localVariableTableElementLengthOffset;
+    @HotSpotVMField(name = "LocalVariableTableElement::name_cp_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int localVariableTableElementNameCpIndexOffset;
+    @HotSpotVMField(name = "LocalVariableTableElement::descriptor_cp_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int localVariableTableElementDescriptorCpIndexOffset;
+    @HotSpotVMField(name = "LocalVariableTableElement::signature_cp_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int localVariableTableElementSignatureCpIndexOffset;
+    @HotSpotVMField(name = "LocalVariableTableElement::slot", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int localVariableTableElementSlotOffset;
+
+    @HotSpotVMType(name = "ConstantPool", get = HotSpotVMType.Type.SIZE) @Stable public int constantPoolSize;
+    @HotSpotVMField(name = "ConstantPool::_tags", type = "Array<u1>*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolTagsOffset;
+    @HotSpotVMField(name = "ConstantPool::_pool_holder", type = "InstanceKlass*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolHolderOffset;
+    @HotSpotVMField(name = "ConstantPool::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolLengthOffset;
+
+    @HotSpotVMConstant(name = "ConstantPool::CPCACHE_INDEX_TAG") @Stable public int constantPoolCpCacheIndexTag;
+
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Utf8") @Stable public int jvmConstantUtf8;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Integer") @Stable public int jvmConstantInteger;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Long") @Stable public int jvmConstantLong;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Float") @Stable public int jvmConstantFloat;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Double") @Stable public int jvmConstantDouble;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Class") @Stable public int jvmConstantClass;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_UnresolvedClass") @Stable public int jvmConstantUnresolvedClass;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_UnresolvedClassInError") @Stable public int jvmConstantUnresolvedClassInError;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_String") @Stable public int jvmConstantString;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Fieldref") @Stable public int jvmConstantFieldref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Methodref") @Stable public int jvmConstantMethodref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_InterfaceMethodref") @Stable public int jvmConstantInterfaceMethodref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_NameAndType") @Stable public int jvmConstantNameAndType;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodHandle") @Stable public int jvmConstantMethodHandle;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodHandleInError") @Stable public int jvmConstantMethodHandleInError;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodType") @Stable public int jvmConstantMethodType;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodTypeInError") @Stable public int jvmConstantMethodTypeInError;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_InvokeDynamic") @Stable public int jvmConstantInvokeDynamic;
+
+    @HotSpotVMConstant(name = "JVM_CONSTANT_ExternalMax") @Stable public int jvmConstantExternalMax;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_InternalMin") @Stable public int jvmConstantInternalMin;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_InternalMax") @Stable public int jvmConstantInternalMax;
+
+    @HotSpotVMConstant(name = "HeapWordSize") @Stable public int heapWordSize;
+
+    @HotSpotVMType(name = "Symbol*", get = HotSpotVMType.Type.SIZE) @Stable public int symbolPointerSize;
+    @HotSpotVMField(name = "Symbol::_length", type = "unsigned short", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolLengthOffset;
+    @HotSpotVMField(name = "Symbol::_body[0]", type = "jbyte", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolBodyOffset;
+
+    @HotSpotVMField(name = "vmSymbols::_symbols[0]", type = "Symbol*", get = HotSpotVMField.Type.ADDRESS) @Stable public long vmSymbolsSymbols;
+    @HotSpotVMConstant(name = "vmSymbols::FIRST_SID") @Stable public int vmSymbolsFirstSID;
+    @HotSpotVMConstant(name = "vmSymbols::SID_LIMIT") @Stable public int vmSymbolsSIDLimit;
+
+    @HotSpotVMConstant(name = "JVM_ACC_HAS_FINALIZER") @Stable public int klassHasFinalizerFlag;
+
+    // Modifier.SYNTHETIC is not public so we get it via vmStructs.
+    @HotSpotVMConstant(name = "JVM_ACC_SYNTHETIC") @Stable public int syntheticFlag;
+
+    /**
+     * @see HotSpotResolvedObjectTypeImpl#createField
+     */
+    @HotSpotVMConstant(name = "JVM_RECOGNIZED_FIELD_MODIFIERS") @Stable public int recognizedFieldModifiers;
+
+    /**
+     * Bit pattern that represents a non-oop. Neither the high bits nor the low bits of this value
+     * are allowed to look like (respectively) the high or low bits of a real oop.
+     */
+    @HotSpotVMField(name = "Universe::_non_oop_bits", type = "intptr_t", get = HotSpotVMField.Type.VALUE) @Stable public long nonOopBits;
+
+    @HotSpotVMField(name = "StubRoutines::_verify_oop_count", type = "jint", get = HotSpotVMField.Type.ADDRESS) @Stable public long verifyOopCounterAddress;
+    @HotSpotVMField(name = "Universe::_verify_oop_mask", type = "uintptr_t", get = HotSpotVMField.Type.VALUE) @Stable public long verifyOopMask;
+    @HotSpotVMField(name = "Universe::_verify_oop_bits", type = "uintptr_t", get = HotSpotVMField.Type.VALUE) @Stable public long verifyOopBits;
+    @HotSpotVMField(name = "Universe::_base_vtable_size", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int universeBaseVtableSize;
+
+    public final int baseVtableLength() {
+        return universeBaseVtableSize / vtableEntrySize;
+    }
+
+    @HotSpotVMField(name = "CollectedHeap::_barrier_set", type = "BarrierSet*", get = HotSpotVMField.Type.OFFSET) @Stable public int collectedHeapBarrierSetOffset;
+
+    @HotSpotVMField(name = "HeapRegion::LogOfHRGrainBytes", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int logOfHRGrainBytes;
+
+    @HotSpotVMField(name = "BarrierSet::_fake_rtti", type = "BarrierSet::FakeRtti", get = HotSpotVMField.Type.OFFSET) @Stable private int barrierSetFakeRttiOffset;
+    @HotSpotVMConstant(name = "BarrierSet::CardTableModRef") @Stable public int barrierSetCardTableModRef;
+    @HotSpotVMConstant(name = "BarrierSet::CardTableForRS") @Stable public int barrierSetCardTableForRS;
+    @HotSpotVMConstant(name = "BarrierSet::CardTableExtension") @Stable public int barrierSetCardTableExtension;
+    @HotSpotVMConstant(name = "BarrierSet::G1SATBCT") @Stable public int barrierSetG1SATBCT;
+    @HotSpotVMConstant(name = "BarrierSet::G1SATBCTLogging") @Stable public int barrierSetG1SATBCTLogging;
+    @HotSpotVMConstant(name = "BarrierSet::ModRef") @Stable public int barrierSetModRef;
+
+    @HotSpotVMField(name = "BarrierSet::FakeRtti::_concrete_tag", type = "BarrierSet::Name", get = HotSpotVMField.Type.OFFSET) @Stable private int fakeRttiConcreteTagOffset;
+
+    @HotSpotVMField(name = "CardTableModRefBS::byte_map_base", type = "jbyte*", get = HotSpotVMField.Type.OFFSET) @Stable private int cardTableModRefBSByteMapBaseOffset;
+    @HotSpotVMConstant(name = "CardTableModRefBS::card_shift") @Stable public int cardTableModRefBSCardShift;
+
+    @HotSpotVMConstant(name = "CardTableModRefBS::dirty_card") @Stable public byte dirtyCardValue;
+    @HotSpotVMConstant(name = "G1SATBCardTableModRefBS::g1_young_gen") @Stable public byte g1YoungCardValue;
+
+    private final long cardtableStartAddress;
+    private final int cardtableShift;
+
+    public long cardtableStartAddress() {
+        if (cardtableStartAddress == -1) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+        return cardtableStartAddress;
+    }
+
+    public int cardtableShift() {
+        if (cardtableShift == -1) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+        return cardtableShift;
+    }
+
+    @HotSpotVMField(name = "os::_polling_page", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long safepointPollingAddress;
+
+    // G1 Collector Related Values.
+
+    public int g1CardQueueIndexOffset() {
+        return javaThreadDirtyCardQueueOffset + ptrQueueIndexOffset;
+    }
+
+    public int g1CardQueueBufferOffset() {
+        return javaThreadDirtyCardQueueOffset + ptrQueueBufferOffset;
+    }
+
+    public int g1SATBQueueMarkingOffset() {
+        return javaThreadSatbMarkQueueOffset + ptrQueueActiveOffset;
+    }
+
+    public int g1SATBQueueIndexOffset() {
+        return javaThreadSatbMarkQueueOffset + ptrQueueIndexOffset;
+    }
+
+    public int g1SATBQueueBufferOffset() {
+        return javaThreadSatbMarkQueueOffset + ptrQueueBufferOffset;
+    }
+
+    @HotSpotVMField(name = "java_lang_Class::_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassOffset;
+    @HotSpotVMField(name = "java_lang_Class::_array_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int arrayKlassOffset;
+
+    @HotSpotVMField(name = "Method::_method_counters", type = "MethodCounters*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCountersOffset;
+    @HotSpotVMField(name = "Method::_method_data", type = "MethodData*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOffset;
+    @HotSpotVMField(name = "Method::_from_compiled_entry", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCompiledEntryOffset;
+    @HotSpotVMField(name = "Method::_code", type = "nmethod*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCodeOffset;
+
+    @HotSpotVMField(name = "MethodCounters::_invocation_counter", type = "InvocationCounter", get = HotSpotVMField.Type.OFFSET) @Stable public int invocationCounterOffset;
+    @HotSpotVMField(name = "MethodCounters::_backedge_counter", type = "InvocationCounter", get = HotSpotVMField.Type.OFFSET) @Stable public int backedgeCounterOffset;
+    @HotSpotVMConstant(name = "InvocationCounter::count_increment") @Stable public int invocationCounterIncrement;
+    @HotSpotVMConstant(name = "InvocationCounter::count_shift") @Stable public int invocationCounterShift;
+
+    @HotSpotVMField(name = "MethodData::_size", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataSize;
+    @HotSpotVMField(name = "MethodData::_data_size", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataDataSize;
+    @HotSpotVMField(name = "MethodData::_data[0]", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopDataOffset;
+    @HotSpotVMField(name = "MethodData::_trap_hist._array[0]", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopTrapHistoryOffset;
+    @HotSpotVMField(name = "MethodData::_jvmci_ir_size", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataIRSizeOffset;
+
+    @HotSpotVMField(name = "nmethod::_verified_entry_point", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodEntryOffset;
+    @HotSpotVMField(name = "nmethod::_comp_level", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodCompLevelOffset;
+
+    @HotSpotVMConstant(name = "CompLevel_full_optimization") @Stable public int compilationLevelFullOptimization;
+
+    @HotSpotVMType(name = "BasicLock", get = HotSpotVMType.Type.SIZE) @Stable public int basicLockSize;
+    @HotSpotVMField(name = "BasicLock::_displaced_header", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int basicLockDisplacedHeaderOffset;
+
+    @HotSpotVMField(name = "Thread::_allocated_bytes", type = "jlong", get = HotSpotVMField.Type.OFFSET) @Stable public int threadAllocatedBytesOffset;
+
+    @HotSpotVMFlag(name = "TLABWasteIncrement") @Stable public int tlabRefillWasteIncrement;
+
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_start", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferStartOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_end", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferEndOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_top", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferTopOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_pf_top", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferPfTopOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_slow_allocations", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferSlowAllocationsOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_fast_refill_waste", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferFastRefillWasteOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_number_of_refills", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferNumberOfRefillsOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_refill_waste_limit", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferRefillWasteLimitOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_desired_size", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferDesiredSizeOffset;
+
+    public int tlabSlowAllocationsOffset() {
+        return threadTlabOffset + threadLocalAllocBufferSlowAllocationsOffset;
+    }
+
+    public int tlabFastRefillWasteOffset() {
+        return threadTlabOffset + threadLocalAllocBufferFastRefillWasteOffset;
+    }
+
+    public int tlabNumberOfRefillsOffset() {
+        return threadTlabOffset + threadLocalAllocBufferNumberOfRefillsOffset;
+    }
+
+    public int tlabRefillWasteLimitOffset() {
+        return threadTlabOffset + threadLocalAllocBufferRefillWasteLimitOffset;
+    }
+
+    public int threadTlabSizeOffset() {
+        return threadTlabOffset + threadLocalAllocBufferDesiredSizeOffset;
+    }
+
+    public int threadTlabStartOffset() {
+        return threadTlabOffset + threadLocalAllocBufferStartOffset;
+    }
+
+    public int threadTlabEndOffset() {
+        return threadTlabOffset + threadLocalAllocBufferEndOffset;
+    }
+
+    public int threadTlabTopOffset() {
+        return threadTlabOffset + threadLocalAllocBufferTopOffset;
+    }
+
+    public int threadTlabPfTopOffset() {
+        return threadTlabOffset + threadLocalAllocBufferPfTopOffset;
+    }
+
+    /**
+     * See: {@code ThreadLocalAllocBuffer::end_reserve()}.
+     */
+    public final int threadLocalAllocBufferEndReserve() {
+        final int typeSizeInBytes = roundUp(arrayOopDescLengthOffset() + Integer.BYTES, heapWordSize);
+        // T_INT arrays need not be 8 byte aligned.
+        final int reserveSize = typeSizeInBytes / heapWordSize;
+        return Integer.max(reserveSize, abstractVmVersionReserveForAllocationPrefetch);
+    }
+
+    /**
+     * See: {@code ThreadLocalAllocBuffer::alignment_reserve()}.
+     */
+    public final int tlabAlignmentReserve() {
+        return roundUp(threadLocalAllocBufferEndReserve(), minObjAlignment());
+    }
+
+    @HotSpotVMFlag(name = "TLABStats") @Stable public boolean tlabStats;
+
+    // FIXME This is only temporary until the GC code is changed.
+    @HotSpotVMField(name = "CompilerToVM::_supports_inline_contig_alloc", type = "bool", get = HotSpotVMField.Type.VALUE) @Stable public boolean inlineContiguousAllocationSupported;
+    @HotSpotVMField(name = "CompilerToVM::_heap_end_addr", type = "HeapWord**", get = HotSpotVMField.Type.VALUE) @Stable public long heapEndAddress;
+    @HotSpotVMField(name = "CompilerToVM::_heap_top_addr", type = "HeapWord**", get = HotSpotVMField.Type.VALUE) @Stable public long heapTopAddress;
+
+    /**
+     * The DataLayout header size is the same as the cell size.
+     */
+    @HotSpotVMConstant(name = "DataLayout::cell_size") @Stable public int dataLayoutHeaderSize;
+    @HotSpotVMField(name = "DataLayout::_header._struct._tag", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutTagOffset;
+    @HotSpotVMField(name = "DataLayout::_header._struct._flags", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutFlagsOffset;
+    @HotSpotVMField(name = "DataLayout::_header._struct._bci", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutBCIOffset;
+    @HotSpotVMField(name = "DataLayout::_cells[0]", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutCellsOffset;
+    @HotSpotVMConstant(name = "DataLayout::cell_size") @Stable public int dataLayoutCellSize;
+
+    @HotSpotVMConstant(name = "DataLayout::no_tag") @Stable public int dataLayoutNoTag;
+    @HotSpotVMConstant(name = "DataLayout::bit_data_tag") @Stable public int dataLayoutBitDataTag;
+    @HotSpotVMConstant(name = "DataLayout::counter_data_tag") @Stable public int dataLayoutCounterDataTag;
+    @HotSpotVMConstant(name = "DataLayout::jump_data_tag") @Stable public int dataLayoutJumpDataTag;
+    @HotSpotVMConstant(name = "DataLayout::receiver_type_data_tag") @Stable public int dataLayoutReceiverTypeDataTag;
+    @HotSpotVMConstant(name = "DataLayout::virtual_call_data_tag") @Stable public int dataLayoutVirtualCallDataTag;
+    @HotSpotVMConstant(name = "DataLayout::ret_data_tag") @Stable public int dataLayoutRetDataTag;
+    @HotSpotVMConstant(name = "DataLayout::branch_data_tag") @Stable public int dataLayoutBranchDataTag;
+    @HotSpotVMConstant(name = "DataLayout::multi_branch_data_tag") @Stable public int dataLayoutMultiBranchDataTag;
+    @HotSpotVMConstant(name = "DataLayout::arg_info_data_tag") @Stable public int dataLayoutArgInfoDataTag;
+    @HotSpotVMConstant(name = "DataLayout::call_type_data_tag") @Stable public int dataLayoutCallTypeDataTag;
+    @HotSpotVMConstant(name = "DataLayout::virtual_call_type_data_tag") @Stable public int dataLayoutVirtualCallTypeDataTag;
+    @HotSpotVMConstant(name = "DataLayout::parameters_type_data_tag") @Stable public int dataLayoutParametersTypeDataTag;
+    @HotSpotVMConstant(name = "DataLayout::speculative_trap_data_tag") @Stable public int dataLayoutSpeculativeTrapDataTag;
+
+    @HotSpotVMFlag(name = "BciProfileWidth") @Stable public int bciProfileWidth;
+    @HotSpotVMFlag(name = "TypeProfileWidth") @Stable public int typeProfileWidth;
+    @HotSpotVMFlag(name = "MethodProfileWidth") @Stable public int methodProfileWidth;
+
+    @HotSpotVMField(name = "CodeBlob::_code_offset", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable private int codeBlobCodeOffsetOffset;
+    @HotSpotVMField(name = "DeoptimizationBlob::_unpack_offset", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable private int deoptimizationBlobUnpackOffsetOffset;
+    @HotSpotVMField(name = "DeoptimizationBlob::_uncommon_trap_offset", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable private int deoptimizationBlobUncommonTrapOffsetOffset;
+
+    @HotSpotVMField(name = "SharedRuntime::_ic_miss_blob", type = "RuntimeStub*", get = HotSpotVMField.Type.VALUE) @Stable private long inlineCacheMissBlob;
+    @HotSpotVMField(name = "SharedRuntime::_wrong_method_blob", type = "RuntimeStub*", get = HotSpotVMField.Type.VALUE) @Stable private long wrongMethodBlob;
+    @HotSpotVMField(name = "SharedRuntime::_deopt_blob", type = "DeoptimizationBlob*", get = HotSpotVMField.Type.VALUE) @Stable private long deoptBlob;
+
+    @HotSpotVMManual(name = "SharedRuntime::get_ic_miss_stub()") public final long inlineCacheMissStub;
+    @HotSpotVMManual(name = "SharedRuntime::get_handle_wrong_method_stub()") public final long handleWrongMethodStub;
+
+    @HotSpotVMManual(name = "SharedRuntime::deopt_blob()->unpack()") public final long handleDeoptStub;
+    @HotSpotVMManual(name = "SharedRuntime::deopt_blob()->uncommon_trap()") public final long uncommonTrapStub;
+
+    @HotSpotVMField(name = "CodeCache::_low_bound", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long codeCacheLowBound;
+    @HotSpotVMField(name = "CodeCache::_high_bound", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long codeCacheHighBound;
+
+    @HotSpotVMField(name = "StubRoutines::_aescrypt_encryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptEncryptBlockStub;
+    @HotSpotVMField(name = "StubRoutines::_aescrypt_decryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptDecryptBlockStub;
+    @HotSpotVMField(name = "StubRoutines::_cipherBlockChaining_encryptAESCrypt", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long cipherBlockChainingEncryptAESCryptStub;
+    @HotSpotVMField(name = "StubRoutines::_cipherBlockChaining_decryptAESCrypt", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long cipherBlockChainingDecryptAESCryptStub;
+    @HotSpotVMField(name = "StubRoutines::_updateBytesCRC32", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long updateBytesCRC32Stub;
+    @HotSpotVMField(name = "StubRoutines::_crc_table_adr", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long crcTableAddress;
+
+    @HotSpotVMField(name = "StubRoutines::_jbyte_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jshort_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jlong_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_jbyte_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jshort_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jint_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jlong_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_disjoint_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopDisjointArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jbyte_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jshort_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jlong_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopAlignedArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jbyte_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jshort_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jint_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jlong_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopAlignedDisjointArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_checkcast_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long checkcastArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_checkcast_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long checkcastArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_unsafe_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long unsafeArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_generic_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long genericArraycopy;
+
+    @HotSpotVMAddress(name = "JVMCIRuntime::new_instance") @Stable public long newInstanceAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::new_array") @Stable public long newArrayAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::new_multi_array") @Stable public long newMultiArrayAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::dynamic_new_array") @Stable public long dynamicNewArrayAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::dynamic_new_instance") @Stable public long dynamicNewInstanceAddress;
+
+    @HotSpotVMAddress(name = "JVMCIRuntime::thread_is_interrupted") @Stable public long threadIsInterruptedAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::vm_message") @Stable public long vmMessageAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::identity_hash_code") @Stable public long identityHashCodeAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::exception_handler_for_pc") @Stable public long exceptionHandlerForPcAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::monitorenter") @Stable public long monitorenterAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::monitorexit") @Stable public long monitorexitAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::create_null_exception") @Stable public long createNullPointerExceptionAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::create_out_of_bounds_exception") @Stable public long createOutOfBoundsExceptionAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::log_primitive") @Stable public long logPrimitiveAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::log_object") @Stable public long logObjectAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::log_printf") @Stable public long logPrintfAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::vm_error") @Stable public long vmErrorAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::load_and_clear_exception") @Stable public long loadAndClearExceptionAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::write_barrier_pre") @Stable public long writeBarrierPreAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::write_barrier_post") @Stable public long writeBarrierPostAddress;
+    @HotSpotVMAddress(name = "JVMCIRuntime::validate_object") @Stable public long validateObject;
+
+    @HotSpotVMAddress(name = "JVMCIRuntime::test_deoptimize_call_int") @Stable public long testDeoptimizeCallInt;
+
+    @HotSpotVMAddress(name = "SharedRuntime::register_finalizer") @Stable public long registerFinalizerAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::exception_handler_for_return_address") @Stable public long exceptionHandlerForReturnAddressAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::OSR_migration_end") @Stable public long osrMigrationEndAddress;
+
+    @HotSpotVMAddress(name = "os::javaTimeMillis") @Stable public long javaTimeMillisAddress;
+    @HotSpotVMAddress(name = "os::javaTimeNanos") @Stable public long javaTimeNanosAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::dsin") @Stable public long arithmeticSinAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::dcos") @Stable public long arithmeticCosAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::dtan") @Stable public long arithmeticTanAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::dexp") @Stable public long arithmeticExpAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::dlog") @Stable public long arithmeticLogAddress;
+    @HotSpotVMAddress(name = "SharedRuntime::dlog10") @Stable public long arithmeticLog10Address;
+    @HotSpotVMAddress(name = "SharedRuntime::dpow") @Stable public long arithmeticPowAddress;
+
+    @HotSpotVMFlag(name = "JVMCICounterSize") @Stable public int jvmciCountersSize;
+
+    @HotSpotVMAddress(name = "Deoptimization::fetch_unroll_info") @Stable public long deoptimizationFetchUnrollInfo;
+    @HotSpotVMAddress(name = "Deoptimization::uncommon_trap") @Stable public long deoptimizationUncommonTrap;
+    @HotSpotVMAddress(name = "Deoptimization::unpack_frames") @Stable public long deoptimizationUnpackFrames;
+
+    @HotSpotVMConstant(name = "Deoptimization::Reason_none") @Stable public int deoptReasonNone;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_null_check") @Stable public int deoptReasonNullCheck;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_range_check") @Stable public int deoptReasonRangeCheck;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_class_check") @Stable public int deoptReasonClassCheck;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_array_check") @Stable public int deoptReasonArrayCheck;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_unreached0") @Stable public int deoptReasonUnreached0;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_type_checked_inlining") @Stable public int deoptReasonTypeCheckInlining;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_optimized_type_check") @Stable public int deoptReasonOptimizedTypeCheck;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_not_compiled_exception_handler") @Stable public int deoptReasonNotCompiledExceptionHandler;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_unresolved") @Stable public int deoptReasonUnresolved;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_jsr_mismatch") @Stable public int deoptReasonJsrMismatch;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_div0_check") @Stable public int deoptReasonDiv0Check;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_constraint") @Stable public int deoptReasonConstraint;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_loop_limit_check") @Stable public int deoptReasonLoopLimitCheck;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_aliasing") @Stable public int deoptReasonAliasing;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_transfer_to_interpreter") @Stable public int deoptReasonTransferToInterpreter;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_LIMIT") @Stable public int deoptReasonOSROffset;
+
+    @HotSpotVMConstant(name = "Deoptimization::Action_none") @Stable public int deoptActionNone;
+    @HotSpotVMConstant(name = "Deoptimization::Action_maybe_recompile") @Stable public int deoptActionMaybeRecompile;
+    @HotSpotVMConstant(name = "Deoptimization::Action_reinterpret") @Stable public int deoptActionReinterpret;
+    @HotSpotVMConstant(name = "Deoptimization::Action_make_not_entrant") @Stable public int deoptActionMakeNotEntrant;
+    @HotSpotVMConstant(name = "Deoptimization::Action_make_not_compilable") @Stable public int deoptActionMakeNotCompilable;
+
+    @HotSpotVMConstant(name = "Deoptimization::_action_bits") @Stable public int deoptimizationActionBits;
+    @HotSpotVMConstant(name = "Deoptimization::_reason_bits") @Stable public int deoptimizationReasonBits;
+    @HotSpotVMConstant(name = "Deoptimization::_debug_id_bits") @Stable public int deoptimizationDebugIdBits;
+    @HotSpotVMConstant(name = "Deoptimization::_action_shift") @Stable public int deoptimizationActionShift;
+    @HotSpotVMConstant(name = "Deoptimization::_reason_shift") @Stable public int deoptimizationReasonShift;
+    @HotSpotVMConstant(name = "Deoptimization::_debug_id_shift") @Stable public int deoptimizationDebugIdShift;
+
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_deopt") @Stable public int deoptimizationUnpackDeopt;
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_exception") @Stable public int deoptimizationUnpackException;
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_uncommon_trap") @Stable public int deoptimizationUnpackUncommonTrap;
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_reexecute") @Stable public int deoptimizationUnpackReexecute;
+
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_size_of_deoptimized_frame", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_caller_adjustment", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockCallerAdjustmentOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_number_of_frames", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockNumberOfFramesOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_total_frame_sizes", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockTotalFrameSizesOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_frame_sizes", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockFrameSizesOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_frame_pcs", type = "address*", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockFramePcsOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_initial_info", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockInitialInfoOffset;
+
+    @HotSpotVMConstant(name = "vmIntrinsics::_invokeBasic") @Stable public int vmIntrinsicInvokeBasic;
+    @HotSpotVMConstant(name = "vmIntrinsics::_linkToVirtual") @Stable public int vmIntrinsicLinkToVirtual;
+    @HotSpotVMConstant(name = "vmIntrinsics::_linkToStatic") @Stable public int vmIntrinsicLinkToStatic;
+    @HotSpotVMConstant(name = "vmIntrinsics::_linkToSpecial") @Stable public int vmIntrinsicLinkToSpecial;
+    @HotSpotVMConstant(name = "vmIntrinsics::_linkToInterface") @Stable public int vmIntrinsicLinkToInterface;
+
+    @HotSpotVMConstant(name = "JVMCIEnv::ok") @Stable public int codeInstallResultOk;
+    @HotSpotVMConstant(name = "JVMCIEnv::dependencies_failed") @Stable public int codeInstallResultDependenciesFailed;
+    @HotSpotVMConstant(name = "JVMCIEnv::dependencies_invalid") @Stable public int codeInstallResultDependenciesInvalid;
+    @HotSpotVMConstant(name = "JVMCIEnv::cache_full") @Stable public int codeInstallResultCacheFull;
+    @HotSpotVMConstant(name = "JVMCIEnv::code_too_large") @Stable public int codeInstallResultCodeTooLarge;
+
+    public String getCodeInstallResultDescription(int codeInstallResult) {
+        if (codeInstallResult == codeInstallResultOk) {
+            return "ok";
+        }
+        if (codeInstallResult == codeInstallResultDependenciesFailed) {
+            return "dependencies failed";
+        }
+        if (codeInstallResult == codeInstallResultDependenciesInvalid) {
+            return "dependencies invalid";
+        }
+        if (codeInstallResult == codeInstallResultCacheFull) {
+            return "code cache is full";
+        }
+        if (codeInstallResult == codeInstallResultCodeTooLarge) {
+            return "code is too large";
+        }
+        assert false : codeInstallResult;
+        return "unknown";
+    }
+
+    @HotSpotVMConstant(name = "CompilerToVM::KLASS_TAG") @Stable public int compilerToVMKlassTag;
+    @HotSpotVMConstant(name = "CompilerToVM::SYMBOL_TAG") @Stable public int compilerToVMSymbolTag;
+
+    // Checkstyle: stop
+    @HotSpotVMConstant(name = "CodeInstaller::VERIFIED_ENTRY") @Stable public int MARKID_VERIFIED_ENTRY;
+    @HotSpotVMConstant(name = "CodeInstaller::UNVERIFIED_ENTRY") @Stable public int MARKID_UNVERIFIED_ENTRY;
+    @HotSpotVMConstant(name = "CodeInstaller::OSR_ENTRY") @Stable public int MARKID_OSR_ENTRY;
+    @HotSpotVMConstant(name = "CodeInstaller::EXCEPTION_HANDLER_ENTRY") @Stable public int MARKID_EXCEPTION_HANDLER_ENTRY;
+    @HotSpotVMConstant(name = "CodeInstaller::DEOPT_HANDLER_ENTRY") @Stable public int MARKID_DEOPT_HANDLER_ENTRY;
+    @HotSpotVMConstant(name = "CodeInstaller::INVOKEINTERFACE") @Stable public int MARKID_INVOKEINTERFACE;
+    @HotSpotVMConstant(name = "CodeInstaller::INVOKEVIRTUAL") @Stable public int MARKID_INVOKEVIRTUAL;
+    @HotSpotVMConstant(name = "CodeInstaller::INVOKESTATIC") @Stable public int MARKID_INVOKESTATIC;
+    @HotSpotVMConstant(name = "CodeInstaller::INVOKESPECIAL") @Stable public int MARKID_INVOKESPECIAL;
+    @HotSpotVMConstant(name = "CodeInstaller::INLINE_INVOKE") @Stable public int MARKID_INLINE_INVOKE;
+    @HotSpotVMConstant(name = "CodeInstaller::POLL_NEAR") @Stable public int MARKID_POLL_NEAR;
+    @HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_NEAR") @Stable public int MARKID_POLL_RETURN_NEAR;
+    @HotSpotVMConstant(name = "CodeInstaller::POLL_FAR") @Stable public int MARKID_POLL_FAR;
+    @HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_FAR") @Stable public int MARKID_POLL_RETURN_FAR;
+    @HotSpotVMConstant(name = "CodeInstaller::CARD_TABLE_ADDRESS") @Stable public int MARKID_CARD_TABLE_ADDRESS;
+    @HotSpotVMConstant(name = "CodeInstaller::HEAP_TOP_ADDRESS") @Stable public int MARKID_HEAP_TOP_ADDRESS;
+    @HotSpotVMConstant(name = "CodeInstaller::HEAP_END_ADDRESS") @Stable public int MARKID_HEAP_END_ADDRESS;
+    @HotSpotVMConstant(name = "CodeInstaller::NARROW_KLASS_BASE_ADDRESS") @Stable public int MARKID_NARROW_KLASS_BASE_ADDRESS;
+    @HotSpotVMConstant(name = "CodeInstaller::CRC_TABLE_ADDRESS") @Stable public int MARKID_CRC_TABLE_ADDRESS;
+    @HotSpotVMConstant(name = "CodeInstaller::INVOKE_INVALID") @Stable public int MARKID_INVOKE_INVALID;
+
+    // Checkstyle: resume
+
+    private boolean check() {
+        for (Field f : getClass().getDeclaredFields()) {
+            int modifiers = f.getModifiers();
+            if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
+                assert Modifier.isFinal(modifiers) || f.getAnnotation(Stable.class) != null : "field should either be final or @Stable: " + f;
+            }
+        }
+
+        assert codeEntryAlignment > 0 : codeEntryAlignment;
+        assert (layoutHelperArrayTagObjectValue & (1 << (Integer.SIZE - 1))) != 0 : "object array must have first bit set";
+        assert (layoutHelperArrayTagTypeValue & (1 << (Integer.SIZE - 1))) != 0 : "type array must have first bit set";
+
+        return true;
+    }
+
+    /**
+     * A compact representation of the different encoding strategies for Objects and metadata.
+     */
+    public static class CompressEncoding {
+        public final long base;
+        public final int shift;
+        public final int alignment;
+
+        CompressEncoding(long base, int shift, int alignment) {
+            this.base = base;
+            this.shift = shift;
+            this.alignment = alignment;
+        }
+
+        public int compress(long ptr) {
+            if (ptr == 0L) {
+                return 0;
+            } else {
+                return (int) ((ptr - base) >>> shift);
+            }
+        }
+
+        public long uncompress(int ptr) {
+            if (ptr == 0) {
+                return 0L;
+            } else {
+                return ((ptr & 0xFFFFFFFFL) << shift) + base;
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "base: " + base + " shift: " + shift + " alignment: " + alignment;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + alignment;
+            result = prime * result + (int) (base ^ (base >>> 32));
+            result = prime * result + shift;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof CompressEncoding) {
+                CompressEncoding other = (CompressEncoding) obj;
+                return alignment == other.alignment && base == other.base && shift == other.shift;
+            } else {
+                return false;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigVerifier.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot;
+
+import static java.lang.String.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.internal.org.objectweb.asm.*;
+import jdk.internal.org.objectweb.asm.Type;
+import jdk.vm.ci.common.*;
+import sun.misc.*;
+
+/**
+ * A {@link ClassVisitor} that verifies {@link HotSpotVMConfig} does not access {@link Unsafe} from
+ * any of its non-static, non-constructor methods. This ensures that a deserialized
+ * {@link HotSpotVMConfig} object does not perform any unsafe reads on addresses that are only valid
+ * in the context in which the object was serialized. Note that this does not catch cases where a
+ * client uses an address stored in a {@link HotSpotVMConfig} field.
+ */
+final class HotSpotVMConfigVerifier extends ClassVisitor {
+
+    public static boolean check() {
+        Class<?> cls = HotSpotVMConfig.class;
+        String classFilePath = "/" + cls.getName().replace('.', '/') + ".class";
+        try {
+            InputStream classfile = cls.getResourceAsStream(classFilePath);
+            ClassReader cr = new ClassReader(Objects.requireNonNull(classfile, "Could not find class file for " + cls.getName()));
+            ClassVisitor cv = new HotSpotVMConfigVerifier();
+            cr.accept(cv, 0);
+            return true;
+        } catch (IOException e) {
+            throw new JVMCIError(e);
+        }
+    }
+
+    /**
+     * Source file context for error reporting.
+     */
+    String sourceFile = null;
+
+    /**
+     * Line number for error reporting.
+     */
+    int lineNo = -1;
+
+    private static Class<?> resolve(String name) {
+        try {
+            return Class.forName(name.replace('/', '.'));
+        } catch (ClassNotFoundException e) {
+            throw new JVMCIError(e);
+        }
+    }
+
+    HotSpotVMConfigVerifier() {
+        super(Opcodes.ASM5);
+    }
+
+    @Override
+    public void visitSource(String source, String debug) {
+        this.sourceFile = source;
+    }
+
+    void verify(boolean condition, String message) {
+        if (!condition) {
+            error(message);
+        }
+    }
+
+    void error(String message) {
+        String errorMessage = format("%s:%d: %s is not allowed in the context of compilation replay. The unsafe access should be moved into the %s constructor and the result cached in a field",
+                        sourceFile, lineNo, message, HotSpotVMConfig.class.getSimpleName());
+        throw new JVMCIError(errorMessage);
+
+    }
+
+    @Override
+    public MethodVisitor visitMethod(int access, String name, String d, String signature, String[] exceptions) {
+        if (!Modifier.isStatic(access) && Modifier.isPublic(access) && !name.equals("<init>")) {
+            return new MethodVisitor(Opcodes.ASM5) {
+
+                @Override
+                public void visitLineNumber(int line, Label start) {
+                    lineNo = line;
+                }
+
+                private Executable resolveMethod(String owner, String methodName, String methodDesc) {
+                    Class<?> declaringClass = resolve(owner);
+                    while (declaringClass != null) {
+                        if (methodName.equals("<init>")) {
+                            for (Constructor<?> c : declaringClass.getDeclaredConstructors()) {
+                                if (methodDesc.equals(Type.getConstructorDescriptor(c))) {
+                                    return c;
+                                }
+                            }
+                        } else {
+                            Type[] argumentTypes = Type.getArgumentTypes(methodDesc);
+                            for (Method m : declaringClass.getDeclaredMethods()) {
+                                if (m.getName().equals(methodName)) {
+                                    if (Arrays.equals(argumentTypes, Type.getArgumentTypes(m))) {
+                                        if (Type.getReturnType(methodDesc).equals(Type.getReturnType(m))) {
+                                            return m;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        declaringClass = declaringClass.getSuperclass();
+                    }
+                    throw new NoSuchMethodError(owner + "." + methodName + methodDesc);
+                }
+
+                /**
+                 * Checks whether a given method is allowed to be called.
+                 */
+                private boolean checkInvokeTarget(Executable method) {
+                    if (method.getDeclaringClass().equals(Unsafe.class)) {
+                        return false;
+                    }
+                    return true;
+                }
+
+                @Override
+                public void visitMethodInsn(int opcode, String owner, String methodName, String methodDesc, boolean itf) {
+                    Executable callee = resolveMethod(owner, methodName, methodDesc);
+                    verify(checkInvokeTarget(callee), "invocation of " + callee);
+                }
+            };
+        } else {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.meta.*;
+
+public interface HotSpotVMEventListener {
+
+    /**
+     * Notifies this client that the VM is shutting down.
+     */
+    default void notifyShutdown() {
+    }
+
+    /**
+     * Notify on successful install into the CodeCache.
+     *
+     * @param hotSpotCodeCacheProvider
+     * @param installedCode
+     * @param compResult
+     */
+    default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompilationResult compResult) {
+    }
+
+    /**
+     * Perform any extra initialization required.
+     *
+     * @param runtime
+     */
+    default void completeInitialization(HotSpotJVMCIRuntime runtime) {
+    }
+
+    /**
+     * Create a custom {@link JVMCIMetaAccessContext} to be used for managing the lifetime of loaded
+     * metadata. It a custom one isn't created then the default implementation will be a single
+     * context with globally shared instances of {@link ResolvedJavaType} that are never released.
+     *
+     * @param hotSpotJVMCIRuntime
+     * @return a custom context or null
+     */
+    default JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime hotSpotJVMCIRuntime) {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVmSymbols.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot;
+
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import sun.misc.*;
+
+/**
+ * Class to access the C++ {@code vmSymbols} table.
+ */
+public final class HotSpotVmSymbols {
+
+    /**
+     * Returns the symbol in the {@code vmSymbols} table at position {@code index} as {@link String}
+     * .
+     *
+     * @param index position in the symbol table
+     * @return the symbol at position id
+     */
+    public static String symbolAt(int index) {
+        HotSpotJVMCIRuntimeProvider runtime = runtime();
+        HotSpotVMConfig config = runtime.getConfig();
+        assert config.vmSymbolsFirstSID <= index && index < config.vmSymbolsSIDLimit : "index " + index + " is out of bounds";
+        assert config.symbolPointerSize == Unsafe.ADDRESS_SIZE : "the following address read is broken";
+        return runtime.getCompilerToVM().getSymbol(UNSAFE.getAddress(config.vmSymbolsSymbols + index * config.symbolPointerSize));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.hotspot;
+
+/**
+ * A tag interface indicating that this type is a wrapper around a HotSpot metaspace object.
+ *
+ * It would preferable if this were the base class containing the pointer but that would require
+ * mixins since most of the wrapper types have complex supertype hierarchies.
+ */
+public interface MetaspaceWrapperObject {
+
+    long getMetaspacePointer();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Stable.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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 jdk.vm.ci.hotspot;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation functions as an alias for the sun.invoke.Stable annotation within JVMCI code. It
+ * is specially recognized during class file parsing in the same way as that annotation.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Stable {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SuppressFBWarnings.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot;
+
+/**
+ * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
+ */
+public @interface SuppressFBWarnings {
+    /**
+     * The set of FindBugs <a
+     * href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
+     * suppressed in annotated element. The value can be a bug category, kind or pattern.
+     */
+    String[] value();
+
+    /**
+     * Reason why the warning is suppressed.
+     */
+    String justification();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+package jdk.vm.ci.hotspot;
+
+import java.lang.reflect.Field;
+
+import sun.misc.Unsafe;
+
+/**
+ * Package private access to the {@link Unsafe} capability.
+ */
+class UnsafeAccess {
+
+    static final Unsafe UNSAFE = initUnsafe();
+
+    private static Unsafe initUnsafe() {
+        try {
+            // Fast path when we are trusted.
+            return Unsafe.getUnsafe();
+        } catch (SecurityException se) {
+            // Slow path when we are not trusted.
+            try {
+                Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+                theUnsafe.setAccessible(true);
+                return (Unsafe) theUnsafe.get(Unsafe.class);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to get Unsafe", e);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EmptyEventProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot.events;
+
+import jdk.vm.ci.common.*;
+
+/**
+ * An empty implementation for {@link EventProvider}. This implementation is used when no logging is
+ * requested.
+ */
+public final class EmptyEventProvider implements EventProvider {
+
+    public CompilationEvent newCompilationEvent() {
+        return new EmptyCompilationEvent();
+    }
+
+    public static class EmptyCompilationEvent implements CompilationEvent {
+        public void commit() {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void begin() {
+        }
+
+        public void end() {
+        }
+
+        public void setMethod(String method) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public void setCompileId(int compileId) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public void setCompileLevel(int compileLevel) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public void setSucceeded(boolean succeeded) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public void setIsOsr(boolean isOsr) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public void setCodeSize(int codeSize) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public void setInlinedBytes(int inlinedBytes) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    public CompilerFailureEvent newCompilerFailureEvent() {
+        return new EmptyCompilerFailureEvent();
+    }
+
+    public static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
+        public void commit() {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void setCompileId(int compileId) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+
+        public void setMessage(String message) {
+            throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EventProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot.events;
+
+/**
+ * A provider that provides a specific implementation for events that can be logged in the compiler.
+ */
+public interface EventProvider {
+
+    /**
+     * An instant event is an event that is not considered to have taken any time.
+     */
+    interface InstantEvent {
+        /**
+         * Commits the event.
+         */
+        void commit();
+
+        /**
+         * Determines if this particular event instance would be committed to the data stream right
+         * now if application called {@link #commit()}. This in turn depends on whether the event is
+         * enabled and possible other factors.
+         *
+         * @return if this event would be committed on a call to {@link #commit()}.
+         */
+        boolean shouldWrite();
+    }
+
+    /**
+     * Timed events describe an operation that somehow consumes time.
+     */
+    interface TimedEvent extends InstantEvent {
+        /**
+         * Starts the timing for this event.
+         */
+        void begin();
+
+        /**
+         * Ends the timing period for this event.
+         */
+        void end();
+    }
+
+    /**
+     * Creates a new {@link CompilationEvent}.
+     *
+     * @return a compilation event
+     */
+    CompilationEvent newCompilationEvent();
+
+    /**
+     * A compilation event.
+     */
+    interface CompilationEvent extends TimedEvent {
+        void setMethod(String method);
+
+        void setCompileId(int compileId);
+
+        void setCompileLevel(int compileLevel);
+
+        void setSucceeded(boolean succeeded);
+
+        void setIsOsr(boolean isOsr);
+
+        void setCodeSize(int codeSize);
+
+        void setInlinedBytes(int inlinedBytes);
+    }
+
+    /**
+     * Creates a new {@link CompilerFailureEvent}.
+     *
+     * @return a compiler failure event
+     */
+    CompilerFailureEvent newCompilerFailureEvent();
+
+    /**
+     * A compiler failure event.
+     */
+    interface CompilerFailureEvent extends InstantEvent {
+        void setCompileId(int compileId);
+
+        void setMessage(String message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/logging/package-info.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011, 2015, 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.
+ */
+/**
+ * Logging framework for the HotSpot CRI implementation.
+ */
+package jdk.vm.ci.hotspot.logging;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMAddress.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspotvmconfig;
+
+import java.lang.annotation.*;
+
+/**
+ * Refers to a C++ address in the VM.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotVMAddress {
+
+    /**
+     * Returns the name of the symbol this address is referring to.
+     *
+     * @return name of symbol of this address
+     */
+    String name();
+
+    /**
+     * List of architectures where this constant is required. Names are derived from
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
+     */
+    @SuppressWarnings("javadoc")
+    String[] archs() default {};
+
+    /**
+     * List of operating systems where this constant is required. Names are derived from
+     * {@link HotSpotVMConfig#getHostOSName()}. An empty list implies that the constant is required
+     * on all operating systems.
+     */
+    @SuppressWarnings("javadoc")
+    String[] os() default {};
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 2014, 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 jdk.vm.ci.hotspotvmconfig;
+
+import java.lang.annotation.*;
+
+/**
+ * Refers to a C++ constant in the VM.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotVMConstant {
+
+    /**
+     * Returns the name of the constant.
+     *
+     * @return name of constant
+     */
+    String name();
+
+    /**
+     * List of architectures where this constant is required. Names are derived from
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
+     */
+    @SuppressWarnings("javadoc")
+    String[] archs() default {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMData.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspotvmconfig;
+
+import java.lang.annotation.*;
+
+/**
+ * Refers to a entry in {@code gHotSpotVMData}.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotVMData {
+
+    /**
+     * Returns the array index of this field.
+     *
+     * @return array index of field
+     */
+    int index();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMField.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 2014, 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 jdk.vm.ci.hotspotvmconfig;
+
+import java.lang.annotation.*;
+
+/**
+ * Refers to a C++ field in the VM.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotVMField {
+
+    /**
+     * Types of information this annotation can return.
+     */
+    enum Type {
+        /**
+         * Returns the offset of this field within the type. Only valid for instance fields.
+         */
+        OFFSET,
+
+        /**
+         * Returns the absolute address of this field. Only valid for static fields.
+         */
+        ADDRESS,
+
+        /**
+         * Returns the value of this field. Only valid for static fields.
+         */
+        VALUE;
+    }
+
+    /**
+     * Specifies what type of information to return.
+     *
+     * @see Type
+     */
+    Type get();
+
+    /**
+     * Returns the type name containing this field.
+     *
+     * @return name of containing type
+     */
+    String type();
+
+    /**
+     * Returns the name of this field.
+     *
+     * @return name of field
+     */
+    String name();
+
+    /**
+     * List of architectures where this constant is required. Names are derived from
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
+     */
+    @SuppressWarnings("javadoc")
+    String[] archs() default {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMFlag.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, 2014, 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 jdk.vm.ci.hotspotvmconfig;
+
+import java.lang.annotation.*;
+
+/**
+ * Refers to a C++ flag in the VM.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotVMFlag {
+
+    /**
+     * Returns the name of this flag.
+     *
+     * @return name of flag.
+     */
+    String name();
+
+    /**
+     * List of architectures where this constant is required. Names are derived from
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
+     */
+    @SuppressWarnings("javadoc")
+    String[] archs() default {};
+
+    boolean optional() default false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMManual.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspotvmconfig;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotates a field in HotSpotVMConfig which is not read from the VM but is calculated manually.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotVMManual {
+
+    /**
+     * Returns the name associated with that field.
+     *
+     * @return name associated with field
+     */
+    String name();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 2014, 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 jdk.vm.ci.hotspotvmconfig;
+
+import java.lang.annotation.*;
+
+/**
+ * Refers to a C++ type in the VM.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotVMType {
+
+    /**
+     * Types of information this annotation can return.
+     */
+    enum Type {
+        /**
+         * Returns the size of the type (C++ {@code sizeof()}).
+         */
+        SIZE;
+    }
+
+    /**
+     * Specifies what type of information to return.
+     *
+     * @see Type
+     */
+    Type get();
+
+    /**
+     * Returns the name of the type.
+     *
+     * @return name of type
+     */
+    String name();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/InitTimer.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.inittimer;
+
+/**
+ * A facility for timing a step in the runtime initialization sequence. This is independent from all
+ * other JVMCI code so as to not perturb the initialization sequence. It is enabled by setting the
+ * {@code "jvmci.inittimer"} system property to {@code "true"}.
+ */
+public final class InitTimer implements AutoCloseable {
+    final String name;
+    final long start;
+
+    private InitTimer(String name) {
+        this.name = name;
+        this.start = System.currentTimeMillis();
+        System.out.println("START: " + SPACES.substring(0, timerDepth * 2) + name);
+        assert Thread.currentThread() == initializingThread : Thread.currentThread() + " != " + initializingThread;
+        timerDepth++;
+    }
+
+    @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "only the initializing thread accesses this field")
+    public void close() {
+        final long end = System.currentTimeMillis();
+        timerDepth--;
+        System.out.println(" DONE: " + SPACES.substring(0, timerDepth * 2) + name + " [" + (end - start) + " ms]");
+    }
+
+    public static InitTimer timer(String name) {
+        return ENABLED ? new InitTimer(name) : null;
+    }
+
+    public static InitTimer timer(String name, Object suffix) {
+        return ENABLED ? new InitTimer(name + suffix) : null;
+    }
+
+    /**
+     * Specifies if initialization timing is enabled.
+     */
+    private static final boolean ENABLED = Boolean.getBoolean("jvmci.inittimer") || Boolean.getBoolean("jvmci.runtime.TimeInit");
+
+    public static int timerDepth = 0;
+    public static final String SPACES = "                                            ";
+
+    /**
+     * Used to assert the invariant that all initialization happens on the same thread.
+     */
+    public static final Thread initializingThread;
+    static {
+        if (ENABLED) {
+            initializingThread = Thread.currentThread();
+            System.out.println("INITIALIZING THREAD: " + initializingThread);
+        } else {
+            initializingThread = null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/SuppressFBWarnings.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.inittimer;
+
+/**
+ * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
+ */
+public @interface SuppressFBWarnings {
+    /**
+     * The set of FindBugs <a
+     * href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
+     * suppressed in annotated element. The value can be a bug category, kind or pattern.
+     */
+    String[] value();
+
+    /**
+     * Reason why the warning is suppressed.
+     */
+    String justification();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/overview.html	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+This code is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+version 2 for more details (a copy is included in the LICENSE file that
+accompanied this code).
+
+You should have received a copy of the GNU General Public License version
+2 along with this work; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+or visit www.oracle.com if you need additional information or have any
+questions.
+-->
+
+</head>
+<body>
+
+The <code>jdk.vm.ci.meta</code> project provides an API to the runtime data structures
+for various Java elements. Unlike standard Java reflection, it can model elements that are not yet loaded.
+It can also expose profiling information collected by the runtime system.
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractJavaProfile.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,158 @@
+/*
+ * 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 jdk.vm.ci.meta;
+
+/**
+ * This object holds probability information for a set of items that were profiled at a specific
+ * BCI. The precision of the supplied values may vary, but a runtime that provides this information
+ * should be aware that it will be used to guide performance-critical decisions like speculative
+ * inlining, etc.
+ *
+ * @param <T> a subclass of AbstractProfiledItem
+ * @param <U> the class of the items that are profiled at the specific BCI and for which
+ *            probabilities are stored. E.g., a ResolvedJavaType or a ResolvedJavaMethod.
+ */
+public abstract class AbstractJavaProfile<T extends AbstractProfiledItem<U>, U> {
+
+    private final double notRecordedProbability;
+    private final T[] pitems;
+
+    public AbstractJavaProfile(double notRecordedProbability, T[] pitems) {
+        this.pitems = pitems;
+        assert !Double.isNaN(notRecordedProbability);
+        this.notRecordedProbability = notRecordedProbability;
+        assert isSorted();
+        assert totalProbablility() >= 0 && totalProbablility() <= 1.0001 : totalProbablility() + " " + this;
+    }
+
+    private double totalProbablility() {
+        double total = notRecordedProbability;
+        for (T item : pitems) {
+            total += item.probability;
+        }
+        return total;
+    }
+
+    /**
+     * Determines if an array of profiled items are sorted in descending order of their
+     * probabilities.
+     */
+    private boolean isSorted() {
+        for (int i = 1; i < pitems.length; i++) {
+            if (pitems[i - 1].getProbability() < pitems[i].getProbability()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the estimated probability of all types that could not be recorded due to profiling
+     * limitations.
+     *
+     * @return double value &ge; 0.0 and &le; 1.0
+     */
+    public double getNotRecordedProbability() {
+        return notRecordedProbability;
+    }
+
+    protected T[] getItems() {
+        return pitems;
+    }
+
+    /**
+     * Searches for an entry of a given resolved Java type.
+     *
+     * @param type the type for which an entry should be searched
+     * @return the entry or null if no entry for this type can be found
+     */
+    public T findEntry(ResolvedJavaType type) {
+        if (pitems != null) {
+            for (T pt : pitems) {
+                if (pt.getItem().equals(type)) {
+                    return pt;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(this.getClass().getName());
+        builder.append("[");
+        if (pitems != null) {
+            for (T pt : pitems) {
+                builder.append(pt.toString());
+                builder.append(", ");
+            }
+        }
+        builder.append(this.notRecordedProbability);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public boolean isIncluded(U item) {
+        if (this.getNotRecordedProbability() > 0.0) {
+            return true;
+        } else {
+            for (int i = 0; i < getItems().length; i++) {
+                T pitem = getItems()[i];
+                U curType = pitem.getItem();
+                if (curType == item) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof AbstractJavaProfile)) {
+            return false;
+        }
+        AbstractJavaProfile<?, ?> that = (AbstractJavaProfile<?, ?>) obj;
+        if (that.notRecordedProbability != notRecordedProbability) {
+            return false;
+        }
+        if (that.pitems.length != pitems.length) {
+            return false;
+        }
+        for (int i = 0; i < pitems.length; ++i) {
+            if (!pitems[i].equals(that.pitems[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) Double.doubleToLongBits(notRecordedProbability) + pitems.length * 13;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AbstractProfiledItem.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,95 @@
+/*
+ * 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 jdk.vm.ci.meta;
+
+/**
+ * A profiled type that has a probability. Profiled types are naturally sorted in descending order
+ * of their probabilities.
+ */
+public abstract class AbstractProfiledItem<T> implements Comparable<AbstractProfiledItem<?>> {
+
+    protected final T item;
+    protected final double probability;
+
+    public AbstractProfiledItem(T item, double probability) {
+        assert item != null;
+        assert probability >= 0.0D && probability <= 1.0D;
+        this.item = item;
+        this.probability = probability;
+    }
+
+    protected T getItem() {
+        return item;
+    }
+
+    /**
+     * Returns the estimated probability of {@link #getItem()}.
+     *
+     * @return double value &ge; 0.0 and &le; 1.0
+     */
+    public double getProbability() {
+        return probability;
+    }
+
+    @Override
+    public int compareTo(AbstractProfiledItem<?> o) {
+        if (getProbability() > o.getProbability()) {
+            return -1;
+        } else if (getProbability() < o.getProbability()) {
+            return 1;
+        }
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        long temp;
+        temp = Double.doubleToLongBits(probability);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        result = prime * result + item.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        AbstractProfiledItem<?> other = (AbstractProfiledItem<?>) obj;
+        if (Double.doubleToLongBits(probability) != Double.doubleToLongBits(other.probability)) {
+            return false;
+        }
+        return item.equals(other.item);
+    }
+
+    @Override
+    public abstract String toString();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Common base class for values that are stored in some location that's managed by the register
+ * allocator (e.g. register, stack slot).
+ */
+public abstract class AllocatableValue extends Value implements JavaValue {
+
+    public static final AllocatableValue[] NONE = {};
+
+    public AllocatableValue(LIRKind lirKind) {
+        super(lirKind);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+import java.lang.invoke.*;
+import java.util.*;
+
+/**
+ * Class for recording assumptions made during compilation.
+ */
+public final class Assumptions implements Iterable<Assumptions.Assumption> {
+
+    /**
+     * Abstract base class for assumptions. An assumption assumes a property of the runtime that may
+     * be invalidated by subsequent execution (e.g., that a class has no subclasses implementing
+     * {@link NoFinalizableSubclass Object.finalize()}).
+     */
+    public abstract static class Assumption {
+    }
+
+    /**
+     * A class for providing information that is only valid in association with a set of
+     * {@link Assumption}s.
+     *
+     * @param <T>
+     */
+    public static class AssumptionResult<T> {
+        Assumption[] assumptions;
+        final T result;
+
+        private static final Assumption[] EMPTY = new Assumption[0];
+
+        public AssumptionResult(T result, Assumption... assumptions) {
+            this.result = result;
+            this.assumptions = assumptions;
+        }
+
+        public AssumptionResult(T result) {
+            this(result, EMPTY);
+        }
+
+        public T getResult() {
+            return result;
+        }
+
+        public boolean isAssumptionFree() {
+            return assumptions.length == 0;
+        }
+
+        public void add(AssumptionResult<T> other) {
+            Assumption[] newAssumptions = Arrays.copyOf(this.assumptions, this.assumptions.length + other.assumptions.length);
+            System.arraycopy(other.assumptions, 0, newAssumptions, this.assumptions.length, other.assumptions.length);
+            this.assumptions = newAssumptions;
+        }
+
+        public boolean canRecordTo(Assumptions target) {
+            /*
+             * We can use the result if it is either assumption free, or if we have a valid
+             * Assumptions object where we can record assumptions.
+             */
+            return assumptions.length == 0 || target != null;
+        }
+
+        public void recordTo(Assumptions target) {
+            assert canRecordTo(target);
+
+            if (assumptions.length > 0) {
+                for (Assumption assumption : assumptions) {
+                    target.record(assumption);
+                }
+            }
+        }
+    }
+
+    /**
+     * An assumption that a given class has no subclasses implementing {@link Object#finalize()}).
+     */
+    public static final class NoFinalizableSubclass extends Assumption {
+
+        private ResolvedJavaType receiverType;
+
+        public NoFinalizableSubclass(ResolvedJavaType receiverType) {
+            this.receiverType = receiverType;
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 + receiverType.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof NoFinalizableSubclass) {
+                NoFinalizableSubclass other = (NoFinalizableSubclass) obj;
+                return other.receiverType.equals(receiverType);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "NoFinalizableSubclass[receiverType=" + receiverType.toJavaName() + "]";
+        }
+
+    }
+
+    /**
+     * An assumption that a given abstract or interface type has one direct concrete subtype. There
+     * is no requirement that the subtype is a leaf type.
+     */
+    public static final class ConcreteSubtype extends Assumption {
+
+        /**
+         * Type the assumption is made about.
+         */
+        public final ResolvedJavaType context;
+
+        /**
+         * Assumed concrete sub-type of the context type.
+         */
+        public final ResolvedJavaType subtype;
+
+        public ConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
+            this.context = context;
+            this.subtype = subtype;
+            assert context.isAbstract();
+            assert subtype.isConcrete() || context.isInterface() : subtype.toString() + " : " + context.toString();
+            assert !subtype.isArray() || subtype.getElementalType().isFinalFlagSet() : subtype.toString() + " : " + context.toString();
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + context.hashCode();
+            result = prime * result + subtype.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteSubtype) {
+                ConcreteSubtype other = (ConcreteSubtype) obj;
+                return other.context.equals(context) && other.subtype.equals(subtype);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "ConcreteSubtype[context=" + context.toJavaName() + ", subtype=" + subtype.toJavaName() + "]";
+        }
+    }
+
+    /**
+     * An assumption that a given type has no subtypes.
+     */
+    public static final class LeafType extends Assumption {
+
+        /**
+         * Type the assumption is made about.
+         */
+        public final ResolvedJavaType context;
+
+        public LeafType(ResolvedJavaType context) {
+            this.context = context;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + context.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof LeafType) {
+                LeafType other = (LeafType) obj;
+                return other.context.equals(context);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "LeafSubtype[context=" + context.toJavaName() + "]";
+        }
+    }
+
+    /**
+     * An assumption that a given virtual method has a given unique implementation.
+     */
+    public static final class ConcreteMethod extends Assumption {
+
+        /**
+         * A virtual (or interface) method whose unique implementation for the receiver type in
+         * {@link #context} is {@link #impl}.
+         */
+        public final ResolvedJavaMethod method;
+
+        /**
+         * A receiver type.
+         */
+        public final ResolvedJavaType context;
+
+        /**
+         * The unique implementation of {@link #method} for {@link #context}.
+         */
+        public final ResolvedJavaMethod impl;
+
+        public ConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
+            this.method = method;
+            this.context = context;
+            this.impl = impl;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + method.hashCode();
+            result = prime * result + context.hashCode();
+            result = prime * result + impl.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteMethod) {
+                ConcreteMethod other = (ConcreteMethod) obj;
+                return other.method.equals(method) && other.context.equals(context) && other.impl.equals(impl);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "ConcreteMethod[method=" + method.format("%H.%n(%p)%r") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)%r") + "]";
+        }
+    }
+
+    /**
+     * An assumption that a given call site's method handle did not change.
+     */
+    public static final class CallSiteTargetValue extends Assumption {
+
+        public final CallSite callSite;
+        public final MethodHandle methodHandle;
+
+        public CallSiteTargetValue(CallSite callSite, MethodHandle methodHandle) {
+            this.callSite = callSite;
+            this.methodHandle = methodHandle;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + callSite.hashCode();
+            result = prime * result + methodHandle.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof CallSiteTargetValue) {
+                CallSiteTargetValue other = (CallSiteTargetValue) obj;
+                return callSite.equals(other.callSite) && methodHandle.equals(other.methodHandle);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "CallSiteTargetValue[callSite=" + callSite + ", methodHandle=" + methodHandle + "]";
+        }
+    }
+
+    private final Set<Assumption> assumptions = new HashSet<>();
+
+    /**
+     * Returns whether any assumptions have been registered.
+     *
+     * @return {@code true} if at least one assumption has been registered, {@code false} otherwise.
+     */
+    public boolean isEmpty() {
+        return assumptions.isEmpty();
+    }
+
+    @Override
+    public int hashCode() {
+        throw new UnsupportedOperationException("hashCode");
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Assumptions) {
+            Assumptions that = (Assumptions) obj;
+            if (!this.assumptions.equals(that.assumptions)) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Iterator<Assumption> iterator() {
+        return assumptions.iterator();
+    }
+
+    /**
+     * Records an assumption that the specified type has no finalizable subclasses.
+     *
+     * @param receiverType the type that is assumed to have no finalizable subclasses
+     */
+    public void recordNoFinalizableSubclassAssumption(ResolvedJavaType receiverType) {
+        record(new NoFinalizableSubclass(receiverType));
+    }
+
+    /**
+     * Records that {@code subtype} is the only concrete subtype in the class hierarchy below
+     * {@code context}.
+     *
+     * @param context the root of the subtree of the class hierarchy that this assumptions is about
+     * @param subtype the one concrete subtype
+     */
+    public void recordConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
+        record(new ConcreteSubtype(context, subtype));
+    }
+
+    /**
+     * Records that {@code impl} is the only possible concrete target for a virtual call to
+     * {@code method} with a receiver of type {@code context}.
+     *
+     * @param method a method that is the target of a virtual call
+     * @param context the receiver type of a call to {@code method}
+     * @param impl the concrete method that is the only possible target for the virtual call
+     */
+    public void recordConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
+        record(new ConcreteMethod(method, context, impl));
+    }
+
+    public void record(Assumption assumption) {
+        assumptions.add(assumption);
+    }
+
+    /**
+     * Gets a copy of the assumptions recorded in this object as an array.
+     */
+    public Assumption[] toArray() {
+        return assumptions.toArray(new Assumption[assumptions.size()]);
+    }
+
+    /**
+     * Copies assumptions recorded by another {@link Assumptions} object into this object.
+     */
+    public void record(Assumptions other) {
+        assert other != this;
+        assumptions.addAll(other.assumptions);
+    }
+
+    @Override
+    public String toString() {
+        return "Assumptions[" + assumptions + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.meta;
+
+/**
+ * Represents a compile-time constant (boxed) value within the compiler.
+ */
+public interface Constant {
+
+    boolean isDefaultForKind();
+
+    String toValueString();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2009, 2014, 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 jdk.vm.ci.meta;
+
+/**
+ * Represents the runtime representation of the constant pool that is used by the compiler when
+ * parsing bytecode. Provides methods to look up a constant pool entry without performing
+ * resolution. They are used during compilation.
+ */
+public interface ConstantPool {
+
+    /**
+     * Returns the number of entries the constant pool.
+     *
+     * @return number of entries in the constant pool
+     */
+    int length();
+
+    /**
+     * Ensures that the type referenced by the specified constant pool entry is loaded and
+     * initialized. This can be used to compile time resolve a type. It works for field, method, or
+     * type constant pool entries.
+     *
+     * @param cpi the index of the constant pool entry that references the type
+     * @param opcode the opcode of the instruction that references the type
+     */
+    void loadReferencedType(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a field. If {@code opcode} is non-negative, then resolution checks
+     * specific to the bytecode it denotes are performed if the field is already resolved. Should
+     * any of these checks fail, an unresolved field reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or
+     *            {@code -1}
+     * @return a reference to the field at {@code cpi} in this pool
+     * @throws ClassFormatError if the entry at {@code cpi} is not a field
+     */
+    JavaField lookupField(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a method. If {@code opcode} is non-negative, then resolution checks
+     * specific to the bytecode it denotes are performed if the method is already resolved. Should
+     * any of these checks fail, an unresolved method reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or
+     *            {@code -1}
+     * @return a reference to the method at {@code cpi} in this pool
+     * @throws ClassFormatError if the entry at {@code cpi} is not a method
+     */
+    JavaMethod lookupMethod(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a type. If {@code opcode} is non-negative, then resolution checks
+     * specific to the bytecode it denotes are performed if the type is already resolved. Should any
+     * of these checks fail, an unresolved type reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or
+     *            {@code -1}
+     * @return a reference to the compiler interface type
+     */
+    JavaType lookupType(int cpi, int opcode);
+
+    /**
+     * Looks up an Utf8 string.
+     *
+     * @param cpi the constant pool index
+     * @return the Utf8 string at index {@code cpi} in this constant pool
+     */
+    String lookupUtf8(int cpi);
+
+    /**
+     * Looks up a method signature.
+     *
+     * @param cpi the constant pool index
+     * @return the method signature at index {@code cpi} in this constant pool
+     */
+    Signature lookupSignature(int cpi);
+
+    /**
+     * Looks up a constant at the specified index.
+     *
+     * @param cpi the constant pool index
+     * @return the {@code Constant} or {@code JavaType} instance representing the constant pool
+     *         entry
+     */
+    Object lookupConstant(int cpi);
+
+    /**
+     * Looks up the appendix at the specified index.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or
+     *            {@code -1}
+     * @return the appendix if it exists and is resolved or {@code null}
+     */
+    JavaConstant lookupAppendix(int cpi, int opcode);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012, 2015, 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 jdk.vm.ci.meta;
+
+import java.lang.invoke.*;
+
+/**
+ * Reflection operations on values represented as {@linkplain JavaConstant constants}. All methods
+ * in this interface require the VM to access the actual object encapsulated in
+ * {@link JavaKind#Object object} constants. This access is not always possible, depending on kind
+ * of VM and the state that the VM is in. Therefore, all methods can return {@code null} at any
+ * time, to indicate that the result is not available at this point. The caller is responsible to
+ * check for {@code null} results and handle them properly, e.g., not perform an optimization.
+ */
+public interface ConstantReflectionProvider {
+
+    /**
+     * Compares two constants for equality. The equality relationship is symmetric. Returns
+     * {@link Boolean#TRUE true} if the two constants represent the same run time value,
+     * {@link Boolean#FALSE false} if they are different. Returns {@code null} if the constants
+     * cannot be compared at this point.
+     */
+    Boolean constantEquals(Constant x, Constant y);
+
+    /**
+     * Returns the length of the array constant. Returns {@code null} if the constant is not an
+     * array, or if the array length is not available at this point.
+     */
+    Integer readArrayLength(JavaConstant array);
+
+    /**
+     * Reads a value from the given array at the given index. Returns {@code null} if the constant
+     * is not an array, if the index is out of bounds, or if the value is not available at this
+     * point.
+     */
+    JavaConstant readArrayElement(JavaConstant array, int index);
+
+    /**
+     * Reads a value from the given array at the given index if it is a stable array. Returns
+     * {@code null} if the constant is not a stable array, if it is a default value, if the index is
+     * out of bounds, or if the value is not available at this point.
+     */
+    JavaConstant readConstantArrayElement(JavaConstant array, int index);
+
+    /**
+     * Reads a value from the given array at the given offset if it is a stable array. The offset
+     * will be decoded relative to the platform addressing into an index into the array. Returns
+     * {@code null} if the constant is not a stable array, if it is a default value, if the offset
+     * is out of bounds, or if the value is not available at this point.
+     */
+    JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset);
+
+    /**
+     * Gets the constant value of this field. Note that a {@code static final} field may not be
+     * considered constant if its declaring class is not yet initialized or if it is a well known
+     * field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}).
+     *
+     * @param receiver object from which this field's value is to be read. This value is ignored if
+     *            this field is static.
+     * @return the constant value of this field or {@code null} if this field is not considered
+     *         constant by the runtime
+     */
+    JavaConstant readConstantFieldValue(JavaField field, JavaConstant receiver);
+
+    /**
+     * Gets the current value of this field for a given object, if available.
+     *
+     * There is no guarantee that the same value will be returned by this method for a field unless
+     * the field is considered to be {@linkplain #readConstantFieldValue(JavaField, JavaConstant)
+     * constant} by the runtime.
+     *
+     * @param receiver object from which this field's value is to be read. This value is ignored if
+     *            this field is static.
+     * @return the value of this field or {@code null} if the value is not available (e.g., because
+     *         the field holder is not yet initialized).
+     */
+    JavaConstant readFieldValue(JavaField field, JavaConstant receiver);
+
+    /**
+     * Gets the current value of this field for a given object, if available. Like
+     * {@link #readFieldValue(JavaField, JavaConstant)} but treats array fields as stable.
+     *
+     * There is no guarantee that the same value will be returned by this method for a field unless
+     * the field is considered to be {@linkplain #readConstantFieldValue(JavaField, JavaConstant)
+     * constant} by the runtime.
+     *
+     * @param receiver object from which this field's value is to be read. This value is ignored if
+     *            this field is static.
+     * @param isDefaultStable if {@code true}, default values are considered stable
+     * @return the value of this field or {@code null} if the value is not available (e.g., because
+     *         the field holder is not yet initialized).
+     */
+    JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable);
+
+    /**
+     * Converts the given {@link JavaKind#isPrimitive() primitive} constant to a boxed
+     * {@link JavaKind#Object object} constant, according to the Java boxing rules. Returns
+     * {@code null} if the source is is not a primitive constant, or the boxed value is not
+     * available at this point.
+     */
+    JavaConstant boxPrimitive(JavaConstant source);
+
+    /**
+     * Converts the given {@link JavaKind#Object object} constant to a
+     * {@link JavaKind#isPrimitive() primitive} constant, according to the Java unboxing rules.
+     * Returns {@code null} if the source is is not an object constant that can be unboxed, or the
+     * unboxed value is not available at this point.
+     */
+    JavaConstant unboxPrimitive(JavaConstant source);
+
+    /**
+     * Gets a string as a {@link JavaConstant}.
+     */
+    JavaConstant forString(String value);
+
+    /**
+     * Returns the {@link ResolvedJavaType} for a {@link Class} object (or any other object regarded
+     * as a class by the VM) encapsulated in the given constant. Returns {@code null} if the
+     * constant does not encapsulate a class, or if the type is not available at this point.
+     */
+    ResolvedJavaType asJavaType(Constant constant);
+
+    /**
+     * Check if the constant is embeddable in the code.
+     */
+    boolean isEmbeddable(Constant constant);
+
+    /**
+     * Gets access to the internals of {@link MethodHandle}.
+     */
+    MethodHandleAccessProvider getMethodHandleAccess();
+
+    /**
+     * Gets raw memory access.
+     */
+    MemoryAccessProvider getMemoryAccessProvider();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DefaultProfilingInfo.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+package jdk.vm.ci.meta;
+
+/**
+ * An implementation of {@link ProfilingInfo} that can used in the absence of real profile
+ * information.
+ */
+public final class DefaultProfilingInfo implements ProfilingInfo {
+
+    private static final ProfilingInfo[] NO_PROFILING_INFO = new ProfilingInfo[]{new DefaultProfilingInfo(TriState.TRUE), new DefaultProfilingInfo(TriState.FALSE),
+                    new DefaultProfilingInfo(TriState.UNKNOWN)};
+
+    private final TriState exceptionSeen;
+
+    DefaultProfilingInfo(TriState exceptionSeen) {
+        this.exceptionSeen = exceptionSeen;
+    }
+
+    @Override
+    public int getCodeSize() {
+        return 0;
+    }
+
+    @Override
+    public JavaTypeProfile getTypeProfile(int bci) {
+        return null;
+    }
+
+    @Override
+    public JavaMethodProfile getMethodProfile(int bci) {
+        return null;
+    }
+
+    @Override
+    public double getBranchTakenProbability(int bci) {
+        return -1;
+    }
+
+    @Override
+    public double[] getSwitchProbabilities(int bci) {
+        return null;
+    }
+
+    @Override
+    public TriState getExceptionSeen(int bci) {
+        return exceptionSeen;
+    }
+
+    @Override
+    public TriState getNullSeen(int bci) {
+        return TriState.UNKNOWN;
+    }
+
+    @Override
+    public int getExecutionCount(int bci) {
+        return -1;
+    }
+
+    public static ProfilingInfo get(TriState exceptionSeen) {
+        return NO_PROFILING_INFO[exceptionSeen.ordinal()];
+    }
+
+    @Override
+    public int getDeoptimizationCount(DeoptimizationReason reason) {
+        return 0;
+    }
+
+    @Override
+    public boolean isMature() {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "BaseProfilingInfo<" + this.toString(null, "; ") + ">";
+    }
+
+    public void setMature() {
+        // Do nothing
+    }
+
+    public boolean setCompilerIRSize(Class<?> irType, int nodeCount) {
+        return false;
+    }
+
+    public int getCompilerIRSize(Class<?> irType) {
+        return -1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationAction.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+package jdk.vm.ci.meta;
+
+/**
+ * Specifies the action that should be taken by the runtime in case a certain deoptimization is
+ * triggered.
+ */
+public enum DeoptimizationAction {
+    /**
+     * Do not invalidate the machine code. This is typically used when deoptimizing at a point where
+     * it's highly likely nothing will change the likelihood of the deoptimization happening again.
+     * For example, a compiled array allocation where the size is negative.
+     */
+    None(false),
+
+    /**
+     * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is
+     * triggered too often.
+     */
+    RecompileIfTooManyDeopts(true),
+
+    /**
+     * Invalidate the machine code and reset the profiling information.
+     */
+    InvalidateReprofile(true),
+
+    /**
+     * Invalidate the machine code and immediately schedule a recompilation. This is typically used
+     * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not
+     * required to determine that the deoptimization will not re-occur.
+     */
+    InvalidateRecompile(true),
+
+    /**
+     * Invalidate the machine code and stop compiling the outermost method of this compilation.
+     */
+    InvalidateStopCompiling(true);
+
+    private final boolean invalidatesCompilation;
+
+    private DeoptimizationAction(boolean invalidatesCompilation) {
+        this.invalidatesCompilation = invalidatesCompilation;
+    }
+
+    public boolean doesInvalidateCompilation() {
+        return invalidatesCompilation;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+package jdk.vm.ci.meta;
+
+/**
+ * Enumeration of reasons for why a deoptimization is happening.
+ */
+public enum DeoptimizationReason {
+    None,
+    NullCheckException,
+    BoundsCheckException,
+    ClassCastException,
+    ArrayStoreException,
+    UnreachedCode,
+    TypeCheckedInliningViolated,
+    OptimizedTypeCheckViolated,
+    NotCompiledExceptionHandler,
+    Unresolved,
+    JavaSubroutineMismatch,
+    ArithmeticException,
+    RuntimeConstraint,
+    LoopLimitCheck,
+    Aliasing,
+    TransferToInterpreter,
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ExceptionHandler.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+package jdk.vm.ci.meta;
+
+import java.util.*;
+
+/**
+ * Represents an exception handler within the bytecodes.
+ */
+public final class ExceptionHandler {
+
+    private final int startBCI;
+    private final int endBCI;
+    private final int handlerBCI;
+    private final int catchTypeCPI;
+    private final JavaType catchType;
+
+    /**
+     * Creates a new exception handler with the specified ranges.
+     *
+     * @param startBCI the start index of the protected range
+     * @param endBCI the end index of the protected range
+     * @param catchBCI the index of the handler
+     * @param catchTypeCPI the index of the throwable class in the constant pool
+     * @param catchType the type caught by this exception handler
+     */
+    public ExceptionHandler(int startBCI, int endBCI, int catchBCI, int catchTypeCPI, JavaType catchType) {
+        this.startBCI = startBCI;
+        this.endBCI = endBCI;
+        this.handlerBCI = catchBCI;
+        this.catchTypeCPI = catchTypeCPI;
+        this.catchType = catchType;
+    }
+
+    /**
+     * Returns the start bytecode index of the protected range of this handler.
+     */
+    public int getStartBCI() {
+        return startBCI;
+    }
+
+    /**
+     * Returns the end bytecode index of the protected range of this handler.
+     */
+    public int getEndBCI() {
+        return endBCI;
+    }
+
+    /**
+     * Returns the bytecode index of the handler block of this handler.
+     */
+    public int getHandlerBCI() {
+        return handlerBCI;
+    }
+
+    /**
+     * Returns the index into the constant pool representing the type of exception caught by this
+     * handler.
+     */
+    public int catchTypeCPI() {
+        return catchTypeCPI;
+    }
+
+    /**
+     * Checks whether this handler catches all exceptions.
+     *
+     * @return {@code true} if this handler catches all exceptions
+     */
+    public boolean isCatchAll() {
+        return catchTypeCPI == 0;
+    }
+
+    /**
+     * Returns the type of exception caught by this exception handler.
+     */
+    public JavaType getCatchType() {
+        return catchType;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ExceptionHandler)) {
+            return false;
+        }
+        ExceptionHandler that = (ExceptionHandler) obj;
+        if (this.startBCI != that.startBCI || this.endBCI != that.endBCI || this.handlerBCI != that.handlerBCI || this.catchTypeCPI != that.catchTypeCPI) {
+            return false;
+        }
+        return Objects.equals(this.catchType, that.catchType);
+    }
+
+    @Override
+    public String toString() {
+        return "ExceptionHandler<startBCI=" + startBCI + ", endBCI=" + endBCI + ", handlerBCI=" + handlerBCI + ", catchTypeCPI=" + catchTypeCPI + ", catchType=" + catchType + ">";
+    }
+
+    @Override
+    public int hashCode() {
+        return catchTypeCPI ^ endBCI ^ handlerBCI;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013, 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 jdk.vm.ci.meta;
+
+/**
+ * Represents the resolved target of an invocation.
+ */
+public interface InvokeTarget {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JVMCIMetaAccessContext.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * A context in which the results looking up the {@link ResolvedJavaType} for a {@link Class} are
+ * cached.
+ */
+public interface JVMCIMetaAccessContext {
+
+    /**
+     * Gets the JVMCI mirror for a {@link Class} object.
+     *
+     * @return the {@link ResolvedJavaType} corresponding to {@code javaClass}
+     */
+
+    ResolvedJavaType fromClass(Class<?> clazz);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Represents a constant (boxed) value, such as an integer, floating point number, or object
+ * reference, within the compiler and across the compiler/runtime interface. Exports a set of
+ * {@code JavaConstant} instances that represent frequently used constant values, such as
+ * {@link #NULL_POINTER}.
+ */
+public interface JavaConstant extends Constant, JavaValue {
+    /*
+     * Using a larger cache for integers leads to only a slight increase in cache hit ratio which is
+     * not enough to justify the impact on startup time.
+     */
+    JavaConstant NULL_POINTER = new NullConstant();
+    PrimitiveConstant INT_MINUS_1 = new PrimitiveConstant(JavaKind.Int, -1);
+    PrimitiveConstant INT_0 = new PrimitiveConstant(JavaKind.Int, 0);
+    PrimitiveConstant INT_1 = new PrimitiveConstant(JavaKind.Int, 1);
+    PrimitiveConstant INT_2 = new PrimitiveConstant(JavaKind.Int, 2);
+    PrimitiveConstant LONG_0 = new PrimitiveConstant(JavaKind.Long, 0L);
+    PrimitiveConstant LONG_1 = new PrimitiveConstant(JavaKind.Long, 1L);
+    PrimitiveConstant FLOAT_0 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(0.0F));
+    PrimitiveConstant FLOAT_1 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(1.0F));
+    PrimitiveConstant DOUBLE_0 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(0.0D));
+    PrimitiveConstant DOUBLE_1 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(1.0D));
+    PrimitiveConstant TRUE = new PrimitiveConstant(JavaKind.Boolean, 1L);
+    PrimitiveConstant FALSE = new PrimitiveConstant(JavaKind.Boolean, 0L);
+
+    /**
+     * Returns the Java kind of this constant.
+     */
+    JavaKind getJavaKind();
+
+    /**
+     * Checks whether this constant is null.
+     *
+     * @return {@code true} if this constant is the null constant
+     */
+    boolean isNull();
+
+    static boolean isNull(Constant c) {
+        if (c instanceof JavaConstant) {
+            return ((JavaConstant) c).isNull();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether this constant is non-null.
+     *
+     * @return {@code true} if this constant is a primitive, or an object constant that is not null
+     */
+    default boolean isNonNull() {
+        return !isNull();
+    }
+
+    /**
+     * Checks whether this constant is the default value for its kind (null, 0, 0.0, false).
+     *
+     * @return {@code true} if this constant is the default value for its kind
+     */
+    boolean isDefaultForKind();
+
+    /**
+     * Returns the value of this constant as a boxed Java value.
+     *
+     * @return the value of this constant
+     */
+    Object asBoxedPrimitive();
+
+    /**
+     * Returns the primitive int value this constant represents. The constant must have a
+     * {@link JavaKind#getStackKind()} of {@link JavaKind#Int}.
+     *
+     * @return the constant value
+     */
+    int asInt();
+
+    /**
+     * Returns the primitive boolean value this constant represents. The constant must have kind
+     * {@link JavaKind#Boolean}.
+     *
+     * @return the constant value
+     */
+    boolean asBoolean();
+
+    /**
+     * Returns the primitive long value this constant represents. The constant must have kind
+     * {@link JavaKind#Long}, a {@link JavaKind#getStackKind()} of {@link JavaKind#Int}.
+     *
+     * @return the constant value
+     */
+    long asLong();
+
+    /**
+     * Returns the primitive float value this constant represents. The constant must have kind
+     * {@link JavaKind#Float}.
+     *
+     * @return the constant value
+     */
+    float asFloat();
+
+    /**
+     * Returns the primitive double value this constant represents. The constant must have kind
+     * {@link JavaKind#Double}.
+     *
+     * @return the constant value
+     */
+    double asDouble();
+
+    default String toValueString() {
+        if (getJavaKind() == JavaKind.Illegal) {
+            return "illegal";
+        } else {
+            return getJavaKind().format(asBoxedPrimitive());
+        }
+    }
+
+    static String toString(JavaConstant constant) {
+        if (constant.getJavaKind() == JavaKind.Illegal) {
+            return "illegal";
+        } else {
+            return constant.getJavaKind().getJavaName() + "[" + constant.toValueString() + "]";
+        }
+    }
+
+    /**
+     * Creates a boxed double constant.
+     *
+     * @param d the double value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forDouble(double d) {
+        if (Double.compare(0.0D, d) == 0) {
+            return DOUBLE_0;
+        }
+        if (Double.compare(d, 1.0D) == 0) {
+            return DOUBLE_1;
+        }
+        return new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(d));
+    }
+
+    /**
+     * Creates a boxed float constant.
+     *
+     * @param f the float value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forFloat(float f) {
+        if (Float.compare(f, 0.0F) == 0) {
+            return FLOAT_0;
+        }
+        if (Float.compare(f, 1.0F) == 0) {
+            return FLOAT_1;
+        }
+        return new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(f));
+    }
+
+    /**
+     * Creates a boxed long constant.
+     *
+     * @param i the long value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forLong(long i) {
+        if (i == 0) {
+            return LONG_0;
+        } else if (i == 1) {
+            return LONG_1;
+        } else {
+            return new PrimitiveConstant(JavaKind.Long, i);
+        }
+    }
+
+    /**
+     * Creates a boxed integer constant.
+     *
+     * @param i the integer value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forInt(int i) {
+        switch (i) {
+            case -1:
+                return INT_MINUS_1;
+            case 0:
+                return INT_0;
+            case 1:
+                return INT_1;
+            case 2:
+                return INT_2;
+            default:
+                return new PrimitiveConstant(JavaKind.Int, i);
+        }
+    }
+
+    /**
+     * Creates a boxed byte constant.
+     *
+     * @param i the byte value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forByte(byte i) {
+        return new PrimitiveConstant(JavaKind.Byte, i);
+    }
+
+    /**
+     * Creates a boxed boolean constant.
+     *
+     * @param i the boolean value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forBoolean(boolean i) {
+        return i ? TRUE : FALSE;
+    }
+
+    /**
+     * Creates a boxed char constant.
+     *
+     * @param i the char value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forChar(char i) {
+        return new PrimitiveConstant(JavaKind.Char, i);
+    }
+
+    /**
+     * Creates a boxed short constant.
+     *
+     * @param i the short value to box
+     * @return a boxed copy of {@code value}
+     */
+    static PrimitiveConstant forShort(short i) {
+        return new PrimitiveConstant(JavaKind.Short, i);
+    }
+
+    /**
+     * Creates a {@link JavaConstant} from a primitive integer of a certain kind.
+     */
+    static PrimitiveConstant forIntegerKind(JavaKind kind, long i) {
+        switch (kind) {
+            case Boolean:
+                return forBoolean(i != 0);
+            case Byte:
+                return forByte((byte) i);
+            case Short:
+                return forShort((short) i);
+            case Char:
+                return forChar((char) i);
+            case Int:
+                return forInt((int) i);
+            case Long:
+                return forLong(i);
+            default:
+                throw new IllegalArgumentException("not an integer kind: " + kind);
+        }
+    }
+
+    /**
+     * Creates a {@link JavaConstant} from a primitive integer of a certain width.
+     */
+    static PrimitiveConstant forPrimitiveInt(int bits, long i) {
+        assert bits <= 64;
+        switch (bits) {
+            case 1:
+                return forBoolean(i != 0);
+            case 8:
+                return forByte((byte) i);
+            case 16:
+                return forShort((short) i);
+            case 32:
+                return forInt((int) i);
+            case 64:
+                return forLong(i);
+            default:
+                throw new IllegalArgumentException("unsupported integer width: " + bits);
+        }
+    }
+
+    /**
+     * Creates a boxed constant for the given boxed primitive value.
+     *
+     * @param value the Java boxed value
+     * @return the primitive constant holding the {@code value}
+     */
+    static PrimitiveConstant forBoxedPrimitive(Object value) {
+        if (value instanceof Boolean) {
+            return forBoolean((Boolean) value);
+        } else if (value instanceof Byte) {
+            return forByte((Byte) value);
+        } else if (value instanceof Character) {
+            return forChar((Character) value);
+        } else if (value instanceof Short) {
+            return forShort((Short) value);
+        } else if (value instanceof Integer) {
+            return forInt((Integer) value);
+        } else if (value instanceof Long) {
+            return forLong((Long) value);
+        } else if (value instanceof Float) {
+            return forFloat((Float) value);
+        } else if (value instanceof Double) {
+            return forDouble((Double) value);
+        } else {
+            return null;
+        }
+    }
+
+    static PrimitiveConstant forIllegal() {
+        return new PrimitiveConstant(JavaKind.Illegal, 0);
+    }
+
+    /**
+     * Returns a constant with the default value for the given kind.
+     */
+    static JavaConstant defaultForKind(JavaKind kind) {
+        switch (kind) {
+            case Boolean:
+                return FALSE;
+            case Byte:
+                return forByte((byte) 0);
+            case Char:
+                return forChar((char) 0);
+            case Short:
+                return forShort((short) 0);
+            case Int:
+                return INT_0;
+            case Double:
+                return DOUBLE_0;
+            case Float:
+                return FLOAT_0;
+            case Long:
+                return LONG_0;
+            case Object:
+                return NULL_POINTER;
+            default:
+                throw new IllegalArgumentException(kind.toString());
+        }
+    }
+
+    /**
+     * Returns the zero value for a given numeric kind.
+     */
+    static JavaConstant zero(JavaKind kind) {
+        switch (kind) {
+            case Boolean:
+                return FALSE;
+            case Byte:
+                return forByte((byte) 0);
+            case Char:
+                return forChar((char) 0);
+            case Double:
+                return DOUBLE_0;
+            case Float:
+                return FLOAT_0;
+            case Int:
+                return INT_0;
+            case Long:
+                return LONG_0;
+            case Short:
+                return forShort((short) 0);
+            default:
+                throw new IllegalArgumentException(kind.toString());
+        }
+    }
+
+    /**
+     * Returns the one value for a given numeric kind.
+     */
+    static JavaConstant one(JavaKind kind) {
+        switch (kind) {
+            case Boolean:
+                return TRUE;
+            case Byte:
+                return forByte((byte) 1);
+            case Char:
+                return forChar((char) 1);
+            case Double:
+                return DOUBLE_1;
+            case Float:
+                return FLOAT_1;
+            case Int:
+                return INT_1;
+            case Long:
+                return LONG_1;
+            case Short:
+                return forShort((short) 1);
+            default:
+                throw new IllegalArgumentException(kind.toString());
+        }
+    }
+
+    /**
+     * Adds two numeric constants.
+     */
+    static JavaConstant add(JavaConstant x, JavaConstant y) {
+        assert x.getJavaKind() == y.getJavaKind();
+        switch (x.getJavaKind()) {
+            case Byte:
+                return forByte((byte) (x.asInt() + y.asInt()));
+            case Char:
+                return forChar((char) (x.asInt() + y.asInt()));
+            case Double:
+                return forDouble(x.asDouble() + y.asDouble());
+            case Float:
+                return forFloat(x.asFloat() + y.asFloat());
+            case Int:
+                return forInt(x.asInt() + y.asInt());
+            case Long:
+                return forLong(x.asLong() + y.asLong());
+            case Short:
+                return forShort((short) (x.asInt() + y.asInt()));
+            default:
+                throw new IllegalArgumentException(x.getJavaKind().toString());
+        }
+    }
+
+    /**
+     * Multiplies two numeric constants.
+     */
+    static PrimitiveConstant mul(JavaConstant x, JavaConstant y) {
+        assert x.getJavaKind() == y.getJavaKind();
+        switch (x.getJavaKind()) {
+            case Byte:
+                return forByte((byte) (x.asInt() * y.asInt()));
+            case Char:
+                return forChar((char) (x.asInt() * y.asInt()));
+            case Double:
+                return forDouble(x.asDouble() * y.asDouble());
+            case Float:
+                return forFloat(x.asFloat() * y.asFloat());
+            case Int:
+                return forInt(x.asInt() * y.asInt());
+            case Long:
+                return forLong(x.asLong() * y.asLong());
+            case Short:
+                return forShort((short) (x.asInt() * y.asInt()));
+            default:
+                throw new IllegalArgumentException(x.getJavaKind().toString());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+import java.util.*;
+
+/**
+ * Represents a reference to a Java field, either resolved or unresolved fields. Fields, like
+ * methods and types, are resolved through {@link ConstantPool constant pools}.
+ */
+public interface JavaField extends TrustedInterface {
+
+    /**
+     * Returns the name of this field.
+     */
+    String getName();
+
+    /**
+     * Returns a {@link JavaType} object that identifies the declared type for this field.
+     */
+    JavaType getType();
+
+    /**
+     * Returns the kind of this field. This is the same as calling {@link #getType}.
+     * {@link JavaType#getJavaKind getJavaKind}.
+     */
+    default JavaKind getJavaKind() {
+        return getType().getJavaKind();
+    }
+
+    /**
+     * Returns the {@link JavaType} object representing the class or interface that declares this
+     * field.
+     */
+    JavaType getDeclaringClass();
+
+    /**
+     * Gets a string for this field formatted according to a given format specification. A format
+     * specification is composed of characters that are to be copied verbatim to the result and
+     * specifiers that denote an attribute of this field that is to be copied to the result. A
+     * specifier is a single character preceded by a '%' character. The accepted specifiers and the
+     * field attributes they denote are described below:
+     *
+     * <pre>
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'T'       | Qualified type                                       | "int" "java.lang.String"
+     *     't'       | Unqualified type                                     | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Field name                                           | "age"
+     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
+     *     '%'       | A '%' character                                      | "%"
+     * </pre>
+     *
+     * @param format a format specification
+     * @return the result of formatting this field according to {@code format}
+     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
+     */
+    @SuppressWarnings("fallthrough")
+    default String format(String format) throws IllegalFormatException {
+        StringBuilder sb = new StringBuilder();
+        int index = 0;
+        JavaType type = getType();
+        while (index < format.length()) {
+            char ch = format.charAt(index++);
+            if (ch == '%') {
+                if (index >= format.length()) {
+                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification");
+                }
+                char specifier = format.charAt(index++);
+                switch (specifier) {
+                    case 'T':
+                    case 't': {
+                        sb.append(type.toJavaName(specifier == 'T'));
+                        break;
+                    }
+                    case 'H':
+                    case 'h': {
+                        sb.append(getDeclaringClass().toJavaName(specifier == 'H'));
+                        break;
+                    }
+                    case 'n': {
+                        sb.append(getName());
+                        break;
+                    }
+                    case 'f': {
+                        sb.append(!(this instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) this).isStatic() ? "static" : "instance");
+                        break;
+                    }
+                    case '%': {
+                        sb.append('%');
+                        break;
+                    }
+                    default: {
+                        throw new UnknownFormatConversionException(String.valueOf(specifier));
+                    }
+                }
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+import java.lang.reflect.*;
+
+//JaCoCo Exclude
+
+/**
+ * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example,
+ * {@link JavaKind#Int} for {@code int} and {@link JavaKind#Object} for all object types. A kind has
+ * a single character short name, a Java name, and a set of flags further describing its behavior.
+ */
+public enum JavaKind implements PlatformKind {
+    /** The primitive boolean kind, represented as an int on the stack. */
+    Boolean('z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
+
+    /** The primitive byte kind, represented as an int on the stack. */
+    Byte('b', "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class),
+
+    /** The primitive short kind, represented as an int on the stack. */
+    Short('s', "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class),
+
+    /** The primitive char kind, represented as an int on the stack. */
+    Char('c', "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class),
+
+    /** The primitive int kind, represented as an int on the stack. */
+    Int('i', "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class),
+
+    /** The primitive float kind. */
+    Float('f', "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class),
+
+    /** The primitive long kind. */
+    Long('j', "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class),
+
+    /** The primitive double kind. */
+    Double('d', "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class),
+
+    /** The Object kind, also used for arrays. */
+    Object('a', "Object", 1, false, null, null),
+
+    /** The void float kind. */
+    Void('v', "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class),
+
+    /** The non-type. */
+    Illegal('-', "illegal", 0, false, null, null);
+
+    private final char typeChar;
+    private final String javaName;
+    private final boolean isStackInt;
+    private final Class<?> primitiveJavaClass;
+    private final Class<?> boxedJavaClass;
+    private final EnumKey<JavaKind> key = new EnumKey<>(this);
+    private final int slotCount;
+
+    private JavaKind(char typeChar, String javaName, int slotCount, boolean isStackInt, Class<?> primitiveJavaClass, Class<?> boxedJavaClass) {
+        this.typeChar = typeChar;
+        this.javaName = javaName;
+        this.slotCount = slotCount;
+        this.isStackInt = isStackInt;
+        this.primitiveJavaClass = primitiveJavaClass;
+        this.boxedJavaClass = boxedJavaClass;
+        assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName());
+    }
+
+    /**
+     * Returns the number of stack slots occupied by this kind according to the Java bytecodes
+     * specification.
+     */
+    public int getSlotCount() {
+        return this.slotCount;
+    }
+
+    /**
+     * Returns whether this kind occupied two stack slots.
+     */
+    public boolean needsTwoSlots() {
+        return this.slotCount == 2;
+    }
+
+    /**
+     * Returns the name of the kind as a single character.
+     */
+    public char getTypeChar() {
+        return typeChar;
+    }
+
+    /**
+     * Returns the name of this kind which will also be it Java programming language name if it is
+     * {@linkplain #isPrimitive() primitive} or {@code void}.
+     */
+    public String getJavaName() {
+        return javaName;
+    }
+
+    public Key getKey() {
+        return key;
+    }
+
+    /**
+     * Checks whether this type is a Java primitive type.
+     *
+     * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char},
+     *         {@link #Short}, {@link #Int}, {@link #Long}, {@link #Float}, {@link #Double}, or
+     *         {@link #Void}.
+     */
+    public boolean isPrimitive() {
+        return primitiveJavaClass != null;
+    }
+
+    /**
+     * Returns the kind that represents this kind when on the Java operand stack.
+     *
+     * @return the kind used on the operand stack
+     */
+    public JavaKind getStackKind() {
+        if (isStackInt) {
+            return Int;
+        }
+        return this;
+    }
+
+    /**
+     * Checks whether this type is a Java primitive type representing an integer number.
+     *
+     * @return {@code true} if the stack kind is {@link #Int} or {@link #Long}.
+     */
+    public boolean isNumericInteger() {
+        return isStackInt || this == JavaKind.Long;
+    }
+
+    /**
+     * Checks whether this type is a Java primitive type representing an unsigned number.
+     *
+     * @return {@code true} if the kind is {@link #Boolean} or {@link #Char}.
+     */
+    public boolean isUnsigned() {
+        return this == JavaKind.Boolean || this == JavaKind.Char;
+    }
+
+    /**
+     * Checks whether this type is a Java primitive type representing a floating point number.
+     *
+     * @return {@code true} if this is {@link #Float} or {@link #Double}.
+     */
+    public boolean isNumericFloat() {
+        return this == JavaKind.Float || this == JavaKind.Double;
+    }
+
+    /**
+     * Checks whether this represent an Object of some sort.
+     *
+     * @return {@code true} if this is {@link #Object}.
+     */
+    public boolean isObject() {
+        return this == JavaKind.Object;
+    }
+
+    /**
+     * Returns the kind corresponding to the Java type string.
+     *
+     * @param typeString the Java type string
+     * @return the kind
+     */
+    public static JavaKind fromTypeString(String typeString) {
+        assert typeString.length() > 0;
+        final char first = typeString.charAt(0);
+        if (first == '[' || first == 'L') {
+            return JavaKind.Object;
+        }
+        return JavaKind.fromPrimitiveOrVoidTypeChar(first);
+    }
+
+    /**
+     * Returns the kind of a word given the size of a word in bytes.
+     *
+     * @param wordSizeInBytes the size of a word in bytes
+     * @return the kind representing a word value
+     */
+    public static JavaKind fromWordSize(int wordSizeInBytes) {
+        if (wordSizeInBytes == 8) {
+            return JavaKind.Long;
+        } else {
+            assert wordSizeInBytes == 4 : "Unsupported word size!";
+            return JavaKind.Int;
+        }
+    }
+
+    /**
+     * Returns the kind from the character describing a primitive or void.
+     *
+     * @param ch the character
+     * @return the kind
+     */
+    public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) {
+        switch (ch) {
+            case 'Z':
+                return Boolean;
+            case 'C':
+                return Char;
+            case 'F':
+                return Float;
+            case 'D':
+                return Double;
+            case 'B':
+                return Byte;
+            case 'S':
+                return Short;
+            case 'I':
+                return Int;
+            case 'J':
+                return Long;
+            case 'V':
+                return Void;
+        }
+        throw new IllegalArgumentException("unknown primitive or void type character: " + ch);
+    }
+
+    /**
+     * Returns the Kind representing the given Java class.
+     *
+     * @param klass the class
+     * @return the kind
+     */
+    public static JavaKind fromJavaClass(Class<?> klass) {
+        if (klass == Boolean.primitiveJavaClass) {
+            return Boolean;
+        } else if (klass == Byte.primitiveJavaClass) {
+            return Byte;
+        } else if (klass == Short.primitiveJavaClass) {
+            return Short;
+        } else if (klass == Char.primitiveJavaClass) {
+            return Char;
+        } else if (klass == Int.primitiveJavaClass) {
+            return Int;
+        } else if (klass == Long.primitiveJavaClass) {
+            return Long;
+        } else if (klass == Float.primitiveJavaClass) {
+            return Float;
+        } else if (klass == Double.primitiveJavaClass) {
+            return Double;
+        } else if (klass == Void.primitiveJavaClass) {
+            return Void;
+        } else {
+            return Object;
+        }
+    }
+
+    /**
+     * Returns the Java class representing this kind.
+     *
+     * @return the Java class
+     */
+    public Class<?> toJavaClass() {
+        return primitiveJavaClass;
+    }
+
+    /**
+     * Returns the Java class for instances of boxed values of this kind.
+     *
+     * @return the Java class
+     */
+    public Class<?> toBoxedJavaClass() {
+        return boxedJavaClass;
+    }
+
+    /**
+     * Converts this value type to a string.
+     */
+    @Override
+    public String toString() {
+        return javaName;
+    }
+
+    /**
+     * Marker interface for types that should be {@linkplain JavaKind#format(Object) formatted} with
+     * their {@link Object#toString()} value. Calling {@link Object#toString()} on other objects
+     * poses a security risk because it can potentially call user code.
+     */
+    public interface FormatWithToString {
+    }
+
+    /**
+     * Classes for which invoking {@link Object#toString()} does not run user code.
+     */
+    private static boolean isToStringSafe(Class<?> c) {
+        return c == Boolean.class || c == Byte.class || c == Character.class || c == Short.class || c == Integer.class || c == Float.class || c == Long.class || c == Double.class;
+    }
+
+    /**
+     * Gets a formatted string for a given value of this kind.
+     *
+     * @param value a value of this kind
+     * @return a formatted string for {@code value} based on this kind
+     */
+    public String format(Object value) {
+        if (isPrimitive()) {
+            assert isToStringSafe(value.getClass());
+            return value.toString();
+        } else {
+            if (value == null) {
+                return "null";
+            } else {
+                if (value instanceof String) {
+                    String s = (String) value;
+                    if (s.length() > 50) {
+                        return "String:\"" + s.substring(0, 30) + "...\"";
+                    } else {
+                        return "String:\"" + s + '"';
+                    }
+                } else if (value instanceof JavaType) {
+                    return "JavaType:" + ((JavaType) value).toJavaName();
+                } else if (value instanceof Enum) {
+                    return MetaUtil.getSimpleName(value.getClass(), true) + ":" + ((Enum<?>) value).name();
+                } else if (value instanceof FormatWithToString) {
+                    return MetaUtil.getSimpleName(value.getClass(), true) + ":" + String.valueOf(value);
+                } else if (value instanceof Class<?>) {
+                    return "Class:" + ((Class<?>) value).getName();
+                } else if (isToStringSafe(value.getClass())) {
+                    return value.toString();
+                } else if (value.getClass().isArray()) {
+                    return formatArray(value);
+                } else {
+                    return MetaUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value);
+                }
+            }
+        }
+    }
+
+    private static final int MAX_FORMAT_ARRAY_LENGTH = 5;
+
+    private static String formatArray(Object array) {
+        Class<?> componentType = array.getClass().getComponentType();
+        assert componentType != null;
+        int arrayLength = Array.getLength(array);
+        StringBuilder buf = new StringBuilder(MetaUtil.getSimpleName(componentType, true)).append('[').append(arrayLength).append("]{");
+        int length = Math.min(MAX_FORMAT_ARRAY_LENGTH, arrayLength);
+        boolean primitive = componentType.isPrimitive();
+        for (int i = 0; i < length; i++) {
+            if (primitive) {
+                buf.append(Array.get(array, i));
+            } else {
+                Object o = ((Object[]) array)[i];
+                buf.append(JavaKind.Object.format(o));
+            }
+            if (i != length - 1) {
+                buf.append(", ");
+            }
+        }
+        if (arrayLength != length) {
+            buf.append(", ...");
+        }
+        return buf.append('}').toString();
+    }
+
+    /**
+     * The minimum value that can be represented as a value of this kind.
+     *
+     * @return the minimum value
+     */
+    public long getMinValue() {
+        switch (this) {
+            case Boolean:
+                return 0;
+            case Byte:
+                return java.lang.Byte.MIN_VALUE;
+            case Char:
+                return java.lang.Character.MIN_VALUE;
+            case Short:
+                return java.lang.Short.MIN_VALUE;
+            case Int:
+                return java.lang.Integer.MIN_VALUE;
+            case Long:
+                return java.lang.Long.MIN_VALUE;
+            default:
+                throw new IllegalArgumentException("illegal call to minValue on " + this);
+        }
+    }
+
+    /**
+     * The maximum value that can be represented as a value of this kind.
+     *
+     * @return the maximum value
+     */
+    public long getMaxValue() {
+        switch (this) {
+            case Boolean:
+                return 1;
+            case Byte:
+                return java.lang.Byte.MAX_VALUE;
+            case Char:
+                return java.lang.Character.MAX_VALUE;
+            case Short:
+                return java.lang.Short.MAX_VALUE;
+            case Int:
+                return java.lang.Integer.MAX_VALUE;
+            case Long:
+                return java.lang.Long.MAX_VALUE;
+            default:
+                throw new IllegalArgumentException("illegal call to maxValue on " + this);
+        }
+    }
+
+    /**
+     * Number of bytes that are necessary to represent a value of this kind.
+     *
+     * @return the number of bytes
+     */
+    public int getByteCount() {
+        if (this == Boolean) {
+            return 1;
+        } else {
+            return getBitCount() >> 3;
+        }
+    }
+
+    /**
+     * Number of bits that are necessary to represent a value of this kind.
+     *
+     * @return the number of bits
+     */
+    public int getBitCount() {
+        switch (this) {
+            case Boolean:
+                return 1;
+            case Byte:
+                return 8;
+            case Char:
+            case Short:
+                return 16;
+            case Float:
+                return 32;
+            case Int:
+                return 32;
+            case Double:
+                return 64;
+            case Long:
+                return 64;
+            default:
+                throw new IllegalArgumentException("illegal call to bits on " + this);
+        }
+    }
+
+    public JavaConstant getDefaultValue() {
+        switch (this) {
+            case Boolean:
+                return JavaConstant.FALSE;
+            case Int:
+                return JavaConstant.INT_0;
+            case Long:
+                return JavaConstant.LONG_0;
+            case Float:
+                return JavaConstant.FLOAT_0;
+            case Double:
+                return JavaConstant.DOUBLE_0;
+            case Object:
+                return JavaConstant.NULL_POINTER;
+            case Byte:
+            case Char:
+            case Short:
+                return new PrimitiveConstant(this, 0);
+            default:
+                throw new IllegalArgumentException("illegal call to getDefaultValue on " + this);
+        }
+    }
+
+    @Override
+    public int getSizeInBytes() {
+        return getByteCount();
+    }
+
+    @Override
+    public int getVectorLength() {
+        return 1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+package jdk.vm.ci.meta;
+
+import java.util.*;
+
+/**
+ * Represents a reference to a Java method, either resolved or unresolved. Methods, like fields and
+ * types, are resolved through {@link ConstantPool constant pools}.
+ */
+public interface JavaMethod extends TrustedInterface {
+
+    /**
+     * Returns the name of this method.
+     */
+    String getName();
+
+    /**
+     * Returns the {@link JavaType} object representing the class or interface that declares this
+     * method.
+     */
+    JavaType getDeclaringClass();
+
+    /**
+     * Returns the signature of this method.
+     */
+    Signature getSignature();
+
+    /**
+     * Gets a string for this method formatted according to a given format specification. A format
+     * specification is composed of characters that are to be copied verbatim to the result and
+     * specifiers that denote an attribute of this method that is to be copied to the result. A
+     * specifier is a single character preceded by a '%' character. The accepted specifiers and the
+     * method attributes they denote are described below:
+     *
+     * <pre>
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'R'       | Qualified return type                                | "int" "java.lang.String"
+     *     'r'       | Unqualified return type                              | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Method name                                          | "add"
+     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
+     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
+     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
+     *     '%'       | A '%' character                                      | "%"
+     * </pre>
+     *
+     * @param format a format specification
+     * @return the result of formatting this method according to {@code format}
+     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
+     */
+    @SuppressWarnings("fallthrough")
+    default String format(String format) throws IllegalFormatException {
+        StringBuilder sb = new StringBuilder();
+        int index = 0;
+        Signature sig = null;
+        while (index < format.length()) {
+            char ch = format.charAt(index++);
+            if (ch == '%') {
+                if (index >= format.length()) {
+                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification");
+                }
+                char specifier = format.charAt(index++);
+                switch (specifier) {
+                    case 'R':
+                    case 'r': {
+                        if (sig == null) {
+                            sig = getSignature();
+                        }
+                        sb.append(sig.getReturnType(null).toJavaName(specifier == 'R'));
+                        break;
+                    }
+                    case 'H':
+                    case 'h': {
+                        sb.append(getDeclaringClass().toJavaName(specifier == 'H'));
+                        break;
+                    }
+                    case 'n': {
+                        sb.append(getName());
+                        break;
+                    }
+                    case 'P':
+                    case 'p': {
+                        if (sig == null) {
+                            sig = getSignature();
+                        }
+                        for (int i = 0; i < sig.getParameterCount(false); i++) {
+                            if (i != 0) {
+                                sb.append(", ");
+                            }
+                            sb.append(sig.getParameterType(i, null).toJavaName(specifier == 'P'));
+                        }
+                        break;
+                    }
+                    case 'f': {
+                        sb.append(!(this instanceof ResolvedJavaMethod) ? "unresolved" : ((ResolvedJavaMethod) this).isStatic() ? "static" : "virtual");
+                        break;
+                    }
+                    case '%': {
+                        sb.append('%');
+                        break;
+                    }
+                    default: {
+                        throw new UnknownFormatConversionException(String.valueOf(specifier));
+                    }
+                }
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethodProfile.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,60 @@
+/*
+ * 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 jdk.vm.ci.meta;
+
+import jdk.vm.ci.meta.JavaMethodProfile.*;
+
+/**
+ * This profile object represents the method profile at a specific BCI. The precision of the
+ * supplied values may vary, but a runtime that provides this information should be aware that it
+ * will be used to guide performance-critical decisions like speculative inlining, etc.
+ */
+public final class JavaMethodProfile extends AbstractJavaProfile<ProfiledMethod, ResolvedJavaMethod> {
+
+    public JavaMethodProfile(double notRecordedProbability, ProfiledMethod[] pitems) {
+        super(notRecordedProbability, pitems);
+    }
+
+    public ProfiledMethod[] getMethods() {
+        return super.getItems();
+    }
+
+    public static class ProfiledMethod extends AbstractProfiledItem<ResolvedJavaMethod> {
+
+        public ProfiledMethod(ResolvedJavaMethod method, double probability) {
+            super(method, probability);
+        }
+
+        /**
+         * Returns the type for this profile entry.
+         */
+        public ResolvedJavaMethod getMethod() {
+            return getItem();
+        }
+
+        @Override
+        public String toString() {
+            return "{" + item.getName() + ", " + probability + "}";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+import static jdk.vm.ci.meta.MetaUtil.*;
+
+/**
+ * Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and
+ * arrays thereof.
+ */
+public interface JavaType extends TrustedInterface {
+
+    /**
+     * Returns the name of this type in internal form. The following are examples of strings
+     * returned by this method:
+     *
+     * <pre>
+     *     "Ljava/lang/Object;"
+     *     "I"
+     *     "[[B"
+     * </pre>
+     */
+    String getName();
+
+    /**
+     * Returns an unqualified name of this type.
+     *
+     * <pre>
+     *     "Object"
+     *     "Integer"
+     * </pre>
+     */
+    default String getUnqualifiedName() {
+        String name = getName();
+        if (name.indexOf('/') != -1) {
+            name = name.substring(name.lastIndexOf('/') + 1);
+        }
+        if (name.endsWith(";")) {
+            name = name.substring(0, name.length() - 1);
+        }
+        return name;
+    }
+
+    /**
+     * For array types, gets the type of the components, or {@code null} if this is not an array
+     * type. This method is analogous to {@link Class#getComponentType()}.
+     */
+    JavaType getComponentType();
+
+    /**
+     * Gets the elemental type for this given type. The elemental type is the corresponding zero
+     * dimensional type of an array type. For example, the elemental type of {@code int[][][]} is
+     * {@code int}. A non-array type is its own elemental type.
+     */
+    default JavaType getElementalType() {
+        JavaType t = this;
+        while (t.getComponentType() != null) {
+            t = t.getComponentType();
+        }
+        return t;
+    }
+
+    /**
+     * Gets the array class type representing an array with elements of this type.
+     */
+    JavaType getArrayClass();
+
+    /**
+     * Gets the {@link JavaKind} of this type.
+     */
+    JavaKind getJavaKind();
+
+    /**
+     * Resolves this type to a {@link ResolvedJavaType}.
+     *
+     * @param accessingClass the context of resolution (must not be null)
+     * @return the resolved Java type
+     * @throws LinkageError if the resolution failed
+     * @throws NullPointerException if {@code accessingClass} is {@code null}
+     */
+    ResolvedJavaType resolve(ResolvedJavaType accessingClass);
+
+    /**
+     * Gets the Java programming language name for this type. The following are examples of strings
+     * returned by this method:
+     *
+     * <pre>
+     *      java.lang.Object
+     *      int
+     *      boolean[][]
+     * </pre>
+     *
+     * @return the Java name corresponding to this type
+     */
+    default String toJavaName() {
+        return internalNameToJava(getName(), true, false);
+    }
+
+    /**
+     * Gets the Java programming language name for this type. The following are examples of strings
+     * returned by this method:
+     *
+     * <pre>
+     *     qualified == true:
+     *         java.lang.Object
+     *         int
+     *         boolean[][]
+     *     qualified == false:
+     *         Object
+     *         int
+     *         boolean[][]
+     * </pre>
+     *
+     * @param qualified specifies if the package prefix of this type should be included in the
+     *            returned name
+     * @return the Java name corresponding to this type
+     */
+    default String toJavaName(boolean qualified) {
+        JavaKind kind = getJavaKind();
+        if (kind == JavaKind.Object) {
+            return internalNameToJava(getName(), qualified, false);
+        }
+        return getJavaKind().getJavaName();
+    }
+
+    /**
+     * Returns this type's name in the same format as {@link Class#getName()}.
+     */
+    default String toClassName() {
+        return internalNameToJava(getName(), true, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.vm.ci.meta;
+
+import java.util.*;
+
+import jdk.vm.ci.meta.JavaTypeProfile.*;
+
+/**
+ * This profile object represents the type profile at a specific BCI. The precision of the supplied
+ * values may vary, but a runtime that provides this information should be aware that it will be
+ * used to guide performance-critical decisions like speculative inlining, etc.
+ */
+public final class JavaTypeProfile extends AbstractJavaProfile<ProfiledType, ResolvedJavaType> {
+
+    private static final ProfiledType[] EMPTY_ARRAY = new ProfiledType[0];
+
+    private final TriState nullSeen;
+
+    public JavaTypeProfile(TriState nullSeen, double notRecordedProbability, ProfiledType[] pitems) {
+        super(notRecordedProbability, pitems);
+        this.nullSeen = nullSeen;
+    }
+
+    /**
+     * Returns whether a null value was at the type check.
+     */
+    public TriState getNullSeen() {
+        return nullSeen;
+    }
+
+    /**
+     * A list of types for which the runtime has recorded probability information. Note that this
+     * includes both positive and negative types where a positive type is a subtype of the checked
+     * type and a negative type is not.
+     */
+    public ProfiledType[] getTypes() {
+        return getItems();
+    }
+
+    public JavaTypeProfile restrict(JavaTypeProfile otherProfile) {
+        if (otherProfile.getNotRecordedProbability() > 0.0) {
+            // Not useful for restricting since there is an unknown set of types occurring.
+            return this;
+        }
+
+        if (this.getNotRecordedProbability() > 0.0) {
+            // We are unrestricted, so the other profile is always a better estimate.
+            return otherProfile;
+        }
+
+        ArrayList<ProfiledType> result = new ArrayList<>();
+        for (int i = 0; i < getItems().length; i++) {
+            ProfiledType ptype = getItems()[i];
+            ResolvedJavaType type = ptype.getItem();
+            if (otherProfile.isIncluded(type)) {
+                result.add(ptype);
+            }
+        }
+
+        TriState newNullSeen = (otherProfile.getNullSeen() == TriState.FALSE) ? TriState.FALSE : getNullSeen();
+        double newNotRecorded = getNotRecordedProbability();
+        return createAdjustedProfile(result, newNullSeen, newNotRecorded);
+    }
+
+    public JavaTypeProfile restrict(ResolvedJavaType declaredType, boolean nonNull) {
+        ArrayList<ProfiledType> result = new ArrayList<>();
+        for (int i = 0; i < getItems().length; i++) {
+            ProfiledType ptype = getItems()[i];
+            ResolvedJavaType type = ptype.getItem();
+            if (declaredType.isAssignableFrom(type)) {
+                result.add(ptype);
+            }
+        }
+
+        TriState newNullSeen = (nonNull) ? TriState.FALSE : getNullSeen();
+        double newNotRecorded = this.getNotRecordedProbability();
+        // Assume for the types not recorded, the incompatibility rate is the same.
+        if (getItems().length != 0) {
+            newNotRecorded *= ((double) result.size() / (double) getItems().length);
+        }
+        return createAdjustedProfile(result, newNullSeen, newNotRecorded);
+    }
+
+    private JavaTypeProfile createAdjustedProfile(ArrayList<ProfiledType> result, TriState newNullSeen, double newNotRecorded) {
+        if (result.size() != this.getItems().length || newNotRecorded != getNotRecordedProbability() || newNullSeen != getNullSeen()) {
+            if (result.size() == 0) {
+                return new JavaTypeProfile(newNullSeen, 1.0, EMPTY_ARRAY);
+            }
+            double factor;
+            if (result.size() == this.getItems().length) {
+                /* List of types did not change, no need to recompute probabilities. */
+                factor = 1.0;
+            } else {
+                double probabilitySum = 0.0;
+                for (int i = 0; i < result.size(); i++) {
+                    probabilitySum += result.get(i).getProbability();
+                }
+                probabilitySum += newNotRecorded;
+
+                factor = 1.0 / probabilitySum; // Normalize to 1.0
+                assert factor >= 1.0;
+            }
+            ProfiledType[] newResult = new ProfiledType[result.size()];
+            for (int i = 0; i < newResult.length; ++i) {
+                ProfiledType curType = result.get(i);
+                newResult[i] = new ProfiledType(curType.getItem(), Math.min(1.0, curType.getProbability() * factor));
+            }
+            double newNotRecordedTypeProbability = Math.min(1.0, newNotRecorded * factor);
+            return new JavaTypeProfile(newNullSeen, newNotRecordedTypeProbability, newResult);
+        }
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return super.equals(other) && nullSeen.equals(((JavaTypeProfile) other).nullSeen);
+    }
+
+    @Override
+    public int hashCode() {
+        return nullSeen.hashCode() + super.hashCode();
+    }
+
+    public static class ProfiledType extends AbstractProfiledItem<ResolvedJavaType> {
+
+        public ProfiledType(ResolvedJavaType type, double probability) {
+            super(type, probability);
+            assert type.isArray() || type.isConcrete() : type;
+        }
+
+        /**
+         * Returns the type for this profile entry.
+         */
+        public ResolvedJavaType getType() {
+            return getItem();
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%.6f#%s", probability, item);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder("JavaTypeProfile<nullSeen=").append(getNullSeen()).append(", types=[");
+        for (int j = 0; j < getTypes().length; j++) {
+            if (j != 0) {
+                buf.append(", ");
+            }
+            ProfiledType ptype = getTypes()[j];
+            buf.append(String.format("%.6f:%s", ptype.getProbability(), ptype.getType()));
+        }
+        return buf.append(String.format("], notRecorded:%.6f>", getNotRecordedProbability())).toString();
+    }
+
+    /**
+     * Returns {@code true} if all types seen at this location have been recorded in the profile.
+     */
+    public boolean allTypesRecorded() {
+        return this.getNotRecordedProbability() == 0.0;
+    }
+
+    /**
+     * Returns the single monormorphic type representing this profile or {@code null} if no such
+     * type exists.
+     */
+    public ResolvedJavaType asSingleType() {
+        if (allTypesRecorded() && this.getTypes().length == 1) {
+            return getTypes()[0].getType();
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Marker interface for things that represent a Java value.
+ */
+public interface JavaValue {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.meta;
+
+import java.util.*;
+
+/**
+ * Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
+ * low level representation of the value, and a {@link #referenceMask} that describes the location
+ * of object references in the value, and optionally a {@link #derivedReferenceBase}.
+ *
+ * <h2>Constructing {@link LIRKind} instances</h2>
+ *
+ * During LIR generation, every new {@link Value} should get a {@link LIRKind} of the correct
+ * {@link PlatformKind} that also contains the correct reference information. {@linkplain LIRKind
+ * LIRKinds} should be created as follows:
+ *
+ * <p>
+ * If the result value is created from one or more input values, the {@link LIRKind} should be
+ * created with {@link LIRKind#combine}(inputs). If the result has a different {@link PlatformKind}
+ * than the inputs, {@link LIRKind#combine}(inputs).{@link #changeType}(resultKind) should be used.
+ * <p>
+ * If the result is an exact copy of one of the inputs, {@link Value#getLIRKind()} can be used. Note
+ * that this is only correct for move-like operations, like conditional move or compare-and-swap.
+ * For convert operations, {@link LIRKind#combine} should be used.
+ * <p>
+ * If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
+ * is a valid oop), {@link LIRKind#reference} should be used.
+ * <p>
+ * If it is known that the result will neither be a reference nor be derived from a reference,
+ * {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
+ * likely wrong, and {@link LIRKind#combine} should be used instead.
+ * <p>
+ * If it is known that the result is derived from a reference in a way that the garbage collector
+ * can not track, {@link LIRKind#unknownReference} can be used. In most cases,
+ * {@link LIRKind#combine} should be used instead, since it is able to detect this automatically.
+ */
+public final class LIRKind {
+
+    /**
+     * The non-type. This uses {@link #unknownReference}, so it can never be part of an oop map.
+     */
+    public static final LIRKind Illegal = unknownReference(JavaKind.Illegal);
+
+    private final PlatformKind platformKind;
+    private final int referenceMask;
+
+    private AllocatableValue derivedReferenceBase;
+
+    private static final int UNKNOWN_REFERENCE = -1;
+
+    private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
+        assert platformKind != JavaKind.Object : "Kind.Object shouldn't be used in the backend";
+        this.platformKind = platformKind;
+        this.referenceMask = referenceMask;
+        this.derivedReferenceBase = derivedReferenceBase;
+
+        assert derivedReferenceBase == null || !derivedReferenceBase.getLIRKind().isDerivedReference() : "derived reference can't have another derived reference as base";
+    }
+
+    /**
+     * Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value. Should
+     * be only used when it's guaranteed that the value is not even indirectly derived from a
+     * reference. Otherwise, {@link #combine(Value...)} should be used instead.
+     */
+    public static LIRKind value(PlatformKind platformKind) {
+        return new LIRKind(platformKind, 0, null);
+    }
+
+    /**
+     * Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
+     * reference.
+     */
+    public static LIRKind reference(PlatformKind platformKind) {
+        return derivedReference(platformKind, null);
+    }
+
+    /**
+     * Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
+     */
+    public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base) {
+        int length = platformKind.getVectorLength();
+        assert 0 < length && length < 32 : "vector of " + length + " references not supported";
+        return new LIRKind(platformKind, (1 << length) - 1, base);
+    }
+
+    /**
+     * Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
+     * from a reference in a non-linear way. Values of this {@link LIRKind} can not be live at
+     * safepoints. In most cases, this should not be called directly. {@link #combine} should be
+     * used instead to automatically propagate this information.
+     */
+    public static LIRKind unknownReference(PlatformKind platformKind) {
+        return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
+    }
+
+    /**
+     * Create a derived reference.
+     *
+     * @param base An {@link AllocatableValue} containing the base pointer of the derived reference.
+     */
+    public LIRKind makeDerivedReference(AllocatableValue base) {
+        assert !isUnknownReference() && derivedReferenceBase == null;
+        if (Value.ILLEGAL.equals(base)) {
+            return makeUnknownReference();
+        } else {
+            if (isValue()) {
+                return derivedReference(platformKind, base);
+            } else {
+                return new LIRKind(platformKind, referenceMask, base);
+            }
+        }
+    }
+
+    /**
+     * Derive a new type from inputs. The result will have the {@link PlatformKind} of one of the
+     * inputs. If all inputs are values, the result is a value. Otherwise, the result is an unknown
+     * reference.
+     *
+     * This method should be used to construct the result {@link LIRKind} of any operation that
+     * modifies values (e.g. arithmetics).
+     */
+    public static LIRKind combine(Value... inputs) {
+        assert inputs.length > 0;
+        for (Value input : inputs) {
+            LIRKind kind = input.getLIRKind();
+            if (kind.isUnknownReference()) {
+                return kind;
+            } else if (!kind.isValue()) {
+                return kind.makeUnknownReference();
+            }
+        }
+
+        // all inputs are values, just return one of them
+        return inputs[0].getLIRKind();
+    }
+
+    /**
+     * Merge the types of the inputs. The result will have the {@link PlatformKind} of one of the
+     * inputs. If all inputs are values (references), the result is a value (reference). Otherwise,
+     * the result is an unknown reference.
+     *
+     * This method should be used to construct the result {@link LIRKind} of merge operation that
+     * does not modify values (e.g. phis).
+     */
+    public static LIRKind merge(Value... inputs) {
+        assert inputs.length > 0;
+        ArrayList<LIRKind> kinds = new ArrayList<>(inputs.length);
+        for (int i = 0; i < inputs.length; i++) {
+            kinds.add(inputs[i].getLIRKind());
+        }
+        return merge(kinds);
+    }
+
+    /**
+     * Helper method to construct derived reference kinds. Returns the base value of a reference or
+     * derived reference. For values it returns {@code null}, and for unknown references it returns
+     * {@link Value#ILLEGAL}.
+     */
+    public static AllocatableValue derivedBaseFromValue(AllocatableValue value) {
+        LIRKind kind = value.getLIRKind();
+        if (kind.isValue()) {
+            return null;
+        } else if (kind.isDerivedReference()) {
+            return kind.getDerivedReferenceBase();
+        } else if (kind.isUnknownReference()) {
+            return Value.ILLEGAL;
+        } else {
+            // kind is a reference
+            return value;
+        }
+    }
+
+    /**
+     * Helper method to construct derived reference kinds. If one of {@code base1} or {@code base2}
+     * are set, it creates a derived reference using it as the base. If both are set, the result is
+     * an unknown reference.
+     */
+    public static LIRKind combineDerived(LIRKind kind, AllocatableValue base1, AllocatableValue base2) {
+        if (base1 == null && base2 == null) {
+            return kind;
+        } else if (base1 == null) {
+            return kind.makeDerivedReference(base2);
+        } else if (base2 == null) {
+            return kind.makeDerivedReference(base1);
+        } else {
+            return kind.makeUnknownReference();
+        }
+    }
+
+    /**
+     * @see #merge(Value...)
+     */
+    public static LIRKind merge(Iterable<LIRKind> kinds) {
+        LIRKind mergeKind = null;
+
+        for (LIRKind kind : kinds) {
+
+            if (kind.isUnknownReference()) {
+                /**
+                 * Kind is an unknown reference, therefore the result can only be also an unknown
+                 * reference.
+                 */
+                mergeKind = kind;
+                break;
+            }
+            if (mergeKind == null) {
+                mergeKind = kind;
+                continue;
+            }
+
+            if (kind.isValue()) {
+                /* Kind is a value. */
+                if (mergeKind.referenceMask != 0) {
+                    /*
+                     * Inputs consists of values and references. Make the result an unknown
+                     * reference.
+                     */
+                    mergeKind = mergeKind.makeUnknownReference();
+                    break;
+                }
+                /* Check that other inputs are also values. */
+            } else {
+                /* Kind is a reference. */
+                if (mergeKind.referenceMask != kind.referenceMask) {
+                    /*
+                     * Reference maps do not match so the result can only be an unknown reference.
+                     */
+                    mergeKind = mergeKind.makeUnknownReference();
+                    break;
+                }
+            }
+
+        }
+        assert mergeKind != null && verifyMerge(mergeKind, kinds);
+
+        // all inputs are values or references, just return one of them
+        return mergeKind;
+    }
+
+    private static boolean verifyMerge(LIRKind mergeKind, Iterable<LIRKind> kinds) {
+        for (LIRKind kind : kinds) {
+            assert mergeKind == null || verifyMoveKinds(mergeKind, kind) : String.format("Input kinds do not match %s vs. %s", mergeKind, kind);
+        }
+        return true;
+    }
+
+    /**
+     * Create a new {@link LIRKind} with the same reference information and a new
+     * {@linkplain #getPlatformKind platform kind}. If the new kind is a longer vector than this,
+     * the new elements are marked as untracked values.
+     */
+    public LIRKind changeType(PlatformKind newPlatformKind) {
+        if (newPlatformKind == platformKind) {
+            return this;
+        } else if (isUnknownReference()) {
+            return unknownReference(newPlatformKind);
+        } else if (referenceMask == 0) {
+            // value type
+            return LIRKind.value(newPlatformKind);
+        } else {
+            // reference type
+            int newLength = Math.min(32, newPlatformKind.getVectorLength());
+            int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
+            assert newReferenceMask != UNKNOWN_REFERENCE;
+            return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
+        }
+    }
+
+    /**
+     * Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
+     * new kind is longer than this, the reference positions are repeated to fill the vector.
+     */
+    public LIRKind repeat(PlatformKind newPlatformKind) {
+        if (isUnknownReference()) {
+            return unknownReference(newPlatformKind);
+        } else if (referenceMask == 0) {
+            // value type
+            return LIRKind.value(newPlatformKind);
+        } else {
+            // reference type
+            int oldLength = platformKind.getVectorLength();
+            int newLength = newPlatformKind.getVectorLength();
+            assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;
+
+            // repeat reference mask to fill new kind
+            int newReferenceMask = 0;
+            for (int i = 0; i < newLength; i += platformKind.getVectorLength()) {
+                newReferenceMask |= referenceMask << i;
+            }
+
+            assert newReferenceMask != UNKNOWN_REFERENCE;
+            return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
+        }
+    }
+
+    /**
+     * Create a new {@link LIRKind} with the same type, but marked as containing an
+     * {@link LIRKind#unknownReference}.
+     */
+    public LIRKind makeUnknownReference() {
+        return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
+    }
+
+    /**
+     * Get the low level type that is used in code generation.
+     */
+    public PlatformKind getPlatformKind() {
+        return platformKind;
+    }
+
+    /**
+     * Check whether this value is a derived reference.
+     */
+    public boolean isDerivedReference() {
+        return getDerivedReferenceBase() != null;
+    }
+
+    /**
+     * Get the base value of a derived reference.
+     */
+    public AllocatableValue getDerivedReferenceBase() {
+        return derivedReferenceBase;
+    }
+
+    /**
+     * Change the base value of a derived reference. This must be called on derived references only.
+     */
+    public void setDerivedReferenceBase(AllocatableValue derivedReferenceBase) {
+        assert isDerivedReference();
+        this.derivedReferenceBase = derivedReferenceBase;
+    }
+
+    /**
+     * Check whether this value is derived from a reference in a non-linear way. If this returns
+     * {@code true}, this value must not be live at safepoints.
+     */
+    public boolean isUnknownReference() {
+        return referenceMask == UNKNOWN_REFERENCE;
+    }
+
+    public int getReferenceCount() {
+        assert !isUnknownReference();
+        return Integer.bitCount(referenceMask);
+    }
+
+    /**
+     * Check whether the {@code idx}th part of this value is a reference that must be tracked at
+     * safepoints.
+     *
+     * @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
+     *            kind.
+     */
+    public boolean isReference(int idx) {
+        assert 0 <= idx && idx < platformKind.getVectorLength() : "invalid index " + idx + " in " + this;
+        return !isUnknownReference() && (referenceMask & 1 << idx) != 0;
+    }
+
+    /**
+     * Check whether this kind is a value type that doesn't need to be tracked at safepoints.
+     */
+    public boolean isValue() {
+        return referenceMask == 0;
+    }
+
+    @Override
+    public String toString() {
+        if (isValue()) {
+            return platformKind.name();
+        } else if (isUnknownReference()) {
+            return platformKind.name() + "[*]";
+        } else {
+            StringBuilder ret = new StringBuilder();
+            ret.append(platformKind.name());
+            ret.append('[');
+            for (int i = 0; i < platformKind.getVectorLength(); i++) {
+                if (isReference(i)) {
+                    ret.append('.');
+                } else {
+                    ret.append(' ');
+                }
+            }
+            ret.append(']');
+            return ret.toString();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((platformKind == null) ? 0 : platformKind.hashCode());
+        result = prime * result + referenceMask;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof LIRKind)) {
+            return false;
+        }
+
+        LIRKind other = (LIRKind) obj;
+        return platformKind == other.platformKind && referenceMask == other.referenceMask;
+    }
+
+    public static boolean verifyMoveKinds(LIRKind dst, LIRKind src) {
+        if (src.equals(dst)) {
+            return true;
+        }
+        /*
+         * TODO(je,rs) What we actually want is toStackKind(src.getPlatformKind()).equals(
+         * dst.getPlatformKind()) but due to the handling of sub-integer at the current point
+         * (phi-)moves from e.g. integer to short can happen. Therefore we compare stack kinds.
+         */
+        if (toStackKind(src.getPlatformKind()).equals(toStackKind(dst.getPlatformKind()))) {
+            return !src.isUnknownReference() || dst.isUnknownReference();
+        }
+        return false;
+    }
+
+    private static PlatformKind toStackKind(PlatformKind platformKind) {
+        if (platformKind instanceof JavaKind) {
+            return ((JavaKind) platformKind).getStackKind();
+        }
+        return platformKind;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTable.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+public interface LineNumberTable {
+
+    int[] getLineNumberEntries();
+
+    int[] getBciEntries();
+
+    int getLineNumber(int bci);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTableImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+public class LineNumberTableImpl implements LineNumberTable {
+
+    private final int[] lineNumbers;
+    private final int[] bci;
+
+    public LineNumberTableImpl(int[] lineNumbers, int[] bci) {
+        this.lineNumbers = lineNumbers;
+        this.bci = bci;
+    }
+
+    @Override
+    public int[] getLineNumberEntries() {
+        return lineNumbers;
+    }
+
+    @Override
+    public int[] getBciEntries() {
+        return bci;
+    }
+
+    @Override
+    public int getLineNumber(@SuppressWarnings("hiding") int bci) {
+        for (int i = 0; i < this.bci.length - 1; i++) {
+            if (this.bci[i] <= bci && bci < this.bci[i + 1]) {
+                return lineNumbers[i];
+            }
+        }
+        return lineNumbers[lineNumbers.length - 1];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Local.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+public interface Local {
+
+    int getStartBCI();
+
+    int getEndBCI();
+
+    int getSlot();
+
+    String getName();
+
+    JavaType getType();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+public class LocalImpl implements Local {
+
+    private final String name;
+    private final int startBci;
+    private final int endBci;
+    private final int slot;
+    private final JavaType type;
+
+    public LocalImpl(String name, JavaType type, int startBci, int endBci, int slot) {
+        this.name = name;
+        this.startBci = startBci;
+        this.endBci = endBci;
+        this.slot = slot;
+        this.type = type;
+    }
+
+    @Override
+    public int getStartBCI() {
+        return startBci;
+    }
+
+    @Override
+    public int getEndBCI() {
+        return endBci;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public JavaType getType() {
+        return type;
+    }
+
+    @Override
+    public int getSlot() {
+        return slot;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof LocalImpl)) {
+            return false;
+        }
+        LocalImpl that = (LocalImpl) obj;
+        return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "LocalImpl<name=" + name + ", type=" + type + ", startBci=" + startBci + ", endBci=" + endBci + ", slot=" + slot + ">";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTable.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+public interface LocalVariableTable {
+
+    Local[] getLocals();
+
+    Local[] getLocalsAt(int bci);
+
+    Local getLocal(int slot, int bci);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTableImpl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+import java.util.*;
+
+public class LocalVariableTableImpl implements LocalVariableTable {
+
+    private final Local[] locals;
+
+    public LocalVariableTableImpl(Local[] locals) {
+        this.locals = locals;
+    }
+
+    @Override
+    public Local getLocal(int slot, int bci) {
+        Local result = null;
+        for (Local local : locals) {
+            if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) {
+                if (result == null) {
+                    result = local;
+                } else {
+                    throw new IllegalStateException("Locals overlap!");
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Local[] getLocals() {
+        return locals;
+    }
+
+    @Override
+    public Local[] getLocalsAt(int bci) {
+        List<Local> result = new ArrayList<>();
+        for (Local l : locals) {
+            if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) {
+                result.add(l);
+            }
+        }
+        return result.toArray(new Local[result.size()]);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocationIdentity.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.vm.ci.meta;
+
+import java.util.*;
+
+// JaCoCo Exclude
+
+/**
+ * Marker interface for location identities. A different location identity of two memory accesses
+ * guarantees that the two accesses do not interfere.
+ *
+ * Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when
+ * comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
+ * {@link IdentityHashMap}s with {@link LocationIdentity} values as keys.
+ */
+public abstract class LocationIdentity {
+
+    private static final class AnyLocationIdentity extends LocationIdentity {
+        @Override
+        public boolean isImmutable() {
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "ANY_LOCATION";
+        }
+    }
+
+    public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity();
+
+    public static LocationIdentity any() {
+        return ANY_LOCATION;
+    }
+
+    /**
+     * Denotes a location is unchanging in all cases. Not that this is different than the Java
+     * notion of final which only requires definite assignment.
+     */
+    public abstract boolean isImmutable();
+
+    public final boolean isMutable() {
+        return !isImmutable();
+    }
+
+    public final boolean isAny() {
+        return this == ANY_LOCATION;
+    }
+
+    public final boolean isSingle() {
+        return this != ANY_LOCATION;
+    }
+
+    public final boolean overlaps(LocationIdentity other) {
+        return isAny() || other.isAny() || this.equals(other);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Provides memory access operations for the target VM.
+ */
+public interface MemoryAccessProvider {
+
+    /**
+     * Reads a value of this kind using a base address and a displacement. No bounds checking or
+     * type checking is performed. Returns {@code null} if the value is not available at this point.
+     *
+     * @param base the base address from which the value is read.
+     * @param displacement the displacement within the object in bytes
+     * @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
+     *         value cannot be read.
+     */
+    JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant base, long displacement);
+
+    /**
+     * Reads a primitive value using a base address and a displacement.
+     *
+     * @param kind the {@link JavaKind} of the returned {@link JavaConstant} object
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @param bits the number of bits to read from memory
+     * @return the read value encapsulated in a {@link JavaConstant} object of {@link JavaKind} kind
+     */
+    JavaConstant readPrimitiveConstant(JavaKind kind, Constant base, long displacement, int bits);
+
+    /**
+     * Reads a Java {@link Object} value using a base address and a displacement.
+     *
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @return the read value encapsulated in a {@link Constant} object
+     */
+    JavaConstant readObjectConstant(Constant base, long displacement);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 2014, 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 jdk.vm.ci.meta;
+
+import java.lang.reflect.*;
+
+/**
+ * Provides access to the metadata of a class typically provided in a class file.
+ */
+public interface MetaAccessProvider {
+
+    /**
+     * Returns the resolved Java type representing a given Java class.
+     *
+     * @param clazz the Java class object
+     * @return the resolved Java type object
+     */
+    ResolvedJavaType lookupJavaType(Class<?> clazz);
+
+    /**
+     * Returns the resolved Java types representing some given Java classes.
+     *
+     * @param classes the Java class objects
+     * @return the resolved Java type objects
+     */
+    default ResolvedJavaType[] lookupJavaTypes(Class<?>[] classes) {
+        ResolvedJavaType[] result = new ResolvedJavaType[classes.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = lookupJavaType(classes[i]);
+        }
+        return result;
+    }
+
+    /**
+     * Provides the {@link ResolvedJavaMethod} for a {@link Method} or {@link Constructor} obtained
+     * via reflection.
+     */
+    ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod);
+
+    /**
+     * Provides the {@link ResolvedJavaField} for a {@link Field} obtained via reflection.
+     */
+    ResolvedJavaField lookupJavaField(Field reflectionField);
+
+    /**
+     * Returns the resolved Java type of the given {@link JavaConstant} object.
+     *
+     * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()}
+     */
+    ResolvedJavaType lookupJavaType(JavaConstant constant);
+
+    /**
+     * Returns the number of bytes occupied by this constant value or constant object.
+     *
+     * @param constant the constant whose bytes should be measured
+     * @return the number of bytes occupied by this constant
+     */
+    long getMemorySize(JavaConstant constant);
+
+    /**
+     * Parses a <a
+     * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
+     * descriptor</a> into a {@link Signature}. The behavior of this method is undefined if the
+     * method descriptor is not well formed.
+     */
+    Signature parseMethodDescriptor(String methodDescriptor);
+
+    /**
+     * Encodes a deoptimization action and a deoptimization reason in an integer value.
+     *
+     * @param debugId an integer that can be used to track the origin of a deoptimization at
+     *            runtime. There is no guarantee that the runtime will use this value. The runtime
+     *            may even keep fewer than 32 bits.
+     *
+     * @return the encoded value as an integer
+     */
+    JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId);
+
+    DeoptimizationReason decodeDeoptReason(JavaConstant constant);
+
+    DeoptimizationAction decodeDeoptAction(JavaConstant constant);
+
+    int decodeDebugId(JavaConstant constant);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2012, 2015, 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 jdk.vm.ci.meta;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients.
+ */
+public class MetaUtil {
+
+    private static class ClassInfo {
+        public long totalSize;
+        public long instanceCount;
+
+        @Override
+        public String toString() {
+            return "totalSize=" + totalSize + ", instanceCount=" + instanceCount;
+        }
+    }
+
+    /**
+     * Returns the number of bytes occupied by this constant value or constant object and
+     * recursively all values reachable from this value.
+     *
+     * @param constant the constant whose bytes should be measured
+     * @param printTopN print total size and instance count of the top n classes is desired
+     * @return the number of bytes occupied by this constant
+     */
+    public static long getMemorySizeRecursive(MetaAccessProvider access, ConstantReflectionProvider constantReflection, JavaConstant constant, PrintStream out, int printTopN) {
+        Set<JavaConstant> marked = new HashSet<>();
+        Deque<JavaConstant> stack = new ArrayDeque<>();
+        if (constant.getJavaKind() == JavaKind.Object && constant.isNonNull()) {
+            marked.add(constant);
+        }
+        final HashMap<ResolvedJavaType, ClassInfo> histogram = new HashMap<>();
+        stack.push(constant);
+        long sum = 0;
+        while (!stack.isEmpty()) {
+            JavaConstant c = stack.pop();
+            long memorySize = access.getMemorySize(constant);
+            sum += memorySize;
+            if (c.getJavaKind() == JavaKind.Object && c.isNonNull()) {
+                ResolvedJavaType clazz = access.lookupJavaType(c);
+                if (!histogram.containsKey(clazz)) {
+                    histogram.put(clazz, new ClassInfo());
+                }
+                ClassInfo info = histogram.get(clazz);
+                info.instanceCount++;
+                info.totalSize += memorySize;
+                ResolvedJavaType type = access.lookupJavaType(c);
+                if (type.isArray()) {
+                    if (!type.getComponentType().isPrimitive()) {
+                        int length = constantReflection.readArrayLength(c);
+                        for (int i = 0; i < length; i++) {
+                            JavaConstant value = constantReflection.readArrayElement(c, i);
+                            pushConstant(marked, stack, value);
+                        }
+                    }
+                } else {
+                    ResolvedJavaField[] instanceFields = type.getInstanceFields(true);
+                    for (ResolvedJavaField f : instanceFields) {
+                        if (f.getJavaKind() == JavaKind.Object) {
+                            JavaConstant value = constantReflection.readFieldValue(f, c);
+                            pushConstant(marked, stack, value);
+                        }
+                    }
+                }
+            }
+        }
+        ArrayList<ResolvedJavaType> clazzes = new ArrayList<>();
+        clazzes.addAll(histogram.keySet());
+        Collections.sort(clazzes, new Comparator<ResolvedJavaType>() {
+
+            @Override
+            public int compare(ResolvedJavaType o1, ResolvedJavaType o2) {
+                long l1 = histogram.get(o1).totalSize;
+                long l2 = histogram.get(o2).totalSize;
+                if (l1 > l2) {
+                    return -1;
+                } else if (l1 == l2) {
+                    return 0;
+                } else {
+                    return 1;
+                }
+            }
+        });
+
+        int z = 0;
+        for (ResolvedJavaType c : clazzes) {
+            if (z > printTopN) {
+                break;
+            }
+            out.println("Class " + c + ", " + histogram.get(c));
+            ++z;
+        }
+
+        return sum;
+    }
+
+    private static void pushConstant(Set<JavaConstant> marked, Deque<JavaConstant> stack, JavaConstant value) {
+        if (value.isNonNull()) {
+            if (!marked.contains(value)) {
+                marked.add(value);
+                stack.push(value);
+            }
+        }
+    }
+
+    /**
+     * Calls {@link JavaType#resolve(ResolvedJavaType)} on an array of types.
+     */
+    public static ResolvedJavaType[] resolveJavaTypes(JavaType[] types, ResolvedJavaType accessingClass) {
+        ResolvedJavaType[] result = new ResolvedJavaType[types.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = types[i].resolve(accessingClass);
+        }
+        return result;
+    }
+
+    /**
+     * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for
+     * anonymous and local classes.
+     *
+     * @param clazz the class for which the simple name is being requested
+     * @param withEnclosingClass specifies if the returned name should be qualified with the name(s)
+     *            of the enclosing class/classes of {@code clazz} (if any). This option is ignored
+     *            if {@code clazz} denotes an anonymous or local class.
+     * @return the simple name
+     */
+    public static String getSimpleName(Class<?> clazz, boolean withEnclosingClass) {
+        final String simpleName = clazz.getSimpleName();
+        if (simpleName.length() != 0) {
+            if (withEnclosingClass) {
+                String prefix = "";
+                Class<?> enclosingClass = clazz;
+                while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) {
+                    prefix = enclosingClass.getSimpleName() + "." + prefix;
+                }
+                return prefix + simpleName;
+            }
+            return simpleName;
+        }
+        // Must be an anonymous or local class
+        final String name = clazz.getName();
+        int index = name.indexOf('$');
+        if (index == -1) {
+            return name;
+        }
+        index = name.lastIndexOf('.', index);
+        if (index == -1) {
+            return name;
+        }
+        return name.substring(index + 1);
+    }
+
+    static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) {
+        switch (name.charAt(0)) {
+            case 'L': {
+                String result = name.substring(1, name.length() - 1).replace('/', '.');
+                if (!qualified) {
+                    final int lastDot = result.lastIndexOf('.');
+                    if (lastDot != -1) {
+                        result = result.substring(lastDot + 1);
+                    }
+                }
+                return result;
+            }
+            case '[':
+                return classForNameCompatible ? name.replace('/', '.') : internalNameToJava(name.substring(1), qualified, classForNameCompatible) + "[]";
+            default:
+                if (name.length() != 1) {
+                    throw new IllegalArgumentException("Illegal internal name: " + name);
+                }
+                return JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)).getJavaName();
+        }
+    }
+
+    /**
+     * Turns an class name in internal format into a resolved Java type.
+     */
+    public static ResolvedJavaType classForName(String internal, MetaAccessProvider metaAccess, ClassLoader cl) {
+        JavaKind k = JavaKind.fromTypeString(internal);
+        try {
+            String n = internalNameToJava(internal, true, true);
+            return metaAccess.lookupJavaType(k.isPrimitive() ? k.toJavaClass() : Class.forName(n, true, cl));
+        } catch (ClassNotFoundException cnfe) {
+            throw new IllegalArgumentException("could not instantiate class described by " + internal, cnfe);
+        }
+    }
+
+    /**
+     * Convenient shortcut for calling
+     * {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a
+     * {@link StringBuilder} instance and convert the result to a string.
+     */
+    public static String toLocation(ResolvedJavaMethod method, int bci) {
+        return appendLocation(new StringBuilder(), method, bci).toString();
+    }
+
+    /**
+     * Appends a string representation of a location specified by a given method and bci to a given
+     * {@link StringBuilder}. If a stack trace element with a non-null file name and non-negative
+     * line number is {@linkplain ResolvedJavaMethod#asStackTraceElement(int) available} for the
+     * given method, then the string returned is the {@link StackTraceElement#toString()} value of
+     * the stack trace element, suffixed by the bci location. For example:
+     *
+     * <pre>
+     *     java.lang.String.valueOf(String.java:2930) [bci: 12]
+     * </pre>
+     *
+     * Otherwise, the string returned is the value of applying {@link JavaMethod#format(String)}
+     * with the format string {@code "%H.%n(%p)"}, suffixed by the bci location. For example:
+     *
+     * <pre>
+     *     java.lang.String.valueOf(int) [bci: 12]
+     * </pre>
+     *
+     * @param sb
+     * @param method
+     * @param bci
+     */
+    public static StringBuilder appendLocation(StringBuilder sb, ResolvedJavaMethod method, int bci) {
+        if (method != null) {
+            StackTraceElement ste = method.asStackTraceElement(bci);
+            if (ste.getFileName() != null && ste.getLineNumber() > 0) {
+                sb.append(ste);
+            } else {
+                sb.append(method.format("%H.%n(%p)"));
+            }
+        } else {
+            sb.append("Null method");
+        }
+        return sb.append(" [bci: ").append(bci).append(']');
+    }
+
+    static void appendProfile(StringBuilder buf, AbstractJavaProfile<?, ?> profile, int bci, String type, String sep) {
+        if (profile != null) {
+            AbstractProfiledItem<?>[] pitems = profile.getItems();
+            if (pitems != null) {
+                buf.append(String.format("%s@%d:", type, bci));
+                for (int j = 0; j < pitems.length; j++) {
+                    AbstractProfiledItem<?> pitem = pitems[j];
+                    buf.append(String.format(" %.6f (%s)%s", pitem.getProbability(), pitem.getItem(), sep));
+                }
+                if (profile.getNotRecordedProbability() != 0) {
+                    buf.append(String.format(" %.6f <other %s>%s", profile.getNotRecordedProbability(), type, sep));
+                } else {
+                    buf.append(String.format(" <no other %s>%s", type, sep));
+                }
+            }
+        }
+    }
+
+    /**
+     * Converts a Java source-language class name into the internal form.
+     *
+     * @param className the class name
+     * @return the internal name form of the class name
+     */
+    public static String toInternalName(String className) {
+        if (className.startsWith("[")) {
+            /* Already in the correct array style. */
+            return className.replace('.', '/');
+        }
+
+        StringBuilder result = new StringBuilder();
+        String base = className;
+        while (base.endsWith("[]")) {
+            result.append("[");
+            base = base.substring(0, base.length() - 2);
+        }
+
+        switch (base) {
+            case "boolean":
+                result.append("Z");
+                break;
+            case "byte":
+                result.append("B");
+                break;
+            case "short":
+                result.append("S");
+                break;
+            case "char":
+                result.append("C");
+                break;
+            case "int":
+                result.append("I");
+                break;
+            case "float":
+                result.append("F");
+                break;
+            case "long":
+                result.append("J");
+                break;
+            case "double":
+                result.append("D");
+                break;
+            case "void":
+                result.append("V");
+                break;
+            default:
+                result.append("L").append(base.replace('.', '/')).append(";");
+                break;
+        }
+        return result.toString();
+    }
+
+    /**
+     * Prepends the String {@code indentation} to every line in String {@code lines}, including a
+     * possibly non-empty line following the final newline.
+     */
+    public static String indent(String lines, String indentation) {
+        if (lines.length() == 0) {
+            return lines;
+        }
+        final String newLine = "\n";
+        if (lines.endsWith(newLine)) {
+            return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
+        }
+        return indentation + lines.replace(newLine, newLine + indentation);
+    }
+
+    /**
+     * Gets a string representation of an object based soley on its class and its
+     * {@linkplain System#identityHashCode(Object) identity hash code}. This avoids and calls to
+     * virtual methods on the object such as {@link Object#hashCode()}.
+     */
+    public static String identityHashCodeString(Object obj) {
+        if (obj == null) {
+            return "null";
+        }
+        return obj.getClass().getName() + "@" + System.identityHashCode(obj);
+    }
+
+    /**
+     * Used to lookup constants from {@link Modifier} that are not public (VARARGS, SYNTHETIC etc.).
+     */
+    static int getNonPublicModifierStaticField(String name) {
+        try {
+            Field field = Modifier.class.getDeclaredField(name);
+            field.setAccessible(true);
+            return field.getInt(null);
+        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+            throw new InternalError(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.meta;
+
+import java.lang.invoke.*;
+
+/**
+ * Interface to access the internals of the {@link MethodHandle} implementation of the VM. An
+ * implementation of this interface is usually required to access non-public classes, methods, and
+ * fields of {@link MethodHandle}, i.e., data that is not standardized by the Java specification.
+ */
+public interface MethodHandleAccessProvider {
+
+    /**
+     * Identification for methods defined on the class {@link MethodHandle} that are processed by
+     * the {@link MethodHandleAccessProvider}.
+     */
+    public enum IntrinsicMethod {
+        /** The method {@code MethodHandle.invokeBasic}. */
+        INVOKE_BASIC,
+        /** The method {@code MethodHandle.linkToStatic}. */
+        LINK_TO_STATIC,
+        /** The method {@code MethodHandle.linkToSpecial}. */
+        LINK_TO_SPECIAL,
+        /** The method {@code MethodHandle.linkToVirtual}. */
+        LINK_TO_VIRTUAL,
+        /** The method {@code MethodHandle.linkToInterface}. */
+        LINK_TO_INTERFACE
+    }
+
+    /**
+     * Returns the method handle method intrinsic identifier for the provided method, or
+     * {@code null} if the method is not an intrinsic processed by this interface.
+     */
+    IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method);
+
+    /**
+     * Resolves the invocation target for an invocation of {@link IntrinsicMethod#INVOKE_BASIC
+     * MethodHandle.invokeBasic} with the given constant receiver {@link MethodHandle}. Returns
+     * {@code null} if the invocation target is not available at this time.
+     * <p>
+     * The first invocations of a method handle can use an interpreter to lookup the actual invoked
+     * method; frequently executed method handles can use Java bytecode generation to avoid the
+     * interpreter overhead. If the parameter forceBytecodeGeneration is set to true, the VM should
+     * try to generate bytecodes before this method returns.
+     */
+    ResolvedJavaMethod resolveInvokeBasicTarget(JavaConstant methodHandle, boolean forceBytecodeGeneration);
+
+    /**
+     * Resolves the invocation target for an invocation of a {@code MethodHandle.linkTo*} method
+     * with the given constant member name. The member name is the last parameter of the
+     * {@code linkTo*} method. Returns {@code null} if the invocation target is not available at
+     * this time.
+     */
+    ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.meta;
+
+import static java.lang.reflect.Modifier.*;
+
+import java.lang.reflect.*;
+
+/**
+ * A Java element (i.e., a class, interface, field or method) that is described by a set of Java
+ * language {@linkplain #getModifiers() modifiers}.
+ */
+public interface ModifiersProvider {
+    int BRIDGE = MetaUtil.getNonPublicModifierStaticField("BRIDGE");
+    int VARARGS = MetaUtil.getNonPublicModifierStaticField("VARARGS");
+    int SYNTHETIC = MetaUtil.getNonPublicModifierStaticField("SYNTHETIC");
+    int ANNOTATION = MetaUtil.getNonPublicModifierStaticField("ANNOTATION");
+    int ENUM = MetaUtil.getNonPublicModifierStaticField("ENUM");
+    int MANDATED = MetaUtil.getNonPublicModifierStaticField("MANDATED");
+
+    /**
+     * Returns the Java Virtual Machine modifiers for this element. Note that this can differ from
+     * standard Java Reflection modifiers. For example at the JVM level, classes (
+     * {@link ResolvedJavaType}) can not be private or protected.
+     */
+    int getModifiers();
+
+    /**
+     * @see Modifier#isInterface(int)
+     */
+    default boolean isInterface() {
+        return Modifier.isInterface(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isSynchronized(int)
+     */
+    default boolean isSynchronized() {
+        return Modifier.isSynchronized(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isStatic(int)
+     */
+    default boolean isStatic() {
+        return Modifier.isStatic(getModifiers());
+    }
+
+    /**
+     * The setting of the final modifier bit for types is somewhat confusing, so don't export
+     * isFinal by default. Subclasses like {@link ResolvedJavaField} and {@link ResolvedJavaMethod}
+     * can export it as isFinal, but {@link ResolvedJavaType} can provide a more sensible equivalent
+     * like {@link ResolvedJavaType#isLeaf}.
+     *
+     * @see Modifier#isFinal(int)
+     */
+    default boolean isFinalFlagSet() {
+        return Modifier.isFinal(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isPublic(int)
+     */
+    default boolean isPublic() {
+        return Modifier.isPublic(getModifiers());
+    }
+
+    /**
+     * Determines if this element is neither {@linkplain #isPublic() public},
+     * {@linkplain #isProtected() protected} nor {@linkplain #isPrivate() private}.
+     */
+    default boolean isPackagePrivate() {
+        return ((PUBLIC | PROTECTED | PRIVATE) & getModifiers()) == 0;
+    }
+
+    /**
+     * @see Modifier#isPrivate(int)
+     */
+    default boolean isPrivate() {
+        return Modifier.isPrivate(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isProtected(int)
+     */
+    default boolean isProtected() {
+        return Modifier.isProtected(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isTransient(int)
+     */
+    default boolean isTransient() {
+        return Modifier.isTransient(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isStrict(int)
+     */
+    default boolean isStrict() {
+        return Modifier.isStrict(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isVolatile(int)
+     */
+    default boolean isVolatile() {
+        return Modifier.isVolatile(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isNative(int)
+     */
+    default boolean isNative() {
+        return Modifier.isNative(getModifiers());
+    }
+
+    /**
+     * @see Modifier#isAbstract(int)
+     */
+    default boolean isAbstract() {
+        return Modifier.isAbstract(getModifiers());
+    }
+
+    /**
+     * Checks that the method is concrete and not abstract.
+     *
+     * @return whether the method is a concrete method
+     */
+    default boolean isConcrete() {
+        return !isAbstract();
+    }
+
+    static int jvmClassModifiers() {
+        // no SUPER
+        return PUBLIC | FINAL | INTERFACE | ABSTRACT | ANNOTATION | ENUM | SYNTHETIC;
+    }
+
+    static int jvmMethodModifiers() {
+        return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | BRIDGE | VARARGS | NATIVE | ABSTRACT | STRICT | SYNTHETIC;
+    }
+
+    static int jvmFieldModifiers() {
+        return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | ENUM | SYNTHETIC;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/NullConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * The implementation type of the {@link JavaConstant#NULL_POINTER null constant}.
+ */
+final class NullConstant implements JavaConstant {
+
+    protected NullConstant() {
+    }
+
+    @Override
+    public JavaKind getJavaKind() {
+        return JavaKind.Object;
+    }
+
+    @Override
+    public boolean isNull() {
+        return true;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return true;
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public int asInt() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public boolean asBoolean() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public long asLong() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public float asFloat() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public double asDouble() {
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public String toString() {
+        return JavaConstant.toString(this);
+    }
+
+    @Override
+    public String toValueString() {
+        return "null";
+    }
+
+    @Override
+    public int hashCode() {
+        return 13;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o instanceof NullConstant;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Represents a platform-specific low-level type for values.
+ */
+public interface PlatformKind {
+
+    String name();
+
+    JavaConstant getDefaultValue();
+
+    public interface Key {
+
+    }
+
+    public class EnumKey<E extends Enum<E>> implements Key {
+        private final Enum<E> e;
+
+        public EnumKey(Enum<E> e) {
+            this.e = e;
+        }
+
+        @Override
+        public int hashCode() {
+            return e.ordinal() ^ e.name().hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof EnumKey) {
+                EnumKey<?> that = (EnumKey<?>) obj;
+                return this.e == that.e;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Gets a value associated with this object that can be used as a stable key in a map. The
+     * {@link Object#hashCode()} implementation of the returned value should be stable between VM
+     * executions.
+     */
+    Key getKey();
+
+    /**
+     * Get the size in bytes of this {@link PlatformKind}.
+     */
+    int getSizeInBytes();
+
+    /**
+     * Returns how many primitive values fit in this {@link PlatformKind}. For scalar types this is
+     * one, for SIMD types it may be higher.
+     */
+    int getVectorLength();
+
+    /**
+     * Gets a single type char that identifies this type for use in debug output.
+     */
+    char getTypeChar();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+import java.nio.*;
+
+/**
+ * Represents a primitive constant value, such as an integer or floating point number, within the
+ * compiler and across the compiler/runtime interface.
+ */
+public class PrimitiveConstant implements JavaConstant, SerializableConstant {
+
+    private final JavaKind kind;
+
+    /**
+     * The boxed primitive value as a {@code long}. For {@code float} and {@code double} values,
+     * this value is the result of {@link Float#floatToRawIntBits(float)} and
+     * {@link Double#doubleToRawLongBits(double)} respectively.
+     */
+    private final long primitive;
+
+    protected PrimitiveConstant(JavaKind kind, long primitive) {
+        this.primitive = primitive;
+        this.kind = kind;
+
+        assert kind.isPrimitive() || kind == JavaKind.Illegal;
+    }
+
+    @Override
+    public JavaKind getJavaKind() {
+        return kind;
+    }
+
+    @Override
+    public boolean isNull() {
+        return false;
+    }
+
+    @Override
+    public boolean isDefaultForKind() {
+        return primitive == 0;
+    }
+
+    @Override
+    public boolean asBoolean() {
+        assert getJavaKind() == JavaKind.Boolean;
+        return primitive != 0L;
+    }
+
+    @Override
+    public int asInt() {
+        assert getJavaKind().getStackKind() == JavaKind.Int : getJavaKind().getStackKind();
+        return (int) primitive;
+    }
+
+    @Override
+    public long asLong() {
+        assert getJavaKind().isNumericInteger();
+        return primitive;
+    }
+
+    @Override
+    public float asFloat() {
+        assert getJavaKind() == JavaKind.Float;
+        return Float.intBitsToFloat((int) primitive);
+    }
+
+    @Override
+    public double asDouble() {
+        assert getJavaKind() == JavaKind.Double;
+        return Double.longBitsToDouble(primitive);
+    }
+
+    @Override
+    public Object asBoxedPrimitive() {
+        switch (getJavaKind()) {
+            case Byte:
+                return Byte.valueOf((byte) primitive);
+            case Boolean:
+                return Boolean.valueOf(asBoolean());
+            case Short:
+                return Short.valueOf((short) primitive);
+            case Char:
+                return Character.valueOf((char) primitive);
+            case Int:
+                return Integer.valueOf(asInt());
+            case Long:
+                return Long.valueOf(asLong());
+            case Float:
+                return Float.valueOf(asFloat());
+            case Double:
+                return Double.valueOf(asDouble());
+            default:
+                throw new IllegalArgumentException("unexpected kind " + getJavaKind());
+        }
+    }
+
+    @Override
+    public int getSerializedSize() {
+        return getJavaKind().getByteCount();
+    }
+
+    @Override
+    public void serialize(ByteBuffer buffer) {
+        switch (getJavaKind()) {
+            case Byte:
+            case Boolean:
+                buffer.put((byte) primitive);
+                break;
+            case Short:
+                buffer.putShort((short) primitive);
+                break;
+            case Char:
+                buffer.putChar((char) primitive);
+                break;
+            case Int:
+                buffer.putInt(asInt());
+                break;
+            case Long:
+                buffer.putLong(asLong());
+                break;
+            case Float:
+                buffer.putFloat(asFloat());
+                break;
+            case Double:
+                buffer.putDouble(asDouble());
+                break;
+            default:
+                throw new IllegalArgumentException("unexpected kind " + getJavaKind());
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) (primitive ^ (primitive >>> 32)) * (getJavaKind().ordinal() + 31);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof PrimitiveConstant)) {
+            return false;
+        }
+        PrimitiveConstant other = (PrimitiveConstant) o;
+        return this.kind.equals(other.kind) && this.primitive == other.primitive;
+    }
+
+    @Override
+    public String toString() {
+        if (getJavaKind() == JavaKind.Illegal) {
+            return "illegal";
+        } else {
+            return getJavaKind().getJavaName() + "[" + asBoxedPrimitive() + "|0x" + Long.toHexString(primitive) + "]";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+package jdk.vm.ci.meta;
+
+/**
+ * Provides access to the profiling information of one specific method. Every accessor method
+ * returns the information that is available at the time of invocation. If a method is invoked
+ * multiple times, it may return significantly different results for every invocation as the
+ * profiling information may be changed by other Java threads at any time.
+ */
+public interface ProfilingInfo {
+
+    /**
+     * Returns the length of the bytecodes associated with this profile.
+     */
+    int getCodeSize();
+
+    /**
+     * Returns an estimate of how often the branch at the given byte code was taken.
+     *
+     * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if
+     *         this information is not available.
+     */
+    double getBranchTakenProbability(int bci);
+
+    /**
+     * Returns an estimate of how often the switch cases are taken at the given BCI. The default
+     * case is stored as the last entry.
+     *
+     * @return A double value that contains the estimated probabilities, with 0.0 meaning never and
+     *         1.0 meaning always, or -1 if this information is not available.
+     */
+    double[] getSwitchProbabilities(int bci);
+
+    /**
+     * Returns the TypeProfile for the given BCI.
+     *
+     * @return Returns a JavaTypeProfile object, or null if not available.
+     */
+    JavaTypeProfile getTypeProfile(int bci);
+
+    /**
+     * Returns the MethodProfile for the given BCI.
+     *
+     * @return Returns a JavaMethodProfile object, or null if not available.
+     */
+    JavaMethodProfile getMethodProfile(int bci);
+
+    /**
+     * Returns information if the given BCI did ever throw an exception.
+     *
+     * @return {@link TriState#TRUE} if the instruction has thrown an exception at least once,
+     *         {@link TriState#FALSE} if it never threw an exception, and {@link TriState#UNKNOWN}
+     *         if this information was not recorded.
+     */
+    TriState getExceptionSeen(int bci);
+
+    /**
+     * Returns information if null was ever seen for the given BCI. This information is collected
+     * for the aastore, checkcast and instanceof bytecodes.
+     *
+     * @return {@link TriState#TRUE} if null was seen for the instruction, {@link TriState#FALSE} if
+     *         null was NOT seen, and {@link TriState#UNKNOWN} if this information was not recorded.
+     */
+    TriState getNullSeen(int bci);
+
+    /**
+     * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts
+     * to each other, as the returned value highly depends on the time of invocation.
+     *
+     * @return the estimated execution count or -1 if not available.
+     */
+    int getExecutionCount(int bci);
+
+    /**
+     * Returns how frequently a method was deoptimized for the given deoptimization reason. This
+     * only indicates how often the method did fall back to the interpreter for the execution and
+     * does not indicate how often it was recompiled.
+     *
+     * @param reason the reason for which the number of deoptimizations should be queried
+     * @return the number of times the compiled method deoptimized for the given reason.
+     */
+    int getDeoptimizationCount(DeoptimizationReason reason);
+
+    /**
+     * Records the size of the compiler intermediate representation (IR) associated with this
+     * method.
+     *
+     * @param irType the IR type for which the size is being recorded
+     * @param irSize the IR size to be recorded. The unit depends on the IR.
+     * @return whether recording this information for {@code irType} is supported
+     */
+    boolean setCompilerIRSize(Class<?> irType, int irSize);
+
+    /**
+     * Gets the size of the compiler intermediate representation (IR) associated with this method
+     * last recorded by {@link #setCompilerIRSize(Class, int)}.
+     *
+     * @param irType the IR type for which the size is being requested
+     * @return the requested IR size or -1 if it is unavailable for {@code irType}
+     */
+    int getCompilerIRSize(Class<?> irType);
+
+    /**
+     * Returns true if the profiling information can be assumed as sufficiently accurate.
+     *
+     * @return true if the profiling information was recorded often enough mature enough, false
+     *         otherwise.
+     */
+    boolean isMature();
+
+    /**
+     * Force data to be treated as mature if possible.
+     */
+    void setMature();
+
+    /**
+     * Formats this profiling information to a string.
+     *
+     * @param method an optional method that augments the profile string returned
+     * @param sep the separator to use for each separate profile record
+     */
+    default String toString(ResolvedJavaMethod method, String sep) {
+        StringBuilder buf = new StringBuilder(100);
+        if (method != null) {
+            buf.append(String.format("canBeStaticallyBound: %b%s", method.canBeStaticallyBound(), sep));
+        }
+        for (int i = 0; i < getCodeSize(); i++) {
+            if (getExecutionCount(i) != -1) {
+                buf.append(String.format("executionCount@%d: %d%s", i, getExecutionCount(i), sep));
+            }
+
+            if (getBranchTakenProbability(i) != -1) {
+                buf.append(String.format("branchProbability@%d: %.6f%s", i, getBranchTakenProbability(i), sep));
+            }
+
+            double[] switchProbabilities = getSwitchProbabilities(i);
+            if (switchProbabilities != null) {
+                buf.append(String.format("switchProbabilities@%d:", i));
+                for (int j = 0; j < switchProbabilities.length; j++) {
+                    buf.append(String.format(" %.6f", switchProbabilities[j]));
+                }
+                buf.append(sep);
+            }
+
+            if (getExceptionSeen(i) != TriState.UNKNOWN) {
+                buf.append(String.format("exceptionSeen@%d: %s%s", i, getExceptionSeen(i).name(), sep));
+            }
+
+            if (getNullSeen(i) != TriState.UNKNOWN) {
+                buf.append(String.format("nullSeen@%d: %s%s", i, getNullSeen(i).name(), sep));
+            }
+
+            JavaTypeProfile typeProfile = getTypeProfile(i);
+            MetaUtil.appendProfile(buf, typeProfile, i, "types", sep);
+
+            JavaMethodProfile methodProfile = getMethodProfile(i);
+            MetaUtil.appendProfile(buf, methodProfile, i, "methods", sep);
+        }
+
+        boolean firstDeoptReason = true;
+        for (DeoptimizationReason reason : DeoptimizationReason.values()) {
+            int count = getDeoptimizationCount(reason);
+            if (count > 0) {
+                if (firstDeoptReason) {
+                    buf.append("deoptimization history").append(sep);
+                    firstDeoptReason = false;
+                }
+                buf.append(String.format(" %s: %d%s", reason.name(), count, sep));
+            }
+        }
+        if (buf.length() == 0) {
+            return "";
+        }
+        String s = buf.toString();
+        return s.substring(0, s.length() - sep.length());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/RawConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+public class RawConstant extends PrimitiveConstant {
+
+    public RawConstant(long rawValue) {
+        super(JavaKind.Int, rawValue);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2009, 2014, 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 jdk.vm.ci.meta;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+/**
+ * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved
+ * through {@link ConstantPool constant pools}.
+ */
+public interface ResolvedJavaField extends JavaField, ModifiersProvider {
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Only the {@linkplain Modifier#fieldModifiers() field flags} specified in the JVM
+     * specification will be included in the returned mask.
+     */
+    int getModifiers();
+
+    default boolean isFinal() {
+        return ModifiersProvider.super.isFinalFlagSet();
+    }
+
+    /**
+     * Determines if this field was injected by the VM. Such a field, for example, is not derived
+     * from a class file.
+     */
+    boolean isInternal();
+
+    /**
+     * Determines if this field is a synthetic field as defined by the Java Language Specification.
+     */
+    boolean isSynthetic();
+
+    /**
+     * Returns the {@link ResolvedJavaType} object representing the class or interface that declares
+     * this field.
+     */
+    ResolvedJavaType getDeclaringClass();
+
+    /**
+     * Returns all annotations of this field. If no annotations are present, an array of length 0 is
+     * returned.
+     */
+    Annotation[] getAnnotations();
+
+    /**
+     * Returns the annotation for the specified type of this field, if such an annotation is
+     * present.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return this element's annotation for the specified annotation type if present on this field,
+     *         else {@code null}
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns an object representing the unique location identity of this resolved Java field.
+     *
+     * @return the location identity of the field
+     */
+    LocationIdentity getLocationIdentity();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2009, 2014, 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 jdk.vm.ci.meta;
+
+import java.lang.annotation.*;
+import java.lang.invoke.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Represents a resolved Java method. Methods, like fields and types, are resolved through
+ * {@link ConstantPool constant pools}.
+ */
+public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider {
+
+    /**
+     * Returns the bytecode of this method, if the method has code. The returned byte array does not
+     * contain breakpoints or non-Java bytecodes. This may return null if the
+     * {@link #getDeclaringClass() holder} is not {@link ResolvedJavaType#isLinked() linked}.
+     *
+     * The contained constant pool indices may not be the ones found in the original class file but
+     * they can be used with the JVMCI API (e.g. methods in {@link ConstantPool}).
+     *
+     * @return the bytecode of the method, or {@code null} if {@code getCodeSize() == 0} or if the
+     *         code is not ready.
+     */
+    byte[] getCode();
+
+    /**
+     * Returns the size of the bytecode of this method, if the method has code. This is equivalent
+     * to {@link #getCode()}. {@code length} if the method has code.
+     *
+     * @return the size of the bytecode in bytes, or 0 if no bytecode is available
+     */
+    int getCodeSize();
+
+    /**
+     * Returns the {@link ResolvedJavaType} object representing the class or interface that declares
+     * this method.
+     */
+    ResolvedJavaType getDeclaringClass();
+
+    /**
+     * Returns the maximum number of locals used in this method's bytecodes.
+     */
+    int getMaxLocals();
+
+    /**
+     * Returns the maximum number of stack slots used in this method's bytecodes.
+     */
+    int getMaxStackSize();
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Only the {@linkplain Modifier#methodModifiers() method flags} specified in the JVM
+     * specification will be included in the returned mask.
+     */
+    int getModifiers();
+
+    default boolean isFinal() {
+        return ModifiersProvider.super.isFinalFlagSet();
+    }
+
+    /**
+     * Determines if this method is a synthetic method as defined by the Java Language
+     * Specification.
+     */
+    default boolean isSynthetic() {
+        return (SYNTHETIC & getModifiers()) == SYNTHETIC;
+    }
+
+    /**
+     * Checks that the method is a <a
+     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">varargs</a>
+     * method.
+     *
+     * @return whether the method is a varargs method
+     */
+    default boolean isVarArgs() {
+        return (VARARGS & getModifiers()) == VARARGS;
+    }
+
+    /**
+     * Checks that the method is a <a
+     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">bridge</a>
+     * method.
+     *
+     * @return whether the method is a bridge method
+     */
+    default boolean isBridge() {
+        return (BRIDGE & getModifiers()) == BRIDGE;
+    }
+
+    /**
+     * Returns {@code true} if this method is a default method; returns {@code false} otherwise.
+     *
+     * A default method is a public non-abstract instance method, that is, a non-static method with
+     * a body, declared in an interface type.
+     *
+     * @return true if and only if this method is a default method as defined by the Java Language
+     *         Specification.
+     */
+    boolean isDefault();
+
+    /**
+     * Checks whether this method is a class initializer.
+     *
+     * @return {@code true} if the method is a class initializer
+     */
+    boolean isClassInitializer();
+
+    /**
+     * Checks whether this method is a constructor.
+     *
+     * @return {@code true} if the method is a constructor
+     */
+    boolean isConstructor();
+
+    /**
+     * Checks whether this method can be statically bound (usually, that means it is final or
+     * private or static, but not abstract, or the declaring class is final).
+     *
+     * @return {@code true} if this method can be statically bound
+     */
+    boolean canBeStaticallyBound();
+
+    /**
+     * Returns the list of exception handlers for this method.
+     */
+    ExceptionHandler[] getExceptionHandlers();
+
+    /**
+     * Returns a stack trace element for this method and a given bytecode index.
+     */
+    StackTraceElement asStackTraceElement(int bci);
+
+    /**
+     * Returns an object that provides access to the profiling information recorded for this method.
+     */
+    default ProfilingInfo getProfilingInfo() {
+        return getProfilingInfo(true, true);
+    }
+
+    /**
+     * Returns an object that provides access to the profiling information recorded for this method.
+     *
+     * @param includeNormal if true,
+     *            {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason)
+     *            deoptimization counts} will include deoptimization that happened during execution
+     *            of standard non-osr methods.
+     * @param includeOSR if true,
+     *            {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason)
+     *            deoptimization counts} will include deoptimization that happened during execution
+     *            of on-stack-replacement methods.
+     */
+    ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR);
+
+    /**
+     * Invalidates the profiling information and restarts profiling upon the next invocation.
+     */
+    void reprofile();
+
+    /**
+     * Returns the constant pool of this method.
+     */
+    ConstantPool getConstantPool();
+
+    /**
+     * Returns all annotations of this method. If no annotations are present, an array of length 0
+     * is returned.
+     */
+    Annotation[] getAnnotations();
+
+    /**
+     * Returns the annotation for the specified type of this method, if such an annotation is
+     * present.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return this element's annotation for the specified annotation type if present on this
+     *         method, else {@code null}
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns an array of arrays that represent the annotations on the formal parameters, in
+     * declaration order, of this method.
+     *
+     * @see Method#getParameterAnnotations()
+     */
+    Annotation[][] getParameterAnnotations();
+
+    /**
+     * Returns an array of {@link Type} objects that represent the formal parameter types, in
+     * declaration order, of this method.
+     *
+     * @see Method#getGenericParameterTypes()
+     */
+    Type[] getGenericParameterTypes();
+
+    /**
+     * Returns {@code true} if this method is not excluded from inlining and has associated Java
+     * bytecodes (@see {@link ResolvedJavaMethod#hasBytecodes()}).
+     */
+    boolean canBeInlined();
+
+    /**
+     * Returns {@code true} if the inlining of this method should be forced.
+     */
+    boolean shouldBeInlined();
+
+    /**
+     * Returns the LineNumberTable of this method or null if this method does not have a line
+     * numbers table.
+     */
+    LineNumberTable getLineNumberTable();
+
+    /**
+     * Returns the local variable table of this method or null if this method does not have a local
+     * variable table.
+     */
+    LocalVariableTable getLocalVariableTable();
+
+    /**
+     * Invokes the underlying method represented by this object, on the specified object with the
+     * specified parameters. This method is similar to a reflective method invocation by
+     * {@link Method#invoke}.
+     *
+     * @param receiver The receiver for the invocation, or {@code null} if it is a static method.
+     * @param arguments The arguments for the invocation.
+     * @return The value returned by the method invocation, or {@code null} if the return type is
+     *         {@code void}.
+     */
+    JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments);
+
+    /**
+     * Gets the encoding of (that is, a constant representing the value of) this method.
+     *
+     * @return a constant representing a reference to this method
+     */
+    Constant getEncoding();
+
+    /**
+     * Checks if this method is present in the virtual table for subtypes of the specified
+     * {@linkplain ResolvedJavaType type}.
+     *
+     * @return true is this method is present in the virtual table for subtypes of this type.
+     */
+    boolean isInVirtualMethodTable(ResolvedJavaType resolved);
+
+    /**
+     * Gets the annotation of a particular type for a formal parameter of this method.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @param parameterIndex the index of a formal parameter of {@code method}
+     * @return the annotation of type {@code annotationClass} for the formal parameter present, else
+     *         null
+     * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal
+     *             parameter
+     */
+    default <T extends Annotation> T getParameterAnnotation(Class<T> annotationClass, int parameterIndex) {
+        if (parameterIndex >= 0) {
+            Annotation[][] parameterAnnotations = getParameterAnnotations();
+            for (Annotation a : parameterAnnotations[parameterIndex]) {
+                if (a.annotationType() == annotationClass) {
+                    return annotationClass.cast(a);
+                }
+            }
+        }
+        return null;
+    }
+
+    default JavaType[] toParameterTypes() {
+        JavaType receiver = isStatic() || isConstructor() ? null : getDeclaringClass();
+        return getSignature().toParameterTypes(receiver);
+    }
+
+    /**
+     * Gets the annotations of a particular type for the formal parameters of this method.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return the annotation of type {@code annotationClass} (if any) for each formal parameter
+     *         present
+     */
+    @SuppressWarnings("unchecked")
+    default <T extends Annotation> T[] getParameterAnnotations(Class<T> annotationClass) {
+        Annotation[][] parameterAnnotations = getParameterAnnotations();
+        T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length);
+        for (int i = 0; i < parameterAnnotations.length; i++) {
+            for (Annotation a : parameterAnnotations[i]) {
+                if (a.annotationType() == annotationClass) {
+                    result[i] = annotationClass.cast(a);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Checks whether the method has bytecodes associated with it. Methods without bytecodes are
+     * either abstract or native methods.
+     *
+     * @return whether the definition of this method is Java bytecodes
+     */
+    default boolean hasBytecodes() {
+        return isConcrete() && !isNative();
+    }
+
+    /**
+     * Checks whether the method has a receiver parameter - i.e., whether it is not static.
+     *
+     * @return whether the method has a receiver parameter
+     */
+    default boolean hasReceiver() {
+        return !isStatic();
+    }
+
+    /**
+     * Determines if this method is {@link java.lang.Object#Object()}.
+     */
+    default boolean isJavaLangObjectInit() {
+        return getDeclaringClass().isJavaLangObject() && getName().equals("<init>");
+    }
+
+    SpeculationLog getSpeculationLog();
+
+    /**
+     * Determines if the method identified by its holder and name is a <a
+     * href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
+     * polymorphic</a> method.
+     */
+    static boolean isSignaturePolymorphic(JavaType holder, String name, MetaAccessProvider metaAccess) {
+        if (!holder.getName().equals("Ljava/lang/invoke/MethodHandle;")) {
+            return false;
+        }
+        ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class);
+        Signature signature = metaAccess.parseMethodDescriptor("([Ljava/lang/Object;)Ljava/lang/Object;");
+        ResolvedJavaMethod method = methodHandleType.findMethod(name, signature);
+        if (method == null) {
+            return false;
+        }
+        return method.isNative() && method.isVarArgs();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+import java.lang.annotation.*;
+import java.net.*;
+
+import jdk.vm.ci.meta.Assumptions.*;
+
+/**
+ * Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays
+ * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools}
+ * .
+ */
+public interface ResolvedJavaType extends JavaType, ModifiersProvider {
+    /**
+     * Gets the runtime representation of the Java class object of this type.
+     */
+    JavaConstant getJavaClass();
+
+    /**
+     * Gets the runtime representation of the "hub" of this type--that is, the closest part of the
+     * type representation which is typically stored in the object header.
+     */
+    Constant getObjectHub();
+
+    /**
+     * Checks whether this type has a finalizer method.
+     *
+     * @return {@code true} if this class has a finalizer
+     */
+    boolean hasFinalizer();
+
+    /**
+     * Checks whether this type has any finalizable subclasses so far. Any decisions based on this
+     * information require the registration of a dependency, since this information may change.
+     *
+     * @return {@code true} if this class has any subclasses with finalizers
+     */
+    AssumptionResult<Boolean> hasFinalizableSubclass();
+
+    /**
+     * Checks whether this type is an interface.
+     *
+     * @return {@code true} if this type is an interface
+     */
+    boolean isInterface();
+
+    /**
+     * Checks whether this type is an instance class.
+     *
+     * @return {@code true} if this type is an instance class
+     */
+    boolean isInstanceClass();
+
+    /**
+     * Checks whether this type is an array class.
+     *
+     * @return {@code true} if this type is an array class
+     */
+    boolean isArray();
+
+    /**
+     * Checks whether this type is primitive.
+     *
+     * @return {@code true} if this type is primitive
+     */
+    boolean isPrimitive();
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Only the flags specified in the JVM specification will be included in the returned mask. This
+     * method is identical to {@link Class#getModifiers()} in terms of the value return for this
+     * type.
+     */
+    int getModifiers();
+
+    /*
+     * The setting of the final bit for types is a bit confusing since arrays are marked as final.
+     * This method provides a semantically equivalent test that appropriate for types.
+     */
+    default boolean isLeaf() {
+        return getElementalType().isFinalFlagSet();
+    }
+
+    /**
+     * Checks whether this type is initialized. If a type is initialized it implies that it was
+     * {@link #isLinked() linked} and that the static initializer has run.
+     *
+     * @return {@code true} if this type is initialized
+     */
+    boolean isInitialized();
+
+    /**
+     * Initializes this type.
+     */
+    void initialize();
+
+    /**
+     * Checks whether this type is linked and verified. When a type is linked the static initializer
+     * has not necessarily run. An {@link #isInitialized() initialized} type is always linked.
+     *
+     * @return {@code true} if this type is linked
+     */
+    boolean isLinked();
+
+    /**
+     * Determines if this type is either the same as, or is a superclass or superinterface of, the
+     * type represented by the specified parameter. This method is identical to
+     * {@link Class#isAssignableFrom(Class)} in terms of the value return for this type.
+     */
+    boolean isAssignableFrom(ResolvedJavaType other);
+
+    /**
+     * Returns true if this type is exactly the type {@link java.lang.Object}.
+     */
+    default boolean isJavaLangObject() {
+        // Removed assertion due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=434442
+        return getSuperclass() == null && !isInterface() && getJavaKind() == JavaKind.Object;
+    }
+
+    /**
+     * Checks whether the specified object is an instance of this type.
+     *
+     * @param obj the object to test
+     * @return {@code true} if the object is an instance of this type
+     */
+    boolean isInstance(JavaConstant obj);
+
+    /**
+     * Returns this type if it is an exact type otherwise returns null. This type is exact if it is
+     * void, primitive, final, or an array of a final or primitive type.
+     *
+     * @return this type if it is exact; {@code null} otherwise
+     */
+    ResolvedJavaType asExactType();
+
+    /**
+     * Gets the super class of this type. If this type represents either the {@code Object} class,
+     * an interface, a primitive type, or void, then null is returned. If this object represents an
+     * array class then the type object representing the {@code Object} class is returned.
+     */
+    ResolvedJavaType getSuperclass();
+
+    /**
+     * Gets the interfaces implemented or extended by this type. This method is analogous to
+     * {@link Class#getInterfaces()} and as such, only returns the interfaces directly implemented
+     * or extended by this type.
+     */
+    ResolvedJavaType[] getInterfaces();
+
+    /**
+     * Gets the single implementor of this type. Calling this method on a non-interface type causes
+     * an exception.
+     * <p>
+     * If the compiler uses the result of this method for its compilation, the usage must be guarded
+     * because the verifier can not guarantee that the assigned type really implements this
+     * interface. Additionally, class loading can invalidate the result of this method.
+     *
+     * @return {@code null} if there is no implementor, the implementor if there is only one, or
+     *         {@code this} if there are more than one.
+     */
+    ResolvedJavaType getSingleImplementor();
+
+    /**
+     * Walks the class hierarchy upwards and returns the least common class that is a superclass of
+     * both the current and the given type.
+     *
+     * @return the least common type that is a super type of both the current and the given type, or
+     *         {@code null} if primitive types are involved.
+     */
+    ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType);
+
+    /**
+     * Attempts to get a leaf concrete subclass of this type.
+     * <p>
+     * For an {@linkplain #isArray() array} type A, the leaf concrete subclass is A if the
+     * {@linkplain #getElementalType() elemental} type of A is final (which includes primitive
+     * types). Otherwise {@code null} is returned for A.
+     * <p>
+     * For a non-array type T, the result is the leaf concrete type in the current hierarchy of T.
+     * <p>
+     * A runtime may decide not to manage or walk a large hierarchy and so the result is
+     * conservative. That is, a non-null result is guaranteed to be the leaf concrete class in T's
+     * hierarchy <b>at the current point in time</b> but a null result does not necessarily imply
+     * that there is no leaf concrete class in T's hierarchy.
+     * <p>
+     * If the compiler uses the result of this method for its compilation, it must register the
+     * {@link AssumptionResult} in its {@link Assumptions} because dynamic class loading can
+     * invalidate the result of this method.
+     *
+     * @return an {@link AssumptionResult} containing the leaf concrete subclass for this type as
+     *         described above
+     */
+    AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype();
+
+    ResolvedJavaType getComponentType();
+
+    default ResolvedJavaType getElementalType() {
+        ResolvedJavaType t = this;
+        while (t.isArray()) {
+            t = t.getComponentType();
+        }
+        return t;
+    }
+
+    ResolvedJavaType getArrayClass();
+
+    /**
+     * Resolves the method implementation for virtual dispatches on objects of this dynamic type.
+     * This resolution process only searches "up" the class hierarchy of this type.
+     *
+     * @param method the method to select the implementation of
+     * @param callerType the caller or context type used to perform access checks
+     * @return the link-time resolved method (might be abstract) or {@code null} if it can not be
+     *         linked
+     */
+    ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType);
+
+    /**
+     * Resolves the method implementation for virtual dispatches on objects of this dynamic type.
+     * This resolution process only searches "up" the class hierarchy of this type. A broader search
+     * that also walks "down" the hierarchy is implemented by
+     * {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}.
+     *
+     * @param method the method to select the implementation of
+     * @param callerType the caller or context type used to perform access checks
+     * @return the concrete method that would be selected at runtime, or {@code null} if there is no
+     *         concrete implementation of {@code method} in this type or any of its superclasses
+     */
+    ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType);
+
+    /**
+     * Given a {@link ResolvedJavaMethod} A, returns a concrete {@link ResolvedJavaMethod} B that is
+     * the only possible unique target for a virtual call on A(). Returns {@code null} if either no
+     * such concrete method or more than one such method exists. Returns the method A if A is a
+     * concrete method that is not overridden.
+     * <p>
+     * If the compiler uses the result of this method for its compilation, it must register an
+     * assumption because dynamic class loading can invalidate the result of this method.
+     *
+     * @param method the method A for which a unique concrete target is searched
+     * @return the unique concrete target or {@code null} if no such target exists or assumptions
+     *         are not supported by this runtime
+     */
+    AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method);
+
+    /**
+     * Returns the instance fields of this class, including
+     * {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned
+     * for array and primitive types. The order of fields returned by this method is stable. That
+     * is, for a single JVM execution the same order is returned each time this method is called. It
+     * is also the "natural" order, which means that the JVM would expect the fields in this order
+     * if no specific order is given.
+     *
+     * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this
+     *            type are included in the result
+     * @return an array of instance fields
+     */
+    ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses);
+
+    /**
+     * Returns the static fields of this class, including
+     * {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned
+     * for array and primitive types. The order of fields returned by this method is stable. That
+     * is, for a single JVM execution the same order is returned each time this method is called.
+     */
+    ResolvedJavaField[] getStaticFields();
+
+    /**
+     * Returns all annotations of this class. If no annotations are present, an array of length 0 is
+     * returned.
+     */
+    Annotation[] getAnnotations();
+
+    /**
+     * Returns the annotation for the specified type of this class, if such an annotation is
+     * present.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return this element's annotation for the specified annotation type if present on this class,
+     *         else {@code null}
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns the instance field of this class (or one of its super classes) at the given offset,
+     * or {@code null} if there is no such field.
+     *
+     * @param offset the offset of the field to look for
+     * @return the field with the given offset, or {@code null} if there is no such field.
+     */
+    ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind);
+
+    /**
+     * Returns name of source file of this type.
+     */
+    String getSourceFileName();
+
+    /**
+     * Returns the class file path - if available - of this type, or {@code null}.
+     */
+    URL getClassFilePath();
+
+    /**
+     * Returns {@code true} if the type is a local type.
+     */
+    boolean isLocal();
+
+    /**
+     * Returns {@code true} if the type is a member type.
+     */
+    boolean isMember();
+
+    /**
+     * Returns the enclosing type of this type, if it exists, or {@code null}.
+     */
+    ResolvedJavaType getEnclosingType();
+
+    /**
+     * Returns an array reflecting all the constructors declared by this type. This method is
+     * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors.
+     */
+    ResolvedJavaMethod[] getDeclaredConstructors();
+
+    /**
+     * Returns an array reflecting all the methods declared by this type. This method is similar to
+     * {@link Class#getDeclaredMethods()} in terms of returned methods.
+     */
+    ResolvedJavaMethod[] getDeclaredMethods();
+
+    /**
+     * Returns the {@code <clinit>} method for this class if there is one.
+     */
+    ResolvedJavaMethod getClassInitializer();
+
+    /**
+     * Returns true if this type represents an interface and it should be trusted even in places
+     * where the JVM verifier would not give any guarantees other than {@link Object}.
+     */
+    boolean isTrustedInterfaceType();
+
+    default ResolvedJavaMethod findMethod(String name, Signature signature) {
+        for (ResolvedJavaMethod method : getDeclaredMethods()) {
+            if (method.getName().equals(name) && method.getSignature().equals(signature)) {
+                return method;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SerializableConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.meta;
+
+import java.nio.*;
+
+/**
+ * Represents a compile-time constant that can be converted to a byte array.
+ */
+public interface SerializableConstant extends Constant {
+
+    /**
+     * Return the size in bytes of the serialized representation of this constant.
+     */
+    int getSerializedSize();
+
+    /**
+     * Serialize the constant into the ByteBuffer. There must be at least
+     * {@link #getSerializedSize()} bytes available capacity in the buffer.
+     */
+    void serialize(ByteBuffer buffer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Signature.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Represents a method signature provided by the runtime.
+ *
+ * @see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">Method
+ *      Descriptors</a>
+ */
+public interface Signature {
+
+    /**
+     * Returns the number of parameters in this signature, adding 1 for a receiver if requested.
+     *
+     * @param receiver true if 1 is to be added to the result for a receiver
+     * @return the number of parameters; + 1 iff {@code receiver == true}
+     */
+    int getParameterCount(boolean receiver);
+
+    /**
+     * Gets the parameter type at the specified position.
+     *
+     * @param index the index into the parameters, with {@code 0} indicating the first parameter
+     * @param accessingClass the context of the type lookup. If non-null, its class loader is used
+     *            for resolving the type. If {@code null}, then the type returned is either
+     *            unresolved or a resolved type whose resolution is context free (e.g., a primitive
+     *            type or a type in a java.* package).
+     * @return the {@code index}'th parameter type
+     * @throws LinkageError if {@code accessingClass != null} and resolution fails
+     *
+     */
+    JavaType getParameterType(int index, ResolvedJavaType accessingClass);
+
+    /**
+     * Gets the parameter kind at the specified position. This is the same as calling
+     * {@link #getParameterType}. {@link JavaType#getJavaKind getJavaKind}.
+     *
+     * @param index the index into the parameters, with {@code 0} indicating the first parameter
+     * @return the kind of the parameter at the specified position
+     */
+    default JavaKind getParameterKind(int index) {
+        return getParameterType(index, null).getJavaKind();
+    }
+
+    /**
+     * Gets the return type of this signature.
+     *
+     * @param accessingClass the context of the type lookup. If non-null, its class loader is used
+     *            for resolving the type. If {@code null}, then the type returned is either
+     *            unresolved or a resolved type whose resolution is context free (e.g., a primitive
+     *            type or a type in a java.* package).
+     * @return the return type
+     * @throws LinkageError if {@code accessingClass != null} and resolution fails
+     */
+    JavaType getReturnType(ResolvedJavaType accessingClass);
+
+    /**
+     * Gets the return kind of this signature. This is the same as calling {@link #getReturnType}.
+     * {@link JavaType#getJavaKind getJavaKind}.
+     */
+    default JavaKind getReturnKind() {
+        return getReturnType(null).getJavaKind();
+    }
+
+    /**
+     * Gets the <a
+     * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
+     * descriptor</a> corresponding to this signature. For example:
+     *
+     * <pre>
+     * (ILjava/lang/String;D)V
+     * </pre>
+     *
+     * @return the signature as a string
+     */
+    default String toMethodDescriptor() {
+        StringBuilder sb = new StringBuilder("(");
+        for (int i = 0; i < getParameterCount(false); ++i) {
+            sb.append(getParameterType(i, null).getName());
+        }
+        sb.append(')').append(getReturnType(null).getName());
+        return sb.toString();
+    }
+
+    default JavaType[] toParameterTypes(JavaType receiverType) {
+        int args = getParameterCount(false);
+        JavaType[] result;
+        int i = 0;
+        if (receiverType != null) {
+            result = new JavaType[args + 1];
+            result[0] = receiverType;
+            i = 1;
+        } else {
+            result = new JavaType[args];
+        }
+        for (int j = 0; j < args; j++) {
+            result[i + j] = getParameterType(j, null);
+        }
+        return result;
+    }
+
+    default JavaKind[] toParameterKinds(boolean receiver) {
+        int args = getParameterCount(false);
+        JavaKind[] result;
+        int i = 0;
+        if (receiver) {
+            result = new JavaKind[args + 1];
+            result[0] = JavaKind.Object;
+            i = 1;
+        } else {
+            result = new JavaKind[args];
+        }
+        for (int j = 0; j < args; j++) {
+            result[i + j] = getParameterKind(j);
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 2014, 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 jdk.vm.ci.meta;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+/**
+ * Manages a list of unique deoptimization reasons.
+ *
+ */
+public abstract class SpeculationLog {
+    private volatile Object lastFailed;
+    private volatile Collection<Object> speculations;
+    private Set<Object> failedSpeculations;
+
+    public synchronized void collectFailedSpeculations() {
+        if (lastFailed != null) {
+            if (failedSpeculations == null) {
+                failedSpeculations = new HashSet<>(2);
+            }
+            failedSpeculations.add(lastFailed);
+            lastFailed = null;
+            speculations = null;
+        }
+    }
+
+    public boolean maySpeculate(Object reason) {
+        if (failedSpeculations != null && failedSpeculations.contains(reason)) {
+            return false;
+        }
+        return true;
+    }
+
+    protected void addSpeculation(Object reason) {
+        assert maySpeculate(reason);
+        if (speculations == null) {
+            synchronized (this) {
+                if (speculations == null) {
+                    speculations = new ConcurrentLinkedQueue<>();
+                }
+            }
+        }
+        speculations.add(reason);
+    }
+
+    public abstract JavaConstant speculate(Object reason);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TriState.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Represents a logic value that can be either {@link #TRUE}, {@link #FALSE}, or {@link #UNKNOWN}.
+ */
+public enum TriState {
+    TRUE,
+    FALSE,
+    UNKNOWN;
+
+    public static TriState get(boolean value) {
+        return value ? TRUE : FALSE;
+    }
+
+    /**
+     * This is optimistic about {@link #UNKNOWN} (it prefers known values over {@link #UNKNOWN}) and
+     * pesimistic about known (it perfers {@link #TRUE} over {@link #FALSE}).
+     */
+    public static TriState merge(TriState a, TriState b) {
+        if (a == TRUE || b == TRUE) {
+            return TRUE;
+        }
+        if (a == FALSE || b == FALSE) {
+            return FALSE;
+        }
+        assert a == UNKNOWN && b == UNKNOWN;
+        return UNKNOWN;
+    }
+
+    public boolean isTrue() {
+        return this == TRUE;
+    }
+
+    public boolean isFalse() {
+        return this == FALSE;
+    }
+
+    public boolean isUnknown() {
+        return this == UNKNOWN;
+    }
+
+    public boolean isKnown() {
+        return this != UNKNOWN;
+    }
+
+    public boolean toBoolean() {
+        if (isTrue()) {
+            return true;
+        } else if (isFalse()) {
+            return false;
+        } else {
+            throw new IllegalStateException("Cannot convert to boolean, TriState is in an unknown state");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TrustedInterface.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.meta;
+
+/**
+ * Interfaces extending this interface should be trusted by the compiler. See
+ * {@link ResolvedJavaType#isTrustedInterfaceType()}.
+ *
+ */
+public interface TrustedInterface {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014, 2014, 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 jdk.vm.ci.meta;
+
+public interface VMConstant extends Constant {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta;
+
+/**
+ * Abstract base class for values.
+ */
+public abstract class Value {
+
+    public static final Value[] NO_VALUES = new Value[0];
+
+    public static final AllocatableValue ILLEGAL = new IllegalValue();
+
+    private static final class IllegalValue extends AllocatableValue {
+        private IllegalValue() {
+            super(LIRKind.Illegal);
+        }
+
+        @Override
+        public String toString() {
+            return "-";
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            // Due to de-serialization this object may exist multiple times. So we compare classes
+            // instead of the individual objects. (This anonymous class has always the same meaning)
+            return other instanceof IllegalValue;
+        }
+    }
+
+    private final LIRKind lirKind;
+
+    /**
+     * Initializes a new value of the specified kind.
+     *
+     * @param lirKind the kind
+     */
+    protected Value(LIRKind lirKind) {
+        this.lirKind = lirKind;
+    }
+
+    /**
+     * Returns a String representation of the kind, which should be the end of all
+     * {@link #toString()} implementation of subclasses.
+     */
+    protected final String getKindSuffix() {
+        return "|" + getPlatformKind().getTypeChar();
+    }
+
+    public final LIRKind getLIRKind() {
+        return lirKind;
+    }
+
+    /**
+     * Returns the platform specific kind used to store this value.
+     */
+    public final PlatformKind getPlatformKind() {
+        return lirKind.getPlatformKind();
+    }
+
+    @Override
+    public int hashCode() {
+        return 41 + lirKind.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Value) {
+            Value that = (Value) obj;
+            return lirKind.equals(that.lirKind);
+        }
+        return false;
+    }
+
+    /**
+     * Checks if this value is identical to {@code other}.
+     *
+     * Warning: Use with caution! Usually equivalence {@link #equals(Object)} is sufficient and
+     * should be used.
+     */
+    public final boolean identityEquals(Value other) {
+        return this == other;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/package-info.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Package that defines the interface between a runtime and a Java application that wants to access meta information. The runtime
+ * provides an implementation of the {@link jdk.vm.ci.meta.MetaAccessProvider} interface.
+ */
+package jdk.vm.ci.meta;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options.processor/src/META-INF/services/javax.annotation.processing.Processor	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+jdk.vm.ci.options.processor.OptionProcessor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options.processor/src/jdk/vm/ci/options/processor/OptionProcessor.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,362 @@
+/*
+ * 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 jdk.vm.ci.options.processor;
+
+import java.io.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+import javax.tools.Diagnostic.Kind;
+
+import jdk.vm.ci.options.*;
+
+import javax.tools.*;
+
+/**
+ * Processes static fields annotated with {@link Option}. An {@link OptionDescriptors}
+ * implementation is generated for each top level class containing at least one such field. The name
+ * of the generated class for top level class {@code com.foo.Bar} is
+ * {@code com.foo.Bar_OptionDescriptors}.
+ */
+@SupportedAnnotationTypes({"jdk.vm.ci.options.Option"})
+public class OptionProcessor extends AbstractProcessor {
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latest();
+    }
+
+    private final Set<Element> processed = new HashSet<>();
+
+    private void processElement(Element element, OptionsInfo info) {
+
+        if (!element.getModifiers().contains(Modifier.STATIC)) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element);
+            return;
+        }
+
+        Option annotation = element.getAnnotation(Option.class);
+        assert annotation != null;
+        assert element instanceof VariableElement;
+        assert element.getKind() == ElementKind.FIELD;
+        VariableElement field = (VariableElement) element;
+        String fieldName = field.getSimpleName().toString();
+
+        Elements elements = processingEnv.getElementUtils();
+        Types types = processingEnv.getTypeUtils();
+
+        TypeMirror fieldType = field.asType();
+        if (fieldType.getKind() != TypeKind.DECLARED) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be of type " + OptionValue.class.getName(), element);
+            return;
+        }
+        DeclaredType declaredFieldType = (DeclaredType) fieldType;
+
+        TypeMirror optionValueType = elements.getTypeElement(OptionValue.class.getName()).asType();
+        if (!types.isSubtype(fieldType, types.erasure(optionValueType))) {
+            String msg = String.format("Option field type %s is not a subclass of %s", fieldType, optionValueType);
+            processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
+            return;
+        }
+
+        if (!field.getModifiers().contains(Modifier.STATIC)) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element);
+            return;
+        }
+
+        String help = annotation.help();
+        if (help.length() != 0) {
+            char firstChar = help.charAt(0);
+            if (!Character.isUpperCase(firstChar)) {
+                processingEnv.getMessager().printMessage(Kind.ERROR, "Option help text must start with upper case letter", element);
+                return;
+            }
+        }
+
+        String optionName = annotation.name();
+        if (optionName.equals("")) {
+            optionName = fieldName;
+        }
+
+        DeclaredType declaredOptionValueType = declaredFieldType;
+        while (!types.isSameType(types.erasure(declaredOptionValueType), types.erasure(optionValueType))) {
+            List<? extends TypeMirror> directSupertypes = types.directSupertypes(declaredFieldType);
+            assert!directSupertypes.isEmpty();
+            declaredOptionValueType = (DeclaredType) directSupertypes.get(0);
+        }
+
+        assert!declaredOptionValueType.getTypeArguments().isEmpty();
+        String optionType = declaredOptionValueType.getTypeArguments().get(0).toString();
+        if (optionType.startsWith("java.lang.")) {
+            optionType = optionType.substring("java.lang.".length());
+        }
+
+        Element enclosing = element.getEnclosingElement();
+        String declaringClass = "";
+        String separator = "";
+        Set<Element> originatingElementsList = info.originatingElements;
+        originatingElementsList.add(field);
+        while (enclosing != null) {
+            if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) {
+                if (enclosing.getModifiers().contains(Modifier.PRIVATE)) {
+                    String msg = String.format("Option field cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing);
+                    processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
+                    return;
+                }
+                originatingElementsList.add(enclosing);
+                declaringClass = enclosing.getSimpleName() + separator + declaringClass;
+                separator = ".";
+            } else {
+                assert enclosing.getKind() == ElementKind.PACKAGE;
+            }
+            enclosing = enclosing.getEnclosingElement();
+        }
+
+        info.options.add(new OptionInfo(optionName, help, optionType, declaringClass, field));
+    }
+
+    private void createFiles(OptionsInfo info) {
+        String pkg = ((PackageElement) info.topDeclaringType.getEnclosingElement()).getQualifiedName().toString();
+        Name topDeclaringClass = info.topDeclaringType.getSimpleName();
+        Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]);
+
+        createOptionsDescriptorsFile(info, pkg, topDeclaringClass, originatingElements);
+    }
+
+    private void createOptionsDescriptorsFile(OptionsInfo info, String pkg, Name topDeclaringClass, Element[] originatingElements) {
+        String optionsClassName = topDeclaringClass + "_" + OptionDescriptors.class.getSimpleName();
+
+        Filer filer = processingEnv.getFiler();
+        try (PrintWriter out = createSourceFile(pkg, optionsClassName, filer, originatingElements)) {
+
+            out.println("// CheckStyle: stop header check");
+            out.println("// CheckStyle: stop line length check");
+            out.println("// GENERATED CONTENT - DO NOT EDIT");
+            out.println("// Source: " + topDeclaringClass + ".java");
+            out.println("package " + pkg + ";");
+            out.println("");
+            out.println("import java.util.*;");
+            out.println("import " + OptionDescriptors.class.getPackage().getName() + ".*;");
+            out.println("");
+            out.println("public class " + optionsClassName + " implements " + OptionDescriptors.class.getSimpleName() + " {");
+
+            String desc = OptionDescriptor.class.getSimpleName();
+
+            boolean needPrivateFieldAccessor = false;
+            int i = 0;
+            Collections.sort(info.options);
+
+            out.println("    @Override");
+            out.println("    public OptionDescriptor get(String value) {");
+            out.println("        // CheckStyle: stop line length check");
+            if (info.options.size() == 1) {
+                out.println("        if (value.equals(\"" + info.options.get(0).name + "\")) {");
+            } else {
+                out.println("        switch (value) {");
+            }
+            for (OptionInfo option : info.options) {
+                String name = option.name;
+                String optionValue;
+                if (option.field.getModifiers().contains(Modifier.PRIVATE)) {
+                    needPrivateFieldAccessor = true;
+                    optionValue = "field(" + option.declaringClass + ".class, \"" + option.field.getSimpleName() + "\")";
+                } else {
+                    optionValue = option.declaringClass + "." + option.field.getSimpleName();
+                }
+                String type = option.type;
+                String help = option.help;
+                String declaringClass = option.declaringClass;
+                Name fieldName = option.field.getSimpleName();
+                if (info.options.size() == 1) {
+                    out.printf("            return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue);
+                } else {
+                    out.printf("            case \"" + name + "\": return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName,
+                                    optionValue);
+                }
+            }
+            out.println("        }");
+            out.println("        // CheckStyle: resume line length check");
+            out.println("        return null;");
+            out.println("    }");
+            out.println();
+            out.println("    @Override");
+            out.println("    public Iterator<" + desc + "> iterator() {");
+            out.println("        // CheckStyle: stop line length check");
+            out.println("        List<" + desc + "> options = Arrays.asList(");
+            for (OptionInfo option : info.options) {
+                String optionValue;
+                if (option.field.getModifiers().contains(Modifier.PRIVATE)) {
+                    needPrivateFieldAccessor = true;
+                    optionValue = "field(" + option.declaringClass + ".class, \"" + option.field.getSimpleName() + "\")";
+                } else {
+                    optionValue = option.declaringClass + "." + option.field.getSimpleName();
+                }
+                String name = option.name;
+                String type = option.type;
+                String help = option.help;
+                String declaringClass = option.declaringClass;
+                Name fieldName = option.field.getSimpleName();
+                String comma = i == info.options.size() - 1 ? "" : ",";
+                out.printf("            %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s)%s\n", desc, name, type, help, declaringClass, fieldName, optionValue, comma);
+                i++;
+            }
+            out.println("        );");
+            out.println("        // CheckStyle: resume line length check");
+            out.println("        return options.iterator();");
+            out.println("    }");
+            if (needPrivateFieldAccessor) {
+                out.println("    private static " + OptionValue.class.getSimpleName() + "<?> field(Class<?> declaringClass, String fieldName) {");
+                out.println("        try {");
+                out.println("            java.lang.reflect.Field field = declaringClass.getDeclaredField(fieldName);");
+                out.println("            field.setAccessible(true);");
+                out.println("            return (" + OptionValue.class.getSimpleName() + "<?>) field.get(null);");
+                out.println("        } catch (Exception e) {");
+                out.println("            throw (InternalError) new InternalError().initCause(e);");
+                out.println("        }");
+                out.println("    }");
+            }
+            out.println("}");
+        }
+
+        try {
+            createOptionsFile(pkg, topDeclaringClass.toString(), originatingElements);
+        } catch (IOException e) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), info.topDeclaringType);
+        }
+    }
+
+    private void createOptionsFile(String pkg, String relativeName, Element... originatingElements) throws IOException {
+        String filename = "META-INF/jvmci.options/" + pkg + "." + relativeName;
+        FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements);
+        PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
+        writer.close();
+    }
+
+    protected PrintWriter createSourceFile(String pkg, String relativeName, Filer filer, Element... originatingElements) {
+        try {
+            // Ensure Unix line endings to comply with code style guide checked by Checkstyle
+            JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, originatingElements);
+            return new PrintWriter(sourceFile.openWriter()) {
+
+                @Override
+                public void println() {
+                    print("\n");
+                }
+            };
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static class OptionInfo implements Comparable<OptionInfo> {
+
+        final String name;
+        final String help;
+        final String type;
+        final String declaringClass;
+        final VariableElement field;
+
+        public OptionInfo(String name, String help, String type, String declaringClass, VariableElement field) {
+            this.name = name;
+            this.help = help;
+            this.type = type;
+            this.declaringClass = declaringClass;
+            this.field = field;
+        }
+
+        @Override
+        public int compareTo(OptionInfo other) {
+            return name.compareTo(other.name);
+        }
+
+        @Override
+        public String toString() {
+            return declaringClass + "." + field;
+        }
+    }
+
+    static class OptionsInfo {
+
+        final Element topDeclaringType;
+        final List<OptionInfo> options = new ArrayList<>();
+        final Set<Element> originatingElements = new HashSet<>();
+
+        public OptionsInfo(Element topDeclaringType) {
+            this.topDeclaringType = topDeclaringType;
+        }
+    }
+
+    private static Element topDeclaringType(Element element) {
+        Element enclosing = element.getEnclosingElement();
+        if (enclosing == null || enclosing.getKind() == ElementKind.PACKAGE) {
+            assert element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.INTERFACE;
+            return element;
+        }
+        return topDeclaringType(enclosing);
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            return true;
+        }
+
+        Map<Element, OptionsInfo> map = new HashMap<>();
+        for (Element element : roundEnv.getElementsAnnotatedWith(Option.class)) {
+            if (!processed.contains(element)) {
+                processed.add(element);
+                Element topDeclaringType = topDeclaringType(element);
+                OptionsInfo options = map.get(topDeclaringType);
+                if (options == null) {
+                    options = new OptionsInfo(topDeclaringType);
+                    map.put(topDeclaringType, options);
+                }
+                processElement(element, options);
+            }
+        }
+
+        boolean ok = true;
+        Map<String, OptionInfo> uniqueness = new HashMap<>();
+        for (OptionsInfo info : map.values()) {
+            for (OptionInfo option : info.options) {
+                OptionInfo conflict = uniqueness.put(option.name, option);
+                if (conflict != null) {
+                    processingEnv.getMessager().printMessage(Kind.ERROR, "Duplicate option names for " + option + " and " + conflict, option.field);
+                    ok = false;
+                }
+            }
+        }
+
+        if (ok) {
+            for (OptionsInfo info : map.values()) {
+                createFiles(info);
+            }
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/DerivedOptionValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.options;
+
+import java.io.*;
+import java.util.function.*;
+
+import jdk.vm.ci.options.OptionValue.*;
+
+/**
+ * A cached value that needs to be recomputed when an option changes.
+ */
+public class DerivedOptionValue<T> {
+
+    public interface OptionSupplier<T> extends Supplier<T>, Serializable {
+    }
+
+    private final T initialValue;
+    private final OptionSupplier<T> supplier;
+
+    public DerivedOptionValue(OptionSupplier<T> supplier) {
+        this.supplier = supplier;
+        assert OptionValue.getOverrideScope() == null : "derived option value should be initialized outside any override scope";
+        this.initialValue = createValue();
+    }
+
+    public T getValue() {
+        OverrideScope overrideScope = OptionValue.getOverrideScope();
+        if (overrideScope != null) {
+            return overrideScope.getDerived(this);
+        } else {
+            return initialValue;
+        }
+    }
+
+    T createValue() {
+        return supplier.get();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/JVMCIJarsOptionDescriptorsProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.options;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
+
+import jdk.vm.ci.options.OptionsParser.*;
+
+/**
+ * Access to the {@link OptionDescriptors} declared by
+ * {@code META-INF/services/jdk.vm.ci.options.OptionDescriptors} files in {@code
+ * <jre>/lib/jvmci/*.jar}.
+ */
+class JVMCIJarsOptionDescriptorsProvider implements OptionDescriptorsProvider {
+
+    static final String OptionDescriptorsServiceFile = "META-INF/services/" + OptionDescriptors.class.getName();
+
+    private final Iterator<File> jars;
+    private final List<OptionDescriptors> optionsDescriptorsList;
+
+    JVMCIJarsOptionDescriptorsProvider() {
+        List<File> jarsList = findJVMCIJars();
+        this.jars = jarsList.iterator();
+        this.optionsDescriptorsList = new ArrayList<>(jarsList.size() * 3);
+    }
+
+    /**
+     * Finds the list of JVMCI jars.
+     */
+    private static List<File> findJVMCIJars() {
+        File javaHome = new File(System.getProperty("java.home"));
+        File lib = new File(javaHome, "lib");
+        File jvmci = new File(lib, "jvmci");
+
+        List<File> jarFiles = new ArrayList<>();
+        if (jvmci.exists()) {
+            for (String fileName : jvmci.list()) {
+                if (fileName.endsWith(".jar")) {
+                    File file = new File(jvmci, fileName);
+                    if (file.isDirectory()) {
+                        continue;
+                    }
+                    jarFiles.add(file);
+                }
+            }
+        }
+        return jarFiles;
+    }
+
+    public OptionDescriptor get(String name) {
+        // Look up loaded option descriptors first
+        for (OptionDescriptors optionDescriptors : optionsDescriptorsList) {
+            OptionDescriptor desc = optionDescriptors.get(name);
+            if (desc != null) {
+                return desc;
+            }
+        }
+        while (jars.hasNext()) {
+            File path = jars.next();
+            try (JarFile jar = new JarFile(path)) {
+                ZipEntry entry = jar.getEntry(OptionDescriptorsServiceFile);
+                if (entry != null) {
+                    BufferedReader br = new BufferedReader(new InputStreamReader(jar.getInputStream(entry)));
+                    String line = null;
+                    OptionDescriptor desc = null;
+                    while ((line = br.readLine()) != null) {
+                        OptionDescriptors options;
+                        try {
+                            options = (OptionDescriptors) Class.forName(line).newInstance();
+                            optionsDescriptorsList.add(options);
+                            if (desc == null) {
+                                desc = options.get(name);
+                            }
+                        } catch (Exception e) {
+                            throw new InternalError("Error instantiating class " + line + " read from " + path, e);
+                        }
+                    }
+                    if (desc != null) {
+                        return desc;
+                    }
+                }
+            } catch (IOException e) {
+                throw new InternalError("Error reading " + path, e);
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/NestedBooleanOptionValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, 2015, 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 jdk.vm.ci.options;
+
+/**
+ * A nested Boolean {@link OptionValue} that can be overridden by a {@link #masterOption master
+ * option}.
+ * <p>
+ * <li>If the option is present on the command line the specified value is used.
+ * <li>Otherwise {@link #getValue()} depends on the {@link #masterOption} and evaluates as follows:
+ * <ul>
+ * <li>If {@link #masterOption} is set, this value equals to {@link #initialValue}.
+ * <li>Otherwise, if {@link #masterOption} is {@code false}, this option is {@code false}.
+ */
+public class NestedBooleanOptionValue extends OptionValue<Boolean> {
+    private final OptionValue<Boolean> masterOption;
+    private final Boolean initialValue;
+
+    public NestedBooleanOptionValue(OptionValue<Boolean> masterOption, Boolean initialValue) {
+        super(null);
+        this.masterOption = masterOption;
+        this.initialValue = initialValue;
+    }
+
+    public OptionValue<Boolean> getMasterOption() {
+        return masterOption;
+    }
+
+    @Override
+    public Boolean getValue() {
+        Boolean v = super.getValue();
+        if (v == null) {
+            return initialValue && masterOption.getValue();
+        }
+        return v;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/Option.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,52 @@
+/*
+ * 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 jdk.vm.ci.options;
+
+import java.lang.annotation.*;
+
+/**
+ * Describes the attributes of an option whose {@link OptionValue value} is in a static field
+ * annotated by this annotation type.
+ *
+ * @see OptionDescriptor
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.FIELD)
+public @interface Option {
+
+    /**
+     * Gets a help message for the option. New lines can be embedded in the message with
+     * {@code "%n"}.
+     */
+    String help();
+
+    /**
+     * The name of the option. By default, the name of the annotated field should be used.
+     */
+    String name() default "";
+
+    /**
+     * Specifies the type of the option.
+     */
+    OptionType type() default OptionType.Debug;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionDescriptor.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,102 @@
+/*
+ * 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 jdk.vm.ci.options;
+
+/**
+ * Describes the attributes of a static field {@linkplain Option option} and provides access to its
+ * {@linkplain OptionValue value}.
+ */
+public final class OptionDescriptor {
+
+    protected final String name;
+    protected final Class<?> type;
+    protected final String help;
+    protected final OptionValue<?> option;
+    protected final Class<?> declaringClass;
+    protected final String fieldName;
+
+    public static OptionDescriptor create(String name, Class<?> type, String help, Class<?> declaringClass, String fieldName, OptionValue<?> option) {
+        OptionDescriptor result = option.getDescriptor();
+        if (result == null) {
+            result = new OptionDescriptor(name, type, help, declaringClass, fieldName, option);
+            option.setDescriptor(result);
+        }
+        assert result.name.equals(name) && result.type == type && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.option == option;
+        return result;
+    }
+
+    private OptionDescriptor(String name, Class<?> type, String help, Class<?> declaringClass, String fieldName, OptionValue<?> option) {
+        this.name = name;
+        this.type = type;
+        this.help = help;
+        this.option = option;
+        this.declaringClass = declaringClass;
+        this.fieldName = fieldName;
+        assert !type.isPrimitive() : "must used boxed type instead of " + type;
+    }
+
+    /**
+     * Gets the type of values stored in the option. This will be the boxed type for a primitive
+     * option.
+     */
+    public Class<?> getType() {
+        return type;
+    }
+
+    /**
+     * Gets a descriptive help message for the option.
+     */
+    public String getHelp() {
+        return help;
+    }
+
+    /**
+     * Gets the name of the option. It's up to the client of this object how to use the name to get
+     * a user specified value for the option from the environment.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Gets the boxed option value.
+     */
+    public OptionValue<?> getOptionValue() {
+        return option;
+    }
+
+    public Class<?> getDeclaringClass() {
+        return declaringClass;
+    }
+
+    public String getFieldName() {
+        return fieldName;
+    }
+
+    /**
+     * Gets a description of the location where this option is stored.
+     */
+    public String getLocation() {
+        return getDeclaringClass().getName() + "." + getFieldName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionDescriptors.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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 jdk.vm.ci.options;
+
+/**
+ * An interface to a set of {@link OptionDescriptor}s.
+ */
+public interface OptionDescriptors extends Iterable<OptionDescriptor> {
+    /**
+     * Gets the {@link OptionDescriptor} matching a given option name or {@code null} if this option
+     * descriptor set doesn't contain a matching option.
+     */
+    OptionDescriptor get(String value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.options;
+
+/**
+ * Classifies JVMCI options in several categories depending on who this option is relevant for.
+ *
+ */
+public enum OptionType {
+    /**
+     * An option common for users to apply.
+     */
+    User,
+
+    /**
+     * An option only relevant in corner cases and for fine-tuning.
+     */
+    Expert,
+
+    /**
+     * An option only relevant when debugging the compiler.
+     */
+    Debug
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,478 @@
+/*
+ * 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 jdk.vm.ci.options;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * An option value.
+ */
+public class OptionValue<T> {
+    /**
+     * Temporarily changes the value for an option. The {@linkplain OptionValue#getValue() value} of
+     * {@code option} is set to {@code value} until {@link OverrideScope#close()} is called on the
+     * object returned by this method.
+     * <p>
+     * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
+     * used:
+     *
+     * <pre>
+     * try (OverrideScope s = OptionValue.override(myOption, myValue) {
+     *     // code that depends on myOption == myValue
+     * }
+     * </pre>
+     */
+    public static OverrideScope override(OptionValue<?> option, Object value) {
+        OverrideScope current = getOverrideScope();
+        if (current == null) {
+            if (!value.equals(option.getValue())) {
+                return new SingleOverrideScope(option, value);
+            }
+            Map<OptionValue<?>, Object> overrides = Collections.emptyMap();
+            return new MultipleOverridesScope(current, overrides);
+        }
+        return new MultipleOverridesScope(current, option, value);
+    }
+
+    /**
+     * Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue()
+     * value} of each {@code option} in {@code overrides} is set to the corresponding {@code value}
+     * in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by
+     * this method.
+     * <p>
+     * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
+     * used:
+     *
+     * <pre>
+     * Map&lt;OptionValue, Object&gt; overrides = new HashMap&lt;&gt;();
+     * overrides.put(myOption1, myValue1);
+     * overrides.put(myOption2, myValue2);
+     * try (OverrideScope s = OptionValue.override(overrides) {
+     *     // code that depends on myOption == myValue
+     * }
+     * </pre>
+     */
+    public static OverrideScope override(Map<OptionValue<?>, Object> overrides) {
+        OverrideScope current = getOverrideScope();
+        if (current == null && overrides.size() == 1) {
+            Entry<OptionValue<?>, Object> single = overrides.entrySet().iterator().next();
+            OptionValue<?> option = single.getKey();
+            Object overrideValue = single.getValue();
+            if (!overrideValue.equals(option.getValue())) {
+                return new SingleOverrideScope(option, overrideValue);
+            }
+        }
+        return new MultipleOverridesScope(current, overrides);
+    }
+
+    /**
+     * Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue()
+     * value} of each {@code option} in {@code overrides} is set to the corresponding {@code value}
+     * in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by
+     * this method.
+     * <p>
+     * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
+     * used:
+     *
+     * <pre>
+     * try (OverrideScope s = OptionValue.override(myOption1, myValue1, myOption2, myValue2) {
+     *     // code that depends on myOption == myValue
+     * }
+     * </pre>
+     *
+     * @param overrides overrides in the form {@code [option1, override1, option2, override2, ...]}
+     */
+    public static OverrideScope override(Object... overrides) {
+        OverrideScope current = getOverrideScope();
+        if (current == null && overrides.length == 2) {
+            OptionValue<?> option = (OptionValue<?>) overrides[0];
+            Object overrideValue = overrides[1];
+            if (!overrideValue.equals(option.getValue())) {
+                return new SingleOverrideScope(option, overrideValue);
+            }
+        }
+        Map<OptionValue<?>, Object> map = Collections.emptyMap();
+        for (int i = 0; i < overrides.length; i += 2) {
+            OptionValue<?> option = (OptionValue<?>) overrides[i];
+            Object overrideValue = overrides[i + 1];
+            if (!overrideValue.equals(option.getValue())) {
+                if (map.isEmpty()) {
+                    map = new HashMap<>();
+                }
+                map.put(option, overrideValue);
+            }
+        }
+        return new MultipleOverridesScope(current, map);
+    }
+
+    private static final ThreadLocal<OverrideScope> overrideScopeTL = new ThreadLocal<>();
+
+    protected static OverrideScope getOverrideScope() {
+        return overrideScopeTL.get();
+    }
+
+    protected static void setOverrideScope(OverrideScope overrideScope) {
+        overrideScopeTL.set(overrideScope);
+    }
+
+    private T defaultValue;
+
+    /**
+     * The raw option value.
+     */
+    protected T value;
+
+    private OptionDescriptor descriptor;
+
+    private long reads;
+    private OptionValue<?> next;
+    private static OptionValue<?> head;
+
+    private static final boolean ShowReadsHistogram = Boolean.getBoolean("jvmci.showOptionValueReadsHistogram");
+
+    private static void addToHistogram(OptionValue<?> option) {
+        if (ShowReadsHistogram) {
+            synchronized (OptionValue.class) {
+                option.next = head;
+                head = option;
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public OptionValue(T value) {
+        this.defaultValue = value;
+        this.value = (T) DEFAULT;
+        addToHistogram(this);
+    }
+
+    private static final Object DEFAULT = "DEFAULT";
+    private static final Object UNINITIALIZED = "UNINITIALIZED";
+
+    /**
+     * Creates an uninitialized option value for a subclass that initializes itself
+     * {@link #defaultValue() lazily}.
+     */
+    @SuppressWarnings("unchecked")
+    protected OptionValue() {
+        this.defaultValue = (T) UNINITIALIZED;
+        this.value = (T) DEFAULT;
+        addToHistogram(this);
+    }
+
+    /**
+     * Lazy initialization of default value.
+     */
+    protected T defaultValue() {
+        throw new InternalError("Option without a default value value must override defaultValue()");
+    }
+
+    /**
+     * Sets the descriptor for this option.
+     */
+    public void setDescriptor(OptionDescriptor descriptor) {
+        assert this.descriptor == null : "Overwriting existing descriptor";
+        this.descriptor = descriptor;
+    }
+
+    /**
+     * Returns the descriptor for this option, if it has been set by
+     * {@link #setDescriptor(OptionDescriptor)}.
+     */
+    public OptionDescriptor getDescriptor() {
+        return descriptor;
+    }
+
+    /**
+     * Gets the name of this option. The name for an option value with a null
+     * {@linkplain #setDescriptor(OptionDescriptor) descriptor} is the value of
+     * {@link Object#toString()}.
+     */
+    public String getName() {
+        return descriptor == null ? super.toString() : (descriptor.getDeclaringClass().getName() + "." + descriptor.getName());
+    }
+
+    @Override
+    public String toString() {
+        return getName() + "=" + getValue();
+    }
+
+    /**
+     * The initial value specified in source code. The returned value is not affected by calls to
+     * {@link #setValue(Object)} or registering {@link OverrideScope}s. Therefore, it is also not
+     * affected by options set on the command line.
+     */
+    public T getDefaultValue() {
+        if (defaultValue == UNINITIALIZED) {
+            defaultValue = defaultValue();
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Returns true if the option has the same value that was set in the source code.
+     */
+    public boolean hasDefaultValue() {
+        if (!(this instanceof StableOptionValue)) {
+            getValue(); // ensure initialized
+        }
+        return value == DEFAULT || Objects.equals(value, getDefaultValue());
+    }
+
+    /**
+     * Gets the value of this option.
+     */
+    public T getValue() {
+        if (ShowReadsHistogram) {
+            reads++;
+        }
+        if (!(this instanceof StableOptionValue)) {
+            OverrideScope overrideScope = getOverrideScope();
+            if (overrideScope != null) {
+                T override = overrideScope.getOverride(this);
+                if (override != null) {
+                    return override;
+                }
+            }
+        }
+        if (value != DEFAULT) {
+            return value;
+        } else {
+            return getDefaultValue();
+        }
+    }
+
+    /**
+     * Gets the values of this option including overridden values.
+     *
+     * @param c the collection to which the values are added. If null, one is allocated.
+     * @return the collection to which the values were added in order from most overridden to
+     *         current value
+     */
+    @SuppressWarnings("unchecked")
+    public Collection<T> getValues(Collection<T> c) {
+        Collection<T> values = c == null ? new ArrayList<>() : c;
+        if (!(this instanceof StableOptionValue)) {
+            OverrideScope overrideScope = getOverrideScope();
+            if (overrideScope != null) {
+                overrideScope.getOverrides(this, (Collection<Object>) values);
+            }
+        }
+        if (value != DEFAULT) {
+            values.add(value);
+        } else {
+            values.add(getDefaultValue());
+        }
+        return values;
+    }
+
+    /**
+     * Sets the value of this option.
+     */
+    @SuppressWarnings("unchecked")
+    public void setValue(Object v) {
+        this.value = (T) v;
+    }
+
+    /**
+     * An object whose {@link #close()} method reverts the option value overriding initiated by
+     * {@link OptionValue#override(OptionValue, Object)} or {@link OptionValue#override(Map)}.
+     */
+    public abstract static class OverrideScope implements AutoCloseable {
+
+        private Map<DerivedOptionValue<?>, Object> derivedCache = null;
+
+        public <T> T getDerived(DerivedOptionValue<T> key) {
+            if (derivedCache == null) {
+                derivedCache = new HashMap<>();
+            }
+            @SuppressWarnings("unchecked")
+            T ret = (T) derivedCache.get(key);
+            if (ret == null) {
+                ret = key.createValue();
+                derivedCache.put(key, ret);
+            }
+            return ret;
+        }
+
+        abstract void addToInherited(Map<OptionValue<?>, Object> inherited);
+
+        abstract <T> T getOverride(OptionValue<T> option);
+
+        abstract void getOverrides(OptionValue<?> option, Collection<Object> c);
+
+        public abstract void close();
+    }
+
+    static class SingleOverrideScope extends OverrideScope {
+
+        private final OptionValue<?> option;
+        private final Object value;
+
+        public SingleOverrideScope(OptionValue<?> option, Object value) {
+            if (option instanceof StableOptionValue) {
+                throw new IllegalArgumentException("Cannot override stable option " + option);
+            }
+            this.option = option;
+            this.value = value;
+            setOverrideScope(this);
+        }
+
+        @Override
+        void addToInherited(Map<OptionValue<?>, Object> inherited) {
+            inherited.put(option, value);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        <T> T getOverride(OptionValue<T> key) {
+            if (key == this.option) {
+                return (T) value;
+            }
+            return null;
+        }
+
+        @Override
+        void getOverrides(OptionValue<?> key, Collection<Object> c) {
+            if (key == this.option) {
+                c.add(value);
+            }
+        }
+
+        @Override
+        public void close() {
+            setOverrideScope(null);
+        }
+    }
+
+    static class MultipleOverridesScope extends OverrideScope {
+        final OverrideScope parent;
+        final Map<OptionValue<?>, Object> overrides;
+
+        public MultipleOverridesScope(OverrideScope parent, OptionValue<?> option, Object value) {
+            this.parent = parent;
+            this.overrides = new HashMap<>();
+            if (parent != null) {
+                parent.addToInherited(overrides);
+            }
+            if (option instanceof StableOptionValue) {
+                throw new IllegalArgumentException("Cannot override stable option " + option);
+            }
+            if (!value.equals(option.getValue())) {
+                this.overrides.put(option, value);
+            }
+            if (!overrides.isEmpty()) {
+                setOverrideScope(this);
+            }
+        }
+
+        MultipleOverridesScope(OverrideScope parent, Map<OptionValue<?>, Object> overrides) {
+            this.parent = parent;
+            if (overrides.isEmpty() && parent == null) {
+                this.overrides = Collections.emptyMap();
+                return;
+            }
+            this.overrides = new HashMap<>();
+            if (parent != null) {
+                parent.addToInherited(this.overrides);
+            }
+            for (Map.Entry<OptionValue<?>, Object> e : overrides.entrySet()) {
+                OptionValue<?> option = e.getKey();
+                if (option instanceof StableOptionValue) {
+                    throw new IllegalArgumentException("Cannot override stable option " + option);
+                }
+                if (!e.getValue().equals(option.getValue())) {
+                    this.overrides.put(option, e.getValue());
+                }
+            }
+            if (!this.overrides.isEmpty()) {
+                setOverrideScope(this);
+            }
+        }
+
+        @Override
+        void addToInherited(Map<OptionValue<?>, Object> inherited) {
+            if (parent != null) {
+                parent.addToInherited(inherited);
+            }
+            inherited.putAll(overrides);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        <T> T getOverride(OptionValue<T> option) {
+            return (T) overrides.get(option);
+        }
+
+        @Override
+        void getOverrides(OptionValue<?> option, Collection<Object> c) {
+            Object v = overrides.get(option);
+            if (v != null) {
+                c.add(v);
+            }
+            if (parent != null) {
+                parent.getOverrides(option, c);
+            }
+        }
+
+        @Override
+        public void close() {
+            if (!overrides.isEmpty()) {
+                setOverrideScope(parent);
+            }
+        }
+    }
+
+    static {
+        if (ShowReadsHistogram) {
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                @Override
+                public void run() {
+                    ArrayList<OptionValue<?>> options = new ArrayList<>();
+                    for (OptionValue<?> option = head; option != null; option = option.next) {
+                        options.add(option);
+                    }
+                    Collections.sort(options, new Comparator<OptionValue<?>>() {
+
+                        public int compare(OptionValue<?> o1, OptionValue<?> o2) {
+                            if (o1.reads < o2.reads) {
+                                return -1;
+                            } else if (o1.reads > o2.reads) {
+                                return 1;
+                            } else {
+                                return o1.getName().compareTo(o2.getName());
+                            }
+                        }
+                    });
+                    PrintStream out = System.out;
+                    out.println("=== OptionValue reads histogram ===");
+                    for (OptionValue<?> option : options) {
+                        out.println(option.reads + "\t" + option);
+                    }
+                }
+            });
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsLoader.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.options;
+
+import java.util.*;
+
+/**
+ * Helper class used to load option descriptors. Only to be used in the slow-path.
+ */
+public class OptionsLoader {
+    public static final SortedMap<String, OptionDescriptor> options = new TreeMap<>();
+
+    /**
+     * Initializes {@link #options} from {@link Options} services.
+     */
+    static {
+        for (OptionDescriptors opts : ServiceLoader.load(OptionDescriptors.class, OptionsLoader.class.getClassLoader())) {
+            for (OptionDescriptor desc : opts) {
+                String name = desc.getName();
+                OptionDescriptor existing = options.put(name, desc);
+                assert existing == null : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsParser.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.options;
+
+import static jdk.vm.ci.inittimer.InitTimer.*;
+
+import java.io.*;
+import java.util.*;
+
+import jdk.vm.ci.inittimer.*;
+
+/**
+ * This class contains methods for parsing JVMCI options and matching them against a set of
+ * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded from JVMCI jars, either
+ * {@linkplain JVMCIJarsOptionDescriptorsProvider directly} or via a {@link ServiceLoader}.
+ */
+public class OptionsParser {
+
+    private static final OptionValue<Boolean> PrintFlags = new OptionValue<>(false);
+
+    /**
+     * A service for looking up {@link OptionDescriptor}s.
+     */
+    public interface OptionDescriptorsProvider {
+        /**
+         * Gets the {@link OptionDescriptor} matching a given option {@linkplain Option#name() name}
+         * or null if no option of that name is provided by this object.
+         */
+        OptionDescriptor get(String name);
+    }
+
+    public interface OptionConsumer {
+        void set(OptionDescriptor desc, Object value);
+    }
+
+    /**
+     * Parses the options in {@code <jre>/lib/jvmci/options} if {@code parseOptionsFile == true} and
+     * the file exists followed by the JVMCI options in {@code options} if {@code options != null}.
+     *
+     * Called from VM. This method has an object return type to allow it to be called with a VM
+     * utility function used to call other static initialization methods.
+     *
+     * @param options JVMCI options as serialized (name, value) pairs
+     * @param parseOptionsFile specifies whether to look for and parse
+     *            {@code <jre>/lib/jvmci/options}
+     */
+    @SuppressWarnings("try")
+    public static Boolean parseOptionsFromVM(String[] options, boolean parseOptionsFile) {
+        try (InitTimer t = timer("ParseOptions")) {
+            JVMCIJarsOptionDescriptorsProvider odp = new JVMCIJarsOptionDescriptorsProvider();
+
+            if (parseOptionsFile) {
+                File javaHome = new File(System.getProperty("java.home"));
+                File lib = new File(javaHome, "lib");
+                File jvmci = new File(lib, "jvmci");
+                File jvmciOptions = new File(jvmci, "options");
+                if (jvmciOptions.exists()) {
+                    try (BufferedReader br = new BufferedReader(new FileReader(jvmciOptions))) {
+                        String optionSetting = null;
+                        int lineNo = 1;
+                        while ((optionSetting = br.readLine()) != null) {
+                            if (!optionSetting.isEmpty() && optionSetting.charAt(0) != '#') {
+                                try {
+                                    parseOptionSetting(optionSetting, null, odp);
+                                } catch (Throwable e) {
+                                    throw new InternalError("Error parsing " + jvmciOptions + ", line " + lineNo, e);
+                                }
+                            }
+                            lineNo++;
+                        }
+                    } catch (IOException e) {
+                        throw new InternalError("Error reading " + jvmciOptions, e);
+                    }
+                }
+            }
+
+            if (options != null) {
+                assert options.length % 2 == 0;
+                for (int i = 0; i < options.length / 2; i++) {
+                    String name = options[i * 2];
+                    String value = options[i * 2 + 1];
+                    parseOption(OptionsLoader.options, name, value, null, odp);
+                }
+            }
+        }
+        return Boolean.TRUE;
+    }
+
+    /**
+     * Parses a given option setting.
+     *
+     * @param optionSetting a string matching the pattern {@code <name>=<value>}
+     * @param setter the object to notify of the parsed option and value
+     */
+    public static void parseOptionSetting(String optionSetting, OptionConsumer setter, OptionDescriptorsProvider odp) {
+        int eqIndex = optionSetting.indexOf('=');
+        if (eqIndex == -1) {
+            throw new InternalError("Option setting has does not match the pattern <name>=<value>: " + optionSetting);
+        }
+        String name = optionSetting.substring(0, eqIndex);
+        String value = optionSetting.substring(eqIndex + 1);
+        parseOption(OptionsLoader.options, name, value, setter, odp);
+    }
+
+    /**
+     * Parses a given option name and value.
+     *
+     * @param options
+     * @param name the option name
+     * @param valueString the option value as a string
+     * @param setter the object to notify of the parsed option and value
+     * @param odp
+     *
+     * @throws IllegalArgumentException if there's a problem parsing {@code option}
+     */
+    public static void parseOption(SortedMap<String, OptionDescriptor> options, String name, String valueString, OptionConsumer setter, OptionDescriptorsProvider odp) {
+        OptionDescriptor desc = options.get(name);
+        if (desc == null && odp != null) {
+            desc = odp.get(name);
+        }
+        if (desc == null && name.equals("PrintFlags")) {
+            desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags);
+        }
+        if (desc == null) {
+            List<OptionDescriptor> matches = fuzzyMatch(options, name);
+            Formatter msg = new Formatter();
+            msg.format("Could not find option %s", name);
+            if (!matches.isEmpty()) {
+                msg.format("%nDid you mean one of the following?");
+                for (OptionDescriptor match : matches) {
+                    msg.format("%n    %s=<value>", match.getName());
+                }
+            }
+            throw new IllegalArgumentException(msg.toString());
+        }
+
+        Class<?> optionType = desc.getType();
+        Object value;
+        if (optionType == Boolean.class) {
+            if ("true".equals(valueString)) {
+                value = Boolean.TRUE;
+            } else if ("false".equals(valueString)) {
+                value = Boolean.FALSE;
+            } else {
+                throw new IllegalArgumentException("Boolean option '" + name + "' must have value \"true\" or \"false\", not \"" + valueString + "\"");
+            }
+        } else if (optionType == Float.class) {
+            value = Float.parseFloat(valueString);
+        } else if (optionType == Double.class) {
+            value = Double.parseDouble(valueString);
+        } else if (optionType == Integer.class) {
+            value = Integer.valueOf((int) parseLong(valueString));
+        } else if (optionType == Long.class) {
+            value = Long.valueOf(parseLong(valueString));
+        } else if (optionType == String.class) {
+            value = valueString;
+        } else {
+            throw new IllegalArgumentException("Wrong value for option '" + name + "'");
+        }
+        if (setter == null) {
+            desc.getOptionValue().setValue(value);
+        } else {
+            setter.set(desc, value);
+        }
+
+        if (PrintFlags.getValue()) {
+            printFlags(options, "JVMCI", System.out);
+            System.exit(0);
+        }
+    }
+
+    private static long parseLong(String v) {
+        String valueString = v.toLowerCase();
+        long scale = 1;
+        if (valueString.endsWith("k")) {
+            scale = 1024L;
+        } else if (valueString.endsWith("m")) {
+            scale = 1024L * 1024L;
+        } else if (valueString.endsWith("g")) {
+            scale = 1024L * 1024L * 1024L;
+        } else if (valueString.endsWith("t")) {
+            scale = 1024L * 1024L * 1024L * 1024L;
+        }
+
+        if (scale != 1) {
+            /* Remove trailing scale character. */
+            valueString = valueString.substring(0, valueString.length() - 1);
+        }
+
+        return Long.parseLong(valueString) * scale;
+    }
+
+    /**
+     * Wraps some given text to one or more lines of a given maximum width.
+     *
+     * @param text text to wrap
+     * @param width maximum width of an output line, exception for words in {@code text} longer than
+     *            this value
+     * @return {@code text} broken into lines
+     */
+    private static List<String> wrap(String text, int width) {
+        List<String> lines = Collections.singletonList(text);
+        if (text.length() > width) {
+            String[] chunks = text.split("\\s+");
+            lines = new ArrayList<>();
+            StringBuilder line = new StringBuilder();
+            for (String chunk : chunks) {
+                if (line.length() + chunk.length() > width) {
+                    lines.add(line.toString());
+                    line.setLength(0);
+                }
+                if (line.length() != 0) {
+                    line.append(' ');
+                }
+                String[] embeddedLines = chunk.split("%n", -2);
+                if (embeddedLines.length == 1) {
+                    line.append(chunk);
+                } else {
+                    for (int i = 0; i < embeddedLines.length; i++) {
+                        line.append(embeddedLines[i]);
+                        if (i < embeddedLines.length - 1) {
+                            lines.add(line.toString());
+                            line.setLength(0);
+                        }
+                    }
+                }
+            }
+            if (line.length() != 0) {
+                lines.add(line.toString());
+            }
+        }
+        return lines;
+    }
+
+    public static void printFlags(SortedMap<String, OptionDescriptor> sortedOptions, String prefix, PrintStream out) {
+        out.println("[List of " + prefix + " options]");
+        for (Map.Entry<String, OptionDescriptor> e : sortedOptions.entrySet()) {
+            e.getKey();
+            OptionDescriptor desc = e.getValue();
+            Object value = desc.getOptionValue().getValue();
+            List<String> helpLines = wrap(desc.getHelp(), 70);
+            out.println(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0)));
+            for (int i = 1; i < helpLines.size(); i++) {
+                out.println(String.format("%67s %s", " ", helpLines.get(i)));
+            }
+        }
+    }
+
+    /**
+     * Compute string similarity based on Dice's coefficient.
+     *
+     * Ported from str_similar() in globals.cpp.
+     */
+    static float stringSimiliarity(String str1, String str2) {
+        int hit = 0;
+        for (int i = 0; i < str1.length() - 1; ++i) {
+            for (int j = 0; j < str2.length() - 1; ++j) {
+                if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) {
+                    ++hit;
+                    break;
+                }
+            }
+        }
+        return 2.0f * hit / (str1.length() + str2.length());
+    }
+
+    private static final float FUZZY_MATCH_THRESHOLD = 0.7F;
+
+    /**
+     * Returns the set of options that fuzzy match a given option name.
+     */
+    private static List<OptionDescriptor> fuzzyMatch(SortedMap<String, OptionDescriptor> options, String optionName) {
+        List<OptionDescriptor> matches = new ArrayList<>();
+        for (Map.Entry<String, OptionDescriptor> e : options.entrySet()) {
+            float score = stringSimiliarity(e.getKey(), optionName);
+            if (score >= FUZZY_MATCH_THRESHOLD) {
+                matches.add(e.getValue());
+            }
+        }
+        return matches;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/StableOptionValue.java	Thu Oct 22 11:13:08 2015 -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.
+ */
+package jdk.vm.ci.options;
+
+/**
+ * An option that always returns the same {@linkplain #getValue() value}.
+ */
+public class StableOptionValue<T> extends OptionValue<T> {
+
+    /**
+     * Creates a stable option value.
+     */
+    public StableOptionValue(T value) {
+        super(value);
+    }
+
+    /**
+     * Used to assert the invariant for stability. Without using locks, this check is not safe
+     * against races and so it's only an assertion.
+     */
+    private boolean getValueCalled;
+
+    /**
+     * Creates an uninitialized stable option value for a subclass that initializes itself
+     * {@link #defaultValue() lazily}.
+     */
+    public StableOptionValue() {
+    }
+
+    /**
+     * Gets the value of this option.
+     */
+    @Override
+    public final T getValue() {
+        T result = super.getValue();
+        assert initGetValueCalled();
+        return result;
+    }
+
+    private boolean initGetValueCalled() {
+        getValueCalled = true;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This must only be called if {@link #getValue()} has never been called.
+     */
+    @Override
+    public final void setValue(Object v) {
+        assert !getValueCalled;
+        super.setValue(v);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.runtime;
+
+import java.util.*;
+
+public class JVMCI {
+
+    private static final JVMCIRuntime runtime;
+
+    private static native JVMCIRuntime initializeRuntime();
+
+    public static void initialize() {
+        // force static initializer
+    }
+
+    /**
+     * Gets the singleton {@link JVMCIRuntime} instance available to the application.
+     *
+     * @throws UnsupportedOperationException if JVMCI is not supported
+     */
+    public static JVMCIRuntime getRuntime() {
+        if (runtime == null) {
+            String javaHome = System.getProperty("java.home");
+            String vmName = System.getProperty("java.vm.name");
+            Formatter errorMessage = new Formatter();
+            errorMessage.format("The VM does not support the JVMCI API.%n");
+            errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
+            errorMessage.format("Currently used VM configuration is: %s", vmName);
+            throw new UnsupportedOperationException(errorMessage.toString());
+        }
+        return runtime;
+    }
+
+    static {
+        JVMCIRuntime rt = null;
+        try {
+            rt = initializeRuntime();
+        } catch (UnsatisfiedLinkError e) {
+        }
+        runtime = rt;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIBackend.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.runtime;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.meta.*;
+
+/**
+ * A JVMCI backend encapsulates the capabilities needed by a Java based compiler for compiling and
+ * installing code for a single compute unit within a JVM. In a JVM with support for heterogeneous
+ * computing, more than one backend may be exposed.
+ */
+public class JVMCIBackend {
+
+    private final MetaAccessProvider metaAccess;
+    private final CodeCacheProvider codeCache;
+    private final ConstantReflectionProvider constantReflection;
+
+    public JVMCIBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection) {
+        this.metaAccess = metaAccess;
+        this.codeCache = codeCache;
+        this.constantReflection = constantReflection;
+    }
+
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccess;
+    }
+
+    public CodeCacheProvider getCodeCache() {
+        return codeCache;
+    }
+
+    public ConstantReflectionProvider getConstantReflection() {
+        return constantReflection;
+    }
+
+    public TargetDescription getTarget() {
+        return codeCache.getTarget();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIRuntime.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.runtime;
+
+import jdk.vm.ci.code.*;
+
+/**
+ * Interface for accessing the {@link JVMCI} APIs supported by the runtime.
+ */
+public interface JVMCIRuntime {
+
+    /**
+     * Gets the host JVMCI backend.
+     */
+    JVMCIBackend getHostJVMCIBackend();
+
+    /**
+     * Gets the backend for a given architecture.
+     *
+     * @param arch a specific architecture class
+     */
+    <T extends Architecture> JVMCIBackend getJVMCIBackend(Class<T> arch);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service.processor/src/META-INF/services/javax.annotation.processing.Processor	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+jdk.vm.ci.service.processor.ServiceProviderProcessor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service.processor/src/jdk/vm/ci/service/processor/ServiceProviderProcessor.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,112 @@
+/*
+ * 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 jdk.vm.ci.service.processor;
+
+import java.io.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.tools.Diagnostic.Kind;
+
+import jdk.vm.ci.service.*;
+
+import javax.tools.*;
+
+@SupportedAnnotationTypes("jdk.vm.ci.service.ServiceProvider")
+public class ServiceProviderProcessor extends AbstractProcessor {
+
+    private final Set<TypeElement> processed = new HashSet<>();
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latest();
+    }
+
+    private boolean verifyAnnotation(TypeMirror serviceInterface, TypeElement serviceProvider) {
+        if (!processingEnv.getTypeUtils().isSubtype(serviceProvider.asType(), serviceInterface)) {
+            String msg = String.format("Service provider class %s must implement service interface %s", serviceProvider.getSimpleName(), serviceInterface);
+            processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
+            return false;
+        }
+
+        return true;
+    }
+
+    private void processElement(TypeElement serviceProvider) {
+        if (processed.contains(serviceProvider)) {
+            return;
+        }
+
+        processed.add(serviceProvider);
+        ServiceProvider annotation = serviceProvider.getAnnotation(ServiceProvider.class);
+        if (annotation != null) {
+            try {
+                annotation.value();
+            } catch (MirroredTypeException ex) {
+                TypeMirror serviceInterface = ex.getTypeMirror();
+                if (verifyAnnotation(serviceInterface, serviceProvider)) {
+                    String interfaceName = ex.getTypeMirror().toString();
+                    createProviderFile(serviceProvider, interfaceName);
+                }
+            }
+        }
+    }
+
+    private void createProviderFile(TypeElement serviceProvider, String interfaceName) {
+        if (serviceProvider.getNestingKind().isNested()) {
+            // This is a simplifying constraint that means we don't have to
+            // processed the qualified name to insert '$' characters at
+            // the relevant positions.
+            String msg = String.format("Service provider class %s must be a top level class", serviceProvider.getSimpleName());
+            processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
+            return;
+        }
+
+        String filename = "META-INF/jvmci.providers/" + serviceProvider.getQualifiedName();
+        try {
+            FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, serviceProvider);
+            PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
+            writer.println(interfaceName);
+            writer.close();
+        } catch (IOException e) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), serviceProvider);
+        }
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            return true;
+        }
+
+        for (Element element : roundEnv.getElementsAnnotatedWith(ServiceProvider.class)) {
+            assert element.getKind().isClass();
+            processElement((TypeElement) element);
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/.checkstyle_checks.xml	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+    Checkstyle-Configuration: Checks
+    Description: none
+-->
+<module name="Checker">
+  <property name="severity" value="error"/>
+  <module name="TreeWalker">
+    <property name="tabWidth" value="4"/>
+    <module name="FileContentsHolder"/>
+    <module name="JavadocStyle">
+      <property name="checkHtml" value="false"/>
+    </module>
+    <module name="LocalFinalVariableName"/>
+    <module name="LocalVariableName"/>
+    <module name="MemberName">
+      <property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
+    </module>
+    <module name="MethodName"/>
+    <module name="PackageName"/>
+    <module name="ParameterName"/>
+    <module name="TypeName">
+      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
+    </module>
+    <module name="RedundantImport"/>
+    <module name="LineLength">
+      <property name="max" value="250"/>
+    </module>
+    <module name="MethodParamPad"/>
+    <module name="NoWhitespaceAfter">
+      <property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+    </module>
+    <module name="NoWhitespaceBefore">
+      <property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
+    </module>
+    <module name="ParenPad"/>
+    <module name="TypecastParenPad">
+      <property name="tokens" value="RPAREN,TYPECAST"/>
+    </module>
+    <module name="WhitespaceAfter"/>
+    <module name="WhitespaceAround">
+      <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
+    </module>
+    <module name="RedundantModifier"/>
+    <module name="AvoidNestedBlocks">
+      <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+      <property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
+    </module>
+    <module name="LeftCurly"/>
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+    <module name="EmptyStatement"/>
+    <module name="HiddenField">
+      <property name="severity" value="ignore"/>
+      <property name="ignoreConstructorParameter" value="true"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="FinalClass"/>
+    <module name="HideUtilityClassConstructor">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ArrayTypeStyle"/>
+    <module name="UpperEll"/>
+    <module name="FallThrough"/>
+    <module name="FinalLocalVariable">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="MultipleVariableDeclarations"/>
+    <module name="StringLiteralEquality">
+      <property name="severity" value="error"/>
+    </module>
+    <module name="SuperFinalize"/>
+    <module name="UnnecessaryParentheses">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="Indentation">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="StaticVariableName">
+      <property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
+    </module>
+    <module name="EmptyForInitializerPad"/>
+    <module name="EmptyForIteratorPad"/>
+    <module name="ModifierOrder"/>
+    <module name="DefaultComesLast"/>
+    <module name="InnerAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ModifiedControlVariable"/>
+    <module name="MutableException">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ParameterAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="format" value="\s$"/>
+      <property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="illegal space before a comma"/>
+      <property name="format" value=" ,"/>
+      <property name="message" value="illegal space before a comma"/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="[^\x00-\x7F]"/>
+      <property name="message" value="Only use ASCII characters."/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="new (Hashtable|Vector|Stack|StringBuffer)[^\w]"/>
+      <property name="message" value="Don't use old synchronized collection classes"/>
+    </module>
+  </module>
+  <module name="RegexpHeader">
+    <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
+    <property name="fileExtensions" value="java"/>
+  </module>
+  <module name="FileTabCharacter">
+    <property name="severity" value="error"/>
+    <property name="fileExtensions" value="java"/>
+  </module>
+  <module name="NewlineAtEndOfFile">
+    <property name="lineSeparator" value="lf"/>
+  </module>
+  <module name="Translation"/>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
+    <property name="checkFormat" value="ConstantNameCheck"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop method name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume method name check"/>
+    <property name="checkFormat" value="MethodName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
+    <property name="checkFormat" value="ParameterAssignment"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
+    <property name="checkFormat" value="FinalLocalVariable"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop"/>
+    <property name="onCommentFormat" value="Checkstyle: resume"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
+    <property name="checkFormat" value="InnerAssignment"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop field name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume field name check"/>
+    <property name="checkFormat" value="MemberName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
+  </module>
+  <module name="RegexpMultiline">
+    <metadata name="net.sf.eclipsecs.core.comment" value="illegal Windows line ending"/>
+    <property name="format" value="\r\n"/>
+    <property name="message" value="illegal Windows line ending"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop header check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume header check"/>
+    <property name="checkFormat" value=".*Header"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable header checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop line length check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume line length check"/>
+    <property name="checkFormat" value="LineLength"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: start generated"/>
+    <property name="onCommentFormat" value="CheckStyle: stop generated"/>
+    <property name="checkFormat" value=".*Name|.*LineLength|.*Header"/>
+  </module>
+</module>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/src/jdk/vm/ci/service/ServiceProvider.java	Thu Oct 22 11:13:08 2015 -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.
+ */
+package jdk.vm.ci.service;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotates a service provider than can be loaded via {@linkplain Services#load(Class)} or
+ * {@link Services#loadSingle(Class, boolean)}.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface ServiceProvider {
+
+    Class<?> value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/src/jdk/vm/ci/service/Services.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.vm.ci.service;
+
+import java.util.*;
+
+/**
+ * A mechanism for accessing service providers via JVMCI.
+ */
+public final class Services {
+
+    private Services() {
+    }
+
+    /**
+     * Gets an {@link Iterable} of the JVMCI providers available for a given service.
+     */
+    public static <S> Iterable<S> load(Class<S> service) {
+        return ServiceLoader.load(service);
+    }
+
+    /**
+     * Gets the JVMCI provider for a given service for which at most one provider must be available.
+     *
+     * @param service the service whose provider is being requested
+     * @param required specifies if an {@link InternalError} should be thrown if no provider of
+     *            {@code service} is available
+     */
+    public static <S> S loadSingle(Class<S> service, boolean required) {
+        Iterable<S> providers = ServiceLoader.load(service);
+        S singleProvider = null;
+        try {
+            for (Iterator<S> it = providers.iterator(); it.hasNext();) {
+                singleProvider = it.next();
+                if (it.hasNext()) {
+                    throw new InternalError(String.format("Multiple %s providers found", service.getName()));
+                }
+            }
+        } catch (ServiceConfigurationError e) {
+            // If the service is required we will bail out below.
+        }
+        if (singleProvider == null && required) {
+            String javaHome = System.getProperty("java.home");
+            String vmName = System.getProperty("java.vm.name");
+            Formatter errorMessage = new Formatter();
+            errorMessage.format("The VM does not expose required service %s.%n", service.getName());
+            errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
+            errorMessage.format("Currently used VM configuration is: %s", vmName);
+            throw new UnsupportedOperationException(errorMessage.toString());
+        }
+        return singleProvider;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.vm.ci.sparc;
+
+import static java.nio.ByteOrder.*;
+import static jdk.vm.ci.code.MemoryBarriers.*;
+
+import java.util.*;
+
+import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.Register.RegisterCategory;
+import jdk.vm.ci.meta.*;
+
+/**
+ * Represents the SPARC architecture.
+ */
+public class SPARC extends Architecture {
+
+    public static final RegisterCategory CPU = new RegisterCategory("CPU");
+
+    // General purpose registers
+    public static final Register r0 = new Register(0, 0, "g0", CPU);
+    public static final Register r1 = new Register(1, 1, "g1", CPU);
+    public static final Register r2 = new Register(2, 2, "g2", CPU);
+    public static final Register r3 = new Register(3, 3, "g3", CPU);
+    public static final Register r4 = new Register(4, 4, "g4", CPU);
+    public static final Register r5 = new Register(5, 5, "g5", CPU);
+    public static final Register r6 = new Register(6, 6, "g6", CPU);
+    public static final Register r7 = new Register(7, 7, "g7", CPU);
+
+    public static final Register r8 = new Register(8, 8, "o0", CPU);
+    public static final Register r9 = new Register(9, 9, "o1", CPU);
+    public static final Register r10 = new Register(10, 10, "o2", CPU);
+    public static final Register r11 = new Register(11, 11, "o3", CPU);
+    public static final Register r12 = new Register(12, 12, "o4", CPU);
+    public static final Register r13 = new Register(13, 13, "o5", CPU);
+    public static final Register r14 = new Register(14, 14, "o6", CPU);
+    public static final Register r15 = new Register(15, 15, "o7", CPU);
+
+    public static final Register r16 = new Register(16, 16, "l0", CPU);
+    public static final Register r17 = new Register(17, 17, "l1", CPU);
+    public static final Register r18 = new Register(18, 18, "l2", CPU);
+    public static final Register r19 = new Register(19, 19, "l3", CPU);
+    public static final Register r20 = new Register(20, 20, "l4", CPU);
+    public static final Register r21 = new Register(21, 21, "l5", CPU);
+    public static final Register r22 = new Register(22, 22, "l6", CPU);
+    public static final Register r23 = new Register(23, 23, "l7", CPU);
+
+    public static final Register r24 = new Register(24, 24, "i0", CPU);
+    public static final Register r25 = new Register(25, 25, "i1", CPU);
+    public static final Register r26 = new Register(26, 26, "i2", CPU);
+    public static final Register r27 = new Register(27, 27, "i3", CPU);
+    public static final Register r28 = new Register(28, 28, "i4", CPU);
+    public static final Register r29 = new Register(29, 29, "i5", CPU);
+    public static final Register r30 = new Register(30, 30, "i6", CPU);
+    public static final Register r31 = new Register(31, 31, "i7", CPU);
+
+    public static final Register g0 = r0;
+    public static final Register g1 = r1;
+    public static final Register g2 = r2;
+    public static final Register g3 = r3;
+    public static final Register g4 = r4;
+    public static final Register g5 = r5;
+    public static final Register g6 = r6;
+    public static final Register g7 = r7;
+
+    public static final Register o0 = r8;
+    public static final Register o1 = r9;
+    public static final Register o2 = r10;
+    public static final Register o3 = r11;
+    public static final Register o4 = r12;
+    public static final Register o5 = r13;
+    public static final Register o6 = r14;
+    public static final Register o7 = r15;
+
+    public static final Register l0 = r16;
+    public static final Register l1 = r17;
+    public static final Register l2 = r18;
+    public static final Register l3 = r19;
+    public static final Register l4 = r20;
+    public static final Register l5 = r21;
+    public static final Register l6 = r22;
+    public static final Register l7 = r23;
+
+    public static final Register i0 = r24;
+    public static final Register i1 = r25;
+    public static final Register i2 = r26;
+    public static final Register i3 = r27;
+    public static final Register i4 = r28;
+    public static final Register i5 = r29;
+    public static final Register i6 = r30;
+    public static final Register i7 = r31;
+
+    public static final Register sp = o6;
+    public static final Register fp = i6;
+
+    // @formatter:off
+    public static final Register[] cpuRegisters = {
+        r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
+        r8,  r9,  r10, r11, r12, r13, r14, r15,
+        r16, r17, r18, r19, r20, r21, r22, r23,
+        r24, r25, r26, r27, r28, r29, r30, r31
+    };
+    // @formatter:on
+
+    public static final RegisterCategory FPUs = new RegisterCategory("FPUs", cpuRegisters.length);
+    public static final RegisterCategory FPUd = new RegisterCategory("FPUd", cpuRegisters.length + 32);
+
+    // Floating point registers
+    public static final Register f0 = new Register(32, 0, "f0", FPUs);
+    public static final Register f1 = new Register(33, 1, "f1", FPUs);
+    public static final Register f2 = new Register(34, 2, "f2", FPUs);
+    public static final Register f3 = new Register(35, 3, "f3", FPUs);
+    public static final Register f4 = new Register(36, 4, "f4", FPUs);
+    public static final Register f5 = new Register(37, 5, "f5", FPUs);
+    public static final Register f6 = new Register(38, 6, "f6", FPUs);
+    public static final Register f7 = new Register(39, 7, "f7", FPUs);
+
+    public static final Register f8 = new Register(40, 8, "f8", FPUs);
+    public static final Register f9 = new Register(41, 9, "f9", FPUs);
+    public static final Register f10 = new Register(42, 10, "f10", FPUs);
+    public static final Register f11 = new Register(43, 11, "f11", FPUs);
+    public static final Register f12 = new Register(44, 12, "f12", FPUs);
+    public static final Register f13 = new Register(45, 13, "f13", FPUs);
+    public static final Register f14 = new Register(46, 14, "f14", FPUs);
+    public static final Register f15 = new Register(47, 15, "f15", FPUs);
+
+    public static final Register f16 = new Register(48, 16, "f16", FPUs);
+    public static final Register f17 = new Register(49, 17, "f17", FPUs);
+    public static final Register f18 = new Register(50, 18, "f18", FPUs);
+    public static final Register f19 = new Register(51, 19, "f19", FPUs);
+    public static final Register f20 = new Register(52, 20, "f20", FPUs);
+    public static final Register f21 = new Register(53, 21, "f21", FPUs);
+    public static final Register f22 = new Register(54, 22, "f22", FPUs);
+    public static final Register f23 = new Register(55, 23, "f23", FPUs);
+
+    public static final Register f24 = new Register(56, 24, "f24", FPUs);
+    public static final Register f25 = new Register(57, 25, "f25", FPUs);
+    public static final Register f26 = new Register(58, 26, "f26", FPUs);
+    public static final Register f27 = new Register(59, 27, "f27", FPUs);
+    public static final Register f28 = new Register(60, 28, "f28", FPUs);
+    public static final Register f29 = new Register(61, 29, "f29", FPUs);
+    public static final Register f30 = new Register(62, 30, "f30", FPUs);
+    public static final Register f31 = new Register(63, 31, "f31", FPUs);
+
+    public static final Register d0 = new Register(32, getDoubleEncoding(0), "d0", FPUs);
+    public static final Register d2 = new Register(34, getDoubleEncoding(2), "d2", FPUs);
+    public static final Register d4 = new Register(36, getDoubleEncoding(4), "d4", FPUs);
+    public static final Register d6 = new Register(38, getDoubleEncoding(6), "d6", FPUs);
+    public static final Register d8 = new Register(40, getDoubleEncoding(8), "d8", FPUs);
+    public static final Register d10 = new Register(42, getDoubleEncoding(10), "d10", FPUs);
+    public static final Register d12 = new Register(44, getDoubleEncoding(12), "d12", FPUs);
+    public static final Register d14 = new Register(46, getDoubleEncoding(14), "d14", FPUs);
+
+    public static final Register d16 = new Register(48, getDoubleEncoding(16), "d16", FPUs);
+    public static final Register d18 = new Register(50, getDoubleEncoding(18), "d18", FPUs);
+    public static final Register d20 = new Register(52, getDoubleEncoding(20), "d20", FPUs);
+    public static final Register d22 = new Register(54, getDoubleEncoding(22), "d22", FPUs);
+    public static final Register d24 = new Register(56, getDoubleEncoding(24), "d24", FPUs);
+    public static final Register d26 = new Register(58, getDoubleEncoding(26), "d26", FPUs);
+    public static final Register d28 = new Register(60, getDoubleEncoding(28), "d28", FPUs);
+    public static final Register d30 = new Register(62, getDoubleEncoding(28), "d28", FPUs);
+
+    public static final Register d32 = new Register(64, getDoubleEncoding(32), "d32", FPUd);
+    public static final Register d34 = new Register(65, getDoubleEncoding(34), "d34", FPUd);
+    public static final Register d36 = new Register(66, getDoubleEncoding(36), "d36", FPUd);
+    public static final Register d38 = new Register(67, getDoubleEncoding(38), "d38", FPUd);
+    public static final Register d40 = new Register(68, getDoubleEncoding(40), "d40", FPUd);
+    public static final Register d42 = new Register(69, getDoubleEncoding(42), "d42", FPUd);
+    public static final Register d44 = new Register(70, getDoubleEncoding(44), "d44", FPUd);
+    public static final Register d46 = new Register(71, getDoubleEncoding(46), "d46", FPUd);
+
+    public static final Register d48 = new Register(72, getDoubleEncoding(48), "d48", FPUd);
+    public static final Register d50 = new Register(73, getDoubleEncoding(50), "d50", FPUd);
+    public static final Register d52 = new Register(74, getDoubleEncoding(52), "d52", FPUd);
+    public static final Register d54 = new Register(75, getDoubleEncoding(54), "d54", FPUd);
+    public static final Register d56 = new Register(76, getDoubleEncoding(56), "d56", FPUd);
+    public static final Register d58 = new Register(77, getDoubleEncoding(58), "d58", FPUd);
+    public static final Register d60 = new Register(78, getDoubleEncoding(60), "d60", FPUd);
+    public static final Register d62 = new Register(79, getDoubleEncoding(62), "d62", FPUd);
+
+    // @formatter:off
+    public static final Register[] fpuRegisters = {
+        f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
+        f8,  f9,  f10, f11, f12, f13, f14, f15,
+        f16, f17, f18, f19, f20, f21, f22, f23,
+        f24, f25, f26, f27, f28, f29, f30, f31,
+        d32, d34, d36, d38, d40, d42, d44, d46,
+        d48, d50, d52, d54, d56, d58, d60, d62
+    };
+    // @formatter:on
+
+    // @formatter:off
+    public static final Register[] allRegisters = {
+        // CPU
+        r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
+        r8,  r9,  r10, r11, r12, r13, r14, r15,
+        r16, r17, r18, r19, r20, r21, r22, r23,
+        r24, r25, r26, r27, r28, r29, r30, r31,
+        // FPU
+        f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
+        f8,  f9,  f10, f11, f12, f13, f14, f15,
+        f16, f17, f18, f19, f20, f21, f22, f23,
+        f24, f25, f26, f27, f28, f29, f30, f31,
+        d32, d34, d36, d38, d40, d42, d44, d46,
+        d48, d50, d52, d54, d56, d58, d60, d62
+    };
+    // @formatter:on
+
+    /**
+     * Stack bias for stack and frame pointer loads.
+     */
+    public static final int STACK_BIAS = 0x7ff;
+    /**
+     * In fact there are 64 single floating point registers, 32 of them could be accessed. TODO:
+     * Improve handling of these float registers
+     */
+    public static final int FLOAT_REGISTER_COUNT = 64;
+
+    /**
+     * Alignment for valid memory access.
+     */
+    public static final int MEMORY_ACCESS_ALIGN = 4;
+
+    public static final int INSTRUCTION_SIZE = 4;
+
+    /**
+     * Size to keep free for flushing the register-window to stack.
+     */
+    public static final int REGISTER_SAFE_AREA_SIZE = 128;
+
+    public final Set<CPUFeature> features;
+
+    public SPARC(Set<CPUFeature> features) {
+        super("SPARC", JavaKind.Long, BIG_ENDIAN, false, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, r31.encoding + FLOAT_REGISTER_COUNT + 1, 8);
+        this.features = features;
+    }
+
+    @Override
+    public boolean canStoreValue(RegisterCategory category, PlatformKind lirKind) {
+        if (!(lirKind instanceof JavaKind)) {
+            return false;
+        }
+
+        JavaKind kind = (JavaKind) lirKind;
+        if (category.equals(CPU)) {
+            switch (kind) {
+                case Boolean:
+                case Byte:
+                case Char:
+                case Short:
+                case Int:
+                case Long:
+                    return true;
+            }
+        } else if (category.equals(FPUs) && kind.equals(JavaKind.Float)) {
+            return true;
+        } else if (category.equals(FPUd) && kind.equals(JavaKind.Double)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public PlatformKind getLargestStorableKind(RegisterCategory category) {
+        if (category.equals(CPU)) {
+            return JavaKind.Long;
+        } else if (category.equals(FPUd)) {
+            return JavaKind.Double;
+        } else if (category.equals(FPUs)) {
+            return JavaKind.Float;
+        } else {
+            return JavaKind.Illegal;
+        }
+    }
+
+    @Override
+    public PlatformKind getPlatformKind(JavaKind javaKind) {
+        if (javaKind.isObject()) {
+            return JavaKind.Long;
+        } else {
+            return javaKind;
+        }
+    }
+
+    public static int spillSlotSize(TargetDescription td, PlatformKind kind) {
+        return Math.max(td.getSizeInBytes(kind), MEMORY_ACCESS_ALIGN);
+    }
+
+    public static int getDoubleEncoding(int reg) {
+        assert reg < 64 && ((reg & 1) == 0);
+        // ignore v8 assertion for now
+        return (reg & 0x1e) | ((reg & 0x20) >> 5);
+    }
+
+    public static boolean isCPURegister(Register r) {
+        return r.getRegisterCategory().equals(CPU);
+    }
+
+    public static boolean isCPURegister(Register... regs) {
+        for (Register reg : regs) {
+            if (!isCPURegister(reg)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean isGlobalRegister(Register r) {
+        return isCPURegister(r) && g0.number <= r.number && r.number <= g7.number;
+    }
+
+    public static boolean isSingleFloatRegister(Register r) {
+        return r.name.startsWith("f");
+    }
+
+    public static boolean isDoubleFloatRegister(Register r) {
+        return r.name.startsWith("d");
+    }
+
+    public Set<CPUFeature> getFeatures() {
+        return features;
+    }
+
+    public boolean hasFeature(CPUFeature feature) {
+        return features.contains(feature);
+    }
+
+    public enum CPUFeature {
+        VIS1,
+        VIS2,
+        VIS3,
+        CBCOND,
+        BLOCK_ZEROING
+    }
+}
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -2286,7 +2286,7 @@
   if (!pd_commit_memory(addr, size, exec)) {
     // Add extra info in product mode for vm_exit_out_of_memory():
     PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
-    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);
   }
 }
 
@@ -3120,8 +3120,8 @@
       // libjsig also interposes the sigaction() call below and saves the
       // old sigaction on it own.
     } else {
-      fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
-                    "%#lx for signal %d.", (long)oldhand, sig));
+      fatal("Encountered unexpected pre-existing sigaction handler "
+            "%#lx for signal %d.", (long)oldhand, sig);
     }
   }
 
@@ -3699,7 +3699,7 @@
 void os::make_polling_page_readable(void) {
   // Changed according to os_linux.cpp.
   if (!checked_mprotect((char *)_polling_page, Aix::page_size(), PROT_READ)) {
-    fatal(err_msg("Could not enable polling page at " PTR_FORMAT, _polling_page));
+    fatal("Could not enable polling page at " PTR_FORMAT, _polling_page);
   }
 };
 
--- a/hotspot/src/os/aix/vm/vmError_aix.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/aix/vm/vmError_aix.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -117,8 +117,7 @@
     return;
   }
 
-  VMError err(NULL, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
 }
 
 void VMError::reset_signal_handlers() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/aix/vm/vmStructs_aix.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_AIX_VM_VMSTRUCTS_AIX_HPP
+#define OS_AIX_VM_VMSTRUCTS_AIX_HPP
+
+// These are the OS-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
+
+#define VM_TYPES_OS(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
+
+#define VM_INT_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_LONG_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_ADDRESSES_OS(declare_address, declare_preprocessor_address, declare_function)
+
+#endif // OS_AIX_VM_VMSTRUCTS_AIX_HPP
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -128,8 +128,6 @@
 
 #define LARGEPAGES_BIT (1 << 6)
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 ////////////////////////////////////////////////////////////////////////////////
 // global variables
 julong os::Bsd::_physical_memory = 0;
@@ -1977,7 +1975,7 @@
 OSXSemaphore::OSXSemaphore(uint value) {
   kern_return_t ret = SEM_INIT(_semaphore, value);
 
-  guarantee(ret == KERN_SUCCESS, err_msg("Failed to create semaphore: %s", sem_init_strerror(ret)));
+  guarantee(ret == KERN_SUCCESS, "Failed to create semaphore: %s", sem_init_strerror(ret));
 }
 
 OSXSemaphore::~OSXSemaphore() {
@@ -2213,7 +2211,7 @@
   if (!pd_commit_memory(addr, size, exec)) {
     // add extra info in product mode for vm_exit_out_of_memory():
     PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
-    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);
   }
 }
 
@@ -3100,8 +3098,8 @@
       // libjsig also interposes the sigaction() call below and saves the
       // old sigaction on it own.
     } else {
-      fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
-                    "%#lx for signal %d.", (long)oldhand, sig));
+      fatal("Encountered unexpected pre-existing sigaction handler "
+            "%#lx for signal %d.", (long)oldhand, sig);
     }
   }
 
@@ -3459,8 +3457,7 @@
 
   Bsd::set_page_size(getpagesize());
   if (Bsd::page_size() == -1) {
-    fatal(err_msg("os_bsd.cpp: os::init: sysconf failed (%s)",
-                  strerror(errno)));
+    fatal("os_bsd.cpp: os::init: sysconf failed (%s)", strerror(errno));
   }
   init_page_sizes((size_t) Bsd::page_size());
 
--- a/hotspot/src/os/bsd/vm/vmError_bsd.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/bsd/vm/vmError_bsd.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -121,8 +121,7 @@
     return;
   }
 
-  VMError err(NULL, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
 }
 
 void VMError::reset_signal_handlers() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/bsd/vm/vmStructs_bsd.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_BSD_VM_VMSTRUCTS_BSD_HPP
+#define OS_BSD_VM_VMSTRUCTS_BSD_HPP
+
+#include <dlfcn.h>
+
+// These are the OS-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
+
+#define VM_TYPES_OS(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
+
+#define VM_INT_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_LONG_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_ADDRESSES_OS(declare_address, declare_preprocessor_address, declare_function) \
+  declare_preprocessor_address("RTLD_DEFAULT", RTLD_DEFAULT)
+
+#endif // OS_BSD_VM_VMSTRUCTS_BSD_HPP
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -106,8 +106,6 @@
 # include <inttypes.h>
 # include <sys/ioctl.h>
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // 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
@@ -1969,7 +1967,8 @@
       char name[PATH_MAX + 1];
 
       // Parse fields from line
-      sscanf(line, "%lx-%lx %4s %lx %5s %ld %s", &base, &top, permissions, &offset, device, &inode, name);
+      sscanf(line, UINT64_FORMAT_X "-" UINT64_FORMAT_X " %4s " UINT64_FORMAT_X " %5s " INT64_FORMAT " %s",
+             &base, &top, permissions, &offset, device, &inode, name);
 
       // Filter by device id '00:00' so that we only get file system mapped files.
       if (strcmp(device, "00:00") != 0) {
@@ -2632,7 +2631,7 @@
 static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
-          ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
+          ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec,
           strerror(err), err);
 }
 
@@ -2640,7 +2639,7 @@
                                     size_t alignment_hint, bool exec,
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
-          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
+          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", p2i(addr), size,
           alignment_hint, exec, strerror(err), err);
 }
 
@@ -2680,7 +2679,7 @@
   if (err != 0) {
     // the caller wants all commit errors to exit with the specified mesg:
     warn_fail_commit_memory(addr, size, exec, err);
-    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);
   }
 }
 
@@ -2716,7 +2715,7 @@
   if (err != 0) {
     // the caller wants all commit errors to exit with the specified mesg:
     warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
-    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);
   }
 }
 
@@ -4278,8 +4277,8 @@
       // libjsig also interposes the sigaction() call below and saves the
       // old sigaction on it own.
     } else {
-      fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
-                    "%#lx for signal %d.", (long)oldhand, sig));
+      fatal("Encountered unexpected pre-existing sigaction handler "
+            "%#lx for signal %d.", (long)oldhand, sig);
     }
   }
 
@@ -4611,8 +4610,8 @@
 
   Linux::set_page_size(sysconf(_SC_PAGESIZE));
   if (Linux::page_size() == -1) {
-    fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)",
-                  strerror(errno)));
+    fatal("os_linux.cpp: os::init: sysconf failed (%s)",
+          strerror(errno));
   }
   init_page_sizes((size_t) Linux::page_size());
 
@@ -4628,7 +4627,7 @@
   int status;
   pthread_condattr_t* _condattr = os::Linux::condAttr();
   if ((status = pthread_condattr_init(_condattr)) != 0) {
-    fatal(err_msg("pthread_condattr_init: %s", strerror(status)));
+    fatal("pthread_condattr_init: %s", strerror(status));
   }
   // Only set the clock if CLOCK_MONOTONIC is available
   if (os::supports_monotonic_clock()) {
@@ -4637,7 +4636,7 @@
         warning("Unable to use monotonic clock with relative timed-waits" \
                 " - changes to the time-of-day clock may have adverse affects");
       } else {
-        fatal(err_msg("pthread_condattr_setclock: %s", strerror(status)));
+        fatal("pthread_condattr_setclock: %s", strerror(status));
       }
     }
   }
@@ -4717,7 +4716,7 @@
   if (threadStackSizeInBytes != 0 &&
       threadStackSizeInBytes < os::Linux::min_stack_allowed) {
     tty->print_cr("\nThe stack size specified is too small, "
-                  "Specify at least %dk",
+                  "Specify at least " SIZE_FORMAT "k",
                   os::Linux::min_stack_allowed/ K);
     return JNI_ERR;
   }
@@ -4918,12 +4917,12 @@
   Dl_info dlinfo;
   memset(&dlinfo, 0, sizeof(dlinfo));
   if (dladdr(addr, &dlinfo) != 0) {
-    st->print(PTR_FORMAT ": ", addr);
+    st->print(PTR_FORMAT ": ", p2i(addr));
     if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
-      st->print("%s+%#x", dlinfo.dli_sname,
-                addr - (intptr_t)dlinfo.dli_saddr);
+      st->print("%s+" PTR_FORMAT, dlinfo.dli_sname,
+                p2i(addr) - p2i(dlinfo.dli_saddr));
     } else if (dlinfo.dli_fbase != NULL) {
-      st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
+      st->print("<offset " PTR_FORMAT ">", p2i(addr) - p2i(dlinfo.dli_fbase));
     } else {
       st->print("<absolute address>");
     }
@@ -4931,7 +4930,7 @@
       st->print(" in %s", dlinfo.dli_fname);
     }
     if (dlinfo.dli_fbase != NULL) {
-      st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
+      st->print(" at " PTR_FORMAT, p2i(dlinfo.dli_fbase));
     }
     st->cr();
 
@@ -5323,7 +5322,7 @@
 void os::pause() {
   char filename[MAX_PATH];
   if (PauseAtStartupFile && PauseAtStartupFile[0]) {
-    jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
+    jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
   } else {
     jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
   }
@@ -5959,7 +5958,7 @@
   int written;
 
   if (core_pattern[0] == '/') {
-    written = jio_snprintf(buffer, bufferSize, core_pattern);
+    written = jio_snprintf(buffer, bufferSize, "%s", core_pattern);
   } else {
     char cwd[PATH_MAX];
 
@@ -6095,7 +6094,7 @@
       for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
         test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " ->  " PTR_FORMAT " %s",
-            size, alignment, p, (p != NULL ? "" : "(failed)"));
+                 size, alignment, p2i(p), (p != NULL ? "" : "(failed)"));
         if (p != NULL) {
           assert(is_ptr_aligned(p, alignment), "must be");
           small_page_write(p, size);
@@ -6114,8 +6113,8 @@
         char* const req_addr = (char*) align_ptr_up(mapping1, alignment);
         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);
         test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " " PTR_FORMAT " ->  " PTR_FORMAT " %s",
-            size, alignment, req_addr, p,
-            ((p != NULL ? (p == req_addr ? "(exact match)" : "") : "(failed)")));
+                 size, alignment, p2i(req_addr), p2i(p),
+                 ((p != NULL ? (p == req_addr ? "(exact match)" : "") : "(failed)")));
         if (p != NULL) {
           assert(p == req_addr, "must be");
           small_page_write(p, size);
@@ -6134,8 +6133,7 @@
         char* const req_addr = (char*) align_ptr_up(mapping2, alignment);
         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);
         test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " " PTR_FORMAT " ->  " PTR_FORMAT " %s",
-            size, alignment, req_addr, p,
-            ((p != NULL ? "" : "(failed)")));
+                 size, alignment, p2i(req_addr), p2i(p), ((p != NULL ? "" : "(failed)")));
         // as the area around req_addr contains already existing mappings, the API should always
         // return NULL (as per contract, it cannot return another address)
         assert(p == NULL, "must be");
--- a/hotspot/src/os/linux/vm/vmError_linux.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/linux/vm/vmError_linux.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -121,8 +121,7 @@
     return;
   }
 
-  VMError err(NULL, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
 }
 
 void VMError::reset_signal_handlers() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/linux/vm/vmStructs_linux.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_LINUX_VM_VMSTRUCTS_LINUX_HPP
+#define OS_LINUX_VM_VMSTRUCTS_LINUX_HPP
+
+#include <dlfcn.h>
+
+// These are the OS-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
+
+#define VM_TYPES_OS(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
+
+#define VM_INT_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_LONG_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_ADDRESSES_OS(declare_address, declare_preprocessor_address, declare_function) \
+  declare_preprocessor_address("RTLD_DEFAULT", RTLD_DEFAULT)
+
+#endif // OS_LINUX_VM_VMSTRUCTS_LINUX_HPP
--- a/hotspot/src/os/posix/vm/os_posix.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,8 +38,6 @@
 #include <semaphore.h>
 #include <signal.h>
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Todo: provide a os::get_max_process_id() or similar. Number of processes
 // may have been configured, can be read more accurately from proc fs etc.
 #ifndef MAX_PID
@@ -194,30 +192,30 @@
   st->print(" STACK ");
   getrlimit(RLIMIT_STACK, &rlim);
   if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
+  else st->print("%luk", rlim.rlim_cur >> 10);
 
   st->print(", CORE ");
   getrlimit(RLIMIT_CORE, &rlim);
   if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
+  else st->print("%luk", rlim.rlim_cur >> 10);
 
   // Isn't there on solaris
 #if !defined(TARGET_OS_FAMILY_solaris) && !defined(TARGET_OS_FAMILY_aix)
   st->print(", NPROC ");
   getrlimit(RLIMIT_NPROC, &rlim);
   if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%d", rlim.rlim_cur);
+  else st->print("%lu", rlim.rlim_cur);
 #endif
 
   st->print(", NOFILE ");
   getrlimit(RLIMIT_NOFILE, &rlim);
   if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%d", rlim.rlim_cur);
+  else st->print("%lu", rlim.rlim_cur);
 
   st->print(", AS ");
   getrlimit(RLIMIT_AS, &rlim);
   if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
+  else st->print("%luk", rlim.rlim_cur >> 10);
   st->cr();
 }
 
@@ -961,7 +959,7 @@
     }
   } else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
              sig == SIGTRAP || sig == SIGFPE) {
-    os->print(", si_addr: " PTR_FORMAT, si->si_addr);
+    os->print(", si_addr: " PTR_FORMAT, p2i(si->si_addr));
 #ifdef SIGPOLL
   } else if (sig == SIGPOLL) {
     os->print(", si_band: " PTR64_FORMAT, (uint64_t)si->si_band);
@@ -1027,10 +1025,10 @@
   }
 }
 
-#define check_with_errno(check_type, cond, msg)                                      \
-  do {                                                                               \
-    int err = errno;                                                                 \
-    check_type(cond, err_msg("%s; error='%s' (errno=%d)", msg, strerror(err), err)); \
+#define check_with_errno(check_type, cond, msg)                             \
+  do {                                                                      \
+    int err = errno;                                                        \
+    check_type(cond, "%s; error='%s' (errno=%d)", msg, strerror(err), err); \
 } while (false)
 
 #define assert_with_errno(cond, msg)    check_with_errno(assert, cond, msg)
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1118,8 +1118,7 @@
 
 
 void _handle_uncaught_cxx_exception() {
-  VMError err("An uncaught C++ exception");
-  err.report_and_die();
+  VMError::report_and_die("An uncaught C++ exception");
 }
 
 
@@ -1330,7 +1329,7 @@
 jlong os::javaTimeMillis() {
   timeval t;
   if (gettimeofday(&t, NULL) == -1) {
-    fatal(err_msg("os::javaTimeMillis: gettimeofday (%s)", strerror(errno)));
+    fatal("os::javaTimeMillis: gettimeofday (%s)", strerror(errno));
   }
   return jlong(t.tv_sec) * 1000  +  jlong(t.tv_usec) / 1000;
 }
@@ -1338,7 +1337,7 @@
 void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
   timeval t;
   if (gettimeofday(&t, NULL) == -1) {
-    fatal(err_msg("os::javaTimeSystemUTC: gettimeofday (%s)", strerror(errno)));
+    fatal("os::javaTimeSystemUTC: gettimeofday (%s)", strerror(errno));
   }
   seconds = jlong(t.tv_sec);
   nanos = jlong(t.tv_usec) * 1000;
@@ -2392,14 +2391,14 @@
   if (err != 0) {
     // the caller wants all commit errors to exit with the specified mesg:
     warn_fail_commit_memory(addr, bytes, exec, err);
-    vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
+    vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "%s", mesg);
   }
 }
 
 size_t os::Solaris::page_size_for_alignment(size_t alignment) {
   assert(is_size_aligned(alignment, (size_t) vm_page_size()),
-         err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT,
-                 alignment, (size_t) vm_page_size()));
+         SIZE_FORMAT " is not aligned to " SIZE_FORMAT,
+         alignment, (size_t) vm_page_size());
 
   for (int i = 0; _page_sizes[i] != 0; i++) {
     if (is_size_aligned(alignment, _page_sizes[i])) {
@@ -2415,7 +2414,7 @@
   int err = Solaris::commit_memory_impl(addr, bytes, exec);
   if (err == 0 && UseLargePages && alignment_hint > 0) {
     assert(is_size_aligned(bytes, alignment_hint),
-           err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, alignment_hint));
+           SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, alignment_hint);
 
     // The syscall memcntl requires an exact page size (see man memcntl for details).
     size_t page_size = page_size_for_alignment(alignment_hint);
@@ -2439,7 +2438,7 @@
   if (err != 0) {
     // the caller wants all commit errors to exit with the specified mesg:
     warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err);
-    vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
+    vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "%s", mesg);
   }
 }
 
@@ -2969,11 +2968,11 @@
 }
 
 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
-  assert(is_valid_page_size(align), err_msg(SIZE_FORMAT " is not a valid page size", align));
+  assert(is_valid_page_size(align), SIZE_FORMAT " is not a valid page size", align);
   assert(is_ptr_aligned((void*) start, align),
-         err_msg(PTR_FORMAT " is not aligned to " SIZE_FORMAT, p2i((void*) start), align));
+         PTR_FORMAT " is not aligned to " SIZE_FORMAT, p2i((void*) start), align);
   assert(is_size_aligned(bytes, align),
-         err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, align));
+         SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, align);
 
   // Signal to OS that we want large pages for addresses
   // from addr, addr + bytes
@@ -3956,8 +3955,8 @@
       // libjsig also interposes the sigaction() call below and saves the
       // old sigaction on it own.
     } else {
-      fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
-                    "%#lx for signal %d.", (long)oldhand, sig));
+      fatal("Encountered unexpected pre-existing sigaction handler "
+            "%#lx for signal %d.", (long)oldhand, sig);
     }
   }
 
@@ -4403,8 +4402,7 @@
 
   page_size = sysconf(_SC_PAGESIZE);
   if (page_size == -1) {
-    fatal(err_msg("os_solaris.cpp: os::init: sysconf failed (%s)",
-                  strerror(errno)));
+    fatal("os_solaris.cpp: os::init: sysconf failed (%s)", strerror(errno));
   }
   init_page_sizes((size_t) page_size);
 
@@ -4416,7 +4414,7 @@
 
   int fd = ::open("/dev/zero", O_RDWR);
   if (fd < 0) {
-    fatal(err_msg("os::init: cannot open /dev/zero (%s)", strerror(errno)));
+    fatal("os::init: cannot open /dev/zero (%s)", strerror(errno));
   } else {
     Solaris::set_dev_zero_fd(fd);
 
--- a/hotspot/src/os/solaris/vm/threadCritical_solaris.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/solaris/vm/threadCritical_solaris.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -48,8 +48,8 @@
     thread_t owner = thr_self();
     if (global_mut_owner != owner) {
       if (os::Solaris::mutex_lock(&global_mut))
-        fatal(err_msg("ThreadCritical::ThreadCritical: mutex_lock failed (%s)",
-                      strerror(errno)));
+        fatal("ThreadCritical::ThreadCritical: mutex_lock failed (%s)",
+              strerror(errno));
       assert(global_mut_count == 0, "must have clean count");
       assert(global_mut_owner == -1, "must have clean owner");
     }
@@ -68,8 +68,7 @@
     if (global_mut_count == 0) {
       global_mut_owner = -1;
       if (os::Solaris::mutex_unlock(&global_mut))
-        fatal(err_msg("ThreadCritical::~ThreadCritical: mutex_unlock failed "
-                      "(%s)", strerror(errno)));
+        fatal("ThreadCritical::~ThreadCritical: mutex_unlock failed (%s)", strerror(errno));
     }
   } else {
     assert (Threads::number_of_threads() == 0, "valid only during initialization");
--- a/hotspot/src/os/solaris/vm/vmError_solaris.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/solaris/vm/vmError_solaris.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -117,8 +117,7 @@
     return;
   }
 
-  VMError err(NULL, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
 }
 
 void VMError::reset_signal_handlers() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/solaris/vm/vmStructs_solaris.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_SOLARIS_VM_VMSTRUCTS_SOLARIS_HPP
+#define OS_SOLARIS_VM_VMSTRUCTS_SOLARIS_HPP
+
+// These are the OS-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
+  nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
+
+#define VM_TYPES_OS(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
+  declare_unsigned_integer_type(OSThread::thread_id_t)
+
+#define VM_INT_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_LONG_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_ADDRESSES_OS(declare_address, declare_preprocessor_address, declare_function)
+
+#endif // OS_SOLARIS_VM_VMSTRUCTS_SOLARIS_HPP
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -823,7 +823,7 @@
   java_origin.wMilliseconds  = 0;
   FILETIME jot;
   if (!SystemTimeToFileTime(&java_origin, &jot)) {
-    fatal(err_msg("Error = %d\nWindows error", GetLastError()));
+    fatal("Error = %d\nWindows error", GetLastError());
   }
   _calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);
   _has_calculated_offset = 1;
@@ -1936,7 +1936,7 @@
 WindowsSemaphore::WindowsSemaphore(uint value) {
   _semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL);
 
-  guarantee(_semaphore != NULL, err_msg("CreateSemaphore failed with error code: %lu", GetLastError()));
+  guarantee(_semaphore != NULL, "CreateSemaphore failed with error code: %lu", GetLastError());
 }
 
 WindowsSemaphore::~WindowsSemaphore() {
@@ -1947,14 +1947,14 @@
   if (count > 0) {
     BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL);
 
-    assert(ret != 0, err_msg("ReleaseSemaphore failed with error code: %lu", GetLastError()));
+    assert(ret != 0, "ReleaseSemaphore failed with error code: %lu", GetLastError());
   }
 }
 
 void WindowsSemaphore::wait() {
   DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE);
-  assert(ret != WAIT_FAILED,   err_msg("WaitForSingleObject failed with error code: %lu", GetLastError()));
-  assert(ret == WAIT_OBJECT_0, err_msg("WaitForSingleObject failed with return value: %lu", ret));
+  assert(ret != WAIT_FAILED,   "WaitForSingleObject failed with error code: %lu", GetLastError());
+  assert(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with return value: %lu", ret);
 }
 
 // sun.misc.Signal
@@ -2272,12 +2272,17 @@
   #ifdef  _M_AMD64
   PCONTEXT ctx = exceptionInfo->ContextRecord;
   address pc = (address)ctx->Rip;
-  assert(pc[0] == 0xF7, "not an idiv opcode");
-  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
-  assert(ctx->Rax == min_jint, "unexpected idiv exception");
-  // set correct result values and continue after idiv instruction
-  ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
-  ctx->Rax = (DWORD)min_jint;      // result
+  assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
+  assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
+  if (pc[0] == 0xF7) {
+    // set correct result values and continue after idiv instruction
+    ctx->Rip = (DWORD64)pc + 2;        // idiv reg, reg  is 2 bytes
+  } else {
+    ctx->Rip = (DWORD64)pc + 3;        // REX idiv reg, reg  is 3 bytes
+  }
+  // Do not set ctx->Rax as it already contains the correct value (either 32 or 64 bit, depending on the operation)
+  // this is the case because the exception only happens for -MinValue/-1 and -MinValue is always in rax because of the
+  // idiv opcode (0xF7).
   ctx->Rdx = (DWORD)0;             // remainder
   // Continue the execution
   #else
@@ -2344,8 +2349,7 @@
 
 static inline void report_error(Thread* t, DWORD exception_code,
                                 address addr, void* siginfo, void* context) {
-  VMError err(t, exception_code, addr, siginfo, context);
-  err.report_and_die();
+  VMError::report_and_die(t, exception_code, addr, siginfo, context);
 
   // If UseOsErrorReporting, this will return here and save the error file
   // somewhere where we can find it in the minidump.
@@ -3325,7 +3329,7 @@
   assert(mesg != NULL, "mesg must be specified");
   if (!pd_commit_memory(addr, size, exec)) {
     warn_fail_commit_memory(addr, size, exec);
-    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);
   }
 }
 
@@ -5259,7 +5263,7 @@
       }
       DWORD err = GetLastError();
       if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) {
-        fatal(err_msg("heap walk aborted with error %d", err));
+        fatal("heap walk aborted with error %d", err);
       }
       HeapUnlock(heap);
     }
@@ -5978,8 +5982,8 @@
       os::release_memory_special(actual_location, expected_allocation_size);
       // only now check, after releasing any memory to avoid any leaks.
       assert(actual_location == expected_location,
-             err_msg("Failed to allocate memory at requested location " PTR_FORMAT " of size " SIZE_FORMAT ", is " PTR_FORMAT " instead",
-             expected_location, expected_allocation_size, actual_location));
+             "Failed to allocate memory at requested location " PTR_FORMAT " of size " SIZE_FORMAT ", is " PTR_FORMAT " instead",
+             expected_location, expected_allocation_size, actual_location);
     }
   }
 
--- a/hotspot/src/os/windows/vm/vmError_windows.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os/windows/vm/vmError_windows.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -70,9 +70,8 @@
 
 LONG WINAPI crash_handler(struct _EXCEPTION_POINTERS* exceptionInfo) {
   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
-  VMError err(NULL, exception_code, NULL,
-                exceptionInfo->ExceptionRecord, exceptionInfo->ContextRecord);
-  err.report_and_die();
+  VMError::report_and_die(NULL, exception_code, NULL, exceptionInfo->ExceptionRecord,
+                          exceptionInfo->ContextRecord);
   return EXCEPTION_CONTINUE_SEARCH;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/windows/vm/vmStructs_windows.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_WINDOWS_VM_VMSTRUCTS_WINDOWS_HPP
+#define OS_WINDOWS_VM_VMSTRUCTS_WINDOWS_HPP
+
+// These are the OS-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
+
+#define VM_TYPES_OS(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
+
+#define VM_INT_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_LONG_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+
+#define VM_ADDRESSES_OS(declare_address, declare_preprocessor_address, declare_function)
+
+#endif // OS_WINDOWS_VM_VMSTRUCTS_WINDOWS_HPP
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -468,8 +468,7 @@
   sigaddset(&newset, sig);
   sigthreadmask(SIG_UNBLOCK, &newset, NULL);
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
   return 0;
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -276,8 +276,6 @@
 # endif
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 address os::current_stack_pointer() {
 #if defined(__clang__) || defined(__llvm__)
   register void *esp;
@@ -731,8 +729,7 @@
   sigaddset(&newset, sig);
   sigprocmask(SIG_UNBLOCK, &newset, NULL);
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
   return false;
@@ -865,7 +862,7 @@
   int rslt = pthread_stackseg_np(pthread_self(), &ss);
 
   if (rslt != 0)
-    fatal(err_msg("pthread_stackseg_np failed with err = %d", rslt));
+    fatal("pthread_stackseg_np failed with err = %d", rslt);
 
   *bottom = (address)((char *)ss.ss_sp - ss.ss_size);
   *size   = ss.ss_size;
@@ -876,12 +873,12 @@
 
   // JVM needs to know exact stack location, abort if it fails
   if (rslt != 0)
-    fatal(err_msg("pthread_attr_init failed with err = %d", rslt));
+    fatal("pthread_attr_init failed with err = %d", rslt);
 
   rslt = pthread_attr_get_np(pthread_self(), &attr);
 
   if (rslt != 0)
-    fatal(err_msg("pthread_attr_get_np failed with err = %d", rslt));
+    fatal("pthread_attr_get_np failed with err = %d", rslt);
 
   if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 ||
     pthread_attr_getstacksize(&attr, size) != 0) {
--- a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -66,8 +66,8 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#ifdef COMPILER2
-      // C2 uses ebp as a general register see if NULL fp helps
+#if defined(COMPILER2) || INCLUDE_JVMCI
+      // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
         // nothing else to try if the frame isn't good
@@ -77,7 +77,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 */
+#endif /* COMPILER2 || INCLUDE_JVMCI */
     }
     *fr_addr = ret_frame;
     return true;
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -320,8 +320,7 @@
   int rslt = pthread_stackseg_np(pthread_self(), &ss);
 
   if (rslt != 0)
-    fatal(err_msg("pthread_stackseg_np failed with err = " INT32_FORMAT,
-          rslt));
+    fatal("pthread_stackseg_np failed with err = " INT32_FORMAT, rslt);
 
   stack_top = (address) ss.ss_sp;
   stack_bytes  = ss.ss_size;
@@ -333,13 +332,12 @@
 
   // JVM needs to know exact stack location, abort if it fails
   if (rslt != 0)
-    fatal(err_msg("pthread_attr_init failed with err = " INT32_FORMAT, rslt));
+    fatal("pthread_attr_init failed with err = " INT32_FORMAT, rslt);
 
   rslt = pthread_attr_get_np(pthread_self(), &attr);
 
   if (rslt != 0)
-    fatal(err_msg("pthread_attr_get_np failed with err = " INT32_FORMAT,
-          rslt));
+    fatal("pthread_attr_get_np failed with err = " INT32_FORMAT, rslt);
 
   if (pthread_attr_getstackaddr(&attr, (void **) &stack_bottom) != 0 ||
       pthread_attr_getstacksize(&attr, &stack_bytes) != 0) {
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -464,8 +464,7 @@
   sigaddset(&newset, sig);
   sigprocmask(SIG_UNBLOCK, &newset, NULL);
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
   return true; // Mute compiler
@@ -558,7 +557,7 @@
        if (rslt == ENOMEM) {
          vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
        } else {
-         fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
+         fatal("pthread_getattr_np failed with errno = %d", rslt);
        }
      }
 
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -439,8 +439,7 @@
   sigaddset(&newset, sig);
   sigprocmask(SIG_UNBLOCK, &newset, NULL);
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
   return false;
@@ -531,7 +530,7 @@
       if (rslt == ENOMEM) {
         vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
       } else {
-        fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
+        fatal("pthread_getattr_np failed with errno = %d", rslt);
       }
     }
 
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -172,7 +172,7 @@
       if (rslt == ENOMEM) {
         vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
       } else {
-        fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
+        fatal("pthread_getattr_np failed with errno = %d", rslt);
       }
     }
 
@@ -692,8 +692,7 @@
   sigaddset(&newset, sig);
   sigprocmask(SIG_UNBLOCK, &newset, NULL);
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
 }
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -89,8 +89,6 @@
 #define SPELL_REG_FP "ebp"
 #endif // AMD64
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 address os::current_stack_pointer() {
 #ifdef SPARC_WORKS
   register void *esp;
@@ -542,8 +540,7 @@
   sigaddset(&newset, sig);
   sigprocmask(SIG_UNBLOCK, &newset, NULL);
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
   return true; // Mute compiler
@@ -689,7 +686,7 @@
        if (rslt == ENOMEM) {
          vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
        } else {
-         fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
+         fatal("pthread_getattr_np failed with errno = %d", rslt);
        }
      }
 
@@ -728,32 +725,32 @@
   ucontext_t *uc = (ucontext_t*)context;
   st->print_cr("Registers:");
 #ifdef AMD64
-  st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
-  st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
-  st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
-  st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
+  st->print(  "RAX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RAX]);
+  st->print(", RBX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RBX]);
+  st->print(", RCX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RCX]);
+  st->print(", RDX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RDX]);
   st->cr();
-  st->print(  "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
-  st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
-  st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
-  st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
+  st->print(  "RSP=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RSP]);
+  st->print(", RBP=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RBP]);
+  st->print(", RSI=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RSI]);
+  st->print(", RDI=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RDI]);
   st->cr();
-  st->print(  "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
-  st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
-  st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
-  st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
+  st->print(  "R8 =" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R8]);
+  st->print(", R9 =" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R9]);
+  st->print(", R10=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R10]);
+  st->print(", R11=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R11]);
   st->cr();
-  st->print(  "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
-  st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
-  st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
-  st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
+  st->print(  "R12=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R12]);
+  st->print(", R13=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R13]);
+  st->print(", R14=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R14]);
+  st->print(", R15=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_R15]);
   st->cr();
-  st->print(  "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]);
-  st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
-  st->print(", CSGSFS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_CSGSFS]);
-  st->print(", ERR=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ERR]);
+  st->print(  "RIP=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RIP]);
+  st->print(", EFLAGS=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_EFL]);
+  st->print(", CSGSFS=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_CSGSFS]);
+  st->print(", ERR=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_ERR]);
   st->cr();
-  st->print("  TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]);
+  st->print("  TRAPNO=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_TRAPNO]);
 #else
   st->print(  "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
   st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
@@ -767,13 +764,13 @@
   st->cr();
   st->print(  "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]);
   st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
-  st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2);
+  st->print(", CR2=" PTR64_FORMAT, (uint64_t)uc->uc_mcontext.cr2);
 #endif // AMD64
   st->cr();
   st->cr();
 
   intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
-  st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
+  st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
   print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
   st->cr();
 
@@ -781,7 +778,7 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
+  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
 }
 
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -67,8 +67,8 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#ifdef COMPILER2
-      // C2 uses ebp as a general register see if NULL fp helps
+#if defined(COMPILER2) || INCLUDE_JVMCI
+      // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
         // nothing else to try if the frame isn't good
@@ -78,7 +78,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 */
+#endif /* COMPILER2 || INCLUDE_JVMCI */
     }
     *fr_addr = ret_frame;
     return true;
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -328,7 +328,7 @@
       vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
     }
     else {
-      fatal(err_msg("pthread_getattr_np failed with errno = %d", res));
+      fatal("pthread_getattr_np failed with errno = %d", res);
     }
   }
 
@@ -336,7 +336,7 @@
   size_t stack_bytes;
   res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
   if (res != 0) {
-    fatal(err_msg("pthread_attr_getstack failed with errno = %d", res));
+    fatal("pthread_attr_getstack failed with errno = %d", res);
   }
   address stack_top = stack_bottom + stack_bytes;
 
@@ -348,7 +348,7 @@
   size_t guard_bytes;
   res = pthread_attr_getguardsize(&attr, &guard_bytes);
   if (res != 0) {
-    fatal(err_msg("pthread_attr_getguardsize failed with errno = %d", res));
+    fatal("pthread_attr_getguardsize failed with errno = %d", res);
   }
   int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes;
   assert(guard_bytes == guard_pages * page_bytes, "unaligned guard");
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -24,6 +24,7 @@
 
 // no precompiled headers
 #include "asm/macroAssembler.hpp"
+#include "macroAssembler_sparc.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -549,8 +550,7 @@
     vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "Out of swap space to map in thread stack.");
   }
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
 }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,29 +30,11 @@
 // referenced by vmStructs.cpp.
 
 #define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
-                                                                                                                                     \
-  /******************************/                                                                                                   \
-  /* Threads (NOTE: incomplete) */                                                                                                   \
-  /******************************/                                                                                                   \
-                                                                                                                                     \
-  nonstatic_field(JavaThread,                  _base_of_stack_pointer,                        intptr_t*)                             \
-  nonstatic_field(OSThread,                    _thread_id,                                    OSThread::thread_id_t)
+  nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*)
 
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
-                                                                          \
-  /**********************/                                                \
-  /* Solaris Thread IDs */                                                \
-  /**********************/                                                \
-                                                                          \
-  declare_unsigned_integer_type(OSThread::thread_id_t)
-
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
 
 #define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
-                                                                        \
-  /************************/                                            \
-  /* JavaThread constants */                                            \
-  /************************/                                            \
-                                                                        \
   declare_constant(JavaFrameAnchor::flushed)
 
 #define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -707,8 +707,7 @@
     vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "Out of swap space to map in thread stack.");
   }
 
-  VMError err(t, sig, pc, info, ucVoid);
-  err.report_and_die();
+  VMError::report_and_die(t, sig, pc, info, ucVoid);
 
   ShouldNotReachHere();
   return false;
--- a/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,21 +29,9 @@
 // constants required by the Serviceability Agent. This file is
 // referenced by vmStructs.cpp.
 
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
-                                                                                                                                     \
-  /******************************/                                                                                                   \
-  /* Threads (NOTE: incomplete) */                                                                                                   \
-  /******************************/                                                                                                   \
-                                                                                                                                     \
-  nonstatic_field(OSThread,                      _thread_id,                                    OSThread::thread_id_t)
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
 
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
-                                                                          \
-  /**********************/                                                \
-  /* Solaris Thread IDs */                                                \
-  /**********************/                                                \
-                                                                          \
-  declare_unsigned_integer_type(OSThread::thread_id_t)
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
 
 #define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
 
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -74,8 +74,8 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#ifdef COMPILER2
-      // C2 uses ebp as a general register see if NULL fp helps
+#if defined(COMPILER2) || INCLUDE_JVMCI
+      // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
         // nothing else to try if the frame isn't good
@@ -85,7 +85,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 */
+#endif /* COMPILER2 || INCLUDE_JVMCI */
     }
     *fr_addr = ret_frame;
     return true;
--- a/hotspot/src/share/vm/Xusage.txt	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/Xusage.txt	Thu Oct 22 11:13:08 2015 -0700
@@ -7,6 +7,7 @@
     -Xbootclasspath/p:<directories and zip/jar files separated by ;>
                       prepend in front of bootstrap class path
     -Xnoclassgc       disable class garbage collection
+    -Xlog:<opts>      control JVM logging, use -Xlog:help for details
     -Xloggc:<file>    log GC status to a file with time stamps
     -Xbatch           disable background compilation
     -Xms<size>        set initial Java heap size
--- a/hotspot/src/share/vm/adlc/formsopt.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/adlc/formsopt.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -234,7 +234,6 @@
 }
 
 RegClass::~RegClass() {
-  delete _classid;
 }
 
 // record a register in this class
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -4006,7 +4006,6 @@
         strcmp(opType,"DivD")==0 ||
         strcmp(opType,"DivF")==0 ||
         strcmp(opType,"DivI")==0 ||
-        strcmp(opType,"ExpD")==0 ||
         strcmp(opType,"LogD")==0 ||
         strcmp(opType,"Log10D")==0 ||
         strcmp(opType,"ModD")==0 ||
@@ -4143,6 +4142,8 @@
     "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",
     "MulVS","MulVI","MulVL","MulVF","MulVD",
     "DivVF","DivVD",
+    "AbsVF","AbsVD",
+    "NegVF","NegVD",
     "SqrtVD",
     "AndV" ,"XorV" ,"OrV",
     "AddReductionVI", "AddReductionVL",
--- a/hotspot/src/share/vm/asm/assembler.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/asm/assembler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,8 +43,7 @@
   CodeSection* cs = code->insts();
   cs->clear_mark();   // new assembler kills old mark
   if (cs->start() == NULL)  {
-    vm_exit_out_of_memory(0, OOM_MMAP_ERROR, err_msg("CodeCache: no room for %s",
-                                     code->name()));
+    vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "CodeCache: no room for %s", code->name());
   }
   _code_section = cs;
   _oop_recorder= code->oop_recorder();
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -602,21 +602,19 @@
   return (csize_t) align_size_up(total, HeapWordSize);
 }
 
-csize_t CodeBuffer::copy_relocations_to(CodeBlob* dest) const {
-  address buf = NULL;
+csize_t CodeBuffer::copy_relocations_to(address buf, csize_t buf_limit, bool only_inst) const {
   csize_t buf_offset = 0;
-  csize_t buf_limit = 0;
-  if (dest != NULL) {
-    buf = (address)dest->relocation_begin();
-    buf_limit = (address)dest->relocation_end() - buf;
-    assert((uintptr_t)buf % HeapWordSize == 0, "buf must be fully aligned");
-    assert(buf_limit % HeapWordSize == 0, "buf must be evenly sized");
-  }
-  // if dest == NULL, this is just the sizing pass
-
   csize_t code_end_so_far = 0;
   csize_t code_point_so_far = 0;
+
+  assert((uintptr_t)buf % HeapWordSize == 0, "buf must be fully aligned");
+  assert(buf_limit % HeapWordSize == 0, "buf must be evenly sized");
+
   for (int n = (int) SECT_FIRST; n < (int)SECT_LIMIT; n++) {
+    if (only_inst && (n != (int)SECT_INSTS)) {
+      // Need only relocation info for code.
+      continue;
+    }
     // pull relocs out of each section
     const CodeSection* cs = code_section(n);
     assert(!(cs->is_empty() && cs->locs_count() > 0), "sanity");
@@ -683,7 +681,23 @@
     buf_offset += sizeof(relocInfo);
   }
 
-  assert(code_end_so_far == total_content_size(), "sanity");
+  assert(only_inst || code_end_so_far == total_content_size(), "sanity");
+
+  return buf_offset;
+}
+
+csize_t CodeBuffer::copy_relocations_to(CodeBlob* dest) const {
+  address buf = NULL;
+  csize_t buf_offset = 0;
+  csize_t buf_limit = 0;
+
+  if (dest != NULL) {
+    buf = (address)dest->relocation_begin();
+    buf_limit = (address)dest->relocation_end() - buf;
+  }
+  // if dest == NULL, this is just the sizing pass
+  //
+  buf_offset = copy_relocations_to(buf, buf_limit, false);
 
   // Account for index:
   if (buf != NULL) {
@@ -1126,7 +1140,8 @@
     while (c && c->offset() == offset) {
       stream->bol();
       stream->print("%s", _prefix);
-      stream->print_cr("%s", c->string());
+      // Don't interpret as format strings since it could contain %
+      stream->print_raw_cr(c->string());
       c = c->next_comment();
     }
   }
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -173,7 +173,7 @@
   bool allocates(address pc) const  { return pc >= _start && pc <  _limit; }
   bool allocates2(address pc) const { return pc >= _start && pc <= _limit; }
 
-  void    set_end(address pc)       { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " INTPTR_FORMAT " <= " INTPTR_FORMAT " <= " INTPTR_FORMAT, p2i(_start), p2i(pc), p2i(_limit))); _end = pc; }
+  void    set_end(address pc)       { assert(allocates2(pc), "not in CodeBuffer memory: " INTPTR_FORMAT " <= " INTPTR_FORMAT " <= " INTPTR_FORMAT, p2i(_start), p2i(pc), p2i(_limit)); _end = pc; }
   void    set_mark(address pc)      { assert(contains2(pc), "not in codeBuffer");
                                       _mark = pc; }
   void    set_mark_off(int offset)  { assert(contains2(offset+_start),"not in codeBuffer");
@@ -375,6 +375,8 @@
   OopRecorder  _default_oop_recorder;  // override with initialize_oop_recorder
   Arena*       _overflow_arena;
 
+  address      _last_membar;     // used to merge consecutive memory barriers
+
   address      _decode_begin;   // start address for decode
   address      decode_begin();
 
@@ -388,6 +390,7 @@
     _decode_begin    = NULL;
     _overflow_arena  = NULL;
     _code_strings    = CodeStrings();
+    _last_membar     = NULL;
   }
 
   void initialize(address code_start, csize_t code_size) {
@@ -452,7 +455,6 @@
     initialize_misc(name);
   }
 
-
   // (4) code buffer allocating codeBlob memory for code & relocation
   // info.  The name must be something informative and code_size must
   // include both code and stubs sizes.
@@ -553,6 +555,8 @@
   // allocated size of all relocation data, including index, rounded up
   csize_t total_relocation_size() const;
 
+  csize_t copy_relocations_to(address buf, csize_t buf_limit, bool only_inst) const;
+
   // allocated size of any and all recorded oops
   csize_t total_oop_size() const {
     OopRecorder* recorder = oop_recorder();
@@ -576,6 +580,10 @@
   OopRecorder* oop_recorder() const   { return _oop_recorder; }
   CodeStrings& strings()              { return _code_strings; }
 
+  address last_membar() const { return _last_membar; }
+  void set_last_membar(address a) { _last_membar = a; }
+  void clear_last_membar() { set_last_membar(NULL); }
+
   void free_strings() {
     if (!_code_strings.is_null()) {
       _code_strings.free(); // sets _strings Null as a side-effect.
--- a/hotspot/src/share/vm/asm/register.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/asm/register.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -121,8 +121,7 @@
 ) {
   assert(
     a != b,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "",
-                p2i(a), p2i(b))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", p2i(a), p2i(b)
   );
 }
 
@@ -135,9 +134,9 @@
   assert(
     a != b && a != c
            && b != c,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c)
   );
 }
 
@@ -152,9 +151,9 @@
     a != b && a != c && a != d
            && b != c && b != d
                      && c != d,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d)
   );
 }
 
@@ -171,9 +170,9 @@
            && b != c && b != d && b != e
                      && c != d && c != e
                                && d != e,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)
   );
 }
 
@@ -192,10 +191,10 @@
                      && c != d && c != e && c != f
                                && d != e && d != f
                                          && e != f,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
-                ", f=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
+    ", f=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)
   );
 }
 
@@ -216,10 +215,10 @@
                                && d != e && d != f && d != g
                                          && e != f && e != g
                                                    && f != g,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
-                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
+    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)
   );
 }
 
@@ -242,10 +241,10 @@
                                          && e != f && e != g && e != h
                                                    && f != g && f != h
                                                              && g != h,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
-                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
+    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)
   );
 }
 
@@ -270,11 +269,11 @@
                                                    && f != g && f != h && f != i
                                                              && g != h && g != i
                                                                        && h != i,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
-                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
-                ", i=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
+    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
+    ", i=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)
   );
 }
 
@@ -300,11 +299,11 @@
                                                              && g != h && g != i && g != j
                                                                        && h != i && h != j
                                                                                  && i != j,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
-                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
-                ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
+    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
+    ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j)
   );
 }
 
@@ -332,11 +331,11 @@
                                                                        && h != i && h != j && h !=k
                                                                                  && i != j && i !=k
                                                                                            && j !=k,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
-                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
-                ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
+    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
+    ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k)
   );
 }
 
@@ -366,12 +365,12 @@
                                                                                  && i != j && i !=k && i !=l
                                                                                            && j !=k && j !=l
                                                                                                     && k !=l,
-    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
-                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
-                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
-                ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT
-                ", l=" INTPTR_FORMAT "",
-                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l))
+    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
+    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
+    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
+    ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT
+    ", l=" INTPTR_FORMAT "",
+    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l)
   );
 }
 
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -325,7 +325,8 @@
                                         locs_buffer_size / sizeof(relocInfo));
   code->initialize_consts_size(Compilation::desired_max_constant_size());
   // Call stubs + two deopt handlers (regular and MH) + exception handler
-  int stub_size = (call_stub_estimate * LIR_Assembler::call_stub_size) +
+  int call_stub_size = LIR_Assembler::call_stub_size;
+  int stub_size = (call_stub_estimate * call_stub_size) +
                    LIR_Assembler::exception_handler_size +
                    (2 * LIR_Assembler::deopt_handler_size);
   if (stub_size >= code->insts_capacity()) return false;
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -3363,11 +3363,9 @@
   return NULL;
 }
 
-
 // negative filter: should callee NOT be inlined?  returns NULL, ok to inline, or rejection msg
 const char* GraphBuilder::should_not_inline(ciMethod* callee) const {
-  if ( callee->should_exclude())       return "excluded by CompilerOracle";
-  if ( callee->should_not_inline())    return "disallowed by CompilerOracle";
+  if ( callee->should_not_inline())    return "disallowed by CompileCommand";
   if ( callee->dont_inline())          return "don't inline by annotation";
   return NULL;
 }
@@ -3698,7 +3696,7 @@
 
     const char* msg = "";
     if (callee->force_inline())  msg = "force inline by annotation";
-    if (callee->should_inline()) msg = "force inline by CompileOracle";
+    if (callee->should_inline()) msg = "force inline by CompileCommand";
     print_inlining(callee, msg);
   } else {
     // use heuristic controls on inlining
@@ -4020,7 +4018,7 @@
     break;
 
   default:
-    fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+    fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
     break;
   }
   set_state(state_before);
--- a/hotspot/src/share/vm/c1/c1_IR.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_IR.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -244,7 +244,8 @@
     // reexecute allowed only for the topmost frame
     bool reexecute = topmost ? should_reexecute() : false;
     bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
-    recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
+    bool rethrow_exception = false;
+    recorder->describe_scope(pc_offset, methodHandle(), scope()->method(), bci(), reexecute, rethrow_exception, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
   }
 };
 
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -732,8 +732,7 @@
     case lir_sin:
     case lir_cos:
     case lir_log:
-    case lir_log10:
-    case lir_exp: {
+    case lir_log10: {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
 
@@ -743,9 +742,6 @@
       // overlap with the input.
       assert(op2->_info == NULL, "not used");
       assert(op2->_tmp5->is_illegal(), "not used");
-      assert(op2->_tmp2->is_valid() == (op->code() == lir_exp), "not used");
-      assert(op2->_tmp3->is_valid() == (op->code() == lir_exp), "not used");
-      assert(op2->_tmp4->is_valid() == (op->code() == lir_exp), "not used");
       assert(op2->_opr1->is_valid(), "used");
       do_input(op2->_opr1); do_temp(op2->_opr1);
 
@@ -1775,7 +1771,6 @@
      case lir_tan:                   s = "tan";           break;
      case lir_log:                   s = "log";           break;
      case lir_log10:                 s = "log10";         break;
-     case lir_exp:                   s = "exp";           break;
      case lir_pow:                   s = "pow";           break;
      case lir_logic_and:             s = "logic_and";     break;
      case lir_logic_or:              s = "logic_or";      break;
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -961,7 +961,6 @@
       , lir_tan
       , lir_log
       , lir_log10
-      , lir_exp
       , lir_pow
       , lir_logic_and
       , lir_logic_or
@@ -2199,7 +2198,6 @@
   void sin (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_sin , from, tmp1, to, tmp2)); }
   void cos (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_cos , from, tmp1, to, tmp2)); }
   void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); }
-  void exp (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, LIR_Opr tmp4, LIR_Opr tmp5)                { append(new LIR_Op2(lir_exp , from, tmp1, to, tmp2, tmp3, tmp4, tmp5)); }
   void pow (LIR_Opr arg1, LIR_Opr arg2, LIR_Opr res, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, LIR_Opr tmp4, LIR_Opr tmp5) { append(new LIR_Op2(lir_pow, arg1, arg2, res, tmp1, tmp2, tmp3, tmp4, tmp5)); }
 
   void add (LIR_Opr left, LIR_Opr right, LIR_Opr res)      { append(new LIR_Op2(lir_add, left, right, res)); }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -405,7 +405,8 @@
     if (s == NULL)  break;
     IRScope* scope = s->scope();
     //Always pass false for reexecute since these ScopeDescs are never used for deopt
-    debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/);
+    methodHandle null_mh;
+    debug_info->describe_scope(pc_offset, null_mh, scope->method(), s->bci(), false/*reexecute*/);
   }
 
   debug_info->end_non_safepoint(pc_offset);
@@ -462,7 +463,7 @@
     vtable_call(op);
     break;
   default:
-    fatal(err_msg_res("unexpected op code: %s", op->name()));
+    fatal("unexpected op code: %s", op->name());
     break;
   }
 
@@ -739,7 +740,6 @@
     case lir_cos:
     case lir_log:
     case lir_log10:
-    case lir_exp:
     case lir_pow:
       intrinsic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op);
       break;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -920,7 +920,7 @@
 
 LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) {
   assert(type2size[t] == type2size[value->type()],
-         err_msg_res("size mismatch: t=%s, value->type()=%s", type2name(t), type2name(value->type())));
+         "size mismatch: t=%s, value->type()=%s", type2name(t), type2name(value->type()));
   if (!value->is_register()) {
     // force into a register
     LIR_Opr r = new_register(value->type());
@@ -1630,6 +1630,9 @@
     __ move(dirty, card_addr);
     __ branch_destination(L_already_dirty->label());
   } else {
+    if (UseConcMarkSweepGC && CMSPrecleaningEnabled) {
+      __ membar_storestore();
+    }
     __ move(dirty, card_addr);
   }
 #endif
@@ -2829,7 +2832,7 @@
 
 void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
   assert(args->length() == arg_list->length(),
-         err_msg_res("args=%d, arg_list=%d", args->length(), arg_list->length()));
+         "args=%d, arg_list=%d", args->length(), arg_list->length());
   for (int i = x->has_receiver() ? 1 : 0; i < args->length(); i++) {
     LIRItem* param = args->at(i);
     LIR_Opr loc = arg_list->at(i);
@@ -2973,7 +2976,7 @@
       break;
     }
     default:
-      fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(x->code())));
+      fatal("unexpected bytecode: %s", Bytecodes::name(x->code()));
       break;
   }
 
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -244,6 +244,7 @@
   void do_getClass(Intrinsic* x);
   void do_currentThread(Intrinsic* x);
   void do_MathIntrinsic(Intrinsic* x);
+  void do_ExpIntrinsic(Intrinsic* x);
   void do_ArrayCopy(Intrinsic* x);
   void do_CompareAndSwap(Intrinsic* x, ValueType* type);
   void do_NIOCheckIndex(Intrinsic* x);
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -6588,7 +6588,6 @@
         case lir_log10:
         case lir_log:
         case lir_pow:
-        case lir_exp:
         case lir_logic_and:
         case lir_logic_or:
         case lir_logic_xor:
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -317,6 +317,7 @@
   FUNCTION_CASE(entry, TRACE_TIME_METHOD);
 #endif
   FUNCTION_CASE(entry, StubRoutines::updateBytesCRC32());
+  FUNCTION_CASE(entry, StubRoutines::dexp());
 
 #undef FUNCTION_CASE
 
--- a/hotspot/src/share/vm/c1/c1_globals.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -152,6 +152,7 @@
                                                                             \
   product(intx, ValueMapMaxLoopSize, 8,                                     \
           "maximum size of a loop optimized by global value numbering")     \
+          range(0, 128)                                                     \
                                                                             \
   develop(bool, EliminateBlocks, true,                                      \
           "Eliminate unneccessary basic blocks")                            \
@@ -220,6 +221,7 @@
                                                                             \
   develop(intx, TraceLinearScanLevel, 0,                                    \
           "Debug levels for the linear scan allocator")                     \
+          range(0, 4)                                                       \
                                                                             \
   develop(bool, StressLinearScan, false,                                    \
           "scramble block order used by LinearScan (stress test)")          \
@@ -294,6 +296,7 @@
                                                                             \
   develop(intx, NMethodSizeLimit, (64*K)*wordSize,                          \
           "Maximum size of a compiled method.")                             \
+          range(0, max_jint)                                                \
                                                                             \
   develop(bool, TraceFPUStack, false,                                       \
           "Trace emulation of the FPU stack (intel only)")                  \
@@ -309,6 +312,7 @@
                                                                             \
   develop(intx, InstructionCountCutoff, 37000,                              \
           "If GraphBuilder adds this many instructions, bails out")         \
+          range(0, max_jint)                                                \
                                                                             \
   develop(bool, ComputeExactFPURegisterUsage, true,                         \
           "Compute additional live set for fpu registers to simplify fpu stack merge (Intel only)") \
--- a/hotspot/src/share/vm/ci/ciKlass.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciKlass.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -66,8 +66,8 @@
 // ------------------------------------------------------------------
 // ciKlass::is_subtype_of
 bool ciKlass::is_subtype_of(ciKlass* that) {
-  assert(this->is_loaded(), err_msg("must be loaded: %s", this->name()->as_quoted_ascii()));
-  assert(that->is_loaded(), err_msg("must be loaded: %s", that->name()->as_quoted_ascii()));
+  assert(this->is_loaded(), "must be loaded: %s", this->name()->as_quoted_ascii());
+  assert(that->is_loaded(), "must be loaded: %s", that->name()->as_quoted_ascii());
 
   // Check to see if the klasses are identical.
   if (this == that) {
@@ -85,8 +85,8 @@
 // ------------------------------------------------------------------
 // ciKlass::is_subclass_of
 bool ciKlass::is_subclass_of(ciKlass* that) {
-  assert(this->is_loaded(), err_msg("must be loaded: %s", this->name()->as_quoted_ascii()));
-  assert(that->is_loaded(), err_msg("must be loaded: %s", that->name()->as_quoted_ascii()));
+  assert(this->is_loaded(), "must be loaded: %s", this->name()->as_quoted_ascii());
+  assert(that->is_loaded(), "must be loaded: %s", that->name()->as_quoted_ascii());
 
   VM_ENTRY_MARK;
   Klass* this_klass = get_Klass();
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -576,13 +576,13 @@
 
 void ciMethod::assert_virtual_call_type_ok(int bci) {
   assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual ||
-         java_code_at_bci(bci) == Bytecodes::_invokeinterface, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
+         java_code_at_bci(bci) == Bytecodes::_invokeinterface, "unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)));
 }
 
 void ciMethod::assert_call_type_ok(int bci) {
   assert(java_code_at_bci(bci) == Bytecodes::_invokestatic ||
          java_code_at_bci(bci) == Bytecodes::_invokespecial ||
-         java_code_at_bci(bci) == Bytecodes::_invokedynamic, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
+         java_code_at_bci(bci) == Bytecodes::_invokedynamic, "unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)));
 }
 
 /**
@@ -1044,18 +1044,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciMethod::should_exclude
-//
-// Should this method be excluded from compilation?
-bool ciMethod::should_exclude() {
-  check_is_loaded();
-  VM_ENTRY_MARK;
-  methodHandle mh(THREAD, get_Method());
-  bool ignore;
-  return CompilerOracle::should_exclude(mh, ignore);
-}
-
-// ------------------------------------------------------------------
 // ciMethod::should_inline
 //
 // Should this method be inlined during compilation?
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -266,7 +266,6 @@
   int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
 
   // Compilation directives
-  bool should_exclude();
   bool should_inline();
   bool should_not_inline();
   bool should_print_assembly();
--- a/hotspot/src/share/vm/ci/ciMethodData.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciMethodData.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -122,7 +122,7 @@
       // An empty slot or ArgInfoData entry marks the end of the trap data
       return;
     default:
-      fatal(err_msg("bad tag = %d", dp_dst->tag()));
+      fatal("bad tag = %d", dp_dst->tag());
     }
   }
 }
@@ -289,7 +289,7 @@
       break;
     }
     default:
-      fatal(err_msg("bad tag = %d", dp->tag()));
+      fatal("bad tag = %d", dp->tag());
     }
   }
   return NULL;
@@ -578,7 +578,7 @@
       break;
     }
     default:
-      fatal(err_msg("bad tag = %d", dp->tag()));
+      fatal("bad tag = %d", dp->tag());
     }
   }
 }
@@ -690,7 +690,7 @@
       data = new ciSpeculativeTrapData(dp);
       break;
     default:
-      fatal(err_msg("unexpected tag %d", dp->tag()));
+      fatal("unexpected tag %d", dp->tag());
     }
     st->print("%d", dp_to_di(data->dp()));
     st->fill_to(6);
--- a/hotspot/src/share/vm/ci/ciReplay.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -730,7 +730,7 @@
           if (parsed_two_word == i) continue;
 
         default:
-          fatal(err_msg_res("Unexpected tag: %d", cp->tag_at(i).value()));
+          fatal("Unexpected tag: %d", cp->tag_at(i).value());
           break;
       }
 
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1964,7 +1964,7 @@
   _has_irreducible_entry = false;
   _osr_bci = osr_bci;
   _failure_reason = NULL;
-  assert(0 <= start_bci() && start_bci() < code_size() , err_msg("correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size()));
+  assert(0 <= start_bci() && start_bci() < code_size() , "correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size());
   _work_list = NULL;
 
   _ciblock_count = _methodBlocks->num_blocks();
--- a/hotspot/src/share/vm/classfile/altHashing.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/altHashing.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -262,10 +262,9 @@
   juint final_hash = murmur3_32(hashes, 4*256);
 
   assert (MURMUR3_32_X86_CHECK_VALUE == final_hash,
-    err_msg(
-        "Calculated hash result not as expected. Expected %08X got %08X\n",
-        MURMUR3_32_X86_CHECK_VALUE,
-        final_hash));
+          "Calculated hash result not as expected. Expected %08X got %08X\n",
+          MURMUR3_32_X86_CHECK_VALUE,
+          final_hash);
 }
 
 void AltHashing::testEquivalentHashes() {
@@ -276,24 +275,24 @@
   jbytes = murmur3_32(TWO_BYTE, 2);
   jchars = murmur3_32(ONE_CHAR, 1);
   assert (jbytes == jchars,
-    err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars));
+          "Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars);
 
   jbytes = murmur3_32(FOUR_BYTE, 4);
   jchars = murmur3_32(TWO_CHAR, 2);
   ints = murmur3_32(ONE_INT, 1);
   assert ((jbytes == jchars) && (jbytes == ints),
-    err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints));
+          "Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints);
 
   jbytes = murmur3_32(SIX_BYTE, 6);
   jchars = murmur3_32(THREE_CHAR, 3);
   assert (jbytes == jchars,
-    err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars));
+         "Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars);
 
   jbytes = murmur3_32(EIGHT_BYTE, 8);
   jchars = murmur3_32(FOUR_CHAR, 4);
   ints = murmur3_32(TWO_INT, 2);
   assert ((jbytes == jchars) && (jbytes == ints),
-    err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints));
+          "Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints);
 }
 
 // Returns true if the alternate hashcode is correct
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -319,12 +319,12 @@
 PRAGMA_FORMAT_NONLITERAL_IGNORED
 void ClassFileParser::report_assert_property_failure(const char* msg, TRAPS) {
   ResourceMark rm(THREAD);
-  fatal(err_msg(msg, _class_name->as_C_string()));
+  fatal(msg, _class_name->as_C_string());
 }
 
 void ClassFileParser::report_assert_property_failure(const char* msg, int index, TRAPS) {
   ResourceMark rm(THREAD);
-  fatal(err_msg(msg, index, _class_name->as_C_string()));
+  fatal(msg, index, _class_name->as_C_string());
 }
 PRAGMA_DIAG_POP
 
@@ -492,8 +492,7 @@
           break;
         }
       default:
-        fatal(err_msg("bad constant pool tag value %u",
-                      cp->tag_at(index).value()));
+        fatal("bad constant pool tag value %u", cp->tag_at(index).value());
         ShouldNotReachHere();
         break;
     } // end of switch
@@ -1755,6 +1754,12 @@
     if (_location != _in_method)  break;  // only allow for methods
     if (!privileged)              break;  // only allow in privileged code
     return _method_HotSpotIntrinsicCandidate;
+#if INCLUDE_JVMCI
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_vm_ci_hotspot_Stable_signature):
+    if (_location != _in_field)   break;  // only allow for fields
+    if (!privileged)              break;  // only allow in privileged code
+    return _field_Stable;
+#endif
   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature):
     if (_location != _in_field)   break;  // only allow for fields
     if (!privileged)              break;  // only allow in privileged code
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -913,7 +913,7 @@
   }
 
   // Nothing more for the iterator to hand out.
-  assert(head == NULL, err_msg("head is " PTR_FORMAT ", expected not null:", p2i(head)));
+  assert(head == NULL, "head is " PTR_FORMAT ", expected not null:", p2i(head));
   return NULL;
 }
 
--- a/hotspot/src/share/vm/classfile/dictionary.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,8 +31,6 @@
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/hashtable.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 DictionaryEntry*  Dictionary::_current_class_entry = NULL;
 int               Dictionary::_current_class_index =    0;
 
@@ -558,7 +556,7 @@
 
 void ProtectionDomainCacheEntry::print() {
   tty->print_cr("entry " PTR_FORMAT " value " PTR_FORMAT " strongly_reachable %d next " PTR_FORMAT,
-                this, (void*)literal(), _strongly_reachable, next());
+                p2i(this), p2i(literal()), _strongly_reachable, p2i(next()));
 }
 #endif
 
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -53,7 +53,9 @@
 #include "runtime/vframe.hpp"
 #include "utilities/preserveException.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciJavaClasses.hpp"
+#endif
 
 #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java)    \
   klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum);
@@ -1579,7 +1581,7 @@
   while (h_throwable.not_null()) {
     objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable())));
     if (result.is_null()) {
-      st->print_cr("%s", no_stack_trace_message());
+      st->print_raw_cr(no_stack_trace_message());
       return;
     }
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -157,7 +157,12 @@
     if (count_offset > 0) {
       return java_string->int_field(count_offset);
     } else {
-      return ((typeArrayOop)java_string->obj_field(value_offset))->length();
+      typeArrayOop value_array = ((typeArrayOop)java_string->obj_field(value_offset));
+      if (value_array == NULL) {
+        return 0;
+      } else {
+        return value_array->length();
+      }
     }
   }
   static int utf8_length(oop java_string);
--- a/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -32,6 +32,9 @@
 #include "runtime/thread.hpp"
 #include "services/threadService.hpp"
 #include "utilities/chunkedList.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 
 MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
 MetadataOnStackBuffer* MetadataOnStackMark::_free_buffers = NULL;
@@ -57,6 +60,9 @@
     CompileBroker::mark_on_stack();
     JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
     ThreadService::metadata_do(Metadata::mark_on_stack);
+#if INCLUDE_JVMCI
+    JVMCIRuntime::metadata_do(Metadata::mark_on_stack);
+#endif
   }
 }
 
@@ -119,7 +125,7 @@
     allocated = new MetadataOnStackBuffer();
   }
 
-  assert(!allocated->is_full(), err_msg("Should not be full: " PTR_FORMAT, p2i(allocated)));
+  assert(!allocated->is_full(), "Should not be full: " PTR_FORMAT, p2i(allocated));
 
   return allocated;
 }
--- a/hotspot/src/share/vm/classfile/stackMapTable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/stackMapTable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -186,7 +186,6 @@
     u2 offset = _stream->get_u2(THREAD);
     if (offset >= _code_length ||
         _code_data[offset] != ClassVerifier::NEW_OFFSET) {
-      ResourceMark rm(THREAD);
       _verifier->class_format_error(
         "StackMapTable format error: bad offset for Uninitialized");
       return VerificationType::bogus_type();
--- a/hotspot/src/share/vm/classfile/stringTable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/stringTable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,8 +43,6 @@
 #include "gc/g1/g1StringDedup.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // the number of buckets a thread claims
 const int ClaimChunkSize = 32;
 
@@ -312,12 +310,12 @@
   const int limit = the_table()->table_size();
 
   assert(0 <= start_idx && start_idx <= limit,
-         err_msg("start_idx (%d) is out of bounds", start_idx));
+         "start_idx (%d) is out of bounds", start_idx);
   assert(0 <= end_idx && end_idx <= limit,
-         err_msg("end_idx (%d) is out of bounds", end_idx));
+         "end_idx (%d) is out of bounds", end_idx);
   assert(start_idx <= end_idx,
-         err_msg("Index ordering: start_idx=%d, end_idx=%d",
-                 start_idx, end_idx));
+         "Index ordering: start_idx=%d, end_idx=%d",
+         start_idx, end_idx);
 
   for (int i = start_idx; i < end_idx; i += 1) {
     HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
@@ -335,12 +333,12 @@
   const int limit = the_table()->table_size();
 
   assert(0 <= start_idx && start_idx <= limit,
-         err_msg("start_idx (%d) is out of bounds", start_idx));
+         "start_idx (%d) is out of bounds", start_idx);
   assert(0 <= end_idx && end_idx <= limit,
-         err_msg("end_idx (%d) is out of bounds", end_idx));
+         "end_idx (%d) is out of bounds", end_idx);
   assert(start_idx <= end_idx,
-         err_msg("Index ordering: start_idx=%d, end_idx=%d",
-                 start_idx, end_idx));
+         "Index ordering: start_idx=%d, end_idx=%d",
+         start_idx, end_idx);
 
   for (int i = start_idx; i < end_idx; ++i) {
     HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
@@ -445,7 +443,7 @@
   if (str1 == str2) {
     tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
                   "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
-                  (void *)str1, bkt1, e_cnt1, bkt2, e_cnt2);
+                  p2i(str1), bkt1, e_cnt1, bkt2, e_cnt2);
     return _verify_fail_continue;
   }
 
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,8 +37,6 @@
 #include "runtime/mutexLocker.hpp"
 #include "utilities/hashtable.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // --------------------------------------------------------------------------
 // the number of buckets a thread claims
 const int ClaimChunkSize = 32;
@@ -623,8 +621,8 @@
           ((float)_symbols_removed/(float)_symbols_counted)* 100);
   }
   tty->print_cr("  Reference counts         %7d", Symbol::_total_count);
-  tty->print_cr("  Symbol arena used        %7dK", arena()->used()/1024);
-  tty->print_cr("  Symbol arena size        %7dK", arena()->size_in_bytes()/1024);
+  tty->print_cr("  Symbol arena used        " SIZE_FORMAT_W(7) "K", arena()->used()/1024);
+  tty->print_cr("  Symbol arena size        " SIZE_FORMAT_W(7) "K", arena()->size_in_bytes()/1024);
   tty->print_cr("  Total symbol length      %7d", total_length);
   tty->print_cr("  Maximum symbol length    %7d", max_length);
   tty->print_cr("  Average symbol length    %7.2f", ((float) total_length / (float) total_count));
@@ -645,7 +643,7 @@
     HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
     if (entry != NULL) {
       while (entry != NULL) {
-        tty->print(PTR_FORMAT " ", entry->literal());
+        tty->print(PTR_FORMAT " ", p2i(entry->literal()));
         entry->literal()->print();
         tty->print(" %d", entry->literal()->refcount());
         p = entry->next_addr();
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -66,6 +66,9 @@
 #include "classfile/sharedClassUtil.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 #if INCLUDE_TRACE
 #include "trace/tracing.hpp"
 #endif
@@ -228,10 +231,10 @@
 // Forwards to resolve_instance_class_or_null
 
 Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) {
-  assert(!THREAD->is_Compiler_thread(),
-         err_msg("can not load classes with compiler thread: class=%s, classloader=%s",
-                 class_name->as_C_string(),
-                 class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string()));
+  assert(THREAD->can_call_java(),
+         "can not load classes with compiler thread: class=%s, classloader=%s",
+         class_name->as_C_string(),
+         class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string());
   if (FieldType::is_array(class_name)) {
     return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD);
   } else if (FieldType::is_obj(class_name)) {
@@ -1917,7 +1920,7 @@
   WKID jsr292_group_end   = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
   initialize_wk_klasses_until(jsr292_group_start, scan, CHECK);
   initialize_wk_klasses_through(jsr292_group_end, scan, CHECK);
-  initialize_wk_klasses_until(WKID_LIMIT, scan, CHECK);
+  initialize_wk_klasses_until(NOT_JVMCI(WKID_LIMIT) JVMCI_ONLY(FIRST_JVMCI_WKID), scan, CHECK);
 
   _box_klasses[T_BOOLEAN] = WK_KLASS(Boolean_klass);
   _box_klasses[T_CHAR]    = WK_KLASS(Character_klass);
@@ -2264,7 +2267,7 @@
   assert(MethodHandles::is_signature_polymorphic(iid) &&
          MethodHandles::is_signature_polymorphic_intrinsic(iid) &&
          iid != vmIntrinsics::_invokeGeneric,
-         err_msg("must be a known MH intrinsic iid=%d: %s", iid, vmIntrinsics::name_at(iid)));
+         "must be a known MH intrinsic iid=%d: %s", iid, vmIntrinsics::name_at(iid));
 
   unsigned int hash  = invoke_method_table()->compute_hash(signature, iid);
   int          index = invoke_method_table()->hash_to_index(hash);
@@ -2343,7 +2346,7 @@
                                                           Handle *method_type_result,
                                                           TRAPS) {
   methodHandle empty;
-  assert(!THREAD->is_Compiler_thread(), "");
+  assert(THREAD->can_call_java() ,"");
   Handle method_type =
     SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty));
 
@@ -2390,7 +2393,7 @@
   if (klass->oop_is_typeArray()) {
     return true; // primitive array
   }
-  assert(klass->oop_is_instance(), klass->external_name());
+  assert(klass->oop_is_instance(), "%s", klass->external_name());
   return klass->is_public() &&
          (InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::Object_klass()) ||       // java.lang
           InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::MethodHandle_klass()));  // java.lang.invoke
@@ -2411,7 +2414,7 @@
   if (spe != NULL && spe->method_type() != NULL) {
     assert(java_lang_invoke_MethodType::is_instance(spe->method_type()), "");
     return Handle(THREAD, spe->method_type());
-  } else if (THREAD->is_Compiler_thread()) {
+  } else if (!THREAD->can_call_java()) {
     warning("SystemDictionary::find_method_handle_type called from compiler thread");  // FIXME
     return Handle();  // do not attempt from within compiler, unless it was cached
   }
@@ -2443,7 +2446,7 @@
       mirror = ss.as_java_mirror(class_loader, protection_domain,
                                  SignatureStream::NCDFError, CHECK_(empty));
     }
-    assert(!oopDesc::is_null(mirror), ss.as_symbol(THREAD)->as_C_string());
+    assert(!oopDesc::is_null(mirror), "%s", ss.as_symbol(THREAD)->as_C_string());
     if (ss.at_return_type())
       rt = Handle(THREAD, mirror);
     else
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -33,6 +33,7 @@
 #include "runtime/reflectionUtils.hpp"
 #include "utilities/hashtable.hpp"
 #include "utilities/hashtable.inline.hpp"
+#include "jvmci/systemDictionary_jvmci.hpp"
 
 
 // The system dictionary stores all loaded classes and maps:
@@ -192,6 +193,10 @@
   do_klass(Short_klass,                                 java_lang_Short,                           Pre                 ) \
   do_klass(Integer_klass,                               java_lang_Integer,                         Pre                 ) \
   do_klass(Long_klass,                                  java_lang_Long,                            Pre                 ) \
+                                                                                                                         \
+  /* JVMCI classes. These are loaded on-demand. */                                                                       \
+  JVMCI_WK_KLASSES_DO(do_klass) \
+
   /*end*/
 
 
@@ -209,6 +214,11 @@
 
     WKID_LIMIT,
 
+#if INCLUDE_JVMCI
+    FIRST_JVMCI_WKID = WK_KLASS_ENUM_NAME(HotSpotCompiledCode_klass),
+    LAST_JVMCI_WKID  = WK_KLASS_ENUM_NAME(Value_klass),
+#endif
+
     FIRST_WKID = NO_WKID + 1
   };
 
@@ -219,6 +229,9 @@
     // Options after this point will use resolve_or_null instead.
 
     Opt,                        // preload tried; NULL if not present
+#if INCLUDE_JVMCI
+    Jvmci,                      // preload tried; error if not present, use only with JVMCI
+#endif
     OPTION_LIMIT,
     CEIL_LG_OPTION_LIMIT = 2    // OPTION_LIMIT <= (1<<CEIL_LG_OPTION_LIMIT)
   };
@@ -398,6 +411,8 @@
   static Klass* check_klass_Pre(       Klass* k) { return check_klass(k); }
   static Klass* check_klass_Opt(       Klass* k) { return k; }
 
+  JVMCI_ONLY(static Klass* check_klass_Jvmci(Klass* k) { return k; })
+
   static bool initialize_wk_klass(WKID id, int init_opt, TRAPS);
   static void initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS);
   static void initialize_wk_klasses_through(WKID end_id, WKID &start_id, TRAPS) {
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -28,6 +28,7 @@
 #include "oops/symbol.hpp"
 #include "memory/iterator.hpp"
 #include "trace/traceMacros.hpp"
+#include "jvmci/vmSymbols_jvmci.hpp"
 
 // The class vmSymbols is a name space for fast lookup of
 // symbols commonly used in the VM.
@@ -44,7 +45,6 @@
 #define VM_SYMBOL_IGNORE(id, name)                       /*ignored*/
 #define VM_ALIAS_IGNORE(id, id2)                         /*ignored*/
 
-
 // Mapping function names to values. New entries should be added below.
 
 #define VM_SYMBOLS_DO(template, do_alias)                                                         \
@@ -300,6 +300,9 @@
   template(DEFAULT_CONTEXT_name,                      "DEFAULT_CONTEXT")                          \
   NOT_LP64(  do_alias(intptr_signature,               int_signature)  )                           \
   LP64_ONLY( do_alias(intptr_signature,               long_signature) )                           \
+                                                                                                                                      \
+  /* Support for JVMCI */                                                                                                             \
+  JVMCI_VM_SYMBOLS_DO(template, do_alias)                                                         \
                                                                                                   \
   /* common method and field names */                                                             \
   template(object_initializer_name,                   "<init>")                                   \
@@ -382,6 +385,7 @@
   template(bitCount_name,                             "bitCount")                                 \
   template(profile_name,                              "profile")                                  \
   template(equals_name,                               "equals")                                   \
+  template(length_name,                               "length")                                   \
   template(target_name,                               "target")                                   \
   template(toString_name,                             "toString")                                 \
   template(values_name,                               "values")                                   \
@@ -432,6 +436,7 @@
   template(void_long_signature,                       "()J")                                      \
   template(void_float_signature,                      "()F")                                      \
   template(void_double_signature,                     "()D")                                      \
+  template(bool_void_signature,                       "(Z)V")                                     \
   template(int_void_signature,                        "(I)V")                                     \
   template(int_int_signature,                         "(I)I")                                     \
   template(char_char_signature,                       "(C)C")                                     \
--- a/hotspot/src/share/vm/code/codeBlob.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -120,6 +120,7 @@
 
   virtual bool is_compiled_by_c2() const         { return false; }
   virtual bool is_compiled_by_c1() const         { return false; }
+  virtual bool is_compiled_by_jvmci() const      { return false; }
 
   // Casting
   nmethod* as_nmethod_or_null()                  { return is_nmethod() ? (nmethod*) this : NULL; }
@@ -380,6 +381,12 @@
 
   int _unpack_with_exception_in_tls;
 
+#if INCLUDE_JVMCI
+  // Offsets when JVMCI calls uncommon_trap.
+  int _uncommon_trap_offset;
+  int _implicit_exception_uncommon_trap_offset;
+#endif
+
   // Creation support
   DeoptimizationBlob(
     CodeBuffer* cb,
@@ -429,6 +436,21 @@
     assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");
   }
   address unpack_with_exception_in_tls() const   { return code_begin() + _unpack_with_exception_in_tls; }
+
+#if INCLUDE_JVMCI
+  // Offsets when JVMCI calls uncommon_trap.
+  void set_uncommon_trap_offset(int offset) {
+    _uncommon_trap_offset = offset;
+    assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob");
+  }
+  address uncommon_trap() const                  { return code_begin() + _uncommon_trap_offset; }
+
+  void set_implicit_exception_uncommon_trap_offset(int offset) {
+    _implicit_exception_uncommon_trap_offset = offset;
+    assert(contains(code_begin() + _implicit_exception_uncommon_trap_offset), "must be PC inside codeblob");
+  }
+  address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; }
+#endif // INCLUDE_JVMCI
 };
 
 
--- a/hotspot/src/share/vm/code/codeCache.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -365,7 +365,7 @@
   // Possibly wakes up the sweeper thread.
   NMethodSweeper::notify(code_blob_type);
   assert_locked_or_safepoint(CodeCache_lock);
-  assert(size > 0, err_msg_res("Code cache allocation request must be > 0 but is %d", size));
+  assert(size > 0, "Code cache allocation request must be > 0 but is %d", size);
   if (size <= 0) {
     return NULL;
   }
@@ -817,7 +817,7 @@
   double max_capacity = (double)heap->max_capacity();
   double result = max_capacity / unallocated_capacity;
   assert (max_capacity >= unallocated_capacity, "Must be");
-  assert (result >= 1.0, err_msg_res("reverse_free_ratio must be at least 1. It is %f", result));
+  assert (result >= 1.0, "reverse_free_ratio must be at least 1. It is %f", result);
   return result;
 }
 
--- a/hotspot/src/share/vm/code/compiledIC.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/compiledIC.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -280,11 +280,13 @@
   bool is_monomorphic = (cb != NULL && cb->is_nmethod());
   // Check that the cached_value is a klass for non-optimized monomorphic calls
   // This assertion is invalid for compiler1: a call that does not look optimized (no static stub) can be used
-  // for calling directly to vep without using the inline cache (i.e., cached_value == NULL)
+  // for calling directly to vep without using the inline cache (i.e., cached_value == NULL).
+  // For JVMCI this occurs because CHA is only used to improve inlining so call sites which could be optimized
+  // virtuals because there are no currently loaded subclasses of a type are left as virtual call sites.
 #ifdef ASSERT
   CodeBlob* caller = CodeCache::find_blob_unsafe(instruction_address());
-  bool is_c1_method = caller->is_compiled_by_c1();
-  assert( is_c1_method ||
+  bool is_c1_or_jvmci_method = caller->is_compiled_by_c1() || caller->is_compiled_by_jvmci();
+  assert( is_c1_or_jvmci_method ||
          !is_monomorphic ||
          is_optimized() ||
          !caller->is_alive() ||
--- a/hotspot/src/share/vm/code/compiledIC.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/compiledIC.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -306,7 +306,7 @@
   friend CompiledStaticCall* compiledStaticCall_at(Relocation* call_site);
 
   // Code
-  static address emit_to_interp_stub(CodeBuffer &cbuf);
+  static address emit_to_interp_stub(CodeBuffer &cbuf, address mark = NULL);
   static int to_interp_stub_size();
   static int reloc_to_interp_stub();
 
--- a/hotspot/src/share/vm/code/debugInfo.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/debugInfo.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,8 +29,6 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Constructors
 
 DebugInfoWriteStream::DebugInfoWriteStream(DebugInformationRecorder* recorder, int initial_size)
@@ -59,7 +57,7 @@
 #ifdef ASSERT
   assert(_obj_pool != NULL, "object pool does not exist");
   for (int i = _obj_pool->length() - 1; i >= 0; i--) {
-    assert(((ObjectValue*) _obj_pool->at(i))->id() != id, "should not be read twice");
+    assert(_obj_pool->at(i)->as_ObjectValue()->id() != id, "should not be read twice");
   }
 #endif
   ObjectValue* result = new ObjectValue(id);
@@ -73,7 +71,7 @@
   int id = read_int();
   assert(_obj_pool != NULL, "object pool does not exist");
   for (int i = _obj_pool->length() - 1; i >= 0; i--) {
-    ObjectValue* ov = (ObjectValue*) _obj_pool->at(i);
+    ObjectValue* ov = _obj_pool->at(i)->as_ObjectValue();
     if (ov->id() == id) {
       return ov;
     }
--- a/hotspot/src/share/vm/code/debugInfo.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/debugInfo.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,6 +41,7 @@
 // - ConstantValue   describes a constant
 
 class ConstantOopReadValue;
+class ObjectValue;
 
 class ScopeValue: public ResourceObj {
  public:
@@ -58,6 +59,11 @@
     return (ConstantOopReadValue*) this;
   }
 
+  ObjectValue* as_ObjectValue() {
+    assert(is_object(), "must be");
+    return (ObjectValue*)this;
+  }
+
   // Serialization of debugging information
   virtual void write_on(DebugInfoWriteStream* stream) = 0;
   static ScopeValue* read_from(DebugInfoReadStream* stream);
--- a/hotspot/src/share/vm/code/debugInfoRec.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/debugInfoRec.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,6 +37,9 @@
   int  _offset; // location in the stream of this scope
   int  _length; // number of bytes in the stream
   int  _hash;   // hash of stream bytes (for quicker reuse)
+#if INCLUDE_JVMCI
+  DebugInformationRecorder* _DIR;
+#endif
 
   void* operator new(size_t ignore, DebugInformationRecorder* dir) throw() {
     assert(ignore == sizeof(DIR_Chunk), "");
@@ -51,6 +54,9 @@
   DIR_Chunk(int offset, int length, DebugInformationRecorder* dir) {
     _offset = offset;
     _length = length;
+#if INCLUDE_JVMCI
+    _DIR = dir;
+#endif
     unsigned int hash = 0;
     address p = dir->stream()->buffer() + _offset;
     for (int i = 0; i < length; i++) {
@@ -77,6 +83,25 @@
     }
     return NULL;
   }
+
+#if INCLUDE_JVMCI
+  static int compare(DIR_Chunk* const & a, DIR_Chunk* const & b) {
+    if (b->_hash > a->_hash) {
+      return 1;
+    }
+    if (b->_hash < a->_hash) {
+      return -1;
+    }
+    if (b->_length > a->_length) {
+      return 1;
+    }
+    if (b->_length < a->_length) {
+      return -1;
+    }
+    address buf = a->_DIR->stream()->buffer();
+    return memcmp(buf + b->_offset, buf + a->_offset, a->_length);
+  }
+#endif
 };
 
 static inline bool compute_recording_non_safepoints() {
@@ -113,7 +138,9 @@
   _oop_recorder = oop_recorder;
 
   _all_chunks    = new GrowableArray<DIR_Chunk*>(300);
+#if !INCLUDE_JVMCI
   _shared_chunks = new GrowableArray<DIR_Chunk*>(30);
+#endif
   _next_chunk = _next_chunk_limit = NULL;
 
   add_new_pc_offset(PcDesc::lower_offset_limit);  // sentinel record
@@ -235,10 +262,13 @@
 
 
 int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
+#if !INCLUDE_JVMCI
   // Only pull this trick if non-safepoint recording
   // is enabled, for now.
-  if (!recording_non_safepoints())
+  if (!recording_non_safepoints()) {
     return serialized_null;
+  }
+#endif // INCLUDE_JVMCI
 
   NOT_PRODUCT(++dir_stats.chunks_queried);
   int stream_length = stream()->position() - stream_offset;
@@ -247,6 +277,19 @@
 
   DIR_Chunk* ns = new(this) DIR_Chunk(stream_offset, stream_length, this);
 
+#if INCLUDE_JVMCI
+  DIR_Chunk* match = _all_chunks->insert_sorted<DIR_Chunk::compare>(ns);
+  if (match != ns) {
+    // Found an existing chunk
+    NOT_PRODUCT(++dir_stats.chunks_shared);
+    assert(ns+1 == _next_chunk, "");
+    _next_chunk = ns;
+    return match->_offset;
+  } else {
+    // Inserted this chunk, so nothing to do
+    return serialized_null;
+  }
+#else // INCLUDE_JVMCI
   // Look in previously shared scopes first:
   DIR_Chunk* ms = ns->find_match(_shared_chunks, 0, this);
   if (ms != NULL) {
@@ -274,15 +317,18 @@
   // No match.  Add this guy to the list, in hopes of future shares.
   _all_chunks->append(ns);
   return serialized_null;
+#endif // INCLUDE_JVMCI
 }
 
 
 // must call add_safepoint before: it sets PcDesc and this routine uses
 // the last PcDesc set
 void DebugInformationRecorder::describe_scope(int         pc_offset,
+                                              methodHandle methodH,
                                               ciMethod*   method,
                                               int         bci,
                                               bool        reexecute,
+                                              bool        rethrow_exception,
                                               bool        is_method_handle_invoke,
                                               bool        return_oop,
                                               DebugToken* locals,
@@ -298,6 +344,7 @@
 
   // Record flags into pcDesc.
   last_pd->set_should_reexecute(reexecute);
+  last_pd->set_rethrow_exception(rethrow_exception);
   last_pd->set_is_method_handle_invoke(is_method_handle_invoke);
   last_pd->set_return_oop(return_oop);
 
@@ -305,8 +352,16 @@
   stream()->write_int(sender_stream_offset);
 
   // serialize scope
-  Metadata* method_enc = (method == NULL)? NULL: method->constant_encoding();
-  stream()->write_int(oop_recorder()->find_index(method_enc));
+  Metadata* method_enc;
+  if (method != NULL) {
+    method_enc = method->constant_encoding();
+  } else if (methodH.not_null()) {
+    method_enc = methodH();
+  } else {
+    method_enc = NULL;
+  }
+  int method_enc_index = oop_recorder()->find_index(method_enc);
+  stream()->write_int(method_enc_index);
   stream()->write_bci(bci);
   assert(method == NULL ||
          (method->is_native() && bci == 0) ||
@@ -338,7 +393,7 @@
   PcDesc* last_pd = &_pcs[_pcs_length-1];
   if (objects != NULL) {
     for (int i = objects->length() - 1; i >= 0; i--) {
-      ((ObjectValue*) objects->at(i))->set_visited(false);
+      objects->at(i)->as_ObjectValue()->set_visited(false);
     }
   }
   int offset = serialize_scope_values(objects);
--- a/hotspot/src/share/vm/code/debugInfoRec.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/debugInfoRec.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -98,9 +98,11 @@
   // by add_non_safepoint, and the locals, expressions, and monitors
   // must all be null.
   void describe_scope(int         pc_offset,
+                      methodHandle methodH,
                       ciMethod*   method,
                       int         bci,
                       bool        reexecute,
+                      bool        rethrow_exception = false,
                       bool        is_method_handle_invoke = false,
                       bool        return_oop = false,
                       DebugToken* locals      = NULL,
@@ -143,6 +145,12 @@
 
   bool recording_non_safepoints() { return _recording_non_safepoints; }
 
+  PcDesc* pcs() const { return _pcs; }
+  int pcs_length() const { return _pcs_length; }
+
+  DebugInfoWriteStream* stream() const { return _stream; }
+
+
  private:
   friend class ScopeDesc;
   friend class vframeStreamCommon;
@@ -155,13 +163,13 @@
 
   DebugInfoWriteStream* _stream;
 
-  DebugInfoWriteStream* stream() const { return _stream; }
-
   OopRecorder* _oop_recorder;
 
   // Scopes that have been described so far.
   GrowableArray<DIR_Chunk*>* _all_chunks;
+#if !INCLUDE_JVMCI
   GrowableArray<DIR_Chunk*>* _shared_chunks;
+#endif
   DIR_Chunk* _next_chunk;
   DIR_Chunk* _next_chunk_limit;
 
--- a/hotspot/src/share/vm/code/dependencies.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/dependencies.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,6 +31,7 @@
 #include "code/dependencies.hpp"
 #include "compiler/compileLog.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/objArrayKlass.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/thread.inline.hpp"
@@ -52,6 +53,9 @@
   _oop_recorder = env->oop_recorder();
   _log = env->log();
   _dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0);
+#if INCLUDE_JVMCI
+  _using_dep_values = false;
+#endif
   DEBUG_ONLY(_deps[end_marker] = NULL);
   for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) {
     _deps[i] = new(arena) GrowableArray<ciBaseObject*>(arena, 10, 0, 0);
@@ -120,6 +124,66 @@
   assert_common_2(call_site_target_value, call_site, method_handle);
 }
 
+#if INCLUDE_JVMCI
+
+Dependencies::Dependencies(Arena* arena, OopRecorder* oop_recorder, CompileLog* log) {
+  _oop_recorder = oop_recorder;
+  _log = log;
+  _dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0);
+  _using_dep_values = true;
+  DEBUG_ONLY(_dep_values[end_marker] = NULL);
+  for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) {
+    _dep_values[i] = new(arena) GrowableArray<DepValue>(arena, 10, 0, DepValue());
+  }
+  _content_bytes = NULL;
+  _size_in_bytes = (size_t)-1;
+
+  assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT), "sanity");
+}
+
+void Dependencies::assert_evol_method(Method* m) {
+  assert_common_1(evol_method, DepValue(_oop_recorder, m));
+}
+
+void Dependencies::assert_has_no_finalizable_subclasses(Klass* ctxk) {
+  check_ctxk(ctxk);
+  assert_common_1(no_finalizable_subclasses, DepValue(_oop_recorder, ctxk));
+}
+
+void Dependencies::assert_leaf_type(Klass* ctxk) {
+  if (ctxk->oop_is_array()) {
+    // As a special case, support this assertion on an array type,
+    // which reduces to an assertion on its element type.
+    // Note that this cannot be done with assertions that
+    // relate to concreteness or abstractness.
+    BasicType elemt = ArrayKlass::cast(ctxk)->element_type();
+    if (is_java_primitive(elemt))  return;   // Ex:  int[][]
+    ctxk = ObjArrayKlass::cast(ctxk)->bottom_klass();
+    //if (ctxk->is_final())  return;            // Ex:  String[][]
+  }
+  check_ctxk(ctxk);
+  assert_common_1(leaf_type, DepValue(_oop_recorder, ctxk));
+}
+
+void Dependencies::assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck) {
+  check_ctxk_abstract(ctxk);
+  DepValue ctxk_dv(_oop_recorder, ctxk);
+  DepValue conck_dv(_oop_recorder, conck, &ctxk_dv);
+  assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, conck_dv);
+}
+
+void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) {
+  check_ctxk(ctxk);
+  assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm));
+}
+
+void Dependencies::assert_call_site_target_value(oop call_site, oop method_handle) {
+  assert_common_2(call_site_target_value, DepValue(_oop_recorder, JNIHandles::make_local(call_site)), DepValue(_oop_recorder, JNIHandles::make_local(method_handle)));
+}
+
+#endif // INCLUDE_JVMCI
+
+
 // Helper function.  If we are adding a new dep. under ctxk2,
 // try to find an old dep. under a broader* ctxk1.  If there is
 //
@@ -230,6 +294,78 @@
   deps->append(x2);
 }
 
+#if INCLUDE_JVMCI
+bool Dependencies::maybe_merge_ctxk(GrowableArray<DepValue>* deps,
+                                    int ctxk_i, DepValue ctxk2_dv) {
+  Klass* ctxk1 = deps->at(ctxk_i).as_klass(_oop_recorder);
+  Klass* ctxk2 = ctxk2_dv.as_klass(_oop_recorder);
+  if (ctxk2->is_subtype_of(ctxk1)) {
+    return true;  // success, and no need to change
+  } else if (ctxk1->is_subtype_of(ctxk2)) {
+    // new context class fully subsumes previous one
+    deps->at_put(ctxk_i, ctxk2_dv);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+void Dependencies::assert_common_1(DepType dept, DepValue x) {
+  assert(dep_args(dept) == 1, "sanity");
+  //log_dependency(dept, x);
+  GrowableArray<DepValue>* deps = _dep_values[dept];
+
+  // see if the same (or a similar) dep is already recorded
+  if (note_dep_seen(dept, x)) {
+    assert(deps->find(x) >= 0, "sanity");
+  } else {
+    deps->append(x);
+  }
+}
+
+void Dependencies::assert_common_2(DepType dept,
+                                   DepValue x0, DepValue x1) {
+  assert(dep_args(dept) == 2, "sanity");
+  //log_dependency(dept, x0, x1);
+  GrowableArray<DepValue>* deps = _dep_values[dept];
+
+  // see if the same (or a similar) dep is already recorded
+  bool has_ctxk = has_explicit_context_arg(dept);
+  if (has_ctxk) {
+    assert(dep_context_arg(dept) == 0, "sanity");
+    if (note_dep_seen(dept, x1)) {
+      // look in this bucket for redundant assertions
+      const int stride = 2;
+      for (int i = deps->length(); (i -= stride) >= 0; ) {
+        DepValue y1 = deps->at(i+1);
+        if (x1 == y1) {  // same subject; check the context
+          if (maybe_merge_ctxk(deps, i+0, x0)) {
+            return;
+          }
+        }
+      }
+    }
+  } else {
+    assert(dep_implicit_context_arg(dept) == 0, "sanity");
+    if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) {
+      // look in this bucket for redundant assertions
+      const int stride = 2;
+      for (int i = deps->length(); (i -= stride) >= 0; ) {
+        DepValue y0 = deps->at(i+0);
+        DepValue y1 = deps->at(i+1);
+        if (x0 == y0 && x1 == y1) {
+          return;
+        }
+      }
+    }
+  }
+
+  // append the assertion in the correct bucket:
+  deps->append(x0);
+  deps->append(x1);
+}
+#endif // INCLUDE_JVMCI
+
 /// Support for encoding dependencies into an nmethod:
 
 void Dependencies::copy_to(nmethod* nm) {
@@ -256,7 +392,40 @@
 static int sort_dep_arg_3(ciBaseObject** p1, ciBaseObject** p2)
 { return sort_dep(p1, p2, 3); }
 
+#if INCLUDE_JVMCI
+// metadata deps are sorted before object deps
+static int sort_dep_value(Dependencies::DepValue* p1, Dependencies::DepValue* p2, int narg) {
+  for (int i = 0; i < narg; i++) {
+    int diff = p1[i].sort_key() - p2[i].sort_key();
+    if (diff != 0)  return diff;
+  }
+  return 0;
+}
+static int sort_dep_value_arg_1(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
+{ return sort_dep_value(p1, p2, 1); }
+static int sort_dep_value_arg_2(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
+{ return sort_dep_value(p1, p2, 2); }
+static int sort_dep_value_arg_3(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
+{ return sort_dep_value(p1, p2, 3); }
+#endif // INCLUDE_JVMCI
+
 void Dependencies::sort_all_deps() {
+#if INCLUDE_JVMCI
+  if (_using_dep_values) {
+    for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
+      DepType dept = (DepType)deptv;
+      GrowableArray<DepValue>* deps = _dep_values[dept];
+      if (deps->length() <= 1)  continue;
+      switch (dep_args(dept)) {
+      case 1: deps->sort(sort_dep_value_arg_1, 1); break;
+      case 2: deps->sort(sort_dep_value_arg_2, 2); break;
+      case 3: deps->sort(sort_dep_value_arg_3, 3); break;
+      default: ShouldNotReachHere();
+      }
+    }
+    return;
+  }
+#endif // INCLUDE_JVMCI
   for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
     DepType dept = (DepType)deptv;
     GrowableArray<ciBaseObject*>* deps = _deps[dept];
@@ -272,6 +441,16 @@
 
 size_t Dependencies::estimate_size_in_bytes() {
   size_t est_size = 100;
+#if INCLUDE_JVMCI
+  if (_using_dep_values) {
+    for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
+      DepType dept = (DepType)deptv;
+      GrowableArray<DepValue>* deps = _dep_values[dept];
+      est_size += deps->length() * 2;  // tags and argument(s)
+    }
+    return est_size;
+  }
+#endif // INCLUDE_JVMCI
   for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
     DepType dept = (DepType)deptv;
     GrowableArray<ciBaseObject*>* deps = _deps[dept];
@@ -311,6 +490,37 @@
   // cast is safe, no deps can overflow INT_MAX
   CompressedWriteStream bytes((int)estimate_size_in_bytes());
 
+#if INCLUDE_JVMCI
+  if (_using_dep_values) {
+    for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
+      DepType dept = (DepType)deptv;
+      GrowableArray<DepValue>* deps = _dep_values[dept];
+      if (deps->length() == 0)  continue;
+      int stride = dep_args(dept);
+      int ctxkj  = dep_context_arg(dept);  // -1 if no context arg
+      assert(stride > 0, "sanity");
+      for (int i = 0; i < deps->length(); i += stride) {
+        jbyte code_byte = (jbyte)dept;
+        int skipj = -1;
+        if (ctxkj >= 0 && ctxkj+1 < stride) {
+          Klass*  ctxk = deps->at(i+ctxkj+0).as_klass(_oop_recorder);
+          DepValue x = deps->at(i+ctxkj+1);  // following argument
+          if (ctxk == ctxk_encoded_as_null(dept, x.as_metadata(_oop_recorder))) {
+            skipj = ctxkj;  // we win:  maybe one less oop to keep track of
+            code_byte |= default_context_type_bit;
+          }
+        }
+        bytes.write_byte(code_byte);
+        for (int j = 0; j < stride; j++) {
+          if (j == skipj)  continue;
+          DepValue v = deps->at(i+j);
+          int idx = v.index();
+          bytes.write_int(idx);
+        }
+      }
+    }
+  } else {
+#endif // INCLUDE_JVMCI
   for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
     DepType dept = (DepType)deptv;
     GrowableArray<ciBaseObject*>* deps = _deps[dept];
@@ -344,6 +554,9 @@
       }
     }
   }
+#if INCLUDE_JVMCI
+  }
+#endif
 
   // write a sentinel byte to mark the end
   bytes.write_byte(end_marker);
@@ -400,7 +613,7 @@
 }
 
 void Dependencies::check_valid_dependency_type(DepType dept) {
-  guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, err_msg("invalid dependency type: %d", (int) dept));
+  guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, "invalid dependency type: %d", (int) dept);
 }
 
 // for the sake of the compiler log, print out current dependencies:
@@ -540,10 +753,10 @@
 }
 
 void Dependencies::print_dependency(DepType dept, GrowableArray<DepArgument>* args,
-                                    Klass* witness) {
+                                    Klass* witness, outputStream* st) {
   ResourceMark rm;
   ttyLocker ttyl;   // keep the following output all in one block
-  tty->print_cr("%s of type %s",
+  st->print_cr("%s of type %s",
                 (witness == NULL)? "Dependency": "Failed dependency",
                 dep_name(dept));
   // print arguments
@@ -565,22 +778,22 @@
     } else {
       what = "object ";
     }
-    tty->print("  %s = %s", what, (put_star? "*": ""));
+    st->print("  %s = %s", what, (put_star? "*": ""));
     if (arg.is_klass()) {
-      tty->print("%s", ((Klass*)arg.metadata_value())->external_name());
+      st->print("%s", ((Klass*)arg.metadata_value())->external_name());
     } else if (arg.is_method()) {
-      ((Method*)arg.metadata_value())->print_value();
+      ((Method*)arg.metadata_value())->print_value_on(st);
     } else if (arg.is_oop()) {
-      arg.oop_value()->print_value_on(tty);
+      arg.oop_value()->print_value_on(st);
     } else {
       ShouldNotReachHere(); // Provide impl for this type.
     }
 
-    tty->cr();
+    st->cr();
   }
   if (witness != NULL) {
     bool put_star = !Dependencies::is_concrete_klass(witness);
-    tty->print_cr("  witness = %s%s",
+    st->print_cr("  witness = %s%s",
                   (put_star? "*": ""),
                   witness->external_name());
   }
@@ -600,14 +813,19 @@
   }
   int argslen = args->length();
   if (_deps != NULL && _deps->log() != NULL) {
-    Dependencies::write_dependency_to(_deps->log(), type(), args, witness);
+    if (ciEnv::current() != NULL) {
+      Dependencies::write_dependency_to(_deps->log(), type(), args, witness);
+    } else {
+      // Treat the CompileLog as an xmlstream instead
+      Dependencies::write_dependency_to((xmlStream*)_deps->log(), type(), args, witness);
+    }
   } else {
     Dependencies::write_dependency_to(xtty, type(), args, witness);
   }
   guarantee(argslen == args->length(), "args array cannot grow inside nested ResoureMark scope");
 }
 
-void Dependencies::DepStream::print_dependency(Klass* witness, bool verbose) {
+void Dependencies::DepStream::print_dependency(Klass* witness, bool verbose, outputStream* st) {
   ResourceMark rm;
   int nargs = argument_count();
   GrowableArray<DepArgument>* args = new GrowableArray<DepArgument>(nargs);
@@ -619,12 +837,12 @@
     }
   }
   int argslen = args->length();
-  Dependencies::print_dependency(type(), args, witness);
+  Dependencies::print_dependency(type(), args, witness, st);
   if (verbose) {
     if (_code != NULL) {
-      tty->print("  code: ");
-      _code->print_value_on(tty);
-      tty->cr();
+      st->print("  code: ");
+      _code->print_value_on(st);
+      st->cr();
     }
   }
   guarantee(argslen == args->length(), "args array cannot grow inside nested ResoureMark scope");
--- a/hotspot/src/share/vm/code/dependencies.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/dependencies.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -202,10 +202,59 @@
 
   static void check_valid_dependency_type(DepType dept);
 
+#if INCLUDE_JVMCI
+  // A Metadata* or object value recorded in an OopRecorder
+  class DepValue VALUE_OBJ_CLASS_SPEC {
+   private:
+    // Unique identifier of the value within the associated OopRecorder that
+    // encodes both the category of the value (0: invalid, positive: metadata, negative: object)
+    // and the index within a category specific array (metadata: index + 1, object: -(index + 1))
+    int _id;
+
+   public:
+    DepValue() : _id(0) {}
+    DepValue(OopRecorder* rec, Metadata* metadata, DepValue* candidate = NULL) {
+      assert(candidate == NULL || candidate->is_metadata(), "oops");
+      if (candidate != NULL && candidate->as_metadata(rec) == metadata) {
+        _id = candidate->_id;
+      } else {
+        _id = rec->find_index(metadata) + 1;
+      }
+    }
+    DepValue(OopRecorder* rec, jobject obj, DepValue* candidate = NULL) {
+      assert(candidate == NULL || candidate->is_object(), "oops");
+      if (candidate != NULL && candidate->as_object(rec) == obj) {
+        _id = candidate->_id;
+      } else {
+        _id = -(rec->find_index(obj) + 1);
+      }
+    }
+
+    // Used to sort values in ascending order of index() with metadata values preceding object values
+    int sort_key() const { return -_id; }
+
+    bool operator == (const DepValue& other) const   { return other._id == _id; }
+
+    bool is_valid() const             { return _id != 0; }
+    int  index() const                { assert(is_valid(), "oops"); return _id < 0 ? -(_id + 1) : _id - 1; }
+    bool is_metadata() const          { assert(is_valid(), "oops"); return _id > 0; }
+    bool is_object() const            { assert(is_valid(), "oops"); return _id < 0; }
+
+    Metadata*  as_metadata(OopRecorder* rec) const    { assert(is_metadata(), "oops"); return rec->metadata_at(index()); }
+    Klass*     as_klass(OopRecorder* rec) const       { assert(as_metadata(rec)->is_klass(), "oops"); return (Klass*) as_metadata(rec); }
+    Method*    as_method(OopRecorder* rec) const      { assert(as_metadata(rec)->is_method(), "oops"); return (Method*) as_metadata(rec); }
+    jobject    as_object(OopRecorder* rec) const      { assert(is_object(), "oops"); return rec->oop_at(index()); }
+  };
+#endif // INCLUDE_JVMCI
+
  private:
   // State for writing a new set of dependencies:
   GrowableArray<int>*       _dep_seen;  // (seen[h->ident] & (1<<dept))
   GrowableArray<ciBaseObject*>*  _deps[TYPE_LIMIT];
+#if INCLUDE_JVMCI
+  bool _using_dep_values;
+  GrowableArray<DepValue>*  _dep_values[TYPE_LIMIT];
+#endif
 
   static const char* _dep_name[TYPE_LIMIT];
   static int         _dep_args[TYPE_LIMIT];
@@ -224,8 +273,25 @@
     return (seen & (1<<dept)) != 0;
   }
 
+#if INCLUDE_JVMCI
+  bool note_dep_seen(int dept, DepValue x) {
+    assert(dept < BitsPerInt, "oops");
+    // place metadata deps at even indexes, object deps at odd indexes
+    int x_id = x.is_metadata() ? x.index() * 2 : (x.index() * 2) + 1;
+    assert(_dep_seen != NULL, "deps must be writable");
+    int seen = _dep_seen->at_grow(x_id, 0);
+    _dep_seen->at_put(x_id, seen | (1<<dept));
+    // return true if we've already seen dept/x
+    return (seen & (1<<dept)) != 0;
+  }
+#endif
+
   bool maybe_merge_ctxk(GrowableArray<ciBaseObject*>* deps,
                         int ctxk_i, ciKlass* ctxk);
+#if INCLUDE_JVMCI
+  bool maybe_merge_ctxk(GrowableArray<DepValue>* deps,
+                        int ctxk_i, DepValue ctxk);
+#endif
 
   void sort_all_deps();
   size_t estimate_size_in_bytes();
@@ -247,6 +313,9 @@
   Dependencies(ciEnv* env) {
     initialize(env);
   }
+#if INCLUDE_JVMCI
+  Dependencies(Arena* arena, OopRecorder* oop_recorder, CompileLog* log);
+#endif
 
  private:
   // Check for a valid context type.
@@ -279,6 +348,27 @@
   void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
   void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
 
+#if INCLUDE_JVMCI
+ private:
+  static void check_ctxk(Klass* ctxk) {
+    assert(ctxk->oop_is_instance(), "java types only");
+  }
+  static void check_ctxk_abstract(Klass* ctxk) {
+    check_ctxk(ctxk);
+    assert(ctxk->is_abstract(), "must be abstract");
+  }
+  void assert_common_1(DepType dept, DepValue x);
+  void assert_common_2(DepType dept, DepValue x0, DepValue x1);
+
+ public:
+  void assert_evol_method(Method* m);
+  void assert_has_no_finalizable_subclasses(Klass* ctxk);
+  void assert_leaf_type(Klass* ctxk);
+  void assert_unique_concrete_method(Klass* ctxk, Method* uniqm);
+  void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck);
+  void assert_call_site_target_value(oop callSite, oop methodHandle);
+#endif // INCLUDE_JVMCI
+
   // Define whether a given method or type is concrete.
   // These methods define the term "concrete" as used in this module.
   // For this module, an "abstract" class is one which is non-concrete.
@@ -422,7 +512,7 @@
 
   static void print_dependency(DepType dept,
                                GrowableArray<DepArgument>* args,
-                               Klass* witness = NULL);
+                               Klass* witness = NULL, outputStream* st = tty);
 
  private:
   // helper for encoding common context types as zero:
@@ -534,7 +624,7 @@
     void log_dependency(Klass* witness = NULL);
 
     // Print the current dependency to tty.
-    void print_dependency(Klass* witness = NULL, bool verbose = false);
+    void print_dependency(Klass* witness = NULL, bool verbose = false, outputStream* st = tty);
   };
   friend class Dependencies::DepStream;
 
--- a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -27,8 +27,6 @@
 #include "code/nmethod.hpp"
 #include "memory/allocation.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 void ExceptionHandlerTable::add_entry(HandlerTableEntry entry) {
   _nesting.check();
   if (_length >= _size) {
@@ -102,9 +100,12 @@
 
 void ExceptionHandlerTable::copy_to(nmethod* nm) {
   assert(size_in_bytes() == nm->handler_table_size(), "size of space allocated in nmethod incorrect");
-  memmove(nm->handler_table_begin(), _table, size_in_bytes());
+  copy_bytes_to(nm->handler_table_begin());
 }
 
+void ExceptionHandlerTable::copy_bytes_to(address addr) {
+  memmove(addr, _table, size_in_bytes());
+}
 
 HandlerTableEntry* ExceptionHandlerTable::entry_for(int catch_pco, int handler_bci, int scope_depth) const {
   HandlerTableEntry* t = subtable_for(catch_pco);
@@ -186,7 +187,7 @@
 void ImplicitExceptionTable::print(address base) const {
   tty->print("{");
   for( uint i=0; i<len(); i++ )
-    tty->print("< " INTPTR_FORMAT ", " INTPTR_FORMAT " > ",base + *adr(i), base + *(adr(i)+1));
+    tty->print("< " INTPTR_FORMAT ", " INTPTR_FORMAT " > ", p2i(base + *adr(i)), p2i(base + *(adr(i)+1)));
   tty->print_cr("}");
 }
 
@@ -225,6 +226,6 @@
   for (uint i = 0; i < len(); i++) {
      if ((*adr(i) > (unsigned int)nm->insts_size()) ||
          (*(adr(i)+1) > (unsigned int)nm->insts_size()))
-       fatal(err_msg("Invalid offset in ImplicitExceptionTable at " PTR_FORMAT, _data));
+       fatal("Invalid offset in ImplicitExceptionTable at " PTR_FORMAT, p2i(_data));
   }
 }
--- a/hotspot/src/share/vm/code/exceptionHandlerTable.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/exceptionHandlerTable.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -89,11 +89,11 @@
   int                _size;     // the number of allocated entries
   ReallocMark        _nesting;  // assertion check for reallocations
 
+ public:
   // add the entry & grow the table if needed
   void add_entry(HandlerTableEntry entry);
   HandlerTableEntry* subtable_for(int catch_pco) const;
 
- public:
   // (compile-time) construction within compiler
   ExceptionHandlerTable(int initial_size = 8);
 
@@ -116,6 +116,7 @@
   // nmethod support
   int  size_in_bytes() const { return round_to(_length * sizeof(HandlerTableEntry), oopSize); }
   void copy_to(nmethod* nm);
+  void copy_bytes_to(address addr);
 
   // lookup
   HandlerTableEntry* entry_for(int catch_pco, int handler_bci, int scope_depth) const;
--- a/hotspot/src/share/vm/code/icBuffer.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/icBuffer.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,8 +38,6 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/stubRoutines.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 DEF_STUB_INTERFACE(ICStub);
 
 StubQueue* InlineCacheBuffer::_buffer    = NULL;
@@ -97,7 +95,7 @@
 }
 
 void ICStub::print() {
-  tty->print_cr("ICStub: site: " INTPTR_FORMAT, _ic_site);
+  tty->print_cr("ICStub: site: " INTPTR_FORMAT, p2i(_ic_site));
 }
 #endif
 
@@ -175,7 +173,7 @@
   assert (CompiledIC_lock->is_locked(), "");
   if (TraceICBuffer) {
     tty->print_cr("  create transition stub for " INTPTR_FORMAT " destination " INTPTR_FORMAT " cached value " INTPTR_FORMAT,
-                  ic->instruction_address(), entry, cached_value);
+                  p2i(ic->instruction_address()), p2i(entry), p2i(cached_value));
   }
 
   // If an transition stub is already associate with the inline cache, then we remove the association.
@@ -230,6 +228,6 @@
   _pending_released = icholder;
   _pending_count++;
   if (TraceICBuffer) {
-    tty->print_cr("enqueueing icholder " INTPTR_FORMAT " to be freed", icholder);
+    tty->print_cr("enqueueing icholder " INTPTR_FORMAT " to be freed", p2i(icholder));
   }
 }
--- a/hotspot/src/share/vm/code/nmethod.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #include "code/codeCache.hpp"
 #include "code/compiledIC.hpp"
 #include "code/dependencies.hpp"
+#include "code/nativeInst.hpp"
 #include "code/nmethod.hpp"
 #include "code/scopeDesc.hpp"
 #include "compiler/abstractCompiler.hpp"
@@ -46,11 +47,27 @@
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/xmlstream.hpp"
+#ifdef TARGET_ARCH_x86
+# include "nativeInst_x86.hpp"
+#endif
+#ifdef TARGET_ARCH_sparc
+# include "nativeInst_sparc.hpp"
+#endif
+#ifdef TARGET_ARCH_zero
+# include "nativeInst_zero.hpp"
+#endif
+#ifdef TARGET_ARCH_arm
+# include "nativeInst_arm.hpp"
+#endif
+#ifdef TARGET_ARCH_ppc
+# include "nativeInst_ppc.hpp"
+#endif
 #ifdef SHARK
 #include "shark/sharkCompiler.hpp"
 #endif
-
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciJavaClasses.hpp"
+#endif
 
 unsigned char nmethod::_global_unloading_clock = 0;
 
@@ -84,6 +101,11 @@
   }
   return compiler()->is_c1();
 }
+bool nmethod::is_compiled_by_jvmci() const {
+  if (compiler() == NULL || method() == NULL)  return false;  // can happen during debug printing
+  if (is_native_method()) return false;
+  return compiler()->is_jvmci();
+}
 bool nmethod::is_compiled_by_c2() const {
   if (compiler() == NULL) {
     return false;
@@ -108,8 +130,7 @@
 #ifndef PRODUCT
 // These variables are put into one block to reduce relocations
 // and make it simpler to print from the debugger.
-static
-struct nmethod_stats_struct {
+struct java_nmethod_stats_struct {
   int nmethod_count;
   int total_size;
   int relocation_size;
@@ -122,6 +143,7 @@
   int handler_table_size;
   int nul_chk_table_size;
   int oops_size;
+  int metadata_size;
 
   void note_nmethod(nmethod* nm) {
     nmethod_count += 1;
@@ -131,39 +153,46 @@
     insts_size          += nm->insts_size();
     stub_size           += nm->stub_size();
     oops_size           += nm->oops_size();
+    metadata_size       += nm->metadata_size();
     scopes_data_size    += nm->scopes_data_size();
     scopes_pcs_size     += nm->scopes_pcs_size();
     dependencies_size   += nm->dependencies_size();
     handler_table_size  += nm->handler_table_size();
     nul_chk_table_size  += nm->nul_chk_table_size();
   }
-  void print_nmethod_stats() {
+  void print_nmethod_stats(const char* name) {
     if (nmethod_count == 0)  return;
-    tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count);
+    tty->print_cr("Statistics for %d bytecoded nmethods for %s:", nmethod_count, name);
     if (total_size != 0)          tty->print_cr(" total in heap  = %d", total_size);
+    if (nmethod_count != 0)       tty->print_cr(" header         = " SIZE_FORMAT, nmethod_count * sizeof(nmethod));
     if (relocation_size != 0)     tty->print_cr(" relocation     = %d", relocation_size);
     if (consts_size != 0)         tty->print_cr(" constants      = %d", consts_size);
     if (insts_size != 0)          tty->print_cr(" main code      = %d", insts_size);
     if (stub_size != 0)           tty->print_cr(" stub code      = %d", stub_size);
     if (oops_size != 0)           tty->print_cr(" oops           = %d", oops_size);
+    if (metadata_size != 0)       tty->print_cr(" metadata       = %d", metadata_size);
     if (scopes_data_size != 0)    tty->print_cr(" scopes data    = %d", scopes_data_size);
     if (scopes_pcs_size != 0)     tty->print_cr(" scopes pcs     = %d", scopes_pcs_size);
     if (dependencies_size != 0)   tty->print_cr(" dependencies   = %d", dependencies_size);
     if (handler_table_size != 0)  tty->print_cr(" handler table  = %d", handler_table_size);
     if (nul_chk_table_size != 0)  tty->print_cr(" nul chk table  = %d", nul_chk_table_size);
   }
-
+};
+
+struct native_nmethod_stats_struct {
   int native_nmethod_count;
   int native_total_size;
   int native_relocation_size;
   int native_insts_size;
   int native_oops_size;
+  int native_metadata_size;
   void note_native_nmethod(nmethod* nm) {
     native_nmethod_count += 1;
     native_total_size       += nm->size();
     native_relocation_size  += nm->relocation_size();
     native_insts_size       += nm->insts_size();
     native_oops_size        += nm->oops_size();
+    native_metadata_size    += nm->metadata_size();
   }
   void print_native_nmethod_stats() {
     if (native_nmethod_count == 0)  return;
@@ -172,8 +201,11 @@
     if (native_relocation_size != 0)  tty->print_cr(" N. relocation  = %d", native_relocation_size);
     if (native_insts_size != 0)       tty->print_cr(" N. main code   = %d", native_insts_size);
     if (native_oops_size != 0)        tty->print_cr(" N. oops        = %d", native_oops_size);
+    if (native_metadata_size != 0)    tty->print_cr(" N. metadata    = %d", native_metadata_size);
   }
-
+};
+
+struct pc_nmethod_stats_struct {
   int pc_desc_resets;   // number of resets (= number of caches)
   int pc_desc_queries;  // queries to nmethod::find_pc_desc
   int pc_desc_approx;   // number of those which have approximate true
@@ -194,9 +226,51 @@
                   pc_desc_repeats, pc_desc_hits,
                   pc_desc_tests, pc_desc_searches, pc_desc_adds);
   }
-} nmethod_stats;
-#endif //PRODUCT
-
+};
+
+#ifdef COMPILER1
+static java_nmethod_stats_struct c1_java_nmethod_stats;
+#endif
+#ifdef COMPILER2
+static java_nmethod_stats_struct c2_java_nmethod_stats;
+#endif
+#if INCLUDE_JVMCI
+static java_nmethod_stats_struct jvmci_java_nmethod_stats;
+#endif
+#ifdef SHARK
+static java_nmethod_stats_struct shark_java_nmethod_stats;
+#endif
+static java_nmethod_stats_struct unknown_java_nmethod_stats;
+
+static native_nmethod_stats_struct native_nmethod_stats;
+static pc_nmethod_stats_struct pc_nmethod_stats;
+
+static void note_java_nmethod(nmethod* nm) {
+#ifdef COMPILER1
+  if (nm->is_compiled_by_c1()) {
+    c1_java_nmethod_stats.note_nmethod(nm);
+  } else
+#endif
+#ifdef COMPILER2
+  if (nm->is_compiled_by_c2()) {
+    c2_java_nmethod_stats.note_nmethod(nm);
+  } else
+#endif
+#if INCLUDE_JVMCI
+  if (nm->is_compiled_by_jvmci()) {
+    jvmci_java_nmethod_stats.note_nmethod(nm);
+  } else
+#endif
+#ifdef SHARK
+  if (nm->is_compiled_by_shark()) {
+    shark_java_nmethod_stats.note_nmethod(nm);
+  } else
+#endif
+  {
+    unknown_java_nmethod_stats.note_nmethod(nm);
+  }
+}
+#endif // !PRODUCT
 
 //---------------------------------------------------------------------------------
 
@@ -276,7 +350,7 @@
 
 // Helper used by both find_pc_desc methods.
 static inline bool match_desc(PcDesc* pc, int pc_offset, bool approximate) {
-  NOT_PRODUCT(++nmethod_stats.pc_desc_tests);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_tests);
   if (!approximate)
     return pc->pc_offset() == pc_offset;
   else
@@ -288,7 +362,7 @@
     _pc_descs[0] = NULL; // native method; no PcDescs at all
     return;
   }
-  NOT_PRODUCT(++nmethod_stats.pc_desc_resets);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_resets);
   // reset the cache by filling it with benign (non-null) values
   assert(initial_pc_desc->pc_offset() < 0, "must be sentinel");
   for (int i = 0; i < cache_size; i++)
@@ -296,8 +370,8 @@
 }
 
 PcDesc* PcDescCache::find_pc_desc(int pc_offset, bool approximate) {
-  NOT_PRODUCT(++nmethod_stats.pc_desc_queries);
-  NOT_PRODUCT(if (approximate) ++nmethod_stats.pc_desc_approx);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_queries);
+  NOT_PRODUCT(if (approximate) ++pc_nmethod_stats.pc_desc_approx);
 
   // Note: one might think that caching the most recently
   // read value separately would be a win, but one would be
@@ -313,7 +387,7 @@
   res = _pc_descs[0];
   if (res == NULL) return NULL;  // native method; no PcDescs at all
   if (match_desc(res, pc_offset, approximate)) {
-    NOT_PRODUCT(++nmethod_stats.pc_desc_repeats);
+    NOT_PRODUCT(++pc_nmethod_stats.pc_desc_repeats);
     return res;
   }
 
@@ -322,7 +396,7 @@
     res = _pc_descs[i];
     if (res->pc_offset() < 0) break;  // optimization: skip empty cache
     if (match_desc(res, pc_offset, approximate)) {
-      NOT_PRODUCT(++nmethod_stats.pc_desc_hits);
+      NOT_PRODUCT(++pc_nmethod_stats.pc_desc_hits);
       return res;
     }
   }
@@ -332,7 +406,7 @@
 }
 
 void PcDescCache::add_pc_desc(PcDesc* pc_desc) {
-  NOT_PRODUCT(++nmethod_stats.pc_desc_adds);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_adds);
   // Update the LRU cache by shifting pc_desc forward.
   for (int i = 0; i < cache_size; i++)  {
     PcDesc* next = _pc_descs[i];
@@ -459,7 +533,7 @@
   _marked_for_deoptimization  = 0;
   _lock_count                 = 0;
   _stack_traversal_mark       = 0;
-  _unload_reported            = false;           // jvmti state
+  _unload_reported            = false; // jvmti state
 
 #ifdef ASSERT
   _oops_are_stale             = false;
@@ -478,6 +552,10 @@
 #if INCLUDE_RTM_OPT
   _rtm_state               = NoRTM;
 #endif
+#if INCLUDE_JVMCI
+  _jvmci_installed_code   = NULL;
+  _speculation_log        = NULL;
+#endif
 }
 
 nmethod* nmethod::new_native_nmethod(methodHandle method,
@@ -503,7 +581,7 @@
                                             code_buffer, frame_size,
                                             basic_lock_owner_sp_offset,
                                             basic_lock_sp_offset, oop_maps);
-    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_native_nmethod(nm));
+    NOT_PRODUCT(if (nm != NULL)  native_nmethod_stats.note_native_nmethod(nm));
     if ((PrintAssembly || CompilerOracle::should_print(method)) && nm != NULL) {
       Disassembler::decode(nm);
     }
@@ -531,6 +609,10 @@
   ImplicitExceptionTable* nul_chk_table,
   AbstractCompiler* compiler,
   int comp_level
+#if INCLUDE_JVMCI
+  , Handle installed_code,
+  Handle speculationLog
+#endif
 )
 {
   assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR");
@@ -553,7 +635,12 @@
             handler_table,
             nul_chk_table,
             compiler,
-            comp_level);
+            comp_level
+#if INCLUDE_JVMCI
+            , installed_code,
+            speculationLog
+#endif
+            );
 
     if (nm != NULL) {
       // To make dependency checking during class loading fast, record
@@ -578,7 +665,7 @@
           InstanceKlass::cast(klass)->add_dependent_nmethod(nm);
         }
       }
-      NOT_PRODUCT(nmethod_stats.note_nmethod(nm));
+      NOT_PRODUCT(if (nm != NULL)  note_java_nmethod(nm));
       if (PrintAssembly || CompilerOracle::has_option_string(method, "PrintAssembly")) {
         Disassembler::decode(nm);
       }
@@ -593,7 +680,10 @@
   return nm;
 }
 
-
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4355) //  warning C4355: 'this' : used in base member initializer list
+#endif
 // For native wrappers
 nmethod::nmethod(
   Method* method,
@@ -683,6 +773,10 @@
   }
 }
 
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
 void* nmethod::operator new(size_t size, int nmethod_size, int comp_level) throw () {
   return CodeCache::allocate(nmethod_size, CodeCache::get_code_blob_type(comp_level));
 }
@@ -703,6 +797,10 @@
   ImplicitExceptionTable* nul_chk_table,
   AbstractCompiler* compiler,
   int comp_level
+#if INCLUDE_JVMCI
+  , Handle installed_code,
+  Handle speculation_log
+#endif
   )
   : CodeBlob("nmethod", code_buffer, sizeof(nmethod),
              nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps),
@@ -727,15 +825,42 @@
     _consts_offset           = content_offset()      + code_buffer->total_offset_of(code_buffer->consts());
     _stub_offset             = content_offset()      + code_buffer->total_offset_of(code_buffer->stubs());
 
+#if INCLUDE_JVMCI
+    _jvmci_installed_code = installed_code();
+    _speculation_log = (instanceOop)speculation_log();
+
+    if (compiler->is_jvmci()) {
+      // JVMCI might not produce any stub sections
+      if (offsets->value(CodeOffsets::Exceptions) != -1) {
+        _exception_offset        = code_offset()          + offsets->value(CodeOffsets::Exceptions);
+      } else {
+        _exception_offset = -1;
+      }
+      if (offsets->value(CodeOffsets::Deopt) != -1) {
+        _deoptimize_offset       = code_offset()          + offsets->value(CodeOffsets::Deopt);
+      } else {
+        _deoptimize_offset = -1;
+      }
+      if (offsets->value(CodeOffsets::DeoptMH) != -1) {
+        _deoptimize_mh_offset  = code_offset()          + offsets->value(CodeOffsets::DeoptMH);
+      } else {
+        _deoptimize_mh_offset  = -1;
+      }
+    } else {
+#endif
     // Exception handler and deopt handler are in the stub section
     assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
     assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
+
     _exception_offset        = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
     _deoptimize_offset       = _stub_offset          + offsets->value(CodeOffsets::Deopt);
     if (offsets->value(CodeOffsets::DeoptMH) != -1) {
       _deoptimize_mh_offset  = _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
     } else {
       _deoptimize_mh_offset  = -1;
+#if INCLUDE_JVMCI
+    }
+#endif
     }
     if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
       _unwind_handler_offset = code_offset()         + offsets->value(CodeOffsets::UnwindHandler);
@@ -779,12 +904,12 @@
 
     // we use the information of entry points to find out if a method is
     // static or non static
-    assert(compiler->is_c2() ||
+    assert(compiler->is_c2() || compiler->is_jvmci() ||
            _method->is_static() == (entry_point() == _verified_entry_point),
            " entry points must be same for static methods and vice versa");
   }
 
-  bool printnmethods = PrintNMethods
+  bool printnmethods = PrintNMethods || PrintNMethodsAtLevel == _comp_level
     || CompilerOracle::should_print(_method)
     || CompilerOracle::has_option_string(_method, "PrintNMethods");
   if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) {
@@ -792,7 +917,6 @@
   }
 }
 
-
 // Print a short set of xml attributes to identify this nmethod.  The
 // output should be embedded in some other element.
 void nmethod::log_identity(xmlStream* log) const {
@@ -809,9 +933,9 @@
 
 
 #define LOG_OFFSET(log, name)                    \
-  if ((intptr_t)name##_end() - (intptr_t)name##_begin()) \
-    log->print(" " XSTR(name) "_offset='%d'"    , \
-               (intptr_t)name##_begin() - (intptr_t)this)
+  if (p2i(name##_end()) - p2i(name##_begin())) \
+    log->print(" " XSTR(name) "_offset='" INTX_FORMAT "'"    , \
+               p2i(name##_begin()) - p2i(this))
 
 
 void nmethod::log_new_nmethod() const {
@@ -820,8 +944,8 @@
     HandleMark hm;
     xtty->begin_elem("nmethod");
     log_identity(xtty);
-    xtty->print(" entry='" INTPTR_FORMAT "' size='%d'", code_begin(), size());
-    xtty->print(" address='" INTPTR_FORMAT "'", (intptr_t) this);
+    xtty->print(" entry='" INTPTR_FORMAT "' size='%d'", p2i(code_begin()), size());
+    xtty->print(" address='" INTPTR_FORMAT "'", p2i(this));
 
     LOG_OFFSET(xtty, relocation);
     LOG_OFFSET(xtty, consts);
@@ -833,6 +957,7 @@
     LOG_OFFSET(xtty, handler_table);
     LOG_OFFSET(xtty, nul_chk_table);
     LOG_OFFSET(xtty, oops);
+    LOG_OFFSET(xtty, metadata);
 
     xtty->method(method());
     xtty->stamp();
@@ -849,7 +974,7 @@
     ttyLocker ttyl;
     if (WizardMode) {
       CompileTask::print(st, this, msg, /*short_form:*/ true);
-      st->print_cr(" (" INTPTR_FORMAT ")", this);
+      st->print_cr(" (" INTPTR_FORMAT ")", p2i(this));
     } else {
       CompileTask::print(st, this, msg, /*short_form:*/ false);
     }
@@ -874,13 +999,13 @@
       oop_maps()->print();
     }
   }
-  if (PrintDebugInfo) {
+  if (PrintDebugInfo || CompilerOracle::has_option_string(_method, "PrintDebugInfo")) {
     print_scopes();
   }
-  if (PrintRelocations) {
+  if (PrintRelocations || CompilerOracle::has_option_string(_method, "PrintRelocations")) {
     print_relocations();
   }
-  if (PrintDependencies) {
+  if (PrintDependencies || CompilerOracle::has_option_string(_method, "PrintDependencies")) {
     print_dependencies();
   }
   if (PrintExceptionHandlers) {
@@ -990,7 +1115,7 @@
   PcDesc* pd = pc_desc_at(pc);
   guarantee(pd != NULL, "scope must be present");
   return new ScopeDesc(this, pd->scope_decode_offset(),
-                       pd->obj_decode_offset(), pd->should_reexecute(),
+                       pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
                        pd->return_oop());
 }
 
@@ -1161,7 +1286,7 @@
 }
 
 void nmethod::inc_decompile_count() {
-  if (!is_compiled_by_c2()) return;
+  if (!is_compiled_by_c2() && !is_compiled_by_jvmci()) return;
   // Could be gated by ProfileTraps, but do not bother...
   Method* m = method();
   if (m == NULL)  return;
@@ -1205,7 +1330,7 @@
     tty->print_cr("[Class unloading: Making nmethod " INTPTR_FORMAT
                   " unloadable], Method*(" INTPTR_FORMAT
                   "), cause(" INTPTR_FORMAT ")",
-                  this, (address)_method, (address)cause);
+                  p2i(this), p2i(_method), p2i(cause));
     if (!Universe::heap()->is_gc_active())
       cause->klass()->print();
   }
@@ -1225,6 +1350,7 @@
     }
     _method = NULL;            // Clear the method of this dead nmethod
   }
+
   // Make the class unloaded - i.e., change state and notify sweeper
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   if (is_in_use()) {
@@ -1237,6 +1363,18 @@
   // Unregister must be done before the state change
   Universe::heap()->unregister_nmethod(this);
 
+#if INCLUDE_JVMCI
+  // The method can only be unloaded after the pointer to the installed code
+  // Java wrapper is no longer alive. Here we need to clear out this weak
+  // reference to the dead object. Nulling out the reference has to happen
+  // after the method is unregistered since the original value may be still
+  // tracked by the rset.
+  if (_jvmci_installed_code != NULL) {
+    InstalledCode::set_address(_jvmci_installed_code, 0);
+    _jvmci_installed_code = NULL;
+  }
+#endif
+
   _state = unloaded;
 
   // Log the unloading.
@@ -1400,9 +1538,16 @@
   } else {
     assert(state == not_entrant, "other cases may need to be handled differently");
   }
+#if INCLUDE_JVMCI
+  if (_jvmci_installed_code != NULL) {
+    // Break the link between nmethod and InstalledCode such that the nmethod can subsequently be flushed safely.
+    InstalledCode::set_address(_jvmci_installed_code, 0);
+  }
+#endif
 
   if (TraceCreateZombies) {
-    tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie");
+    ResourceMark m;
+    tty->print_cr("nmethod <" INTPTR_FORMAT "> %s code made %s", p2i(this), this->method() ? this->method()->name_and_sig_as_C_string() : "null", (state == not_entrant) ? "not entrant" : "zombie");
   }
 
   NMethodSweeper::report_state_change(this);
@@ -1418,10 +1563,12 @@
   assert_locked_or_safepoint(CodeCache_lock);
 
   // completely deallocate this method
-  Events::log(JavaThread::current(), "flushing nmethod " INTPTR_FORMAT, this);
+  Events::log(JavaThread::current(), "flushing nmethod " INTPTR_FORMAT, p2i(this));
   if (PrintMethodFlushing) {
-    tty->print_cr("*flushing nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT "/Free CodeCache:" SIZE_FORMAT "Kb",
-        _compile_id, this, CodeCache::nof_blobs(), CodeCache::unallocated_capacity(CodeCache::get_code_blob_type(this))/1024);
+    tty->print_cr("*flushing nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT
+                  "/Free CodeCache:" SIZE_FORMAT "Kb",
+                  _compile_id, p2i(this), CodeCache::nof_blobs(),
+                  CodeCache::unallocated_capacity(CodeCache::get_code_blob_type(this))/1024);
   }
 
   // We need to deallocate any ExceptionCache data.
@@ -1690,6 +1837,33 @@
     }
   }
 
+#if INCLUDE_JVMCI
+  // Follow JVMCI method
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  if (_jvmci_installed_code != NULL) {
+    if (_jvmci_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_jvmci_installed_code)) {
+      if (!is_alive->do_object_b(_jvmci_installed_code)) {
+        bs->write_ref_nmethod_pre(&_jvmci_installed_code, this);
+        _jvmci_installed_code = NULL;
+        bs->write_ref_nmethod_post(&_jvmci_installed_code, this);
+      }
+    } else {
+      if (can_unload(is_alive, (oop*)&_jvmci_installed_code, unloading_occurred)) {
+        return;
+      }
+    }
+  }
+
+  if (_speculation_log != NULL) {
+    if (!is_alive->do_object_b(_speculation_log)) {
+      bs->write_ref_nmethod_pre(&_speculation_log, this);
+      _speculation_log = NULL;
+      bs->write_ref_nmethod_post(&_speculation_log, this);
+    }
+  }
+#endif
+
+
   // Ensure that all metadata is still alive
   verify_metadata_loaders(low_boundary, is_alive);
 }
@@ -1709,7 +1883,7 @@
     // Clean inline caches pointing to both zombie and not_entrant methods
     if (!nm->is_in_use() || (nm->method()->code() != nm)) {
       ic->set_to_clean();
-      assert(ic->is_clean(), err_msg("nmethod " PTR_FORMAT "not clean %s", from, from->method()->name_and_sig_as_C_string()));
+      assert(ic->is_clean(), "nmethod " PTR_FORMAT "not clean %s", p2i(from), from->method()->name_and_sig_as_C_string());
     }
   }
 
@@ -1772,6 +1946,27 @@
     unloading_occurred = true;
   }
 
+#if INCLUDE_JVMCI
+  // Follow JVMCI method
+  if (_jvmci_installed_code != NULL) {
+    if (_jvmci_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_jvmci_installed_code)) {
+      if (!is_alive->do_object_b(_jvmci_installed_code)) {
+        _jvmci_installed_code = NULL;
+      }
+    } else {
+      if (can_unload(is_alive, (oop*)&_jvmci_installed_code, unloading_occurred)) {
+        return false;
+      }
+    }
+  }
+
+  if (_speculation_log != NULL) {
+    if (!is_alive->do_object_b(_speculation_log)) {
+      _speculation_log = NULL;
+    }
+  }
+#endif
+
   // Exception cache
   clean_exception_cache(is_alive);
 
@@ -1829,6 +2024,32 @@
     return postponed;
   }
 
+#if INCLUDE_JVMCI
+  // Follow JVMCI method
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  if (_jvmci_installed_code != NULL) {
+    if (_jvmci_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_jvmci_installed_code)) {
+      if (!is_alive->do_object_b(_jvmci_installed_code)) {
+        bs->write_ref_nmethod_pre(&_jvmci_installed_code, this);
+        _jvmci_installed_code = NULL;
+        bs->write_ref_nmethod_post(&_jvmci_installed_code, this);
+      }
+    } else {
+      if (can_unload(is_alive, (oop*)&_jvmci_installed_code, unloading_occurred)) {
+        is_unloaded = true;
+      }
+    }
+  }
+
+  if (_speculation_log != NULL) {
+    if (!is_alive->do_object_b(_speculation_log)) {
+      bs->write_ref_nmethod_pre(&_speculation_log, this);
+      _speculation_log = NULL;
+      bs->write_ref_nmethod_post(&_speculation_log, this);
+    }
+  }
+#endif
+
   // Ensure that all metadata is still alive
   verify_metadata_loaders(low_boundary, is_alive);
 
@@ -2013,6 +2234,15 @@
     // (See comment above.)
   }
 
+#if INCLUDE_JVMCI
+  if (_jvmci_installed_code != NULL) {
+    f->do_oop((oop*) &_jvmci_installed_code);
+  }
+  if (_speculation_log != NULL) {
+    f->do_oop((oop*) &_speculation_log);
+  }
+#endif
+
   RelocIterator iter(this, low_boundary);
 
   while (iter.next()) {
@@ -2119,8 +2349,8 @@
     if (_print_nm == NULL)  return;
     if (!_detected_scavenge_root)  _print_nm->print_on(tty, "new scavenge root");
     tty->print_cr("" PTR_FORMAT "[offset=%d] detected scavengable oop " PTR_FORMAT " (found at " PTR_FORMAT ")",
-                  _print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
-                  (void *)(*p), (intptr_t)p);
+                  p2i(_print_nm), (int)((intptr_t)p - (intptr_t)_print_nm),
+                  p2i(*p), p2i(p));
     (*p)->print();
   }
 #endif //PRODUCT
@@ -2137,7 +2367,7 @@
 // called with a frame corresponding to a Java invoke
 void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
 #ifndef SHARK
-  if (!method()->is_native()) {
+  if (method() != NULL && !method()->is_native()) {
     SimpleScopeDesc ssd(this, fr.pc());
     Bytecode_invoke call(ssd.method(), ssd.bci());
     bool has_receiver = call.has_receiver();
@@ -2203,6 +2433,14 @@
   memcpy(scopes_data_begin(), buffer, size);
 }
 
+// When using JVMCI the address might be off by the size of a call instruction.
+bool nmethod::is_deopt_entry(address pc) {
+  return pc == deopt_handler_begin()
+#if INCLUDE_JVMCI
+    || pc == (deopt_handler_begin() + NativeCall::instruction_size)
+#endif
+    ;
+}
 
 #ifdef ASSERT
 static PcDesc* linear_search(nmethod* nm, int pc_offset, bool approximate) {
@@ -2211,7 +2449,7 @@
   lower += 1; // exclude initial sentinel
   PcDesc* res = NULL;
   for (PcDesc* p = lower; p < upper; p++) {
-    NOT_PRODUCT(--nmethod_stats.pc_desc_tests);  // don't count this call to match_desc
+    NOT_PRODUCT(--pc_nmethod_stats.pc_desc_tests);  // don't count this call to match_desc
     if (match_desc(p, pc_offset, approximate)) {
       if (res == NULL)
         res = p;
@@ -2258,7 +2496,7 @@
 
   // Use the last successful return as a split point.
   PcDesc* mid = _pc_desc_cache.last_pc_desc();
-  NOT_PRODUCT(++nmethod_stats.pc_desc_searches);
+  NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
   if (mid->pc_offset() < pc_offset) {
     lower = mid;
   } else {
@@ -2271,7 +2509,7 @@
   for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) {
     while ((mid = lower + step) < upper) {
       assert_LU_OK;
-      NOT_PRODUCT(++nmethod_stats.pc_desc_searches);
+      NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
       if (mid->pc_offset() < pc_offset) {
         lower = mid;
       } else {
@@ -2286,7 +2524,7 @@
   while (true) {
     assert_LU_OK;
     mid = lower + 1;
-    NOT_PRODUCT(++nmethod_stats.pc_desc_searches);
+    NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
     if (mid->pc_offset() < pc_offset) {
       lower = mid;
     } else {
@@ -2426,7 +2664,7 @@
     ResourceMark rm(thread);
     CodeBlob* cb = CodeCache::find_blob(pc);
     assert(cb != NULL && cb == this, "");
-    tty->print_cr("implicit exception happened at " INTPTR_FORMAT, pc);
+    tty->print_cr("implicit exception happened at " INTPTR_FORMAT, p2i(pc));
     print();
     method()->print_codes();
     print_code();
@@ -2473,7 +2711,6 @@
   assert(nm->_lock_count >= 0, "unmatched nmethod lock/unlock");
 }
 
-
 // -----------------------------------------------------------------------------
 // nmethod::get_deopt_original_pc
 //
@@ -2519,7 +2756,7 @@
       _ok = false;
     }
     tty->print_cr("*** non-oop " PTR_FORMAT " found at " PTR_FORMAT " (offset %d)",
-                  (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
+                  p2i(*p), p2i(p), (int)((intptr_t)p - (intptr_t)_nm));
   }
   virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
 };
@@ -2540,7 +2777,7 @@
   ResourceMark rm;
 
   if (!CodeCache::contains(this)) {
-    fatal(err_msg("nmethod at " INTPTR_FORMAT " not in zone", this));
+    fatal("nmethod at " INTPTR_FORMAT " not in zone", p2i(this));
   }
 
   if(is_native_method() )
@@ -2548,13 +2785,12 @@
 
   nmethod* nm = CodeCache::find_nmethod(verified_entry_point());
   if (nm != this) {
-    fatal(err_msg("findNMethod did not find this nmethod (" INTPTR_FORMAT ")",
-                  this));
+    fatal("findNMethod did not find this nmethod (" INTPTR_FORMAT ")", p2i(this));
   }
 
   for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
     if (! p->verify(this)) {
-      tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", this);
+      tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", p2i(this));
     }
   }
 
@@ -2587,7 +2823,7 @@
   PcDesc* pd = pc_desc_at(nativeCall_at(call_site)->return_address());
   assert(pd != NULL, "PcDesc must exist");
   for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
-                                     pd->obj_decode_offset(), pd->should_reexecute(),
+                                     pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
                                      pd->return_oop());
        !sd->is_top(); sd = sd->sender()) {
     sd->verify();
@@ -2643,7 +2879,7 @@
       _ok = false;
     }
     tty->print_cr("*** scavengable oop " PTR_FORMAT " found at " PTR_FORMAT " (offset %d)",
-                  (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
+                  p2i(*p), p2i(p), (int)((intptr_t)p - (intptr_t)_nm));
     (*p)->print();
   }
   virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
@@ -2680,6 +2916,8 @@
     tty->print("(c2) ");
   } else if (is_compiled_by_shark()) {
     tty->print("(shark) ");
+  } else if (is_compiled_by_jvmci()) {
+    tty->print("(JVMCI) ");
   } else {
     tty->print("(nm) ");
   }
@@ -2687,8 +2925,8 @@
   print_on(tty, NULL);
 
   if (WizardMode) {
-    tty->print("((nmethod*) " INTPTR_FORMAT ") ", this);
-    tty->print(" for method " INTPTR_FORMAT , (address)method());
+    tty->print("((nmethod*) " INTPTR_FORMAT ") ", p2i(this));
+    tty->print(" for method " INTPTR_FORMAT , p2i(method()));
     tty->print(" { ");
     if (is_in_use())      tty->print("in_use ");
     if (is_not_entrant()) tty->print("not_entrant ");
@@ -2698,52 +2936,52 @@
     tty->print_cr("}:");
   }
   if (size              () > 0) tty->print_cr(" total in heap  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              (address)this,
-                                              (address)this + size(),
+                                              p2i(this),
+                                              p2i(this) + size(),
                                               size());
   if (relocation_size   () > 0) tty->print_cr(" relocation     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              relocation_begin(),
-                                              relocation_end(),
+                                              p2i(relocation_begin()),
+                                              p2i(relocation_end()),
                                               relocation_size());
   if (consts_size       () > 0) tty->print_cr(" constants      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              consts_begin(),
-                                              consts_end(),
+                                              p2i(consts_begin()),
+                                              p2i(consts_end()),
                                               consts_size());
   if (insts_size        () > 0) tty->print_cr(" main code      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              insts_begin(),
-                                              insts_end(),
+                                              p2i(insts_begin()),
+                                              p2i(insts_end()),
                                               insts_size());
   if (stub_size         () > 0) tty->print_cr(" stub code      [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              stub_begin(),
-                                              stub_end(),
+                                              p2i(stub_begin()),
+                                              p2i(stub_end()),
                                               stub_size());
   if (oops_size         () > 0) tty->print_cr(" oops           [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              oops_begin(),
-                                              oops_end(),
+                                              p2i(oops_begin()),
+                                              p2i(oops_end()),
                                               oops_size());
   if (metadata_size      () > 0) tty->print_cr(" metadata       [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              metadata_begin(),
-                                              metadata_end(),
+                                              p2i(metadata_begin()),
+                                              p2i(metadata_end()),
                                               metadata_size());
   if (scopes_data_size  () > 0) tty->print_cr(" scopes data    [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              scopes_data_begin(),
-                                              scopes_data_end(),
+                                              p2i(scopes_data_begin()),
+                                              p2i(scopes_data_end()),
                                               scopes_data_size());
   if (scopes_pcs_size   () > 0) tty->print_cr(" scopes pcs     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              scopes_pcs_begin(),
-                                              scopes_pcs_end(),
+                                              p2i(scopes_pcs_begin()),
+                                              p2i(scopes_pcs_end()),
                                               scopes_pcs_size());
   if (dependencies_size () > 0) tty->print_cr(" dependencies   [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              dependencies_begin(),
-                                              dependencies_end(),
+                                              p2i(dependencies_begin()),
+                                              p2i(dependencies_end()),
                                               dependencies_size());
   if (handler_table_size() > 0) tty->print_cr(" handler table  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              handler_table_begin(),
-                                              handler_table_end(),
+                                              p2i(handler_table_begin()),
+                                              p2i(handler_table_end()),
                                               handler_table_size());
   if (nul_chk_table_size() > 0) tty->print_cr(" nul chk table  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
-                                              nul_chk_table_begin(),
-                                              nul_chk_table_end(),
+                                              p2i(nul_chk_table_begin()),
+                                              p2i(nul_chk_table_end()),
                                               nul_chk_table_size());
 }
 
@@ -2764,7 +3002,10 @@
       continue;
 
     ScopeDesc* sd = scope_desc_at(p->real_pc(this));
-    sd->print_on(tty, p);
+    while (sd != NULL) {
+      sd->print_on(tty, p);
+      sd = sd->sender();
+    }
   }
 }
 
@@ -2794,20 +3035,20 @@
     jint* index_end   = (jint*)relocation_end() - 1;
     jint  index_size  = *index_end;
     jint* index_start = (jint*)( (address)index_end - index_size );
-    tty->print_cr("    index @" INTPTR_FORMAT ": index_size=%d", index_start, index_size);
+    tty->print_cr("    index @" INTPTR_FORMAT ": index_size=%d", p2i(index_start), index_size);
     if (index_size > 0) {
       jint* ip;
       for (ip = index_start; ip+2 <= index_end; ip += 2)
         tty->print_cr("  (%d %d) addr=" INTPTR_FORMAT " @" INTPTR_FORMAT,
                       ip[0],
                       ip[1],
-                      header_end()+ip[0],
-                      relocation_begin()-1+ip[1]);
+                      p2i(header_end()+ip[0]),
+                      p2i(relocation_begin()-1+ip[1]));
       for (; ip < index_end; ip++)
         tty->print_cr("  (%d ?)", ip[0]);
-      tty->print_cr("          @" INTPTR_FORMAT ": index_size=%d", ip, *ip);
+      tty->print_cr("          @" INTPTR_FORMAT ": index_size=%d", p2i(ip), *ip);
       ip++;
-      tty->print_cr("reloc_end @" INTPTR_FORMAT ":", ip);
+      tty->print_cr("reloc_end @" INTPTR_FORMAT ":", p2i(ip));
     }
   }
 }
@@ -2881,7 +3122,7 @@
   PcDesc* p = pc_desc_near(begin+1);
   if (p != NULL && p->real_pc(this) <= end) {
     return new ScopeDesc(this, p->scope_decode_offset(),
-                         p->obj_decode_offset(), p->should_reexecute(),
+                         p->obj_decode_offset(), p->should_reexecute(), p->rethrow_exception(),
                          p->return_oop());
   }
   return NULL;
@@ -2890,9 +3131,9 @@
 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const {
   if (block_begin == entry_point())             stream->print_cr("[Entry Point]");
   if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");
-  if (block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
+  if (JVMCI_ONLY(_exception_offset >= 0 &&) block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
   if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
-  if (block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
+  if (JVMCI_ONLY(_deoptimize_offset >= 0 &&) block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
 
   if (has_method_handle_invokes())
     if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
@@ -3058,6 +3299,7 @@
           }
         }
       }
+      st->print(" {reexecute=%d rethrow=%d return_oop=%d}", sd->should_reexecute(), sd->rethrow_exception(), sd->return_oop());
     }
 
     // Print all scopes
@@ -3089,7 +3331,7 @@
   int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
   if (cont_offset != 0) {
     st->move_to(column);
-    st->print("; implicit exception: dispatches to " INTPTR_FORMAT, code_begin() + cont_offset);
+    st->print("; implicit exception: dispatches to " INTPTR_FORMAT, p2i(code_begin() + cont_offset));
   }
 
 }
@@ -3112,7 +3354,7 @@
       break;
     }
     case relocInfo::static_call_type:
-      st->print_cr("Static call at " INTPTR_FORMAT, iter.reloc()->addr());
+      st->print_cr("Static call at " INTPTR_FORMAT, p2i(iter.reloc()->addr()));
       compiledStaticCall_at(iter.reloc())->print();
       break;
     }
@@ -3130,12 +3372,49 @@
 void nmethod::print_statistics() {
   ttyLocker ttyl;
   if (xtty != NULL)  xtty->head("statistics type='nmethod'");
-  nmethod_stats.print_native_nmethod_stats();
-  nmethod_stats.print_nmethod_stats();
+  native_nmethod_stats.print_native_nmethod_stats();
+#ifdef COMPILER1
+  c1_java_nmethod_stats.print_nmethod_stats("C1");
+#endif
+#ifdef COMPILER2
+  c2_java_nmethod_stats.print_nmethod_stats("C2");
+#endif
+#if INCLUDE_JVMCI
+  jvmci_java_nmethod_stats.print_nmethod_stats("JVMCI");
+#endif
+#ifdef SHARK
+  shark_java_nmethod_stats.print_nmethod_stats("Shark");
+#endif
+  unknown_java_nmethod_stats.print_nmethod_stats("Unknown");
   DebugInformationRecorder::print_statistics();
-  nmethod_stats.print_pc_stats();
+#ifndef PRODUCT
+  pc_nmethod_stats.print_pc_stats();
+#endif
   Dependencies::print_statistics();
   if (xtty != NULL)  xtty->tail("statistics");
 }
 
-#endif // PRODUCT
+#endif // !PRODUCT
+
+#if INCLUDE_JVMCI
+char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) {
+  if (!this->is_compiled_by_jvmci()) {
+    return NULL;
+  }
+  oop installedCode = this->jvmci_installed_code();
+  if (installedCode != NULL) {
+    oop installedCodeName = NULL;
+    if (installedCode->is_a(InstalledCode::klass())) {
+      installedCodeName = InstalledCode::name(installedCode);
+    }
+    if (installedCodeName != NULL) {
+      return java_lang_String::as_utf8_string(installedCodeName, buf, (int)buflen);
+    } else {
+      jio_snprintf(buf, buflen, "null");
+      return buf;
+    }
+  }
+  jio_snprintf(buf, buflen, "noInstalledCode");
+  return buf;
+}
+#endif
--- a/hotspot/src/share/vm/code/nmethod.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -126,6 +126,12 @@
   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
 
+#if INCLUDE_JVMCI
+  // Needed to keep nmethods alive that are not the default nmethod for the associated Method.
+  oop       _jvmci_installed_code;
+  oop       _speculation_log;
+#endif
+
   // To support simple linked-list chaining of nmethods:
   nmethod*  _osr_link;         // from InstanceKlass::osr_nmethods_head
 
@@ -273,7 +279,12 @@
           ExceptionHandlerTable* handler_table,
           ImplicitExceptionTable* nul_chk_table,
           AbstractCompiler* compiler,
-          int comp_level);
+          int comp_level
+#if INCLUDE_JVMCI
+          , Handle installed_code,
+          Handle speculation_log
+#endif
+          );
 
   // helper methods
   void* operator new(size_t size, int nmethod_size, int comp_level) throw();
@@ -309,7 +320,12 @@
                               ExceptionHandlerTable* handler_table,
                               ImplicitExceptionTable* nul_chk_table,
                               AbstractCompiler* compiler,
-                              int comp_level);
+                              int comp_level
+#if INCLUDE_JVMCI
+                              , Handle installed_code = Handle(),
+                              Handle speculation_log = Handle()
+#endif
+                             );
 
   static nmethod* new_native_nmethod(methodHandle method,
                                      int compile_id,
@@ -332,6 +348,7 @@
   bool is_osr_method() const                      { return _entry_bci != InvocationEntryBci; }
 
   bool is_compiled_by_c1() const;
+  bool is_compiled_by_jvmci() const;
   bool is_compiled_by_c2() const;
   bool is_compiled_by_shark() const;
 
@@ -582,6 +599,14 @@
   // Evolution support. We make old (discarded) compiled methods point to new Method*s.
   void set_method(Method* method) { _method = method; }
 
+#if INCLUDE_JVMCI
+  oop jvmci_installed_code() { return _jvmci_installed_code ; }
+  char* jvmci_installed_code_name(char* buf, size_t buflen);
+  void set_jvmci_installed_code(oop installed_code) { _jvmci_installed_code = installed_code;  }
+  oop speculation_log() { return _speculation_log ; }
+  void set_speculation_log(oop speculation_log) { _speculation_log = speculation_log;  }
+#endif
+
   // GC support
   void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
   //  The parallel versions are used by G1.
@@ -639,7 +664,7 @@
   // Deopt
   // Return true is the PC is one would expect if the frame is being deopted.
   bool is_deopt_pc      (address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
-  bool is_deopt_entry   (address pc) { return pc == deopt_handler_begin(); }
+  bool is_deopt_entry   (address pc);
   bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); }
   // Accessor/mutator for the original pc of a frame before a frame was deopted.
   address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); }
@@ -690,7 +715,7 @@
 
   // Prints a comment for one native instruction (reloc info, pc desc)
   void print_code_comment_on(outputStream* st, int column, address begin, address end);
-  static void print_statistics()                  PRODUCT_RETURN;
+  static void print_statistics() PRODUCT_RETURN;
 
   // Compiler task identification.  Note that all OSR methods
   // are numbered in an independent sequence if CICountOSR is true,
--- a/hotspot/src/share/vm/code/oopRecorder.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/oopRecorder.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -157,3 +157,48 @@
 // Explicitly instantiate these types
 template class ValueRecorder<Metadata*>;
 template class ValueRecorder<jobject>;
+
+oop ObjectLookup::ObjectEntry::oop_value() const { return JNIHandles::resolve(_value); }
+
+ObjectLookup::ObjectLookup(): _gc_count(Universe::heap()->total_collections()), _values(4) {}
+
+void ObjectLookup::maybe_resort() {
+  // The values are kept sorted by address which may be invalidated
+  // after a GC, so resort if a GC has occurred since last time.
+  if (_gc_count != Universe::heap()->total_collections()) {
+    _gc_count = Universe::heap()->total_collections();
+    _values.sort(sort_by_address);
+  }
+}
+
+int ObjectLookup::sort_by_address(oop a, oop b) {
+  if (b > a) return 1;
+  if (a > b) return -1;
+  return 0;
+}
+
+int ObjectLookup::sort_by_address(ObjectEntry* a, ObjectEntry* b) {
+  return sort_by_address(a->oop_value(), b->oop_value());
+}
+
+int ObjectLookup::sort_oop_by_address(oop const& a, ObjectEntry const& b) {
+  return sort_by_address(a, b.oop_value());
+}
+
+int ObjectLookup::find_index(jobject handle, OopRecorder* oop_recorder) {
+  if (handle == NULL) {
+    return 0;
+  }
+  oop object = JNIHandles::resolve(handle);
+  maybe_resort();
+  bool found;
+  int location = _values.find_sorted<oop, sort_oop_by_address>(object, found);
+  if (!found) {
+    jobject handle = JNIHandles::make_local(object);
+    ObjectEntry r(handle, oop_recorder->allocate_oop_index(handle));
+    _values.insert_before(location, r);
+    return r.index();
+  }
+  return _values.at(location).index();
+}
+
--- a/hotspot/src/share/vm/code/oopRecorder.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/oopRecorder.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -146,18 +146,57 @@
 #endif
 };
 
+class OopRecorder;
+
+class ObjectLookup : public ResourceObj {
+ private:
+  class ObjectEntry {
+   private:
+    jobject _value;
+    int     _index;
+
+   public:
+    ObjectEntry(jobject value, int index) : _value(value), _index(index) {}
+    ObjectEntry() : _value(NULL), _index(0) {}
+    oop oop_value() const;
+    int index() { return _index; }
+  };
+
+  GrowableArray<ObjectEntry> _values;
+  unsigned int _gc_count;
+
+  // Utility sort functions
+  static int sort_by_address(oop a, oop b);
+  static int sort_by_address(ObjectEntry* a, ObjectEntry* b);
+  static int sort_oop_by_address(oop const& a, ObjectEntry const& b);
+
+ public:
+  ObjectLookup();
+
+  // Resort list if a GC has occurred since the last sort
+  void maybe_resort();
+  int find_index(jobject object, OopRecorder* oop_recorder);
+};
+
 class OopRecorder : public ResourceObj {
  private:
   ValueRecorder<jobject>      _oops;
   ValueRecorder<Metadata*>    _metadata;
+  ObjectLookup*               _object_lookup;
  public:
-  OopRecorder(Arena* arena = NULL): _oops(arena), _metadata(arena) {}
+  OopRecorder(Arena* arena = NULL, bool deduplicate = false): _oops(arena), _metadata(arena) {
+    if (deduplicate) {
+      _object_lookup = new ObjectLookup();
+    } else {
+      _object_lookup = NULL;
+    }
+  }
 
   int allocate_oop_index(jobject h) {
     return _oops.allocate_index(h);
   }
-  int find_index(jobject h) {
-    return _oops.find_index(h);
+  virtual int find_index(jobject h) {
+    return _object_lookup != NULL ? _object_lookup->find_index(h, this) : _oops.find_index(h);
   }
   jobject oop_at(int index) {
     return _oops.at(index);
@@ -175,7 +214,7 @@
   int allocate_metadata_index(Metadata* oop) {
     return _metadata.allocate_index(oop);
   }
-  int find_index(Metadata* h) {
+  virtual int find_index(Metadata* h) {
     return _metadata.find_index(h);
   }
   Metadata* metadata_at(int index) {
--- a/hotspot/src/share/vm/code/pcDesc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/pcDesc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,8 +29,6 @@
 #include "code/scopeDesc.hpp"
 #include "memory/resourceArea.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) {
   _pc_offset           = pc_offset;
   _scope_decode_offset = scope_decode_offset;
@@ -45,7 +43,7 @@
 void PcDesc::print(nmethod* code) {
 #ifndef PRODUCT
   ResourceMark rm;
-  tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags);
+  tty->print_cr("PcDesc(pc=" PTR_FORMAT " offset=%x bits=%x):", p2i(real_pc(code)), pc_offset(), _flags);
 
   if (scope_decode_offset() == DebugInformationRecorder::serialized_null) {
     return;
--- a/hotspot/src/share/vm/code/pcDesc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/pcDesc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,7 +42,8 @@
   enum {
     PCDESC_reexecute               = 1 << 0,
     PCDESC_is_method_handle_invoke = 1 << 1,
-    PCDESC_return_oop              = 1 << 2
+    PCDESC_return_oop              = 1 << 2,
+    PCDESC_rethrow_exception       = 1 << 3
   };
 
   int _flags;
@@ -71,6 +72,8 @@
   };
 
   // Flags
+  bool     rethrow_exception()              const { return (_flags & PCDESC_rethrow_exception) != 0; }
+  void set_rethrow_exception(bool z)              { set_flag(PCDESC_rethrow_exception, z); }
   bool     should_reexecute()              const { return (_flags & PCDESC_reexecute) != 0; }
   void set_should_reexecute(bool z)              { set_flag(PCDESC_reexecute, z); }
 
--- a/hotspot/src/share/vm/code/relocInfo.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/relocInfo.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,8 +30,7 @@
 #include "memory/resourceArea.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "utilities/copy.hpp"
-
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+#include "oops/oop.inline.hpp"
 
 const RelocationHolder RelocationHolder::none; // its type is relocInfo::none
 
@@ -424,6 +423,30 @@
   ShouldNotReachHere();
 }
 
+void Relocation::const_set_data_value(address x) {
+#ifdef _LP64
+  if (format() == relocInfo::narrow_oop_in_const) {
+    *(narrowOop*)addr() = oopDesc::encode_heap_oop((oop) x);
+  } else {
+#endif
+    *(address*)addr() = x;
+#ifdef _LP64
+  }
+#endif
+}
+
+void Relocation::const_verify_data_value(address x) {
+#ifdef _LP64
+  if (format() == relocInfo::narrow_oop_in_const) {
+    assert(*(narrowOop*)addr() == oopDesc::encode_heap_oop((oop) x), "must agree");
+  } else {
+#endif
+    assert(*(address*)addr() == x, "must agree");
+#ifdef _LP64
+  }
+#endif
+}
+
 
 RelocationHolder Relocation::spec_simple(relocInfo::relocType rtype) {
   if (rtype == relocInfo::none)  return RelocationHolder::none;
@@ -447,7 +470,7 @@
     // Known "miscellaneous" non-stub pointers:
     // os::get_polling_page(), SafepointSynchronize::address_of_state()
     if (PrintRelocations) {
-      tty->print_cr("random unregistered address in relocInfo: " INTPTR_FORMAT, runtime_address);
+      tty->print_cr("random unregistered address in relocInfo: " INTPTR_FORMAT, p2i(runtime_address));
     }
 #ifndef _LP64
     return (int32_t) (intptr_t)runtime_address;
@@ -580,7 +603,8 @@
 
 void static_stub_Relocation::unpack_data() {
   address base = binding()->section_start(CodeBuffer::SECT_INSTS);
-  _static_call = address_from_scaled_offset(unpack_1_int(), base);
+  jint offset = unpack_1_int();
+  _static_call = address_from_scaled_offset(offset, base);
 }
 
 void trampoline_stub_Relocation::pack_data_to(CodeSection* dest ) {
@@ -794,7 +818,8 @@
   RelocIterator iter(code());
   while (iter.next()) {
     if (iter.type() == relocInfo::static_stub_type) {
-      if (iter.static_stub_reloc()->static_call() == static_call_addr) {
+      static_stub_Relocation* stub_reloc = iter.static_stub_reloc();
+      if (stub_reloc->static_call() == static_call_addr) {
         return iter.addr();
       }
     }
@@ -816,7 +841,8 @@
   RelocIterator iter(code());
   while (iter.next()) {
     if (iter.type() == relocInfo::static_stub_type) {
-      if (iter.static_stub_reloc()->static_call() == static_call_addr) {
+      static_stub_Relocation* stub_reloc = iter.static_stub_reloc();
+      if (stub_reloc->static_call() == static_call_addr) {
         return iter.addr();
       }
     }
@@ -925,7 +951,7 @@
     return;
   }
   tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
-             _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr, _current->addr_offset());
+             p2i(_current), type(), reloc_type_string((relocInfo::relocType) type()), p2i(_addr), _current->addr_offset());
   if (current()->format() != 0)
     tty->print(" format=%d", current()->format());
   if (datalen() == 1) {
@@ -951,11 +977,11 @@
         oop_value = r->oop_value();
       }
       tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]",
-                 oop_addr, (address)raw_oop, r->offset());
+                 p2i(oop_addr), p2i(raw_oop), r->offset());
       // Do not print the oop by default--we want this routine to
       // work even during GC or other inconvenient times.
       if (WizardMode && oop_value != NULL) {
-        tty->print("oop_value=" INTPTR_FORMAT ": ", (address)oop_value);
+        tty->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
         oop_value->print_value_on(tty);
       }
       break;
@@ -972,9 +998,9 @@
         metadata_value = r->metadata_value();
       }
       tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]",
-                 metadata_addr, (address)raw_metadata, r->offset());
+                 p2i(metadata_addr), p2i(raw_metadata), r->offset());
       if (metadata_value != NULL) {
-        tty->print("metadata_value=" INTPTR_FORMAT ": ", (address)metadata_value);
+        tty->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
         metadata_value->print_value_on(tty);
       }
       break;
@@ -984,33 +1010,33 @@
   case relocInfo::section_word_type:
     {
       DataRelocation* r = (DataRelocation*) reloc();
-      tty->print(" | [target=" INTPTR_FORMAT "]", r->value()); //value==target
+      tty->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
       break;
     }
   case relocInfo::static_call_type:
   case relocInfo::runtime_call_type:
     {
       CallRelocation* r = (CallRelocation*) reloc();
-      tty->print(" | [destination=" INTPTR_FORMAT "]", r->destination());
+      tty->print(" | [destination=" INTPTR_FORMAT "]", p2i(r->destination()));
       break;
     }
   case relocInfo::virtual_call_type:
     {
       virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
       tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT "]",
-                 r->destination(), r->cached_value());
+                 p2i(r->destination()), p2i(r->cached_value()));
       break;
     }
   case relocInfo::static_stub_type:
     {
       static_stub_Relocation* r = (static_stub_Relocation*) reloc();
-      tty->print(" | [static_call=" INTPTR_FORMAT "]", r->static_call());
+      tty->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
       break;
     }
   case relocInfo::trampoline_stub_type:
     {
       trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc();
-      tty->print(" | [trampoline owner=" INTPTR_FORMAT "]", r->owner());
+      tty->print(" | [trampoline owner=" INTPTR_FORMAT "]", p2i(r->owner()));
       break;
     }
   }
@@ -1029,7 +1055,7 @@
     got_next = (skip_next || next());
     skip_next = false;
 
-    tty->print("         @" INTPTR_FORMAT ": ", scan);
+    tty->print("         @" INTPTR_FORMAT ": ", p2i(scan));
     relocInfo* newscan = _current+1;
     if (!has_current())  newscan -= 1;  // nothing to scan here!
     while (scan < newscan) {
--- a/hotspot/src/share/vm/code/relocInfo.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/relocInfo.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -210,6 +210,11 @@
 //   See [About Offsets] below.
 //   //%note reloc_2
 //
+// relocInfo::poll_[return_]type -- a safepoint poll
+//   Value:  none
+//   Instruction types: memory load or test
+//   Data:  none
+//
 // For example:
 //
 //   INSTRUCTIONS                        RELOC: TYPE    PREFIX DATA
@@ -443,6 +448,11 @@
   };
  public:
   enum {
+#ifdef _LP64
+    // for use in format
+    // format_width must be at least 1 on _LP64
+    narrow_oop_in_const = 1,
+#endif
     // Conservatively large estimate of maximum length (in shorts)
     // of any relocation record.
     // Extended format is length prefix, data words, and tag/offset suffix.
@@ -525,19 +535,19 @@
   typedef relocInfo::relocType relocType;
 
  private:
-  address    _limit;   // stop producing relocations after this _addr
-  relocInfo* _current; // the current relocation information
-  relocInfo* _end;     // end marker; we're done iterating when _current == _end
-  nmethod*   _code;    // compiled method containing _addr
-  address    _addr;    // instruction to which the relocation applies
-  short      _databuf; // spare buffer for compressed data
-  short*     _data;    // pointer to the relocation's data
-  short      _datalen; // number of halfwords in _data
-  char       _format;  // position within the instruction
+  address         _limit;   // stop producing relocations after this _addr
+  relocInfo*      _current; // the current relocation information
+  relocInfo*      _end;     // end marker; we're done iterating when _current == _end
+  nmethod*        _code;    // compiled method containing _addr
+  address         _addr;    // instruction to which the relocation applies
+  short           _databuf; // spare buffer for compressed data
+  short*          _data;    // pointer to the relocation's data
+  short           _datalen; // number of halfwords in _data
+  char            _format;  // position within the instruction
 
   // Base addresses needed to compute targets of section_word_type relocs.
-  address    _section_start[SECT_LIMIT];
-  address    _section_end  [SECT_LIMIT];
+  address _section_start[SECT_LIMIT];
+  address _section_end  [SECT_LIMIT];
 
   void set_has_current(bool b) {
     _datalen = !b ? -1 : 0;
@@ -565,7 +575,7 @@
 
  public:
   // constructor
-  RelocIterator(nmethod* nm,     address begin = NULL, address limit = NULL);
+  RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL);
   RelocIterator(CodeSection* cb, address begin = NULL, address limit = NULL);
 
   // get next reloc info, return !eos
@@ -762,6 +772,9 @@
   }
 
  protected:
+  // platform-independent utility for patching constant section
+  void       const_set_data_value    (address x);
+  void       const_verify_data_value (address x);
   // platform-dependent utilities for decoding and patching instructions
   void       pd_set_data_value       (address x, intptr_t off, bool verify_only = false); // a set or mem-ref
   void       pd_verify_data_value    (address x, intptr_t off) { pd_set_data_value(x, off, true); }
@@ -872,13 +885,13 @@
   void        set_value(address x)             { set_value(x, offset()); }
   void        set_value(address x, intptr_t o) {
     if (addr_in_const())
-      *(address*)addr() = x;
+      const_set_data_value(x);
     else
       pd_set_data_value(x, o);
   }
   void        verify_value(address x) {
     if (addr_in_const())
-      assert(*(address*)addr() == x, "must agree");
+      const_verify_data_value(x);
     else
       pd_verify_data_value(x, offset());
   }
@@ -1117,7 +1130,7 @@
   }
 
  private:
-  address _static_call;             // location of corresponding static_call
+  address _static_call;  // location of corresponding static_call
 
   static_stub_Relocation(address static_call) {
     _static_call = static_call;
@@ -1318,10 +1331,8 @@
   void     fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
 };
 
-class poll_return_Relocation : public Relocation {
-  bool          is_data()                      { return true; }
+class poll_return_Relocation : public poll_Relocation {
   relocInfo::relocType type() { return relocInfo::poll_return_type; }
-  void     fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
 };
 
 // We know all the xxx_Relocation classes, so now we can define these:
--- a/hotspot/src/share/vm/code/scopeDesc.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/scopeDesc.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,22 +30,22 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(obj_decode_offset);
   _reexecute     = reexecute;
+  _rethrow_exception = rethrow_exception;
   _return_oop    = return_oop;
   decode_body();
 }
 
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(DebugInformationRecorder::serialized_null);
   _reexecute     = reexecute;
+  _rethrow_exception = rethrow_exception;
   _return_oop    = return_oop;
   decode_body();
 }
@@ -56,6 +56,7 @@
   _decode_offset = parent->_sender_decode_offset;
   _objects       = parent->_objects;
   _reexecute     = false; //reexecute only applies to the first scope
+  _rethrow_exception = false;
   _return_oop    = false;
   decode_body();
 }
@@ -178,13 +179,13 @@
 void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const {
   // header
   if (pd != NULL) {
-    st->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", pd->real_pc(_code), pd->pc_offset());
+    st->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", p2i(pd->real_pc(_code)), pd->pc_offset());
   }
 
   print_value_on(st);
   // decode offsets
   if (WizardMode) {
-    st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->content_begin());
+    st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, p2i(_code->content_begin()));
     st->print_cr(" offset:     %d",    _decode_offset);
     st->print_cr(" bci:        %d",    bci());
     st->print_cr(" reexecute:  %s",    should_reexecute() ? "true" : "false");
@@ -227,17 +228,18 @@
     }
   }
 
-#ifdef COMPILER2
-  if (DoEscapeAnalysis && is_top() && _objects != NULL) {
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  if (NOT_JVMCI(DoEscapeAnalysis &&) is_top() && _objects != NULL) {
     st->print_cr("   Objects");
     for (int i = 0; i < _objects->length(); i++) {
       ObjectValue* sv = (ObjectValue*) _objects->at(i);
       st->print("    - %d: ", sv->id());
+      st->print("%s ", java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())->external_name());
       sv->print_fields_on(st);
       st->cr();
     }
   }
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 }
 
 #endif
--- a/hotspot/src/share/vm/code/scopeDesc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/scopeDesc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,7 +41,7 @@
   int _bci;
 
  public:
-  SimpleScopeDesc(nmethod* code,address pc) {
+  SimpleScopeDesc(nmethod* code, address pc) {
     PcDesc* pc_desc = code->pc_desc_at(pc);
     assert(pc_desc != NULL, "Must be able to find matching PcDesc");
     DebugInfoReadStream buffer(code, pc_desc->scope_decode_offset());
@@ -60,17 +60,18 @@
 class ScopeDesc : public ResourceObj {
  public:
   // Constructor
-  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop);
+  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // Calls above, giving default value of "serialized_null" to the
   // "obj_decode_offset" argument.  (We don't use a default argument to
   // avoid a .hpp-.hpp dependency.)
-  ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop);
+  ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // JVM state
   Method* method()      const { return _method; }
   int          bci()      const { return _bci;    }
   bool should_reexecute() const { return _reexecute; }
+  bool rethrow_exception() const { return _rethrow_exception; }
   bool return_oop()       const { return _return_oop; }
 
   GrowableArray<ScopeValue*>*   locals();
@@ -95,6 +96,7 @@
   Method*       _method;
   int           _bci;
   bool          _reexecute;
+  bool          _rethrow_exception;
   bool          _return_oop;
 
   // Decoding offsets
--- a/hotspot/src/share/vm/code/stubs.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/stubs.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -67,7 +67,7 @@
   intptr_t size = round_to(buffer_size, 2*BytesPerWord);
   BufferBlob* blob = BufferBlob::create(name, size);
   if( blob == NULL) {
-    vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, err_msg("CodeCache: no room for %s", name));
+    vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "CodeCache: no room for %s", name);
   }
   _stub_interface  = stub_interface;
   _buffer_size     = blob->content_size();
--- a/hotspot/src/share/vm/code/vtableStubs.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -40,8 +40,6 @@
 #include "opto/matcher.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // -----------------------------------------------------------------------------------------
 // Implementation of VtableStub
 
@@ -79,8 +77,8 @@
 
 
 void VtableStub::print_on(outputStream* st) const {
-  st->print("vtable stub (index = %d, receiver_location = %d, code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "[)",
-             index(), receiver_location(), code_begin(), code_end());
+  st->print("vtable stub (index = %d, receiver_location = " INTX_FORMAT ", code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "[)",
+             index(), p2i(receiver_location()), p2i(code_begin()), p2i(code_end()));
 }
 
 
@@ -126,8 +124,8 @@
 
     enter(is_vtable_stub, vtable_index, s);
     if (PrintAdapterHandlers) {
-      tty->print_cr("Decoding VtableStub %s[%d]@%d",
-                    is_vtable_stub? "vtbl": "itbl", vtable_index, VtableStub::receiver_location());
+      tty->print_cr("Decoding VtableStub %s[%d]@" INTX_FORMAT,
+                    is_vtable_stub? "vtbl": "itbl", vtable_index, p2i(VtableStub::receiver_location()));
       Disassembler::decode(s->code_begin(), s->code_end());
     }
     // Notify JVMTI about this stub. The event will be recorded by the enclosing
@@ -222,9 +220,9 @@
   InstanceKlass* ik = InstanceKlass::cast(klass);
   klassVtable* vt = ik->vtable();
   ik->print();
-  fatal(err_msg("bad compiled vtable dispatch: receiver " INTPTR_FORMAT ", "
-                "index %d (vtable length %d)",
-                (address)receiver, index, vt->length()));
+  fatal("bad compiled vtable dispatch: receiver " INTPTR_FORMAT ", "
+        "index %d (vtable length %d)",
+        p2i(receiver), index, vt->length());
 }
 
-#endif // Product
+#endif // PRODUCT
--- a/hotspot/src/share/vm/compiler/abstractCompiler.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -58,7 +58,7 @@
 }
 
 void AbstractCompiler::set_state(int state) {
-  // Ensure that ste is only set by one thread at a time
+  // Ensure that state is only set by one thread at a time
   MutexLocker only_one(CompileThread_lock);
   _compiler_state =  state;
   CompileThread_lock->notify_all();
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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,47 @@
 
 #include "ci/compilerInterface.hpp"
 
+typedef void (*initializer)(void);
+
+#if INCLUDE_JVMCI
+// Per-compiler statistics
+class CompilerStatistics VALUE_OBJ_CLASS_SPEC {
+  friend class VMStructs;
+
+  class Data VALUE_OBJ_CLASS_SPEC {
+    friend class VMStructs;
+  public:
+    elapsedTimer _time;  // time spent compiling
+    int _bytes;          // number of bytecodes compiled, including inlined bytecodes
+    int _count;          // number of compilations
+    Data() : _bytes(0), _count(0) {}
+    void update(elapsedTimer time, int bytes) {
+      _time.add(time);
+      _bytes += bytes;
+      _count++;
+    }
+    void reset() {
+      _time.reset();
+    }
+  };
+
+ public:
+  Data _standard;  // stats for non-OSR compilations
+  Data _osr;       // stats for OSR compilations
+  int _nmethods_size; //
+  int _nmethods_code_size;
+  int bytes_per_second() {
+    int bytes = _standard._bytes + _osr._bytes;
+    if (bytes == 0) {
+      return 0;
+    }
+    double seconds = _standard._time.seconds() + _osr._time.seconds();
+    return seconds == 0.0 ? 0 : (int) (bytes / seconds);
+  }
+  CompilerStatistics() : _nmethods_size(0), _nmethods_code_size(0) {}
+};
+#endif // INCLUDE_JVMCI
+
 class AbstractCompiler : public CHeapObj<mtCompiler> {
  private:
   volatile int _num_compiler_threads;
@@ -45,12 +86,17 @@
     none,
     c1,
     c2,
+    jvmci,
     shark
   };
 
  private:
   Type _type;
 
+#if INCLUDE_JVMCI
+  CompilerStatistics _stats;
+#endif
+
  public:
   AbstractCompiler(Type type) : _type(type), _compiler_state(uninitialized), _num_compiler_threads(0) {}
 
@@ -115,6 +161,7 @@
   // Compiler type queries.
   bool is_c1()                                   { return _type == c1; }
   bool is_c2()                                   { return _type == c2; }
+  bool is_jvmci()                                { return _type == jvmci; }
   bool is_shark()                                { return _type == shark; }
 
   // Customization
@@ -138,6 +185,10 @@
   virtual void print_timers() {
     ShouldNotReachHere();
   }
+
+#if INCLUDE_JVMCI
+  CompilerStatistics* stats() { return &_stats; }
+#endif
 };
 
 #endif // SHARE_VM_COMPILER_ABSTRACTCOMPILER_HPP
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -51,6 +51,11 @@
 #ifdef COMPILER1
 #include "c1/c1_Compiler.hpp"
 #endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "runtime/vframe.hpp"
+#endif
 #ifdef COMPILER2
 #include "opto/c2compiler.hpp"
 #endif
@@ -453,41 +458,9 @@
   print(tty);
 }
 
-CompilerCounters::CompilerCounters(const char* thread_name, int instance, TRAPS) {
-
+CompilerCounters::CompilerCounters() {
   _current_method[0] = '\0';
   _compile_type = CompileBroker::no_compile;
-
-  if (UsePerfData) {
-    ResourceMark rm;
-
-    // create the thread instance name space string - don't create an
-    // instance subspace if instance is -1 - keeps the adapterThread
-    // counters  from having a ".0" namespace.
-    const char* thread_i = (instance == -1) ? thread_name :
-                      PerfDataManager::name_space(thread_name, instance);
-
-
-    char* name = PerfDataManager::counter_name(thread_i, "method");
-    _perf_current_method =
-               PerfDataManager::create_string_variable(SUN_CI, name,
-                                                       cmname_buffer_length,
-                                                       _current_method, CHECK);
-
-    name = PerfDataManager::counter_name(thread_i, "type");
-    _perf_compile_type = PerfDataManager::create_variable(SUN_CI, name,
-                                                          PerfData::U_None,
-                                                         (jlong)_compile_type,
-                                                          CHECK);
-
-    name = PerfDataManager::counter_name(thread_i, "time");
-    _perf_time = PerfDataManager::create_counter(SUN_CI, name,
-                                                 PerfData::U_Ticks, CHECK);
-
-    name = PerfDataManager::counter_name(thread_i, "compiles");
-    _perf_compiles = PerfDataManager::create_counter(SUN_CI, name,
-                                                     PerfData::U_Events, CHECK);
-  }
 }
 
 // ------------------------------------------------------------------
@@ -505,6 +478,30 @@
   // Set the interface to the current compiler(s).
   int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
   int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
+
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    // This is creating a JVMCICompiler singleton.
+    JVMCICompiler* jvmci = new JVMCICompiler();
+
+    if (UseJVMCICompiler) {
+      _compilers[1] = jvmci;
+      if (FLAG_IS_DEFAULT(JVMCIThreads)) {
+        if (BootstrapJVMCI) {
+          // JVMCI will bootstrap so give it more threads
+          c2_count = MIN2(32, os::active_processor_count());
+        }
+      } else {
+        c2_count = JVMCIThreads;
+      }
+      if (FLAG_IS_DEFAULT(JVMCIHostThreads)) {
+      } else {
+        c1_count = JVMCIHostThreads;
+      }
+    }
+  }
+#endif // INCLUDE_JVMCI
+
 #ifdef COMPILER1
   if (c1_count > 0) {
     _compilers[0] = new Compiler();
@@ -512,8 +509,10 @@
 #endif // COMPILER1
 
 #ifdef COMPILER2
-  if (c2_count > 0) {
-    _compilers[1] = new C2Compiler();
+  if (true JVMCI_ONLY( && !UseJVMCICompiler)) {
+    if (c2_count > 0) {
+      _compilers[1] = new C2Compiler();
+    }
   }
 #endif // COMPILER2
 
@@ -733,8 +732,8 @@
   const bool compiler_thread = true;
   for (int i = 0; i < c2_compiler_count; i++) {
     // Create a name for our thread.
-    sprintf(name_buffer, "C2 CompilerThread%d", i);
-    CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
+    sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i);
+    CompilerCounters* counters = new CompilerCounters();
     // Shark and C2
     make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK);
   }
@@ -742,7 +741,7 @@
   for (int i = c2_compiler_count; i < compiler_count; i++) {
     // Create a name for our thread.
     sprintf(name_buffer, "C1 CompilerThread%d", i);
-    CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
+    CompilerCounters* counters = new CompilerCounters();
     // C1
     make_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], compiler_thread, CHECK);
   }
@@ -803,7 +802,7 @@
     if (osr_bci != InvocationEntryBci) {
       tty->print(" osr_bci: %d", osr_bci);
     }
-    tty->print(" comment: %s count: %d", comment, hot_count);
+    tty->print(" level: %d comment: %s count: %d", comp_level, comment, hot_count);
     if (!hot_method.is_null()) {
       tty->print(" hot: ");
       if (hot_method() != method()) {
@@ -895,6 +894,41 @@
     // Should this thread wait for completion of the compile?
     blocking = is_compile_blocking();
 
+#if INCLUDE_JVMCI
+    if (UseJVMCICompiler) {
+      if (blocking) {
+        // Don't allow blocking compiles for requests triggered by JVMCI.
+        if (thread->is_Compiler_thread()) {
+          blocking = false;
+        }
+
+        // Don't allow blocking compiles if inside a class initializer or while performing class loading
+        vframeStream vfst((JavaThread*) thread);
+        for (; !vfst.at_end(); vfst.next()) {
+          if (vfst.method()->is_static_initializer() ||
+              (vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
+                  vfst.method()->name() == vmSymbols::loadClass_name())) {
+            blocking = false;
+            break;
+          }
+        }
+
+        // Don't allow blocking compilation requests to JVMCI
+        // if JVMCI itself is not yet initialized
+        if (!JVMCIRuntime::is_HotSpotJVMCIRuntime_initialized() && compiler(comp_level)->is_jvmci()) {
+          blocking = false;
+        }
+
+        // Don't allow blocking compilation requests if we are in JVMCIRuntime::shutdown
+        // to avoid deadlock between compiler thread(s) and threads run at shutdown
+        // such as the DestroyJavaVM thread.
+        if (JVMCIRuntime::shutdown_called()) {
+          blocking = false;
+        }
+      }
+    }
+#endif // INCLUDE_JVMCI
+
     // We will enter the compilation in the queue.
     // 14012000: Note that this sets the queued_for_compile bits in
     // the target method. We can now reason that a method cannot be
@@ -1076,7 +1110,10 @@
 
   // return requested nmethod
   // We accept a higher level osr method
-  return osr_bci  == InvocationEntryBci ? method->code() : method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
+  if (osr_bci == InvocationEntryBci) {
+    return method->code();
+  }
+  return method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
 }
 
 
@@ -1157,7 +1194,7 @@
       method->print_short_name(tty);
       tty->cr();
     }
-    method->set_not_compilable(CompLevel_all, !quietly, "excluded by CompilerOracle");
+    method->set_not_compilable(CompLevel_all, !quietly, "excluded by CompileCommand");
   }
 
   return false;
@@ -1199,6 +1236,15 @@
 #endif
 }
 
+// ------------------------------------------------------------------
+// CompileBroker::assign_compile_id_unlocked
+//
+// Public wrapper for assign_compile_id that acquires the needed locks
+uint CompileBroker::assign_compile_id_unlocked(Thread* thread, methodHandle method, int osr_bci) {
+  MutexLocker locker(MethodCompileQueue_lock, thread);
+  return assign_compile_id(method, osr_bci);
+}
+
 /**
  * Should the current thread block until this compilation request
  * has been fulfilled?
@@ -1436,10 +1482,6 @@
       os::hint_no_preempt();
     }
 
-    // trace per thread time and compile statistics
-    CompilerCounters* counters = ((CompilerThread*)thread)->counters();
-    PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter());
-
     // Assign the task to the current thread.  Mark this compilation
     // thread as active for the profiler.
     CompileTaskWrapper ctw(task);
@@ -1558,6 +1600,35 @@
   tty->print("%s", s.as_string());
 }
 
+void CompileBroker::post_compile(CompilerThread* thread, CompileTask* task, EventCompilation& event, bool success, ciEnv* ci_env) {
+
+  if (success) {
+    task->mark_success();
+    if (ci_env != NULL) {
+      task->set_num_inlined_bytecodes(ci_env->num_inlined_bytecodes());
+    }
+    if (_compilation_log != NULL) {
+      nmethod* code = task->code();
+      if (code != NULL) {
+        _compilation_log->log_nmethod(thread, code);
+      }
+    }
+  }
+
+  // simulate crash during compilation
+  assert(task->compile_id() != CICrashAt, "just as planned");
+  if (event.should_commit()) {
+    event.set_method(task->method());
+    event.set_compileID(task->compile_id());
+    event.set_compileLevel(task->comp_level());
+    event.set_succeded(task->is_success());
+    event.set_isOsr(task->osr_bci() != CompileBroker::standard_entry_bci);
+    event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size());
+    event.set_inlinedBytes(task->num_inlined_bytecodes());
+    event.commit();
+  }
+}
+
 // ------------------------------------------------------------------
 // CompileBroker::invoke_compiler_on_method
 //
@@ -1606,12 +1677,27 @@
   push_jni_handle_block();
   Method* target_handle = task->method();
   int compilable = ciEnv::MethodCompilable;
+  AbstractCompiler *comp = compiler(task_level);
+
+  int system_dictionary_modification_counter;
   {
-    int system_dictionary_modification_counter;
-    {
-      MutexLocker locker(Compile_lock, thread);
-      system_dictionary_modification_counter = SystemDictionary::number_of_modifications();
-    }
+    MutexLocker locker(Compile_lock, thread);
+    system_dictionary_modification_counter = SystemDictionary::number_of_modifications();
+  }
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler && comp != NULL && comp->is_jvmci()) {
+    JVMCICompiler* jvmci = (JVMCICompiler*) comp;
+
+    TraceTime t1("compilation", &time);
+    EventCompilation event;
+
+    JVMCIEnv env(task, system_dictionary_modification_counter);
+    jvmci->compile_method(target_handle, osr_bci, &env);
+
+    post_compile(thread, task, event, task->code() != NULL, NULL);
+  } else
+#endif // INCLUDE_JVMCI
+  {
 
     NoHandleMark  nhm;
     ThreadToNativeFromVM ttn(thread);
@@ -1637,7 +1723,6 @@
     TraceTime t1("compilation", &time);
     EventCompilation event;
 
-    AbstractCompiler *comp = compiler(task_level);
     if (comp == NULL) {
       ci_env.record_method_not_compilable("no compiler", !TieredCompilation);
     } else {
@@ -1669,32 +1754,13 @@
       }
       if (PrintCompilation) {
         FormatBufferResource msg = retry_message != NULL ?
-            err_msg_res("COMPILE SKIPPED: %s (%s)", ci_env.failure_reason(), retry_message) :
-            err_msg_res("COMPILE SKIPPED: %s",      ci_env.failure_reason());
+            FormatBufferResource("COMPILE SKIPPED: %s (%s)", ci_env.failure_reason(), retry_message) :
+            FormatBufferResource("COMPILE SKIPPED: %s",      ci_env.failure_reason());
         task->print(tty, msg);
       }
-    } else {
-      task->mark_success();
-      task->set_num_inlined_bytecodes(ci_env.num_inlined_bytecodes());
-      if (_compilation_log != NULL) {
-        nmethod* code = task->code();
-        if (code != NULL) {
-          _compilation_log->log_nmethod(thread, code);
-        }
-      }
     }
-    // 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();
-    }
+
+    post_compile(thread, task, event, !ci_env.failing(), &ci_env);
   }
   pop_jni_handle_block();
 
@@ -1945,13 +2011,19 @@
     _peak_compilation_time = time.milliseconds() > _peak_compilation_time ? time.milliseconds() : _peak_compilation_time;
 
     if (CITime) {
+      int bytes_compiled = method->code_size() + task->num_inlined_bytecodes();
+      JVMCI_ONLY(CompilerStatistics* stats = compiler(task->comp_level())->stats();)
       if (is_osr) {
         _t_osr_compilation.add(time);
-        _sum_osr_bytes_compiled += method->code_size() + task->num_inlined_bytecodes();
+        _sum_osr_bytes_compiled += bytes_compiled;
+        JVMCI_ONLY(stats->_osr.update(time, bytes_compiled);)
       } else {
         _t_standard_compilation.add(time);
         _sum_standard_bytes_compiled += method->code_size() + task->num_inlined_bytecodes();
+        JVMCI_ONLY(stats->_standard.update(time, bytes_compiled);)
       }
+      JVMCI_ONLY(stats->_nmethods_size += code->total_size();)
+      JVMCI_ONLY(stats->_nmethods_code_size += code->insts_size();)
     }
 
     if (UsePerfData) {
@@ -2007,22 +2079,106 @@
   }
 }
 
-void CompileBroker::print_times() {
+#if INCLUDE_JVMCI
+void CompileBroker::print_times(AbstractCompiler* comp) {
+  CompilerStatistics* stats = comp->stats();
+  tty->print_cr("  %s {speed: %d bytes/s; standard: %6.3f s, %d bytes, %d methods; osr: %6.3f s, %d bytes, %d methods; nmethods_size: %d bytes; nmethods_code_size: %d bytes}",
+                comp->name(), stats->bytes_per_second(),
+                stats->_standard._time.seconds(), stats->_standard._bytes, stats->_standard._count,
+                stats->_osr._time.seconds(), stats->_osr._bytes, stats->_osr._count,
+                stats->_nmethods_size, stats->_nmethods_code_size);
+  comp->print_timers();
+}
+#endif // INCLUDE_JVMCI
+
+void CompileBroker::print_times(bool per_compiler, bool aggregate) {
+#if INCLUDE_JVMCI
+  elapsedTimer standard_compilation;
+  elapsedTimer total_compilation;
+  elapsedTimer osr_compilation;
+
+  int standard_bytes_compiled = 0;
+  int osr_bytes_compiled = 0;
+
+  int standard_compile_count = 0;
+  int osr_compile_count = 0;
+  int total_compile_count = 0;
+
+  int nmethods_size = 0;
+  int nmethods_code_size = 0;
+  bool printedHeader = false;
+
+  for (unsigned int i = 0; i < sizeof(_compilers) / sizeof(AbstractCompiler*); i++) {
+    AbstractCompiler* comp = _compilers[i];
+    if (comp != NULL) {
+      if (per_compiler && aggregate && !printedHeader) {
+        printedHeader = true;
+        tty->cr();
+        tty->print_cr("Individual compiler times (for compiled methods only)");
+        tty->print_cr("------------------------------------------------");
+        tty->cr();
+      }
+      CompilerStatistics* stats = comp->stats();
+
+      standard_compilation.add(stats->_standard._time);
+      osr_compilation.add(stats->_osr._time);
+
+      standard_bytes_compiled += stats->_standard._bytes;
+      osr_bytes_compiled += stats->_osr._bytes;
+
+      standard_compile_count += stats->_standard._count;
+      osr_compile_count += stats->_osr._count;
+
+      nmethods_size += stats->_nmethods_size;
+      nmethods_code_size += stats->_nmethods_code_size;
+
+      if (per_compiler) {
+        print_times(comp);
+      }
+    }
+  }
+  total_compile_count = osr_compile_count + standard_compile_count;
+  total_compilation.add(osr_compilation);
+  total_compilation.add(standard_compilation);
+
+  // In hosted mode, print the JVMCI compiler specific counters manually.
+  if (!UseJVMCICompiler) {
+    JVMCICompiler::print_compilation_timers();
+  }
+#else // INCLUDE_JVMCI
+  elapsedTimer standard_compilation = CompileBroker::_t_standard_compilation;
+  elapsedTimer osr_compilation = CompileBroker::_t_osr_compilation;
+  elapsedTimer total_compilation = CompileBroker::_t_total_compilation;
+
+  int standard_bytes_compiled = CompileBroker::_sum_standard_bytes_compiled;
+  int osr_bytes_compiled = CompileBroker::_sum_osr_bytes_compiled;
+
+  int standard_compile_count = CompileBroker::_total_standard_compile_count;
+  int osr_compile_count = CompileBroker::_total_osr_compile_count;
+  int total_compile_count = CompileBroker::_total_compile_count;
+
+  int nmethods_size = CompileBroker::_sum_nmethod_code_size;
+  int nmethods_code_size = CompileBroker::_sum_nmethod_size;
+#endif // INCLUDE_JVMCI
+
+  if (!aggregate) {
+    return;
+  }
   tty->cr();
   tty->print_cr("Accumulated compiler times");
   tty->print_cr("----------------------------------------------------------");
                //0000000000111111111122222222223333333333444444444455555555556666666666
                //0123456789012345678901234567890123456789012345678901234567890123456789
-  tty->print_cr("  Total compilation time   : %7.3f s", CompileBroker::_t_total_compilation.seconds());
+  tty->print_cr("  Total compilation time   : %7.3f s", total_compilation.seconds());
   tty->print_cr("    Standard compilation   : %7.3f s, Average : %2.3f s",
-                CompileBroker::_t_standard_compilation.seconds(),
-                CompileBroker::_t_standard_compilation.seconds() / CompileBroker::_total_standard_compile_count);
+                standard_compilation.seconds(),
+                standard_compilation.seconds() / standard_compile_count);
   tty->print_cr("    Bailed out compilation : %7.3f s, Average : %2.3f s",
                 CompileBroker::_t_bailedout_compilation.seconds(),
                 CompileBroker::_t_bailedout_compilation.seconds() / CompileBroker::_total_bailout_count);
   tty->print_cr("    On stack replacement   : %7.3f s, Average : %2.3f s",
-                CompileBroker::_t_osr_compilation.seconds(),
-                CompileBroker::_t_osr_compilation.seconds() / CompileBroker::_total_osr_compile_count);
+                osr_compilation.seconds(),
+                osr_compilation.seconds() / osr_compile_count);
   tty->print_cr("    Invalidated            : %7.3f s, Average : %2.3f s",
                 CompileBroker::_t_invalidated_compilation.seconds(),
                 CompileBroker::_t_invalidated_compilation.seconds() / CompileBroker::_total_invalidated_count);
@@ -2038,18 +2194,19 @@
     comp->print_timers();
   }
   tty->cr();
-  tty->print_cr("  Total compiled methods    : %8d methods", CompileBroker::_total_compile_count);
-  tty->print_cr("    Standard compilation    : %8d methods", CompileBroker::_total_standard_compile_count);
-  tty->print_cr("    On stack replacement    : %8d methods", CompileBroker::_total_osr_compile_count);
-  int tcb = CompileBroker::_sum_osr_bytes_compiled + CompileBroker::_sum_standard_bytes_compiled;
+  tty->print_cr("  Total compiled methods    : %8d methods", total_compile_count);
+  tty->print_cr("    Standard compilation    : %8d methods", standard_compile_count);
+  tty->print_cr("    On stack replacement    : %8d methods", osr_compile_count);
+  int tcb = osr_bytes_compiled + standard_bytes_compiled;
   tty->print_cr("  Total compiled bytecodes  : %8d bytes", tcb);
-  tty->print_cr("    Standard compilation    : %8d bytes", CompileBroker::_sum_standard_bytes_compiled);
-  tty->print_cr("    On stack replacement    : %8d bytes", CompileBroker::_sum_osr_bytes_compiled);
-  int bps = (int)(tcb / CompileBroker::_t_total_compilation.seconds());
+  tty->print_cr("    Standard compilation    : %8d bytes", standard_bytes_compiled);
+  tty->print_cr("    On stack replacement    : %8d bytes", osr_bytes_compiled);
+  double tcs = total_compilation.seconds();
+  int bps = tcs == 0.0 ? 0 : (int)(tcb / tcs);
   tty->print_cr("  Average compilation speed : %8d bytes/s", bps);
   tty->cr();
-  tty->print_cr("  nmethod code size         : %8d bytes", CompileBroker::_sum_nmethod_code_size);
-  tty->print_cr("  nmethod total size        : %8d bytes", CompileBroker::_sum_nmethod_size);
+  tty->print_cr("  nmethod code size         : %8d bytes", nmethods_code_size);
+  tty->print_cr("  nmethod total size        : %8d bytes", nmethods_size);
 }
 
 // Debugging output for failure
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,6 +29,7 @@
 #include "compiler/abstractCompiler.hpp"
 #include "compiler/compileTask.hpp"
 #include "runtime/perfData.hpp"
+#include "trace/tracing.hpp"
 
 class nmethod;
 class nmethodLocker;
@@ -47,36 +48,26 @@
   private:
 
     char _current_method[cmname_buffer_length];
-    PerfStringVariable* _perf_current_method;
-
     int  _compile_type;
-    PerfVariable* _perf_compile_type;
-
-    PerfCounter* _perf_time;
-    PerfCounter* _perf_compiles;
 
   public:
-    CompilerCounters(const char* name, int instance, TRAPS);
+    CompilerCounters();
 
     // these methods should be called in a thread safe context
 
     void set_current_method(const char* method) {
       strncpy(_current_method, method, (size_t)cmname_buffer_length-1);
       _current_method[cmname_buffer_length-1] = '\0';
-      if (UsePerfData) _perf_current_method->set_value(method);
     }
 
     char* current_method()                  { return _current_method; }
 
     void set_compile_type(int compile_type) {
       _compile_type = compile_type;
-      if (UsePerfData) _perf_compile_type->set_value((jlong)compile_type);
     }
 
     int compile_type()                       { return _compile_type; }
 
-    PerfCounter* time_counter()              { return _perf_time; }
-    PerfCounter* compile_counter()           { return _perf_compiles; }
 };
 
 // CompileQueue
@@ -243,6 +234,7 @@
   static void wait_for_completion(CompileTask* task);
 
   static void invoke_compiler_on_method(CompileTask* task);
+  static void post_compile(CompilerThread* thread, CompileTask* task, EventCompilation& event, bool success, ciEnv* ci_env);
   static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level);
   static void push_jni_handle_block();
   static void pop_jni_handle_block();
@@ -288,6 +280,9 @@
                                  int hot_count,
                                  const char* comment, Thread* thread);
 
+  // Acquire any needed locks and assign a compile id
+  static uint assign_compile_id_unlocked(Thread* thread, methodHandle method, int osr_bci);
+
   static void compiler_thread_loop();
   static uint get_compilation_id() { return _compilation_id; }
 
@@ -336,8 +331,13 @@
   // Redefine Classes support
   static void mark_on_stack();
 
+#if INCLUDE_JVMCI
+  // Print curent compilation time stats for a given compiler
+  static void print_times(AbstractCompiler* comp);
+#endif
+
   // Print a detailed accounting of compilation time
-  static void print_times();
+  static void print_times(bool per_compiler = true, bool aggregate = true);
 
   // Debugging output for failure
   static void print_last_compile();
--- a/hotspot/src/share/vm/compiler/compileTask.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compileTask.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -183,6 +183,10 @@
   if (!short_form) {
     st->print("%7d ", (int) st->time_stamp().milliseconds());  // print timestamp
   }
+  // print compiler name if requested
+  if (CIPrintCompilerName) {
+    st->print("%s:", CompileBroker::compiler_name(comp_level));
+  }
   st->print("%4d ", compile_id);    // print compilation number
 
   // For unloaded methods the transition to zombie occurs after the
@@ -271,7 +275,8 @@
   if (_osr_bci != CompileBroker::standard_entry_bci) {
     log->print(" osr_bci='%d'", _osr_bci);
   }
-  if (_comp_level != CompLevel_highest_tier) {
+  // Always print the level in tiered.
+  if (_comp_level != CompLevel_highest_tier || TieredCompilation) {
     log->print(" level='%d'", _comp_level);
   }
   if (_is_blocking) {
@@ -307,6 +312,24 @@
 
 
 // ------------------------------------------------------------------
+// CompileTask::log_task_dequeued
+void CompileTask::log_task_dequeued(const char* comment) {
+  if (LogCompilation && xtty != NULL) {
+    Thread* thread = Thread::current();
+    ttyLocker ttyl;
+    ResourceMark rm(thread);
+
+    xtty->begin_elem("task_dequeued");
+    log_task(xtty);
+    if (comment != NULL) {
+      xtty->print(" comment='%s'", comment);
+    }
+    xtty->end_elem();
+  }
+}
+
+
+// ------------------------------------------------------------------
 // CompileTask::log_task_start
 void CompileTask::log_task_start(CompileLog* log)   {
   log->begin_head("task");
--- a/hotspot/src/share/vm/compiler/compileTask.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compileTask.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -133,6 +133,7 @@
 
   void         log_task(xmlStream* log);
   void         log_task_queued();
+  void         log_task_dequeued(const char* comment);
   void         log_task_start(CompileLog* log);
   void         log_task_done(CompileLog* log);
 
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -24,149 +24,17 @@
 
 #include "precompiled.hpp"
 #include "compiler/compilerOracle.hpp"
+#include "compiler/methodMatcher.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/klass.hpp"
 #include "oops/method.hpp"
-#include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/jniHandles.hpp"
 #include "runtime/os.hpp"
 
-class MethodMatcher : public CHeapObj<mtCompiler> {
- public:
-  enum Mode {
-    Exact,
-    Prefix = 1,
-    Suffix = 2,
-    Substring = Prefix | Suffix,
-    Any,
-    Unknown = -1
-  };
-
- protected:
-  Symbol*        _class_name;
-  Symbol*        _method_name;
-  Symbol*        _signature;
-  Mode           _class_mode;
-  Mode           _method_mode;
-  MethodMatcher* _next;
-
-  static bool match(Symbol* candidate, Symbol* match, Mode match_mode);
-
-  Symbol* class_name() const { return _class_name; }
-  Symbol* method_name() const { return _method_name; }
-  Symbol* signature() const { return _signature; }
-
- public:
-  MethodMatcher(Symbol* class_name, Mode class_mode,
-                Symbol* method_name, Mode method_mode,
-                Symbol* signature, MethodMatcher* next);
-  MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next);
-
-  // utility method
-  MethodMatcher* find(methodHandle method) {
-    Symbol* class_name  = method->method_holder()->name();
-    Symbol* method_name = method->name();
-    for (MethodMatcher* current = this; current != NULL; current = current->_next) {
-      if (match(class_name, current->class_name(), current->_class_mode) &&
-          match(method_name, current->method_name(), current->_method_mode) &&
-          (current->signature() == NULL || current->signature() == method->signature())) {
-        return current;
-      }
-    }
-    return NULL;
-  }
-
-  bool match(methodHandle method) {
-    return find(method) != NULL;
-  }
-
-  MethodMatcher* next() const { return _next; }
-
-  static void print_symbol(Symbol* h, Mode mode) {
-    ResourceMark rm;
-
-    if (mode == Suffix || mode == Substring || mode == Any) {
-      tty->print("*");
-    }
-    if (mode != Any) {
-      h->print_symbol_on(tty);
-    }
-    if (mode == Prefix || mode == Substring) {
-      tty->print("*");
-    }
-  }
-
-  void print_base() {
-    print_symbol(class_name(), _class_mode);
-    tty->print(".");
-    print_symbol(method_name(), _method_mode);
-    if (signature() != NULL) {
-      signature()->print_symbol_on(tty);
-    }
-  }
-
-  virtual void print() {
-    print_base();
-    tty->cr();
-  }
-};
-
-MethodMatcher::MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next) {
-  _class_name  = class_name;
-  _method_name = method_name;
-  _next        = next;
-  _class_mode  = MethodMatcher::Exact;
-  _method_mode = MethodMatcher::Exact;
-  _signature   = NULL;
-}
-
-
-MethodMatcher::MethodMatcher(Symbol* class_name, Mode class_mode,
-                             Symbol* method_name, Mode method_mode,
-                             Symbol* signature, MethodMatcher* next):
-    _class_mode(class_mode)
-  , _method_mode(method_mode)
-  , _next(next)
-  , _class_name(class_name)
-  , _method_name(method_name)
-  , _signature(signature) {
-}
-
-bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) {
-  if (match_mode == Any) {
-    return true;
-  }
-
-  if (match_mode == Exact) {
-    return candidate == match;
-  }
-
-  ResourceMark rm;
-  const char * candidate_string = candidate->as_C_string();
-  const char * match_string = match->as_C_string();
-
-  switch (match_mode) {
-  case Prefix:
-    return strstr(candidate_string, match_string) == candidate_string;
-
-  case Suffix: {
-    size_t clen = strlen(candidate_string);
-    size_t mlen = strlen(match_string);
-    return clen >= mlen && strcmp(candidate_string + clen - mlen, match_string) == 0;
-  }
-
-  case Substring:
-    return strstr(candidate_string, match_string) != NULL;
-
-  default:
-    return false;
-  }
-}
-
 enum OptionType {
   IntxType,
   UintxType,
@@ -202,114 +70,6 @@
   return DoubleType;
 }
 
-template<typename T>
-static const T copy_value(const T value) {
-  return value;
-}
-
-template<> const ccstr copy_value<ccstr>(const ccstr value) {
-  return (const ccstr)os::strdup_check_oom(value);
-}
-
-template <typename T>
-class TypedMethodOptionMatcher : public MethodMatcher {
-  const char* _option;
-  OptionType _type;
-  const T _value;
-
-public:
-  TypedMethodOptionMatcher(Symbol* class_name, Mode class_mode,
-                           Symbol* method_name, Mode method_mode,
-                           Symbol* signature, const char* opt,
-                           const T value,  MethodMatcher* next) :
-    MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next),
-                  _type(get_type_for<T>()), _value(copy_value<T>(value)) {
-    _option = os::strdup_check_oom(opt);
-  }
-
-  ~TypedMethodOptionMatcher() {
-    os::free((void*)_option);
-  }
-
-  TypedMethodOptionMatcher* match(methodHandle method, const char* opt) {
-    TypedMethodOptionMatcher* current = this;
-    while (current != NULL) {
-      current = (TypedMethodOptionMatcher*)current->find(method);
-      if (current == NULL) {
-        return NULL;
-      }
-      if (strcmp(current->_option, opt) == 0) {
-        return current;
-      }
-      current = current->next();
-    }
-    return NULL;
-  }
-
-  TypedMethodOptionMatcher* next() {
-    return (TypedMethodOptionMatcher*)_next;
-  }
-
-  OptionType get_type(void) {
-      return _type;
-  };
-
-  T value() { return _value; }
-
-  void print() {
-    ttyLocker ttyl;
-    print_base();
-    tty->print(" %s", _option);
-    tty->print(" <unknown option type>");
-    tty->cr();
-  }
-};
-
-template<>
-void TypedMethodOptionMatcher<intx>::print() {
-  ttyLocker ttyl;
-  print_base();
-  tty->print(" intx %s", _option);
-  tty->print(" = " INTX_FORMAT, _value);
-  tty->cr();
-};
-
-template<>
-void TypedMethodOptionMatcher<uintx>::print() {
-  ttyLocker ttyl;
-  print_base();
-  tty->print(" uintx %s", _option);
-  tty->print(" = " UINTX_FORMAT, _value);
-  tty->cr();
-};
-
-template<>
-void TypedMethodOptionMatcher<bool>::print() {
-  ttyLocker ttyl;
-  print_base();
-  tty->print(" bool %s", _option);
-  tty->print(" = %s", _value ? "true" : "false");
-  tty->cr();
-};
-
-template<>
-void TypedMethodOptionMatcher<ccstr>::print() {
-  ttyLocker ttyl;
-  print_base();
-  tty->print(" const char* %s", _option);
-  tty->print(" = '%s'", _value);
-  tty->cr();
-};
-
-template<>
-void TypedMethodOptionMatcher<double>::print() {
-  ttyLocker ttyl;
-  print_base();
-  tty->print(" double %s", _option);
-  tty->print(" = %f", _value);
-  tty->cr();
-};
-
 // this must parallel the command_names below
 enum OracleCommand {
   UnknownCommand = -1,
@@ -342,8 +102,198 @@
 };
 
 class MethodMatcher;
-static MethodMatcher* lists[OracleCommandCount] = { 0, };
+class TypedMethodOptionMatcher;
+
+static BasicMatcher* lists[OracleCommandCount] = { 0, };
+static TypedMethodOptionMatcher* option_list = NULL;
+
+class TypedMethodOptionMatcher : public MethodMatcher {
+ private:
+  TypedMethodOptionMatcher* _next;
+  const char*   _option;
+  OptionType    _type;
+ public:
+
+  union {
+    bool bool_value;
+    intx intx_value;
+    uintx uintx_value;
+    double double_value;
+    ccstr ccstr_value;
+  } _u;
+
+  TypedMethodOptionMatcher() : MethodMatcher(),
+    _next(NULL),
+    _type(UnknownType) {
+      _option = NULL;
+      memset(&_u, 0, sizeof(_u));
+  }
+
+  static TypedMethodOptionMatcher* parse_method_pattern(char*& line, const char*& error_msg);
+  TypedMethodOptionMatcher* match(methodHandle method, const char* opt, OptionType type);
+
+  void init(const char* opt, OptionType type, TypedMethodOptionMatcher* next) {
+    _next = next;
+    _type = type;
+    _option = os::strdup_check_oom(opt);
+  }
+
+  void set_next(TypedMethodOptionMatcher* next) {_next = next; }
+  TypedMethodOptionMatcher* next() { return _next; }
+  OptionType type() { return _type; }
+  template<typename T> T value();
+  template<typename T> void set_value(T value);
+  void print();
+  void print_all();
+  TypedMethodOptionMatcher* clone();
+  ~TypedMethodOptionMatcher();
+};
+
+// A few templated accessors instead of a full template class.
+template<> intx TypedMethodOptionMatcher::value<intx>() {
+  return _u.intx_value;
+}
+
+template<> uintx TypedMethodOptionMatcher::value<uintx>() {
+  return _u.uintx_value;
+}
+
+template<> bool TypedMethodOptionMatcher::value<bool>() {
+  return _u.bool_value;
+}
+
+template<> double TypedMethodOptionMatcher::value<double>() {
+  return _u.double_value;
+}
+
+template<> ccstr TypedMethodOptionMatcher::value<ccstr>() {
+  return _u.ccstr_value;
+}
+
+template<> void TypedMethodOptionMatcher::set_value(intx value) {
+  _u.intx_value = value;
+}
+
+template<> void TypedMethodOptionMatcher::set_value(uintx value) {
+  _u.uintx_value = value;
+}
+
+template<> void TypedMethodOptionMatcher::set_value(double value) {
+  _u.double_value = value;
+}
+
+template<> void TypedMethodOptionMatcher::set_value(bool value) {
+  _u.bool_value = value;
+}
+
+template<> void TypedMethodOptionMatcher::set_value(ccstr value) {
+  _u.ccstr_value = (const ccstr)os::strdup_check_oom(value);
+}
 
+void TypedMethodOptionMatcher::print() {
+  ttyLocker ttyl;
+  print_base(tty);
+  switch (_type) {
+  case IntxType:
+    tty->print_cr(" intx %s = " INTX_FORMAT, _option, value<intx>());
+    break;
+  case UintxType:
+    tty->print_cr(" uintx %s = " UINTX_FORMAT, _option, value<uintx>());
+    break;
+  case BoolType:
+    tty->print_cr(" bool %s = %s", _option, value<bool>() ? "true" : "false");
+    break;
+  case DoubleType:
+    tty->print_cr(" double %s = %f", _option, value<double>());
+    break;
+  case CcstrType:
+    tty->print_cr(" const char* %s = '%s'", _option, value<ccstr>());
+    break;
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+void TypedMethodOptionMatcher::print_all() {
+   print();
+   if (_next != NULL) {
+     tty->print(" ");
+     _next->print_all();
+   }
+ }
+
+TypedMethodOptionMatcher* TypedMethodOptionMatcher::clone() {
+  TypedMethodOptionMatcher* m = new TypedMethodOptionMatcher();
+  m->_class_mode = _class_mode;
+  m->_class_name = _class_name;
+  m->_method_mode = _method_mode;
+  m->_method_name = _method_name;
+  m->_signature = _signature;
+  // Need to ref count the symbols
+  if (_class_name != NULL) {
+    _class_name->increment_refcount();
+  }
+  if (_method_name != NULL) {
+    _method_name->increment_refcount();
+  }
+  if (_signature != NULL) {
+    _signature->increment_refcount();
+  }
+  return m;
+}
+
+TypedMethodOptionMatcher::~TypedMethodOptionMatcher() {
+  if (_option != NULL) {
+    os::free((void*)_option);
+  }
+  if (_class_name != NULL) {
+    _class_name->decrement_refcount();
+  }
+  if (_method_name != NULL) {
+    _method_name->decrement_refcount();
+  }
+  if (_signature != NULL) {
+    _signature->decrement_refcount();
+  }
+}
+
+TypedMethodOptionMatcher* TypedMethodOptionMatcher::parse_method_pattern(char*& line, const char*& error_msg) {
+  assert(error_msg == NULL, "Dont call here with error_msg already set");
+  TypedMethodOptionMatcher* tom = new TypedMethodOptionMatcher();
+  MethodMatcher::parse_method_pattern(line, error_msg, tom);
+  if (error_msg != NULL) {
+    delete tom;
+    return NULL;
+  }
+  return tom;
+}
+
+TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(methodHandle method, const char* opt, OptionType type) {
+  TypedMethodOptionMatcher* current = this;
+  while (current != NULL) {
+    // Fastest compare first.
+    if (current->type() == type) {
+      if (strcmp(current->_option, opt) == 0) {
+        if (current->matches(method)) {
+          return current;
+        }
+      }
+    }
+    current = current->next();
+  }
+  return NULL;
+}
+
+template<typename T>
+static void add_option_string(TypedMethodOptionMatcher* matcher,
+                                        const char* option,
+                                        T value) {
+  assert(matcher != option_list, "No circular lists please");
+  matcher->init(option, get_type_for<T>(), option_list);
+  matcher->set_value<T>(value);
+  option_list = matcher;
+  return;
+}
 
 static bool check_predicate(OracleCommand command, methodHandle method) {
   return ((lists[command] != NULL) &&
@@ -351,51 +301,27 @@
           lists[command]->match(method));
 }
 
-
-static MethodMatcher* add_predicate(OracleCommand command,
-                                    Symbol* class_name, MethodMatcher::Mode c_mode,
-                                    Symbol* method_name, MethodMatcher::Mode m_mode,
-                                    Symbol* signature) {
+static void add_predicate(OracleCommand command, BasicMatcher* bm) {
   assert(command != OptionCommand, "must use add_option_string");
-  if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL)
+  if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) {
     tty->print_cr("Warning:  +LogCompilation must be enabled in order for individual methods to be logged.");
-  lists[command] = new MethodMatcher(class_name, c_mode, method_name, m_mode, signature, lists[command]);
-  return lists[command];
-}
+  }
+  bm->set_next(lists[command]);
+  lists[command] = bm;
 
-template<typename T>
-static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode,
-                                        Symbol* method_name, MethodMatcher::Mode m_mode,
-                                        Symbol* signature,
-                                        const char* option,
-                                        T value) {
-  lists[OptionCommand] = new TypedMethodOptionMatcher<T>(class_name, c_mode, method_name, m_mode,
-                                                         signature, option, value, lists[OptionCommand]);
-  return lists[OptionCommand];
-}
-
-template<typename T>
-static bool get_option_value(methodHandle method, const char* option, T& value) {
-   TypedMethodOptionMatcher<T>* m;
-   if (lists[OptionCommand] != NULL
-       && (m = ((TypedMethodOptionMatcher<T>*)lists[OptionCommand])->match(method, option)) != NULL
-       && m->get_type() == get_type_for<T>()) {
-       value = m->value();
-       return true;
-   } else {
-     return false;
-   }
-}
-
-bool CompilerOracle::has_option_string(methodHandle method, const char* option) {
-  bool value = false;
-  get_option_value(method, option, value);
-  return value;
+  return;
 }
 
 template<typename T>
 bool CompilerOracle::has_option_value(methodHandle method, const char* option, T& value) {
-  return ::get_option_value(method, option, value);
+  if (option_list != NULL) {
+    TypedMethodOptionMatcher* m = option_list->match(method, option, get_type_for<T>());
+    if (m != NULL) {
+      value = m->value<T>();
+      return true;
+    }
+  }
+  return false;
 }
 
 // Explicit instantiation for all OptionTypes supported.
@@ -405,6 +331,12 @@
 template bool CompilerOracle::has_option_value<ccstr>(methodHandle method, const char* option, ccstr& value);
 template bool CompilerOracle::has_option_value<double>(methodHandle method, const char* option, double& value);
 
+bool CompilerOracle::has_option_string(methodHandle method, const char* option) {
+  bool value = false;
+  has_option_value(method, option, value);
+  return value;
+}
+
 bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) {
   quietly = true;
   if (lists[ExcludeCommand] != NULL) {
@@ -420,19 +352,18 @@
   return false;
 }
 
-
 bool CompilerOracle::should_inline(methodHandle method) {
   return (check_predicate(InlineCommand, method));
 }
 
-
+// Check both DontInlineCommand and ExcludeCommand here
+// - consistent behavior for all compilers
 bool CompilerOracle::should_not_inline(methodHandle method) {
-  return (check_predicate(DontInlineCommand, method));
+  return check_predicate(DontInlineCommand, method) || check_predicate(ExcludeCommand, method);
 }
 
-
 bool CompilerOracle::should_print(methodHandle method) {
-  return (check_predicate(PrintCommand, method));
+  return check_predicate(PrintCommand, method);
 }
 
 bool CompilerOracle::should_print_methods() {
@@ -445,12 +376,10 @@
   return (check_predicate(LogCommand, method));
 }
 
-
 bool CompilerOracle::should_break_at(methodHandle method) {
   return check_predicate(BreakCommand, method);
 }
 
-
 static OracleCommand parse_command_name(const char * line, int* bytes_read) {
   assert(ARRAY_SIZE(command_names) == OracleCommandCount,
          "command_names size mismatch");
@@ -516,84 +445,12 @@
   tty->cr();
 };
 
-// The JVM specification defines the allowed characters.
-// Tokens that are disallowed by the JVM specification can have
-// a meaning to the parser so we need to include them here.
-// The parser does not enforce all rules of the JVMS - a successful parse
-// does not mean that it is an allowed name. Illegal names will
-// be ignored since they never can match a class or method.
-//
-// '\0' and 0xf0-0xff are disallowed in constant string values
-// 0x20 ' ', 0x09 '\t' and, 0x2c ',' are used in the matching
-// 0x5b '[' and 0x5d ']' can not be used because of the matcher
-// 0x28 '(' and 0x29 ')' are used for the signature
-// 0x2e '.' is always replaced before the matching
-// 0x2f '/' is only used in the class name as package separator
-
-#define RANGEBASE "\x1\x2\x3\x4\x5\x6\x7\x8\xa\xb\xc\xd\xe\xf" \
-    "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \
-    "\x21\x22\x23\x24\x25\x26\x27\x2a\x2b\x2c\x2d" \
-    "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \
-    "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \
-    "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5c\x5e\x5f" \
-    "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \
-    "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \
-    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \
-    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \
-    "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \
-    "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \
-    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \
-    "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \
-    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-
-#define RANGE0 "[*" RANGEBASE "]"
-#define RANGESLASH "[*" RANGEBASE "/]"
-
-static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) {
-  int match = MethodMatcher::Exact;
-  while (name[0] == '*') {
-    match |= MethodMatcher::Suffix;
-    // Copy remaining string plus NUL to the beginning
-    memmove(name, name + 1, strlen(name + 1) + 1);
-  }
-
-  if (strcmp(name, "*") == 0) return MethodMatcher::Any;
-
-  size_t len = strlen(name);
-  while (len > 0 && name[len - 1] == '*') {
-    match |= MethodMatcher::Prefix;
-    name[--len] = '\0';
-  }
-
-  if (strstr(name, "*") != NULL) {
-    error_msg = "  Embedded * not allowed";
-    return MethodMatcher::Unknown;
-  }
-  return (MethodMatcher::Mode)match;
-}
-
-static bool scan_line(const char * line,
-                      char class_name[],  MethodMatcher::Mode* c_mode,
-                      char method_name[], MethodMatcher::Mode* m_mode,
-                      int* bytes_read, const char*& error_msg) {
-  *bytes_read = 0;
-  error_msg = NULL;
-  if (2 == sscanf(line, "%*[ \t]%255" RANGESLASH "%*[ ]" "%255" RANGE0 "%n", class_name, method_name, bytes_read)) {
-    *c_mode = check_mode(class_name, error_msg);
-    *m_mode = check_mode(method_name, error_msg);
-    return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown;
-  }
-  return false;
-}
-
 // Scan next flag and value in line, return MethodMatcher object on success, NULL on failure.
 // On failure, error_msg contains description for the first error.
 // For future extensions: set error_msg on first error.
-static MethodMatcher* scan_flag_and_value(const char* type, const char* line, int& total_bytes_read,
-                                          Symbol* c_name, MethodMatcher::Mode c_match,
-                                          Symbol* m_name, MethodMatcher::Mode m_match,
-                                          Symbol* signature,
-                                          char* errorbuf, const int buf_size) {
+static void scan_flag_and_value(const char* type, const char* line, int& total_bytes_read,
+                                            TypedMethodOptionMatcher* matcher,
+                                            char* errorbuf, const int buf_size) {
   total_bytes_read = 0;
   int bytes_read = 0;
   char flag[256];
@@ -608,7 +465,8 @@
       intx value;
       if (sscanf(line, "%*[ \t]" INTX_FORMAT "%n", &value, &bytes_read) == 1) {
         total_bytes_read += bytes_read;
-        return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value);
+        add_option_string(matcher, flag, value);
+        return;
       } else {
         jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s ", flag, type);
       }
@@ -616,7 +474,8 @@
       uintx value;
       if (sscanf(line, "%*[ \t]" UINTX_FORMAT "%n", &value, &bytes_read) == 1) {
         total_bytes_read += bytes_read;
-        return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value);
+        add_option_string(matcher, flag, value);
+        return;
       } else {
         jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
       }
@@ -625,7 +484,8 @@
       char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1);
       if (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", value, &bytes_read) == 1) {
         total_bytes_read += bytes_read;
-        return add_option_string(c_name, c_match, m_name, m_match, signature, flag, (ccstr)value);
+        add_option_string(matcher, flag, (ccstr)value);
+        return;
       } else {
         jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
       }
@@ -646,7 +506,8 @@
           next_value += bytes_read;
           end_value = next_value-1;
         }
-        return add_option_string(c_name, c_match, m_name, m_match, signature, flag, (ccstr)value);
+        add_option_string(matcher, flag, (ccstr)value);
+        return;
       } else {
         jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
       }
@@ -655,10 +516,12 @@
       if (sscanf(line, "%*[ \t]%255[a-zA-Z]%n", value, &bytes_read) == 1) {
         if (strcmp(value, "true") == 0) {
           total_bytes_read += bytes_read;
-          return add_option_string(c_name, c_match, m_name, m_match, signature, flag, true);
+          add_option_string(matcher, flag, true);
+          return;
         } else if (strcmp(value, "false") == 0) {
           total_bytes_read += bytes_read;
-          return add_option_string(c_name, c_match, m_name, m_match, signature, flag, false);
+          add_option_string(matcher, flag, false);
+          return;
         } else {
           jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
         }
@@ -673,7 +536,8 @@
         char value[512] = "";
         jio_snprintf(value, sizeof(value), "%s.%s", buffer[0], buffer[1]);
         total_bytes_read += bytes_read;
-        return add_option_string(c_name, c_match, m_name, m_match, signature, flag, atof(value));
+        add_option_string(matcher, flag, atof(value));
+        return;
       } else {
         jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
       }
@@ -683,7 +547,7 @@
   } else {
     jio_snprintf(errorbuf, buf_size, "  Flag name for type %s should be alphanumeric ", type);
   }
-  return NULL;
+  return;
 }
 
 int skip_whitespace(char* line) {
@@ -693,31 +557,20 @@
   return whitespace_read;
 }
 
+void CompilerOracle::print_parse_error(const char*&  error_msg, char* original_line) {
+  assert(error_msg != NULL, "Must have error_message");
+
+  ttyLocker ttyl;
+  tty->print_cr("CompileCommand: An error occurred during parsing");
+  tty->print_cr("Line: %s", original_line);
+  tty->print_cr("Error: %s", error_msg);
+  CompilerOracle::print_tip();
+}
+
 void CompilerOracle::parse_from_line(char* line) {
   if (line[0] == '\0') return;
   if (line[0] == '#')  return;
 
-  bool have_colon = (strstr(line, "::") != NULL);
-  for (char* lp = line; *lp != '\0'; lp++) {
-    // Allow '.' to separate the class name from the method name.
-    // This is the preferred spelling of methods:
-    //      exclude java/lang/String.indexOf(I)I
-    // Allow ',' for spaces (eases command line quoting).
-    //      exclude,java/lang/String.indexOf
-    // For backward compatibility, allow space as separator also.
-    //      exclude java/lang/String indexOf
-    //      exclude,java/lang/String,indexOf
-    // For easy cut-and-paste of method names, allow VM output format
-    // as produced by Method::print_short_name:
-    //      exclude java.lang.String::indexOf
-    // For simple implementation convenience here, convert them all to space.
-    if (have_colon) {
-      if (*lp == '.')  *lp = '/';   // dots build the package prefix
-      if (*lp == ':')  *lp = ' ';
-    }
-    if (*lp == ',' || *lp == '.')  *lp = ' ';
-  }
-
   char* original_line = line;
   int bytes_read;
   OracleCommand command = parse_command_name(line, &bytes_read);
@@ -742,109 +595,86 @@
     return;
   }
 
-  MethodMatcher::Mode c_match = MethodMatcher::Exact;
-  MethodMatcher::Mode m_match = MethodMatcher::Exact;
-  char class_name[256];
-  char method_name[256];
-  char sig[1024];
-  char errorbuf[1024];
-  const char* error_msg = NULL; // description of first error that appears
-  MethodMatcher* match = NULL;
+  const char* error_msg = NULL;
+  if (command == OptionCommand) {
+    // Look for trailing options.
+    //
+    // Two types of trailing options are
+    // supported:
+    //
+    // (1) CompileCommand=option,Klass::method,flag
+    // (2) CompileCommand=option,Klass::method,type,flag,value
+    //
+    // Type (1) is used to enable a boolean flag for a method.
+    //
+    // Type (2) is used to support options with a value. Values can have the
+    // the following types: intx, uintx, bool, ccstr, ccstrlist, and double.
+    //
+    // For future extensions: extend scan_flag_and_value()
 
-  if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) {
-    EXCEPTION_MARK;
-    Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK);
-    Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK);
-    Symbol* signature = NULL;
-
-    line += bytes_read;
-
-    // there might be a signature following the method.
-    // signatures always begin with ( so match that by hand
-    line += skip_whitespace(line);
-    if (1 == sscanf(line, "(%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
-      sig[0] = '(';
-      line += bytes_read;
-      signature = SymbolTable::new_symbol(sig, CHECK);
+    char option[256]; // stores flag for Type (1) and type of Type (2)
+    line++; // skip the ','
+    TypedMethodOptionMatcher* archetype = TypedMethodOptionMatcher::parse_method_pattern(line, error_msg);
+    if (archetype == NULL) {
+      assert(error_msg != NULL, "Must have error_message");
+      print_parse_error(error_msg, original_line);
+      return;
     }
 
-    if (command == OptionCommand) {
-      // Look for trailing options.
-      //
-      // Two types of trailing options are
-      // supported:
-      //
-      // (1) CompileCommand=option,Klass::method,flag
-      // (2) CompileCommand=option,Klass::method,type,flag,value
-      //
-      // Type (1) is used to enable a boolean flag for a method.
-      //
-      // Type (2) is used to support options with a value. Values can have the
-      // the following types: intx, uintx, bool, ccstr, ccstrlist, and double.
-      //
-      // For future extensions: extend scan_flag_and_value()
-      char option[256]; // stores flag for Type (1) and type of Type (2)
+    line += skip_whitespace(line);
+
+    // This is unnecessarily complex. Should retire multi-option lines and skip while loop
+    while (sscanf(line, "%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
+      line += bytes_read;
 
-      line += skip_whitespace(line);
-      while (sscanf(line, "%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
-        if (match != NULL && !_quiet) {
-          // Print out the last match added
-          ttyLocker ttyl;
-          tty->print("CompileCommand: %s ", command_names[command]);
-          match->print();
+      // typed_matcher is used as a blueprint for each option, deleted at the end
+      TypedMethodOptionMatcher* typed_matcher = archetype->clone();
+      if (strcmp(option, "intx") == 0
+          || strcmp(option, "uintx") == 0
+          || strcmp(option, "bool") == 0
+          || strcmp(option, "ccstr") == 0
+          || strcmp(option, "ccstrlist") == 0
+          || strcmp(option, "double") == 0
+          ) {
+        char errorbuf[1024] = {0};
+        // Type (2) option: parse flag name and value.
+        scan_flag_and_value(option, line, bytes_read, typed_matcher, errorbuf, sizeof(errorbuf));
+        if (*errorbuf != '\0') {
+          error_msg = errorbuf;
+          print_parse_error(error_msg, original_line);
+          return;
         }
         line += bytes_read;
-
-        if (strcmp(option, "intx") == 0
-            || strcmp(option, "uintx") == 0
-            || strcmp(option, "bool") == 0
-            || strcmp(option, "ccstr") == 0
-            || strcmp(option, "ccstrlist") == 0
-            || strcmp(option, "double") == 0
-            ) {
+      } else {
+        // Type (1) option
+        add_option_string(typed_matcher, option, true);
+      }
+      if (typed_matcher != NULL && !_quiet) {
+        // Print out the last match added
+        assert(error_msg == NULL, "No error here");
+        ttyLocker ttyl;
+        tty->print("CompileCommand: %s ", command_names[command]);
+        typed_matcher->print();
+      }
+      line += skip_whitespace(line);
+    } // while(
+    delete archetype;
+  } else {  // not an OptionCommand)
+    assert(error_msg == NULL, "Don't call here with error_msg already set");
 
-          // Type (2) option: parse flag name and value.
-          match = scan_flag_and_value(option, line, bytes_read,
-                                      c_name, c_match, m_name, m_match, signature,
-                                      errorbuf, sizeof(errorbuf));
-          if (match == NULL) {
-            error_msg = errorbuf;
-            break;
-          }
-          line += bytes_read;
-        } else {
-          // Type (1) option
-          match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true);
-        }
-        line += skip_whitespace(line);
-      } // while(
-    } else {
-      match = add_predicate(command, c_name, c_match, m_name, m_match, signature);
+    BasicMatcher* matcher = BasicMatcher::parse_method_pattern(line, error_msg);
+    if (error_msg != NULL) {
+      assert(matcher == NULL, "consistency");
+      print_parse_error(error_msg, original_line);
+      return;
     }
-  }
 
-  ttyLocker ttyl;
-  if (error_msg != NULL) {
-    // an error has happened
-    tty->print_cr("CompileCommand: An error occured during parsing");
-    tty->print_cr("  \"%s\"", original_line);
-    if (error_msg != NULL) {
-      tty->print_cr("%s", error_msg);
-    }
-    CompilerOracle::print_tip();
-
-  } else {
-    // check for remaining characters
-    bytes_read = 0;
-    sscanf(line, "%*[ \t]%n", &bytes_read);
-    if (line[bytes_read] != '\0') {
-      tty->print_cr("CompileCommand: Bad pattern");
-      tty->print_cr("  \"%s\"", original_line);
-      tty->print_cr("  Unrecognized text %s after command ", line);
-      CompilerOracle::print_tip();
-    } else if (match != NULL && !_quiet) {
+    add_predicate(command, matcher);
+    if (!_quiet) {
+      ttyLocker ttyl;
       tty->print("CompileCommand: %s ", command_names[command]);
-      match->print();
+      matcher->print(tty);
+      tty->cr();
     }
   }
 }
@@ -1045,10 +875,12 @@
       Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK);
       Symbol* signature = NULL;
 
-      add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature);
+      BasicMatcher* bm = new BasicMatcher();
+      bm->init(c_name, c_match, m_name, m_match, signature);
+      add_predicate(CompileOnlyCommand, bm);
       if (PrintVMOptions) {
         tty->print("CompileOnly: compileonly ");
-        lists[CompileOnlyCommand]->print();
+        lists[CompileOnlyCommand]->print_all(tty);
       }
 
       className = NULL;
--- a/hotspot/src/share/vm/compiler/compilerOracle.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compilerOracle.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -35,6 +35,7 @@
  private:
   static bool _quiet;
   static void print_tip();
+  static void print_parse_error(const char*&  error_msg, char* original_line);
 
  public:
 
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -56,8 +56,6 @@
 #include "shark/sharkEntry.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 void*       Disassembler::_library               = NULL;
 bool        Disassembler::_tried_to_load_library = false;
 
@@ -330,16 +328,19 @@
   if (Universe::is_fully_initialized()) {
     if (StubRoutines::contains(adr)) {
       StubCodeDesc* desc = StubCodeDesc::desc_for(adr);
-      if (desc == NULL)
+      if (desc == NULL) {
         desc = StubCodeDesc::desc_for(adr + frame::pc_return_offset);
+      }
       if (desc != NULL) {
         st->print("Stub::%s", desc->name());
-        if (desc->begin() != adr)
-          st->print("%+d 0x%p",adr - desc->begin(), adr);
-        else if (WizardMode) st->print(" " PTR_FORMAT, adr);
+        if (desc->begin() != adr) {
+          st->print(INTX_FORMAT_W(+) " " PTR_FORMAT, adr - desc->begin(), p2i(adr));
+        } else if (WizardMode) {
+          st->print(" " PTR_FORMAT, p2i(adr));
+        }
         return;
       }
-      st->print("Stub::<unknown> " PTR_FORMAT, adr);
+      st->print("Stub::<unknown> " PTR_FORMAT, p2i(adr));
       return;
     }
 
@@ -347,13 +348,13 @@
     if (bs->is_a(BarrierSet::CardTableModRef) &&
         adr == (address)(barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base)) {
       st->print("word_map_base");
-      if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr);
+      if (WizardMode) st->print(" " INTPTR_FORMAT, p2i(adr));
       return;
     }
   }
 
   // Fall through to a simple (hexadecimal) numeral.
-  st->print(PTR_FORMAT, adr);
+  st->print(PTR_FORMAT, p2i(adr));
 }
 
 void decode_env::print_insn_labels() {
@@ -365,7 +366,7 @@
   }
   _strings.print_block_comment(st, (intptr_t)(p - _start));
   if (_print_pc) {
-    st->print("  " PTR_FORMAT ": ", p);
+    st->print("  " PTR_FORMAT ": ", p2i(p));
   }
 }
 
@@ -386,13 +387,16 @@
     address pc1 = pc + perline;
     if (pc1 > pc_limit)  pc1 = pc_limit;
     for (; pc < pc1; pc += incr) {
-      if (pc == pc0)
+      if (pc == pc0) {
         st->print(BYTES_COMMENT);
-      else if ((uint)(pc - pc0) % sizeof(int) == 0)
+      } else if ((uint)(pc - pc0) % sizeof(int) == 0) {
         st->print(" ");         // put out a space on word boundaries
-      if (incr == sizeof(int))
-            st->print("%08lx", *(int*)pc);
-      else  st->print("%02x",   (*pc)&0xFF);
+      }
+      if (incr == sizeof(int)) {
+        st->print("%08x", *(int*)pc);
+      } else {
+        st->print("%02x", (*pc)&0xFF);
+      }
     }
     st->cr();
   }
@@ -487,8 +491,14 @@
 
 void Disassembler::decode(CodeBlob* cb, outputStream* st) {
   if (!load_library())  return;
+  if (cb->is_nmethod()) {
+    decode((nmethod*)cb, st);
+    return;
+  }
   decode_env env(cb, st);
-  env.output()->print_cr("Decoding CodeBlob " PTR_FORMAT, cb);
+  env.output()->print_cr("----------------------------------------------------------------------");
+  env.output()->print_cr("%s", cb->name());
+  env.output()->print_cr(" at  [" PTR_FORMAT ", " PTR_FORMAT "]  " JLONG_FORMAT " bytes", p2i(cb->code_begin()), p2i(cb->code_end()), ((jlong)(cb->code_end() - cb->code_begin())) * sizeof(unsigned char*));
   env.decode_instructions(cb->code_begin(), cb->code_end());
 }
 
@@ -501,8 +511,7 @@
 void Disassembler::decode(nmethod* nm, outputStream* st) {
   if (!load_library())  return;
   decode_env env(nm, st);
-  env.output()->print_cr("Decoding compiled method " PTR_FORMAT ":", nm);
-  env.output()->print_cr("Code:");
+  env.output()->print_cr("----------------------------------------------------------------------");
 
 #ifdef SHARK
   SharkEntry* entry = (SharkEntry *) nm->code_begin();
@@ -513,6 +522,21 @@
   unsigned char* end = nm->code_end();
 #endif // SHARK
 
+  nm->method()->method_holder()->name()->print_symbol_on(env.output());
+  env.output()->print(".");
+  nm->method()->name()->print_symbol_on(env.output());
+  nm->method()->signature()->print_symbol_on(env.output());
+#if INCLUDE_JVMCI
+  {
+    char buffer[O_BUFLEN];
+    char* jvmciName = nm->jvmci_installed_code_name(buffer, O_BUFLEN);
+    if (jvmciName != NULL) {
+      env.output()->print(" (%s)", jvmciName);
+    }
+  }
+#endif
+  env.output()->print_cr("  [" PTR_FORMAT ", " PTR_FORMAT "]  " JLONG_FORMAT " bytes", p2i(p), p2i(end), ((jlong)(end - p)));
+
   // If there has been profiling, print the buckets.
   if (FlatProfiler::bucket_start_for(p) != NULL) {
     unsigned char* p1 = p;
@@ -533,9 +557,9 @@
     int offset = 0;
     for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) {
       if ((offset % 8) == 0) {
-        env.output()->print_cr("  " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT "   " PTR64_FORMAT, p, offset, *((int32_t*) p), *((int64_t*) p));
+        env.output()->print_cr("  " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT "   " PTR64_FORMAT, p2i(p), offset, *((int32_t*) p), *((int64_t*) p));
       } else {
-        env.output()->print_cr("  " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT,                    p, offset, *((int32_t*) p));
+        env.output()->print_cr("  " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT,                    p2i(p), offset, *((int32_t*) p));
       }
     }
   }
--- a/hotspot/src/share/vm/compiler/methodLiveness.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/methodLiveness.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -32,8 +32,6 @@
 #include "memory/allocation.inline.hpp"
 #include "utilities/bitMap.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // The MethodLiveness class performs a simple liveness analysis on a method
 // in order to decide which locals are live (that is, will be used again) at
 // a particular bytecode index (bci).
@@ -540,7 +538,7 @@
                  _time_flow.seconds() * 100 / _time_total.seconds());
   tty->print_cr ("    Query       : %3.3f sec. (%2.2f%%)", _time_query.seconds(),
                  _time_query.seconds() * 100 / _time_total.seconds());
-  tty->print_cr ("  #bytes   : %8d (%3.0f bytes per sec)",
+  tty->print_cr ("  #bytes   : %8ld (%3.0f bytes per sec)",
                  _total_bytes,
                  _total_bytes / _time_total.seconds());
   tty->print_cr ("  #methods : %8d (%3.0f methods per sec)",
@@ -554,7 +552,7 @@
                  _max_method_blocks);
   tty->print_cr ("    avg bytes  : %3.3f",
                  (float)_total_bytes / _total_methods);
-  tty->print_cr ("  #blocks  : %8d",
+  tty->print_cr ("  #blocks  : %8ld",
                  _total_blocks);
   tty->print_cr ("    avg normal predecessors    : %3.3f  max normal predecessors    : %3d",
                  (float)_total_edges / _total_blocks,
@@ -564,7 +562,7 @@
                  _max_block_exc_edges);
   tty->print_cr ("    avg visits                 : %3.3f",
                  (float)_total_visits / _total_blocks);
-  tty->print_cr ("  #locals queried : %8d    #live : %8d   %%live : %2.2f%%",
+  tty->print_cr ("  #locals queried : %8ld    #live : %8ld   %%live : %2.2f%%",
                  _total_locals_queried,
                  _total_live_locals_queried,
                  100.0 * _total_live_locals_queried / _total_locals_queried);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/compiler/methodMatcher.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2015, 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 "compiler/methodMatcher.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/oop.inline.hpp"
+
+// The JVM specification defines the allowed characters.
+// Tokens that are disallowed by the JVM specification can have
+// a meaning to the parser so we need to include them here.
+// The parser does not enforce all rules of the JVMS - a successful parse
+// does not mean that it is an allowed name. Illegal names will
+// be ignored since they never can match a class or method.
+//
+// '\0' and 0xf0-0xff are disallowed in constant string values
+// 0x20 ' ', 0x09 '\t' and, 0x2c ',' are used in the matching
+// 0x5b '[' and 0x5d ']' can not be used because of the matcher
+// 0x28 '(' and 0x29 ')' are used for the signature
+// 0x2e '.' is always replaced before the matching
+// 0x2f '/' is only used in the class name as package separator
+
+#define RANGEBASE "\x1\x2\x3\x4\x5\x6\x7\x8\xa\xb\xc\xd\xe\xf" \
+    "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \
+    "\x21\x22\x23\x24\x25\x26\x27\x2a\x2b\x2c\x2d" \
+    "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \
+    "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \
+    "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5c\x5e\x5f" \
+    "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \
+    "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \
+    "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \
+    "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \
+    "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+
+#define RANGE0 "[*" RANGEBASE "]"
+#define RANGESLASH "[*" RANGEBASE "/]"
+
+MethodMatcher::MethodMatcher():
+    _class_mode(Exact)
+  , _method_mode(Exact)
+  , _class_name(NULL)
+  , _method_name(NULL)
+  , _signature(NULL) {
+}
+
+MethodMatcher::~MethodMatcher() {
+  if (_class_name != NULL) {
+    _class_name->decrement_refcount();
+  }
+  if (_method_name != NULL) {
+    _method_name->decrement_refcount();
+  }
+  if (_signature != NULL) {
+    _signature->decrement_refcount();
+  }
+}
+
+void MethodMatcher::init(Symbol* class_name, Mode class_mode,
+                             Symbol* method_name, Mode method_mode,
+                             Symbol* signature) {
+ _class_mode = class_mode;
+ _method_mode = method_mode;
+ _class_name = class_name;
+ _method_name = method_name;
+ _signature = signature;
+}
+
+bool MethodMatcher::canonicalize(char * line, const char *& error_msg) {
+  char* colon = strstr(line, "::");
+  bool have_colon = (colon != NULL);
+  if (have_colon) {
+    // Don't allow multiple '::'
+    if (colon + 2 != '\0') {
+      if (strstr(colon+2, "::")) {
+        error_msg = "Method pattern only allows one '::' allowed";
+        return false;
+      }
+    }
+
+    bool in_signature = false;
+    char* pos = line;
+    if (pos != NULL) {
+      for (char* lp = pos + 1; *lp != '\0'; lp++) {
+        if (*lp == '(') {
+          break;
+        }
+
+        if (*lp == '/') {
+          error_msg = "Method pattern uses '/' together with '::'";
+          return false;
+        }
+      }
+    }
+  } else {
+    // Don't allow mixed package separators
+    char* pos = strchr(line, '.');
+    bool in_signature = false;
+    if (pos != NULL) {
+      for (char* lp = pos + 1; *lp != '\0'; lp++) {
+        if (*lp == '(') {
+          in_signature = true;
+        }
+
+        // After any comma the method pattern has ended
+        if (*lp == ',') {
+          break;
+        }
+
+        if (!in_signature && (*lp == '/')) {
+          error_msg = "Method pattern uses mixed '/' and '.' package separators";
+          return false;
+        }
+
+        if (*lp == '.') {
+          error_msg = "Method pattern uses multiple '.' in pattern";
+          return false;
+        }
+      }
+    }
+  }
+
+  for (char* lp = line; *lp != '\0'; lp++) {
+    // Allow '.' to separate the class name from the method name.
+    // This is the preferred spelling of methods:
+    //      exclude java/lang/String.indexOf(I)I
+    // Allow ',' for spaces (eases command line quoting).
+    //      exclude,java/lang/String.indexOf
+    // For backward compatibility, allow space as separator also.
+    //      exclude java/lang/String indexOf
+    //      exclude,java/lang/String,indexOf
+    // For easy cut-and-paste of method names, allow VM output format
+    // as produced by Method::print_short_name:
+    //      exclude java.lang.String::indexOf
+    // For simple implementation convenience here, convert them all to space.
+
+    if (have_colon) {
+      if (*lp == '.')  *lp = '/';   // dots build the package prefix
+      if (*lp == ':')  *lp = ' ';
+    }
+    if (*lp == ',' || *lp == '.')  *lp = ' ';
+  }
+  return true;
+}
+
+bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) const {
+  if (match_mode == Any) {
+    return true;
+  }
+
+  if (match_mode == Exact) {
+    return candidate == match;
+  }
+
+  ResourceMark rm;
+  const char * candidate_string = candidate->as_C_string();
+  const char * match_string = match->as_C_string();
+
+  switch (match_mode) {
+  case Prefix:
+    return strstr(candidate_string, match_string) == candidate_string;
+
+  case Suffix: {
+    size_t clen = strlen(candidate_string);
+    size_t mlen = strlen(match_string);
+    return clen >= mlen && strcmp(candidate_string + clen - mlen, match_string) == 0;
+  }
+
+  case Substring:
+    return strstr(candidate_string, match_string) != NULL;
+
+  default:
+    return false;
+  }
+}
+
+static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) {
+  int match = MethodMatcher::Exact;
+  if (name[0] == '*') {
+    if (strlen(name) == 1) {
+      return MethodMatcher::Any;
+    }
+    match |= MethodMatcher::Suffix;
+    memmove(name, name + 1, strlen(name + 1) + 1);
+  }
+
+  size_t len = strlen(name);
+  if (len > 0 && name[len - 1] == '*') {
+    match |= MethodMatcher::Prefix;
+    name[--len] = '\0';
+  }
+
+  if (strlen(name) == 0) {
+    error_msg = "** Not a valid pattern";
+    return MethodMatcher::Any;
+  }
+
+  if (strstr(name, "*") != NULL) {
+    error_msg = " Embedded * not allowed";
+    return MethodMatcher::Unknown;
+  }
+  return (MethodMatcher::Mode)match;
+}
+
+// Skip any leading spaces
+void skip_leading_spaces(char*& line, int* total_bytes_read ) {
+  int bytes_read = 0;
+  sscanf(line, "%*[ \t]%n", &bytes_read);
+  if (bytes_read > 0) {
+    line += bytes_read;
+    *total_bytes_read += bytes_read;
+  }
+}
+
+void MethodMatcher::parse_method_pattern(char*& line, const char*& error_msg, MethodMatcher* matcher) {
+  MethodMatcher::Mode c_match;
+  MethodMatcher::Mode m_match;
+  char class_name[256] = {0};
+  char method_name[256] = {0};
+  char sig[1024] = {0};
+  int bytes_read = 0;
+  int total_bytes_read = 0;
+
+  assert(error_msg == NULL, "Dont call here with error_msg already set");
+
+  if (!MethodMatcher::canonicalize(line, error_msg)) {
+    assert(error_msg != NULL, "Message must be set if parsing failed");
+    return;
+  }
+
+  skip_leading_spaces(line, &total_bytes_read);
+
+  if (2 == sscanf(line, "%255" RANGESLASH "%*[ ]" "%255"  RANGE0 "%n", class_name, method_name, &bytes_read)) {
+    c_match = check_mode(class_name, error_msg);
+    m_match = check_mode(method_name, error_msg);
+
+    if ((strchr(class_name, '<') != NULL) || (strchr(class_name, '>') != NULL)) {
+      error_msg = "Chars '<' and '>' not allowed in class name";
+      return;
+    }
+    if ((strchr(method_name, '<') != NULL) || (strchr(method_name, '>') != NULL)) {
+      if ((strncmp("<init>", method_name, 255) != 0) && (strncmp("<clinit>", method_name, 255) != 0)) {
+        error_msg = "Chars '<' and '>' only allowed in <init> and <clinit>";
+        return;
+      }
+    }
+
+    if (c_match == MethodMatcher::Unknown || m_match == MethodMatcher::Unknown) {
+      assert(error_msg != NULL, "Must have been set by check_mode()");
+      return;
+    }
+
+    EXCEPTION_MARK;
+    Symbol* signature = NULL;
+    line += bytes_read;
+    bytes_read = 0;
+
+    skip_leading_spaces(line, &total_bytes_read);
+
+    // there might be a signature following the method.
+    // signatures always begin with ( so match that by hand
+    if (line[0] == '(') {
+      line++;
+      sig[0] = '(';
+      // scan the rest
+      if (1 == sscanf(line, "%254[[);/" RANGEBASE "]%n", sig+1, &bytes_read)) {
+        if (strchr(sig, '*') != NULL) {
+          error_msg = " Wildcard * not allowed in signature";
+          return;
+        }
+        line += bytes_read;
+      }
+      signature = SymbolTable::new_symbol(sig, CHECK);
+    }
+    Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK);
+    Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK);
+
+    matcher->init(c_name, c_match, m_name, m_match, signature);
+    return;
+  } else {
+    error_msg = "Could not parse method pattern";
+  }
+}
+
+bool MethodMatcher::matches(methodHandle method) const {
+  Symbol* class_name  = method->method_holder()->name();
+  Symbol* method_name = method->name();
+  Symbol* signature = method->signature();
+
+  if (match(class_name, this->class_name(), _class_mode) &&
+      match(method_name, this->method_name(), _method_mode) &&
+      ((this->signature() == NULL) || match(signature, this->signature(), Prefix))) {
+    return true;
+  }
+  return false;
+}
+
+void MethodMatcher::print_symbol(outputStream* st, Symbol* h, Mode mode) {
+  ResourceMark rm;
+
+  if (mode == Suffix || mode == Substring || mode == Any) {
+    st->print("*");
+  }
+  if (mode != Any) {
+    h->print_symbol_on(st);
+  }
+  if (mode == Prefix || mode == Substring) {
+    st->print("*");
+  }
+}
+
+void MethodMatcher::print_base(outputStream* st) {
+  print_symbol(st, class_name(), _class_mode);
+  st->print(".");
+  print_symbol(st, method_name(), _method_mode);
+  if (signature() != NULL) {
+    signature()->print_symbol_on(st);
+  }
+}
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/compiler/methodMatcher.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, 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_COMPILER_METHODMATCHER_HPP
+#define SHARE_VM_COMPILER_METHODMATCHER_HPP
+
+#include "memory/allocation.inline.hpp"
+#include "runtime/handles.inline.hpp"
+#include "memory/resourceArea.hpp"
+
+class MethodMatcher : public CHeapObj<mtCompiler> {
+ public:
+  enum Mode {
+    Exact,
+    Prefix = 1,
+    Suffix = 2,
+    Substring = Prefix | Suffix,
+    Any,
+    Unknown = -1
+  };
+
+ protected:
+  Symbol*        _class_name;
+  Symbol*        _method_name;
+  Symbol*        _signature;
+  Mode           _class_mode;
+  Mode           _method_mode;
+
+ public:
+  Symbol* class_name() const { return _class_name; }
+  Mode class_mode() const { return _class_mode; }
+  Symbol* method_name() const { return _method_name; }
+  Mode method_mode() const { return _method_mode; }
+  Symbol* signature() const { return _signature; }
+
+  MethodMatcher();
+  ~MethodMatcher();
+
+  void init(Symbol* class_name, Mode class_mode, Symbol* method_name, Mode method_mode, Symbol* signature);
+  static void parse_method_pattern(char*& line, const char*& error_msg, MethodMatcher* m);
+  static void print_symbol(outputStream* st, Symbol* h, Mode mode);
+  bool matches(methodHandle method) const;
+  void print_base(outputStream* st);
+
+ private:
+  static bool canonicalize(char * line, const char *& error_msg);
+  bool match(Symbol* candidate, Symbol* match, Mode match_mode) const;
+};
+
+class BasicMatcher : public MethodMatcher {
+private:
+  BasicMatcher* _next;
+public:
+
+  BasicMatcher() : MethodMatcher(),
+    _next(NULL) {
+  }
+
+  BasicMatcher(BasicMatcher* next) :
+    _next(next) {
+  }
+
+  static BasicMatcher* parse_method_pattern(char* line, const char*& error_msg) {
+    assert(error_msg == NULL, "Dont call here with error_msg already set");
+    BasicMatcher* bm = new BasicMatcher();
+    MethodMatcher::parse_method_pattern(line, error_msg, bm);
+    if (error_msg != NULL) {
+      delete bm;
+      return NULL;
+    }
+
+    // check for bad trailing characters
+    int bytes_read = 0;
+    sscanf(line, "%*[ \t]%n", &bytes_read);
+    if (line[bytes_read] != '\0') {
+      error_msg = "Unrecognized trailing text after method pattern";
+      delete bm;
+      return NULL;
+    }
+    return bm;
+  }
+
+  bool match(methodHandle method) {
+    for (BasicMatcher* current = this; current != NULL; current = current->next()) {
+      if (current->matches(method)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void set_next(BasicMatcher* next) { _next = next; }
+  BasicMatcher* next() { return _next; }
+
+  void print(outputStream* st) { print_base(st); }
+  void print_all(outputStream* st) {
+    print_base(st);
+    if (_next != NULL) {
+      _next->print_all(st);
+    }
+  }
+};
+
+#endif // SHARE_VM_COMPILER_METHODMATCHER_HPP
+
--- a/hotspot/src/share/vm/compiler/oopMap.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -39,6 +39,9 @@
 #ifdef COMPILER2
 #include "opto/optoreg.hpp"
 #endif
+#ifdef SPARC
+#include "vmreg_sparc.inline.hpp"
+#endif
 
 // OopMapStream
 
@@ -58,7 +61,6 @@
   _valid_omv = false;
 }
 
-
 void OopMapStream::find_next() {
   while(_position++ < _size) {
     _omv.read_from(_stream);
@@ -156,9 +158,7 @@
 
 
 void OopMap::set_value(VMReg reg) {
-  // At this time, we only need value entries in our OopMap when ZapDeadCompiledLocals is active.
-  if (ZapDeadCompiledLocals)
-    set_xxx(reg, OopMapValue::value_value, VMRegImpl::Bad());
+  // At this time, we don't need value entries in our OopMap.
 }
 
 
@@ -199,7 +199,6 @@
   set_om_data(new_data);
 }
 
-
 void OopMapSet::add_gc_map(int pc_offset, OopMap *map ) {
   assert(om_size() != -1,"Cannot grow a fixed OopMapSet");
 
@@ -276,10 +275,15 @@
 static void add_derived_oop(oop* base, oop* derived) {
 #ifndef TIERED
   COMPILER1_PRESENT(ShouldNotReachHere();)
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    ShouldNotReachHere();
+  }
+#endif
 #endif // TIERED
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   DerivedPointerTable::add(derived, base);
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 }
 
 
@@ -288,7 +292,7 @@
   // Print oopmap and regmap
   tty->print_cr("------ ");
   CodeBlob* cb = fr->cb();
-  ImmutableOopMapSet* maps = cb->oop_maps();
+  const ImmutableOopMapSet* maps = cb->oop_maps();
   const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
   map->print();
   if( cb->is_nmethod() ) {
@@ -325,7 +329,7 @@
 
   NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
 
-  ImmutableOopMapSet* maps = cb->oop_maps();
+  const ImmutableOopMapSet* maps = cb->oop_maps();
   const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
   assert(map != NULL, "no ptr map found");
 
@@ -337,6 +341,11 @@
     if (!oms.is_done()) {
 #ifndef TIERED
       COMPILER1_PRESENT(ShouldNotReachHere();)
+#if INCLUDE_JVMCI
+      if (UseJVMCICompiler) {
+        ShouldNotReachHere();
+      }
+#endif
 #endif // !TIERED
       // Protect the operation on the derived pointers.  This
       // protects the addition of derived pointers to the shared
@@ -345,72 +354,73 @@
       do {
         omv = oms.current();
         oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
-        if ( loc != NULL ) {
-          oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
-          oop *derived_loc = loc;
-          oop val = *base_loc;
-          if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
-            // Ignore NULL oops and decoded NULL narrow oops which
-            // equal to Universe::narrow_oop_base when a narrow oop
-            // implicit null check is used in compiled code.
-            // The narrow_oop_base could be NULL or be the address
-            // of the page below heap depending on compressed oops mode.
-          } else
-            derived_oop_fn(base_loc, derived_loc);
+        guarantee(loc != NULL, "missing saved register");
+        oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
+        oop *derived_loc = loc;
+        oop val = *base_loc;
+        if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
+          // Ignore NULL oops and decoded NULL narrow oops which
+          // equal to Universe::narrow_oop_base when a narrow oop
+          // implicit null check is used in compiled code.
+          // The narrow_oop_base could be NULL or be the address
+          // of the page below heap depending on compressed oops mode.
+        } else {
+          derived_oop_fn(base_loc, derived_loc);
         }
         oms.next();
       }  while (!oms.is_done());
     }
   }
 
-  // We want coop, value and oop oop_types
-  int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::narrowoop_value;
+  // We want coop and oop oop_types
+  int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
   {
     for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
       omv = oms.current();
       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
-      if ( loc != NULL ) {
-        if ( omv.type() == OopMapValue::oop_value ) {
-          oop val = *loc;
-          if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
-            // Ignore NULL oops and decoded NULL narrow oops which
-            // equal to Universe::narrow_oop_base when a narrow oop
-            // implicit null check is used in compiled code.
-            // The narrow_oop_base could be NULL or be the address
-            // of the page below heap depending on compressed oops mode.
-            continue;
-          }
+      // It should be an error if no location can be found for a
+      // register mentioned as contained an oop of some kind.  Maybe
+      // this was allowed previously because value_value items might
+      // be missing?
+      guarantee(loc != NULL, "missing saved register");
+      if ( omv.type() == OopMapValue::oop_value ) {
+        oop val = *loc;
+        if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
+          // Ignore NULL oops and decoded NULL narrow oops which
+          // equal to Universe::narrow_oop_base when a narrow oop
+          // implicit null check is used in compiled code.
+          // The narrow_oop_base could be NULL or be the address
+          // of the page below heap depending on compressed oops mode.
+          continue;
+        }
 #ifdef ASSERT
-          if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
-             !Universe::heap()->is_in_or_null(*loc)) {
-            tty->print_cr("# Found non oop pointer.  Dumping state at failure");
-            // try to dump out some helpful debugging information
-            trace_codeblob_maps(fr, reg_map);
-            omv.print();
-            tty->print_cr("register r");
-            omv.reg()->print();
-            tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
-            // do the real assert.
-            assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
-          }
+        if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
+            !Universe::heap()->is_in_or_null(*loc)) {
+          tty->print_cr("# Found non oop pointer.  Dumping state at failure");
+          // try to dump out some helpful debugging information
+          trace_codeblob_maps(fr, reg_map);
+          omv.print();
+          tty->print_cr("register r");
+          omv.reg()->print();
+          tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
+          // do the real assert.
+          assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
+        }
 #endif // ASSERT
-          oop_fn->do_oop(loc);
-        } else if ( omv.type() == OopMapValue::value_value ) {
-          assert((*loc) == (oop)NULL || !Universe::is_narrow_oop_base(*loc),
-                 "found invalid value pointer");
-          value_fn->do_oop(loc);
-        } else if ( omv.type() == OopMapValue::narrowoop_value ) {
-          narrowOop *nl = (narrowOop*)loc;
+        oop_fn->do_oop(loc);
+      } else if ( omv.type() == OopMapValue::narrowoop_value ) {
+        narrowOop *nl = (narrowOop*)loc;
 #ifndef VM_LITTLE_ENDIAN
-          if (!omv.reg()->is_stack()) {
-            // compressed oops in registers only take up 4 bytes of an
-            // 8 byte register but they are in the wrong part of the
-            // word so adjust loc to point at the right place.
-            nl = (narrowOop*)((address)nl + 4);
-          }
+        VMReg vmReg = omv.reg();
+        // Don't do this on SPARC float registers as they can be individually addressed
+        if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
+          // compressed oops in registers only take up 4 bytes of an
+          // 8 byte register but they are in the wrong part of the
+          // word so adjust loc to point at the right place.
+          nl = (narrowOop*)((address)nl + 4);
+        }
 #endif
-          oop_fn->do_oop(nl);
-        }
+        oop_fn->do_oop(nl);
       }
     }
   }
@@ -451,7 +461,7 @@
 
   // Check that runtime stubs save all callee-saved registers
 #ifdef COMPILER2
-  assert(cb->is_compiled_by_c1() || !cb->is_runtime_stub() ||
+  assert(cb->is_compiled_by_c1() || cb->is_compiled_by_jvmci() || !cb->is_runtime_stub() ||
          (nof_callee >= SAVED_ON_ENTRY_REG_COUNT || nof_callee >= C_SAVED_ON_ENTRY_REG_COUNT),
          "must save all");
 #endif // COMPILER2
@@ -465,13 +475,18 @@
 bool ImmutableOopMap::has_derived_pointer() const {
 #ifndef TIERED
   COMPILER1_PRESENT(return false);
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    return false;
+  }
+#endif
 #endif // !TIERED
-#ifdef COMPILER2
-  OopMapStream oms((OopMap*)this,OopMapValue::derived_oop_value);
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  OopMapStream oms(this,OopMapValue::derived_oop_value);
   return oms.is_done();
 #else
   return false;
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 }
 
 #endif //PRODUCT
@@ -485,9 +500,6 @@
   case OopMapValue::oop_value:
     st->print("Oop");
     break;
-  case OopMapValue::value_value:
-    st->print("Value");
-    break;
   case OopMapValue::narrowoop_value:
     st->print("NarrowOop");
     break;
@@ -607,74 +619,9 @@
 }
 #endif
 
-class ImmutableOopMapBuilder {
-private:
-  class Mapping;
-
-private:
-  const OopMapSet* _set;
-  const OopMap* _empty;
-  const OopMap* _last;
-  int _empty_offset;
-  int _last_offset;
-  int _offset;
-  Mapping* _mapping;
-  ImmutableOopMapSet* _new_set;
-
-  /* Used for bookkeeping when building ImmutableOopMaps */
-  class Mapping : public ResourceObj {
-  public:
-    enum kind_t { OOPMAP_UNKNOWN = 0, OOPMAP_NEW = 1, OOPMAP_EMPTY = 2, OOPMAP_DUPLICATE = 3 };
-
-    kind_t _kind;
-    int _offset;
-    int _size;
-    const OopMap* _map;
-    const OopMap* _other;
-
-    Mapping() : _kind(OOPMAP_UNKNOWN), _offset(-1), _size(-1), _map(NULL) {}
-
-    void set(kind_t kind, int offset, int size, const OopMap* map = 0, const OopMap* other = 0) {
-      _kind = kind;
-      _offset = offset;
-      _size = size;
-      _map = map;
-      _other = other;
-    }
-  };
-
-public:
-  ImmutableOopMapBuilder(const OopMapSet* set) : _set(set), _new_set(NULL), _empty(NULL), _last(NULL), _empty_offset(-1), _last_offset(-1), _offset(0) {
-    _mapping = NEW_RESOURCE_ARRAY(Mapping, _set->size());
-  }
-
-  int heap_size();
-  ImmutableOopMapSet* build();
-private:
-  bool is_empty(const OopMap* map) const {
-    return map->count() == 0;
-  }
-
-  bool is_last_duplicate(const OopMap* map) {
-    if (_last != NULL && _last->count() > 0 && _last->equals(map)) {
-      return true;
-    }
-    return false;
-  }
-
-#ifdef ASSERT
-  void verify(address buffer, int size, const ImmutableOopMapSet* set);
-#endif
-
-  bool has_empty() const {
-    return _empty_offset != -1;
-  }
-
-  int size_for(const OopMap* map) const;
-  void fill_pair(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
-  int fill_map(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
-  void fill(ImmutableOopMapSet* set, int size);
-};
+ImmutableOopMapBuilder::ImmutableOopMapBuilder(const OopMapSet* set) : _set(set), _new_set(NULL), _empty(NULL), _last(NULL), _empty_offset(-1), _last_offset(-1), _offset(0), _required(-1) {
+  _mapping = NEW_RESOURCE_ARRAY(Mapping, _set->size());
+}
 
 int ImmutableOopMapBuilder::size_for(const OopMap* map) const {
   return align_size_up(sizeof(ImmutableOopMap) + map->data_size(), 8);
@@ -719,6 +666,7 @@
 
   int total = base + pairs + _offset;
   DEBUG_ONLY(total += 8);
+  _required = total;
   return total;
 }
 
@@ -770,19 +718,23 @@
 }
 #endif
 
+ImmutableOopMapSet* ImmutableOopMapBuilder::generate_into(address buffer) {
+  DEBUG_ONLY(memset(&buffer[_required-8], 0xff, 8));
+
+  _new_set = new (buffer) ImmutableOopMapSet(_set, _required);
+  fill(_new_set, _required);
+
+  DEBUG_ONLY(verify(buffer, _required, _new_set));
+
+  return _new_set;
+}
+
 ImmutableOopMapSet* ImmutableOopMapBuilder::build() {
-  int required = heap_size();
+  _required = heap_size();
 
   // We need to allocate a chunk big enough to hold the ImmutableOopMapSet and all of its ImmutableOopMaps
-  address buffer = (address) NEW_C_HEAP_ARRAY(unsigned char, required, mtCode);
-  DEBUG_ONLY(memset(&buffer[required-8], 0xff, 8));
-
-  _new_set = new (buffer) ImmutableOopMapSet(_set, required);
-  fill(_new_set, required);
-
-  DEBUG_ONLY(verify(buffer, required, _new_set));
-
-  return _new_set;
+  address buffer = (address) NEW_C_HEAP_ARRAY(unsigned char, _required, mtCode);
+  return generate_into(buffer);
 }
 
 ImmutableOopMapSet* ImmutableOopMapSet::build_from(const OopMapSet* oopmap_set) {
@@ -794,7 +746,7 @@
 
 //------------------------------DerivedPointerTable---------------------------
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
 
 class DerivedPointerEntry : public CHeapObj<mtCompiler> {
  private:
@@ -887,4 +839,4 @@
   _active = false;
 }
 
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
--- a/hotspot/src/share/vm/compiler/oopMap.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/compiler/oopMap.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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,7 +33,6 @@
 // Interface for generating the frame map for compiled code.  A frame map
 // describes for a specific pc whether each register and frame stack slot is:
 //   Oop         - A GC root for current frame
-//   Value       - Live non-oop, non-float value: int, either half of double
 //   Dead        - Dead; can be Zapped for debugging
 //   CalleeXX    - Callee saved; also describes which caller register is saved
 //   DerivedXX   - A derived oop; original oop is described.
@@ -54,7 +53,7 @@
 
 public:
   // Constants
-  enum { type_bits                = 5,
+  enum { type_bits                = 4,
          register_bits            = BitsPerShort - type_bits };
 
   enum { type_shift               = 0,
@@ -68,10 +67,9 @@
   enum oop_types {              // must fit in type_bits
          unused_value =0,       // powers of 2, for masking OopMapStream
          oop_value = 1,
-         value_value = 2,
-         narrowoop_value = 4,
-         callee_saved_value = 8,
-         derived_oop_value= 16 };
+         narrowoop_value = 2,
+         callee_saved_value = 4,
+         derived_oop_value= 8 };
 
   // Constructors
   OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
@@ -96,13 +94,11 @@
 
   // Querying
   bool is_oop()               { return mask_bits(value(), type_mask_in_place) == oop_value; }
-  bool is_value()             { return mask_bits(value(), type_mask_in_place) == value_value; }
   bool is_narrowoop()           { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
   bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
   bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
 
   void set_oop()              { set_value((value() & register_mask_in_place) | oop_value); }
-  void set_value()            { set_value((value() & register_mask_in_place) | value_value); }
   void set_narrowoop()          { set_value((value() & register_mask_in_place) | narrowoop_value); }
   void set_callee_saved()     { set_value((value() & register_mask_in_place) | callee_saved_value); }
   void set_derived_oop()      { set_value((value() & register_mask_in_place) | derived_oop_value); }
@@ -188,6 +184,8 @@
   void copy_data_to(address addr) const;
   OopMap* deep_copy();
 
+  bool has_derived_pointer() const PRODUCT_RETURN0;
+
   bool legal_vm_reg_name(VMReg local) {
      return OopMapValue::legal_vm_reg_name(local);
   }
@@ -354,13 +352,82 @@
 #endif
 };
 
+class ImmutableOopMapBuilder {
+private:
+  class Mapping;
+
+private:
+  const OopMapSet* _set;
+  const OopMap* _empty;
+  const OopMap* _last;
+  int _empty_offset;
+  int _last_offset;
+  int _offset;
+  int _required;
+  Mapping* _mapping;
+  ImmutableOopMapSet* _new_set;
+
+  /* Used for bookkeeping when building ImmutableOopMaps */
+  class Mapping : public ResourceObj {
+  public:
+    enum kind_t { OOPMAP_UNKNOWN = 0, OOPMAP_NEW = 1, OOPMAP_EMPTY = 2, OOPMAP_DUPLICATE = 3 };
+
+    kind_t _kind;
+    int _offset;
+    int _size;
+    const OopMap* _map;
+    const OopMap* _other;
+
+    Mapping() : _kind(OOPMAP_UNKNOWN), _offset(-1), _size(-1), _map(NULL) {}
+
+    void set(kind_t kind, int offset, int size, const OopMap* map = 0, const OopMap* other = 0) {
+      _kind = kind;
+      _offset = offset;
+      _size = size;
+      _map = map;
+      _other = other;
+    }
+  };
+
+public:
+  ImmutableOopMapBuilder(const OopMapSet* set);
+
+  int heap_size();
+  ImmutableOopMapSet* build();
+  ImmutableOopMapSet* generate_into(address buffer);
+private:
+  bool is_empty(const OopMap* map) const {
+    return map->count() == 0;
+  }
+
+  bool is_last_duplicate(const OopMap* map) {
+    if (_last != NULL && _last->count() > 0 && _last->equals(map)) {
+      return true;
+    }
+    return false;
+  }
+
+#ifdef ASSERT
+  void verify(address buffer, int size, const ImmutableOopMapSet* set);
+#endif
+
+  bool has_empty() const {
+    return _empty_offset != -1;
+  }
+
+  int size_for(const OopMap* map) const;
+  void fill_pair(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
+  int fill_map(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
+  void fill(ImmutableOopMapSet* set, int size);
+};
+
 
 // Derived pointer support. This table keeps track of all derived points on a
 // stack.  It is cleared before each scavenge/GC.  During the traversal of all
 // oops, it is filled in with references to all locations that contains a
 // derived oop (assumed to be very few).  When the GC is complete, the derived
 // pointers are updated based on their base pointers new value and an offset.
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
 class DerivedPointerTable : public AllStatic {
   friend class VMStructs;
  private:
@@ -396,6 +463,6 @@
     }
   }
 };
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 
 #endif // SHARE_VM_COMPILER_OOPMAP_HPP
--- a/hotspot/src/share/vm/gc/cms/adaptiveFreeList.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/adaptiveFreeList.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -133,17 +133,17 @@
           + _allocation_stats.coal_births() + 1)   // Total Production Stock + 1
          >= (_allocation_stats.split_deaths() + _allocation_stats.coal_deaths()
              + (ssize_t)count()),                // Total Current Stock + depletion
-         err_msg("FreeList " PTR_FORMAT " of size " SIZE_FORMAT
-                 " violates Conservation Principle: "
-                 "prev_sweep(" SIZE_FORMAT ")"
-                 " + split_births(" SIZE_FORMAT ")"
-                 " + coal_births(" SIZE_FORMAT ") + 1 >= "
-                 " split_deaths(" SIZE_FORMAT ")"
-                 " coal_deaths(" SIZE_FORMAT ")"
-                 " + count(" SSIZE_FORMAT ")",
-                 p2i(this), size(), _allocation_stats.prev_sweep(), _allocation_stats.split_births(),
-                 _allocation_stats.coal_births(), _allocation_stats.split_deaths(),
-                 _allocation_stats.coal_deaths(), count()));
+         "FreeList " PTR_FORMAT " of size " SIZE_FORMAT
+         " violates Conservation Principle: "
+         "prev_sweep(" SIZE_FORMAT ")"
+         " + split_births(" SIZE_FORMAT ")"
+         " + coal_births(" SIZE_FORMAT ") + 1 >= "
+         " split_deaths(" SIZE_FORMAT ")"
+         " coal_deaths(" SIZE_FORMAT ")"
+         " + count(" SSIZE_FORMAT ")",
+         p2i(this), size(), _allocation_stats.prev_sweep(), _allocation_stats.split_births(),
+         _allocation_stats.coal_births(), _allocation_stats.split_deaths(),
+         _allocation_stats.coal_deaths(), count());
 }
 #endif
 
--- a/hotspot/src/share/vm/gc/cms/allocationStats.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/allocationStats.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -105,9 +105,9 @@
       ssize_t demand = prev_sweep() - (ssize_t)count + split_births() + coal_births()
                        - split_deaths() - coal_deaths();
       assert(demand >= 0,
-             err_msg("Demand (" SSIZE_FORMAT ") should be non-negative for "
-                     PTR_FORMAT " (size=" SIZE_FORMAT ")",
-                     demand, p2i(this), count));
+             "Demand (" SSIZE_FORMAT ") should be non-negative for "
+             PTR_FORMAT " (size=" SIZE_FORMAT ")",
+             demand, p2i(this), count);
       // Defensive: adjust for imprecision in event counting
       if (demand < 0) {
         demand = 0;
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1959,9 +1959,9 @@
   MemRegion ur    = used_region();
   MemRegion urasm = used_region_at_save_marks();
   assert(ur.contains(urasm),
-         err_msg(" Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")"
-                 " should contain [" PTR_FORMAT "," PTR_FORMAT ")",
-                 p2i(ur.start()), p2i(ur.end()), p2i(urasm.start()), p2i(urasm.end())));
+         " Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")"
+         " should contain [" PTR_FORMAT "," PTR_FORMAT ")",
+         p2i(ur.start()), p2i(ur.end()), p2i(urasm.start()), p2i(urasm.end()));
 #endif
   // inform allocator that promotions should be tracked.
   assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
@@ -2875,9 +2875,9 @@
     smallSplitBirth(rem);
   }
   assert(n * word_sz == fc->size(),
-    err_msg("Chunk size " SIZE_FORMAT " is not exactly splittable by "
-    SIZE_FORMAT " sized chunks of size " SIZE_FORMAT,
-    fc->size(), n, word_sz));
+         "Chunk size " SIZE_FORMAT " is not exactly splittable by "
+         SIZE_FORMAT " sized chunks of size " SIZE_FORMAT,
+         fc->size(), n, word_sz);
   return fc;
 }
 
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1593,7 +1593,7 @@
   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, gc_tracer->gc_id());
+  GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL);
 
   // Temporarily widen the span of the weak reference processing to
   // the entire heap.
@@ -1654,7 +1654,7 @@
   _collectorState = Resetting;
   assert(_restart_addr == NULL,
          "Should have been NULL'd before baton was passed");
-  reset(false /* == !concurrent */);
+  reset_stw();
   _cmsGen->reset_after_compaction();
   _concurrent_cycles_since_last_unload = 0;
 
@@ -1934,7 +1934,7 @@
       }
       case Resetting:
         // CMS heap resizing has been completed
-        reset(true);
+        reset_concurrent();
         assert(_collectorState == Idling, "Collector state should "
           "have changed");
 
@@ -2367,7 +2367,9 @@
   // way with the marking information used by GC.
   NoRefDiscovery no_discovery(ref_processor());
 
-  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  DerivedPointerTableDeactivate dpt_deact;
+#endif
 
   // Clear any marks from a previous round
   verification_mark_bm()->clear_all();
@@ -2825,7 +2827,6 @@
  public:
   CMSPhaseAccounting(CMSCollector *collector,
                      const char *phase,
-                     const GCId gc_id,
                      bool print_cr = true);
   ~CMSPhaseAccounting();
 
@@ -2834,7 +2835,6 @@
   const char *_phase;
   elapsedTimer _wallclock;
   bool _print_cr;
-  const GCId _gc_id;
 
  public:
   // Not MT-safe; so do not pass around these StackObj's
@@ -2850,15 +2850,14 @@
 
 CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
                                        const char *phase,
-                                       const GCId gc_id,
                                        bool print_cr) :
-  _collector(collector), _phase(phase), _print_cr(print_cr), _gc_id(gc_id) {
+  _collector(collector), _phase(phase), _print_cr(print_cr) {
 
   if (PrintCMSStatistics != 0) {
     _collector->resetYields();
   }
   if (PrintGCDetails) {
-    gclog_or_tty->gclog_stamp(_gc_id);
+    gclog_or_tty->gclog_stamp();
     gclog_or_tty->print_cr("[%s-concurrent-%s-start]",
       _collector->cmsGen()->short_name(), _phase);
   }
@@ -2872,7 +2871,7 @@
   _collector->stopTimer();
   _wallclock.stop();
   if (PrintGCDetails) {
-    gclog_or_tty->gclog_stamp(_gc_id);
+    gclog_or_tty->gclog_stamp();
     gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
                  _collector->cmsGen()->short_name(),
                  _phase, _collector->timerValue(), _wallclock.seconds());
@@ -2951,7 +2950,7 @@
   setup_cms_unloading_and_verification_state();
 
   NOT_PRODUCT(GCTraceTime t("\ncheckpointRootsInitialWork",
-    PrintGCDetails && Verbose, true, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+    PrintGCDetails && Verbose, true, _gc_timer_cm);)
 
   // Reset all the PLAB chunk arrays if necessary.
   if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
@@ -2987,7 +2986,9 @@
   }
 
   {
-    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTableDeactivate dpt_deact;
+#endif
     if (CMSParallelInitialMarkEnabled) {
       // The parallel version.
       WorkGang* workers = gch->workers();
@@ -3054,7 +3055,7 @@
 
   CMSTokenSyncWithLocks ts(true, bitMapLock());
   TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  CMSPhaseAccounting pa(this, "mark", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+  CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
   bool res = markFromRootsWork();
   if (res) {
     _collectorState = Precleaning;
@@ -3476,7 +3477,7 @@
 // been published), so we do not need to check for
 // uninitialized objects before pushing here.
 void Par_ConcMarkingClosure::do_oop(oop obj) {
-  assert(obj->is_oop_or_null(true), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(obj)));
+  assert(obj->is_oop_or_null(true), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
   HeapWord* addr = (HeapWord*)obj;
   // Check if oop points into the CMS generation
   // and is not marked
@@ -3751,7 +3752,7 @@
       _start_sampling = false;
     }
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    CMSPhaseAccounting pa(this, "preclean", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+    CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
     preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
   }
   CMSTokenSync x(true); // is cms thread
@@ -3780,7 +3781,7 @@
   // we will never do an actual abortable preclean cycle.
   if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    CMSPhaseAccounting pa(this, "abortable-preclean", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+    CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
     // We need more smarts in the abortable preclean
     // loop below to deal with cases where allocation
     // in young gen is very very slow, and our precleaning
@@ -3925,7 +3926,7 @@
     GCTimer *gc_timer = NULL; // Currently not tracing concurrent phases
     rp->preclean_discovered_references(
           rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl,
-          gc_timer, _gc_tracer_cm->gc_id());
+          gc_timer);
   }
 
   if (clean_survivor) {  // preclean the active survivor space(s)
@@ -4261,7 +4262,7 @@
       // expect it to be false and set to true
       FlagSetting fl(gch->_is_gc_active, false);
       NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark",
-        PrintGCDetails && Verbose, true, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+        PrintGCDetails && Verbose, true, _gc_timer_cm);)
       gch->do_collection(true,                      // full (i.e. force, see below)
                          false,                     // !clear_all_soft_refs
                          0,                         // size
@@ -4279,7 +4280,7 @@
 }
 
 void CMSCollector::checkpointRootsFinalWork() {
-  NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+  NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm);)
 
   assert(haveFreelistLocks(), "must have free list locks");
   assert_lock_strong(bitMapLock());
@@ -4316,7 +4317,9 @@
   }
 
   {
-    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTableDeactivate dpt_deact;
+#endif
 
     // Note on the role of the mod union table:
     // Since the marker in "markFromRoots" marks concurrently with
@@ -4329,11 +4332,10 @@
     // the most recent young generation GC, minus those cleaned up by the
     // concurrent precleaning.
     if (CMSParallelRemarkEnabled) {
-      GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+      GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm);
       do_remark_parallel();
     } else {
-      GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
-                  _gc_timer_cm, _gc_tracer_cm->gc_id());
+      GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false, _gc_timer_cm);
       do_remark_non_parallel();
     }
   }
@@ -4341,7 +4343,7 @@
   verify_overflow_empty();
 
   {
-    NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+    NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm);)
     refProcessingWork();
   }
   verify_work_stacks_empty();
@@ -5116,7 +5118,7 @@
                               NULL,  // space is set further below
                               &_markBitMap, &_markStack, &mrias_cl);
   {
-    GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+    GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm);
     // Iterate over the dirty cards, setting the corresponding bits in the
     // mod union table.
     {
@@ -5153,7 +5155,7 @@
     Universe::verify();
   }
   {
-    GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+    GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5175,7 +5177,7 @@
   }
 
   {
-    GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+    GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5194,7 +5196,7 @@
   }
 
   {
-    GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+    GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5403,7 +5405,7 @@
                                 _span, &_markBitMap, &_markStack,
                                 &cmsKeepAliveClosure, false /* !preclean */);
   {
-    GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+    GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm);
 
     ReferenceProcessorStats stats;
     if (rp->processing_is_mt()) {
@@ -5428,15 +5430,13 @@
                                         &cmsKeepAliveClosure,
                                         &cmsDrainMarkingStackClosure,
                                         &task_executor,
-                                        _gc_timer_cm,
-                                        _gc_tracer_cm->gc_id());
+                                        _gc_timer_cm);
     } else {
       stats = rp->process_discovered_references(&_is_alive_closure,
                                         &cmsKeepAliveClosure,
                                         &cmsDrainMarkingStackClosure,
                                         NULL,
-                                        _gc_timer_cm,
-                                        _gc_tracer_cm->gc_id());
+                                        _gc_timer_cm);
     }
     _gc_tracer_cm->report_gc_reference_stats(stats);
 
@@ -5447,7 +5447,7 @@
 
   if (should_unload_classes()) {
     {
-      GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+      GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm);
 
       // Unload classes and purge the SystemDictionary.
       bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
@@ -5460,13 +5460,13 @@
     }
 
     {
-      GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+      GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm);
       // Clean up unreferenced symbols in symbol table.
       SymbolTable::unlink();
     }
 
     {
-      GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+      GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm);
       // Delete entries for dead interned strings.
       StringTable::unlink(&_is_alive_closure);
     }
@@ -5534,7 +5534,7 @@
   _intra_sweep_timer.start();
   {
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    CMSPhaseAccounting pa(this, "sweep", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+    CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
     // First sweep the old gen
     {
       CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
@@ -5704,74 +5704,77 @@
 
 // Reset CMS data structures (for now just the marking bit map)
 // preparatory for the next cycle.
-void CMSCollector::reset(bool concurrent) {
-  if (concurrent) {
-    CMSTokenSyncWithLocks ts(true, bitMapLock());
-
-    // If the state is not "Resetting", the foreground  thread
-    // has done a collection and the resetting.
-    if (_collectorState != Resetting) {
-      assert(_collectorState == Idling, "The state should only change"
-        " because the foreground collector has finished the collection");
-      return;
-    }
-
-    // Clear the mark bitmap (no grey objects to start with)
-    // for the next cycle.
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    CMSPhaseAccounting cmspa(this, "reset", _gc_tracer_cm->gc_id(), !PrintGCDetails);
-
-    HeapWord* curAddr = _markBitMap.startWord();
-    while (curAddr < _markBitMap.endWord()) {
-      size_t remaining  = pointer_delta(_markBitMap.endWord(), curAddr);
-      MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
-      _markBitMap.clear_large_range(chunk);
-      if (ConcurrentMarkSweepThread::should_yield() &&
-          !foregroundGCIsActive() &&
-          CMSYield) {
-        assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
-               "CMS thread should hold CMS token");
-        assert_lock_strong(bitMapLock());
-        bitMapLock()->unlock();
-        ConcurrentMarkSweepThread::desynchronize(true);
-        stopTimer();
-        if (PrintCMSStatistics != 0) {
-          incrementYields();
-        }
-
-        // See the comment in coordinator_yield()
-        for (unsigned i = 0; i < CMSYieldSleepCount &&
-                         ConcurrentMarkSweepThread::should_yield() &&
-                         !CMSCollector::foregroundGCIsActive(); ++i) {
-          os::sleep(Thread::current(), 1, false);
-        }
-
-        ConcurrentMarkSweepThread::synchronize(true);
-        bitMapLock()->lock_without_safepoint_check();
-        startTimer();
+void CMSCollector::reset_concurrent() {
+  CMSTokenSyncWithLocks ts(true, bitMapLock());
+
+  // If the state is not "Resetting", the foreground  thread
+  // has done a collection and the resetting.
+  if (_collectorState != Resetting) {
+    assert(_collectorState == Idling, "The state should only change"
+      " because the foreground collector has finished the collection");
+    return;
+  }
+
+  // Clear the mark bitmap (no grey objects to start with)
+  // for the next cycle.
+  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+  CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
+
+  HeapWord* curAddr = _markBitMap.startWord();
+  while (curAddr < _markBitMap.endWord()) {
+    size_t remaining  = pointer_delta(_markBitMap.endWord(), curAddr);
+    MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
+    _markBitMap.clear_large_range(chunk);
+    if (ConcurrentMarkSweepThread::should_yield() &&
+        !foregroundGCIsActive() &&
+        CMSYield) {
+      assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
+             "CMS thread should hold CMS token");
+      assert_lock_strong(bitMapLock());
+      bitMapLock()->unlock();
+      ConcurrentMarkSweepThread::desynchronize(true);
+      stopTimer();
+      if (PrintCMSStatistics != 0) {
+        incrementYields();
       }
-      curAddr = chunk.end();
-    }
-    // A successful mostly concurrent collection has been done.
-    // Because only the full (i.e., concurrent mode failure) collections
-    // are being measured for gc overhead limits, clean the "near" flag
-    // and count.
-    size_policy()->reset_gc_overhead_limit_count();
-    _collectorState = Idling;
-  } else {
-    // already have the lock
-    assert(_collectorState == Resetting, "just checking");
-    assert_lock_strong(bitMapLock());
-    _markBitMap.clear_all();
-    _collectorState = Idling;
-  }
-
+
+      // See the comment in coordinator_yield()
+      for (unsigned i = 0; i < CMSYieldSleepCount &&
+                       ConcurrentMarkSweepThread::should_yield() &&
+                       !CMSCollector::foregroundGCIsActive(); ++i) {
+        os::sleep(Thread::current(), 1, false);
+      }
+
+      ConcurrentMarkSweepThread::synchronize(true);
+      bitMapLock()->lock_without_safepoint_check();
+      startTimer();
+    }
+    curAddr = chunk.end();
+  }
+  // A successful mostly concurrent collection has been done.
+  // Because only the full (i.e., concurrent mode failure) collections
+  // are being measured for gc overhead limits, clean the "near" flag
+  // and count.
+  size_policy()->reset_gc_overhead_limit_count();
+  _collectorState = Idling;
+
+  register_gc_end();
+}
+
+// Same as above but for STW paths
+void CMSCollector::reset_stw() {
+  // already have the lock
+  assert(_collectorState == Resetting, "just checking");
+  assert_lock_strong(bitMapLock());
+  GCIdMarkAndRestore gc_id_mark(_cmsThread->gc_id());
+  _markBitMap.clear_all();
+  _collectorState = Idling;
   register_gc_end();
 }
 
 void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
   TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer_cm->gc_id());
+  GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
   TraceCollectorStats tcs(counters());
 
   switch (op) {
@@ -6458,7 +6461,7 @@
 // isMarked() query is "safe".
 bool ScanMarkedObjectsAgainClosure::do_object_bm(oop p, MemRegion mr) {
   // Ignore mark word because we are running concurrent with mutators
-  assert(p->is_oop_or_null(true), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(p)));
+  assert(p->is_oop_or_null(true), "Expected an oop or NULL at " PTR_FORMAT, p2i(p));
   HeapWord* addr = (HeapWord*)p;
   assert(_span.contains(addr), "we are scanning the CMS generation");
   bool is_obj_array = false;
@@ -6893,7 +6896,7 @@
 }
 
 void PushAndMarkVerifyClosure::do_oop(oop obj) {
-  assert(obj->is_oop_or_null(), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(obj)));
+  assert(obj->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
   HeapWord* addr = (HeapWord*)obj;
   if (_span.contains(addr) && !_verification_bm->isMarked(addr)) {
     // Oop lies in _span and isn't yet grey or black
@@ -6991,7 +6994,7 @@
 
 void PushOrMarkClosure::do_oop(oop obj) {
   // Ignore mark word because we are running concurrent with mutators.
-  assert(obj->is_oop_or_null(true), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(obj)));
+  assert(obj->is_oop_or_null(true), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
   HeapWord* addr = (HeapWord*)obj;
   if (_span.contains(addr) && !_bitMap->isMarked(addr)) {
     // Oop lies in _span and isn't yet grey or black
@@ -7029,7 +7032,7 @@
 
 void Par_PushOrMarkClosure::do_oop(oop obj) {
   // Ignore mark word because we are running concurrent with mutators.
-  assert(obj->is_oop_or_null(true), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(obj)));
+  assert(obj->is_oop_or_null(true), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
   HeapWord* addr = (HeapWord*)obj;
   if (_whole_span.contains(addr) && !_bit_map->isMarked(addr)) {
     // Oop lies in _span and isn't yet grey or black
@@ -7106,7 +7109,7 @@
   // path and may be at the end of the global overflow list (so
   // the mark word may be NULL).
   assert(obj->is_oop_or_null(true /* ignore mark word */),
-         err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(obj)));
+         "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
   HeapWord* addr = (HeapWord*)obj;
   // Check if oop points into the CMS generation
   // and is not marked
@@ -7186,7 +7189,7 @@
   // the debugger, is_oop_or_null(false) may subsequently start
   // to hold.
   assert(obj->is_oop_or_null(true),
-         err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(obj)));
+         "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
   HeapWord* addr = (HeapWord*)obj;
   // Check if oop points into the CMS generation
   // and is not marked
@@ -7423,7 +7426,7 @@
     // coalesced chunk to the appropriate free list.
     if (inFreeRange()) {
       assert(freeFinger() >= _sp->bottom() && freeFinger() < _limit,
-             err_msg("freeFinger() " PTR_FORMAT " is out-of-bounds", p2i(freeFinger())));
+             "freeFinger() " PTR_FORMAT " is out-of-bounds", p2i(freeFinger()));
       flush_cur_free_chunk(freeFinger(),
                            pointer_delta(addr, freeFinger()));
       if (CMSTraceSweeper) {
@@ -7825,10 +7828,10 @@
   assert(inFreeRange(), "Should only be called if currently in a free range.");
   HeapWord* const eob = ((HeapWord*)fc) + chunk_size;
   assert(_sp->used_region().contains(eob - 1),
-         err_msg("eob = " PTR_FORMAT " eob-1 = " PTR_FORMAT " _limit = " PTR_FORMAT
-                 " out of bounds wrt _sp = [" PTR_FORMAT "," PTR_FORMAT ")"
-                 " when examining fc = " PTR_FORMAT "(" SIZE_FORMAT ")",
-                 p2i(eob), p2i(eob-1), p2i(_limit), p2i(_sp->bottom()), p2i(_sp->end()), p2i(fc), chunk_size));
+         "eob = " PTR_FORMAT " eob-1 = " PTR_FORMAT " _limit = " PTR_FORMAT
+         " out of bounds wrt _sp = [" PTR_FORMAT "," PTR_FORMAT ")"
+         " when examining fc = " PTR_FORMAT "(" SIZE_FORMAT ")",
+         p2i(eob), p2i(eob-1), p2i(_limit), p2i(_sp->bottom()), p2i(_sp->end()), p2i(fc), chunk_size);
   if (eob >= _limit) {
     assert(eob == _limit || fc->is_free(), "Only a free chunk should allow us to cross over the limit");
     if (CMSTraceSweeper) {
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -296,8 +296,8 @@
 
   size_t end() {
     assert(_index <= capacity(),
-           err_msg("_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT "): out of bounds",
-                   _index, _capacity));
+           "_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT "): out of bounds",
+           _index, _capacity);
     return _index;
   }  // exclusive
 
@@ -322,9 +322,9 @@
     } else {
       ++_overflows;
       assert(_index == _capacity,
-             err_msg("_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT
-                     "): out of bounds at overflow#" SIZE_FORMAT,
-                     _index, _capacity, _overflows));
+             "_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT
+             "): out of bounds at overflow#" SIZE_FORMAT,
+             _index, _capacity, _overflows);
     }
   }
 };
@@ -799,8 +799,10 @@
   // Concurrent sweeping work
   void sweepWork(ConcurrentMarkSweepGeneration* old_gen);
 
-  // (Concurrent) resetting of support data structures
-  void reset(bool concurrent);
+  // Concurrent resetting of support data structures
+  void reset_concurrent();
+  // Resetting of support data structures from a STW full GC
+  void reset_stw();
 
   // Clear _expansion_cause fields of constituent generations
   void clear_expansion_cause();
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
 #include "gc/cms/concurrentMarkSweepThread.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/oop.inline.hpp"
@@ -124,6 +125,7 @@
   while (!_should_terminate) {
     sleepBeforeNextCycle();
     if (_should_terminate) break;
+    GCIdMark gc_id_mark;
     GCCause::Cause cause = _collector->_full_gc_requested ?
       _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
     _collector->collect_in_background(cause);
--- a/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,7 +43,7 @@
                                      uint n_threads) {
   assert(n_threads > 0, "expected n_threads > 0");
   assert(n_threads <= ParallelGCThreads,
-         err_msg("n_threads: %u > ParallelGCThreads: %u", n_threads, ParallelGCThreads));
+         "n_threads: %u > ParallelGCThreads: %u", n_threads, ParallelGCThreads);
 
   // Make sure the LNC array is valid for the space.
   jbyte**   lowest_non_clean;
@@ -370,18 +370,18 @@
                                               - lowest_non_clean_base_chunk_index;
         if (last_chunk_index_to_check > last_chunk_index) {
           assert(last_block + last_block_size > used.end(),
-                 err_msg("Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]"
-                         " does not exceed used.end() = " PTR_FORMAT ","
-                         " yet last_chunk_index_to_check " INTPTR_FORMAT
-                         " exceeds last_chunk_index " INTPTR_FORMAT,
-                         p2i(last_block), p2i(last_block + last_block_size),
-                         p2i(used.end()),
-                         last_chunk_index_to_check, last_chunk_index));
+                 "Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]"
+                 " does not exceed used.end() = " PTR_FORMAT ","
+                 " yet last_chunk_index_to_check " INTPTR_FORMAT
+                 " exceeds last_chunk_index " INTPTR_FORMAT,
+                 p2i(last_block), p2i(last_block + last_block_size),
+                 p2i(used.end()),
+                 last_chunk_index_to_check, last_chunk_index);
           assert(sp->used_region().end() > used.end(),
-                 err_msg("Expansion did not happen: "
-                         "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
-                         p2i(sp->used_region().start()), p2i(sp->used_region().end()),
-                         p2i(used.start()), p2i(used.end())));
+                 "Expansion did not happen: "
+                 "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
+                 p2i(sp->used_region().start()), p2i(sp->used_region().end()),
+                 p2i(used.start()), p2i(used.end()));
           NOISY(tty->print_cr(" process_chunk_boundary: heap expanded; explicitly bounding last_chunk");)
           last_chunk_index_to_check = last_chunk_index;
         }
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -896,7 +896,7 @@
     size_policy->minor_collection_begin();
   }
 
-  GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, _gc_tracer.gc_id());
+  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();
 
@@ -959,15 +959,17 @@
     ParNewRefProcTaskExecutor task_executor(*this, *_old_gen, thread_state_set);
     stats = rp->process_discovered_references(&is_alive, &keep_alive,
                                               &evacuate_followers, &task_executor,
-                                              _gc_timer, _gc_tracer.gc_id());
+                                              _gc_timer);
   } else {
     thread_state_set.flush();
     gch->save_marks();
     stats = rp->process_discovered_references(&is_alive, &keep_alive,
                                               &evacuate_followers, NULL,
-                                              _gc_timer, _gc_tracer.gc_id());
+                                              _gc_timer);
   }
   _gc_tracer.report_gc_reference_stats(stats);
+  _gc_tracer.report_tenuring_threshold(tenuring_threshold());
+
   if (!promotion_failed()) {
     // Swap the survivor spaces.
     eden()->clear(SpaceDecorator::Mangle);
@@ -1030,7 +1032,6 @@
   rp->verify_no_references_recorded();
 
   gch->trace_heap_after_gc(gc_tracer());
-  _gc_tracer.report_tenuring_threshold(tenuring_threshold());
 
   _gc_timer->register_gc_end();
 
--- a/hotspot/src/share/vm/gc/cms/promotionInfo.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/promotionInfo.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -73,7 +73,7 @@
     } else {
       res = (PromotedObject*)(_next & next_mask);
     }
-    assert(oop(res)->is_oop_or_null(true /* ignore mark word */), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(oop(res))));
+    assert(oop(res)->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(oop(res)));
     return res;
   }
   inline void setNext(PromotedObject* x) {
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -58,7 +58,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, _collector->_gc_tracer_cm->gc_id());
+    GCTraceTime tm("Verify Before", false, false, _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -70,7 +70,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, _collector->_gc_tracer_cm->gc_id());
+    GCTraceTime tm("Verify After", false, false, _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -134,6 +134,7 @@
     return;
   }
   HS_PRIVATE_CMS_INITMARK_BEGIN();
+  GCIdMark gc_id_mark(_gc_id);
 
   _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark");
 
@@ -161,6 +162,7 @@
     return;
   }
   HS_PRIVATE_CMS_REMARK_BEGIN();
+  GCIdMark gc_id_mark(_gc_id);
 
   _collector->_gc_timer_cm->register_gc_pause_start("Final Mark");
 
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -27,6 +27,7 @@
 
 #include "gc/cms/concurrentMarkSweepGeneration.hpp"
 #include "gc/shared/gcCause.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 #include "runtime/vm_operations.hpp"
 
@@ -53,6 +54,7 @@
  protected:
   CMSCollector*  _collector;                 // associated collector
   bool           _prologue_succeeded;     // whether doit_prologue succeeded
+  uint           _gc_id;
 
   bool lost_race() const;
 
@@ -63,7 +65,8 @@
  public:
   VM_CMS_Operation(CMSCollector* collector):
     _collector(collector),
-    _prologue_succeeded(false) {}
+    _prologue_succeeded(false),
+    _gc_id(GCId::current()) {}
   ~VM_CMS_Operation() {}
 
   // The legal collector state for executing this CMS op.
--- a/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/cms/yieldingWorkgroup.hpp"
+#include "gc/shared/gcId.hpp"
 #include "utilities/macros.hpp"
 
 YieldingFlexibleGangWorker::YieldingFlexibleGangWorker(YieldingFlexibleWorkGang* gang, int id)
@@ -340,6 +341,7 @@
         // Now, release the gang mutex and do the work.
         {
           MutexUnlockerEx mul(gang_monitor, Mutex::_no_safepoint_check_flag);
+          GCIdMark gc_id_mark(data.task()->gc_id());
           data.task()->work(id);   // This might include yielding
         }
         // Reacquire monitor and note completion of this worker
--- a/hotspot/src/share/vm/gc/g1/bufferingOopClosure.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/bufferingOopClosure.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -153,10 +153,10 @@
 
     boc.done();
 
-    #define assert_testCount(got, expected)                                     \
-       assert((got) == (expected),                                              \
-           err_msg("Expected: %d, got: %d, when running testCount(%d, %d, %d)", \
-               (got), (expected), num_narrow, num_full, do_oop_order))
+    #define assert_testCount(got, expected)                                \
+       assert((got) == (expected),                                         \
+              "Expected: %d, got: %d, when running testCount(%d, %d, %d)", \
+              (got), (expected), num_narrow, num_full, do_oop_order)
 
     assert_testCount(num_narrow, coc.narrow_oop_count());
     assert_testCount(num_full, coc.full_oop_count());
@@ -190,11 +190,11 @@
 
     fr.oops_do(&boc, 0);
 
-    #define assert_testIsBufferEmptyOrFull(got, expected)                             \
-        assert((got) == (expected),                                                   \
-            err_msg("Expected: %d, got: %d. testIsBufferEmptyOrFull(%d, %d, %s, %s)", \
-                (got), (expected), num_narrow, num_full,                              \
-                BOOL_TO_STR(expect_empty), BOOL_TO_STR(expect_full)))
+    #define assert_testIsBufferEmptyOrFull(got, expected)                        \
+        assert((got) == (expected),                                              \
+               "Expected: %d, got: %d. testIsBufferEmptyOrFull(%d, %d, %s, %s)", \
+               (got), (expected), num_narrow, num_full,                          \
+               BOOL_TO_STR(expect_empty), BOOL_TO_STR(expect_full))
 
     assert_testIsBufferEmptyOrFull(expect_empty, boc.is_buffer_empty());
     assert_testIsBufferEmptyOrFull(expect_full, boc.is_buffer_full());
@@ -232,8 +232,8 @@
     boc.done();
 
     assert(boc.is_buffer_empty(),
-        err_msg("Should be empty after call to done(). testEmptyAfterDone(%d, %d)",
-            num_narrow, num_full));
+           "Should be empty after call to done(). testEmptyAfterDone(%d, %d)",
+           num_narrow, num_full);
   }
 
   static void testEmptyAfterDone() {
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -91,10 +91,8 @@
 
 #ifndef PRODUCT
 void CollectionSetChooser::verify() {
-  guarantee(_end <= regions_length(),
-         err_msg("_end: %u regions length: %u", _end, regions_length()));
-  guarantee(_front <= _end,
-            err_msg("_front: %u _end: %u", _front, _end));
+  guarantee(_end <= regions_length(), "_end: %u regions length: %u", _end, regions_length());
+  guarantee(_front <= _end, "_front: %u _end: %u", _front, _end);
   uint index = 0;
   size_t sum_of_reclaimable_bytes = 0;
   while (index < _front) {
@@ -108,19 +106,19 @@
     guarantee(curr != NULL, "Regions in _regions array cannot be NULL");
     guarantee(!curr->is_young(), "should not be young!");
     guarantee(!curr->is_pinned(),
-              err_msg("Pinned region should not be in collection set (index %u)", curr->hrm_index()));
+              "Pinned region should not be in collection set (index %u)", curr->hrm_index());
     if (prev != NULL) {
       guarantee(order_regions(prev, curr) != 1,
-                err_msg("GC eff prev: %1.4f GC eff curr: %1.4f",
-                        prev->gc_efficiency(), curr->gc_efficiency()));
+                "GC eff prev: %1.4f GC eff curr: %1.4f",
+                prev->gc_efficiency(), curr->gc_efficiency());
     }
     sum_of_reclaimable_bytes += curr->reclaimable_bytes();
     prev = curr;
   }
   guarantee(sum_of_reclaimable_bytes == _remaining_reclaimable_bytes,
-            err_msg("reclaimable bytes inconsistent, "
-                    "remaining: " SIZE_FORMAT " sum: " SIZE_FORMAT,
-                    _remaining_reclaimable_bytes, sum_of_reclaimable_bytes));
+            "reclaimable bytes inconsistent, "
+            "remaining: " SIZE_FORMAT " sum: " SIZE_FORMAT,
+            _remaining_reclaimable_bytes, sum_of_reclaimable_bytes);
 }
 #endif // !PRODUCT
 
@@ -151,7 +149,7 @@
 
 void CollectionSetChooser::add_region(HeapRegion* hr) {
   assert(!hr->is_pinned(),
-         err_msg("Pinned region shouldn't be added to the collection set (index %u)", hr->hrm_index()));
+         "Pinned region shouldn't be added to the collection set (index %u)", hr->hrm_index());
   assert(!hr->is_young(), "should not be young!");
   _regions.append(hr);
   _end++;
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -73,9 +73,7 @@
     HeapRegion* res = NULL;
     if (_front < _end) {
       res = regions_at(_front);
-      assert(res != NULL,
-             err_msg("Unexpected NULL hr in _regions at index %u",
-                     _front));
+      assert(res != NULL, "Unexpected NULL hr in _regions at index %u", _front);
     }
     return res;
   }
@@ -88,9 +86,9 @@
     assert(_front < _end, "pre-condition");
     regions_at_put(_front, NULL);
     assert(hr->reclaimable_bytes() <= _remaining_reclaimable_bytes,
-           err_msg("remaining reclaimable bytes inconsistent "
-                   "from region: " SIZE_FORMAT " remaining: " SIZE_FORMAT,
-                   hr->reclaimable_bytes(), _remaining_reclaimable_bytes));
+           "remaining reclaimable bytes inconsistent "
+           "from region: " SIZE_FORMAT " remaining: " SIZE_FORMAT,
+           hr->reclaimable_bytes(), _remaining_reclaimable_bytes);
     _remaining_reclaimable_bytes -= hr->reclaimable_bytes();
     _front += 1;
     return hr;
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,6 +41,7 @@
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
 #include "gc/shared/gcTraceTime.hpp"
@@ -245,10 +246,6 @@
 
 CMMarkStack::CMMarkStack(ConcurrentMark* cm) :
   _base(NULL), _cm(cm)
-#ifdef ASSERT
-  , _drain_in_progress(false)
-  , _drain_in_progress_yields(false)
-#endif
 {}
 
 bool CMMarkStack::allocate(size_t capacity) {
@@ -362,30 +359,6 @@
   }
 }
 
-template<class OopClosureClass>
-bool CMMarkStack::drain(OopClosureClass* cl, CMBitMap* bm, bool yield_after) {
-  assert(!_drain_in_progress || !_drain_in_progress_yields || yield_after
-         || SafepointSynchronize::is_at_safepoint(),
-         "Drain recursion must be yield-safe.");
-  bool res = true;
-  debug_only(_drain_in_progress = true);
-  debug_only(_drain_in_progress_yields = yield_after);
-  while (!isEmpty()) {
-    oop newOop = pop();
-    assert(G1CollectedHeap::heap()->is_in_reserved(newOop), "Bad pop");
-    assert(newOop->is_oop(), "Expected an oop");
-    assert(bm == NULL || bm->isMarked((HeapWord*)newOop),
-           "only grey objects on this stack");
-    newOop->oop_iterate(cl);
-    if (yield_after && _cm->do_yield_check()) {
-      res = false;
-      break;
-    }
-  }
-  debug_only(_drain_in_progress = false);
-  return res;
-}
-
 void CMMarkStack::note_start_of_gc() {
   assert(_saved_index == -1,
          "note_start_of_gc()/end_of_gc() bracketed incorrectly");
@@ -399,7 +372,7 @@
   // only check this once per GC anyway, so it won't be a performance
   // issue in any way.
   guarantee(_saved_index == _index,
-            err_msg("saved index: %d index: %d", _saved_index, _index));
+            "saved index: %d index: %d", _saved_index, _index);
   _saved_index = -1;
 }
 
@@ -520,7 +493,6 @@
   _has_overflown(false),
   _concurrent(false),
   _has_aborted(false),
-  _aborted_gc_id(GCId::undefined()),
   _restart_for_overflow(false),
   _concurrent_marking_in_progress(false),
 
@@ -794,8 +766,8 @@
     // in a STW phase.
     assert(!concurrent_marking_in_progress(), "invariant");
     assert(out_of_regions(),
-           err_msg("only way to get here: _finger: " PTR_FORMAT ", _heap_end: " PTR_FORMAT,
-                   p2i(_finger), p2i(_heap_end)));
+           "only way to get here: _finger: " PTR_FORMAT ", _heap_end: " PTR_FORMAT,
+           p2i(_finger), p2i(_heap_end));
   }
 }
 
@@ -991,7 +963,7 @@
       force_overflow()->update();
 
       if (G1Log::fine()) {
-        gclog_or_tty->gclog_stamp(concurrent_gc_id());
+        gclog_or_tty->gclog_stamp();
         gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]");
       }
     }
@@ -1181,7 +1153,7 @@
   // should not attempt to do any further work.
   if (root_regions()->scan_in_progress()) {
     if (G1Log::fine()) {
-      gclog_or_tty->gclog_stamp(concurrent_gc_id());
+      gclog_or_tty->gclog_stamp();
       gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]");
     }
 
@@ -1195,7 +1167,7 @@
     _parallel_workers->run_task(&task);
 
     if (G1Log::fine()) {
-      gclog_or_tty->gclog_stamp(concurrent_gc_id());
+      gclog_or_tty->gclog_stamp();
       gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]", os::elapsedTime() - scan_start);
     }
 
@@ -1235,7 +1207,8 @@
 }
 
 // Helper class to get rid of some boilerplate code.
-class G1CMTraceTime : public GCTraceTime {
+class G1CMTraceTime : public StackObj {
+  GCTraceTimeImpl _gc_trace_time;
   static bool doit_and_prepend(bool doit) {
     if (doit) {
       gclog_or_tty->put(' ');
@@ -1245,8 +1218,7 @@
 
  public:
   G1CMTraceTime(const char* title, bool doit)
-    : GCTraceTime(title, doit_and_prepend(doit), false, G1CollectedHeap::heap()->gc_timer_cm(),
-        G1CollectedHeap::heap()->concurrent_mark()->concurrent_gc_id()) {
+    : _gc_trace_time(title, doit_and_prepend(doit), false, G1CollectedHeap::heap()->gc_timer_cm()) {
   }
 };
 
@@ -1415,9 +1387,9 @@
     HeapWord* start = hr->bottom();
 
     assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
-           err_msg("Preconditions not met - "
-                   "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT,
-                   p2i(start), p2i(ntams), p2i(hr->end())));
+           "Preconditions not met - "
+           "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT,
+           p2i(start), p2i(ntams), p2i(hr->end()));
 
     // Find the first marked object at or after "start".
     start = _bm->getNextMarkedWordAddress(start, ntams);
@@ -1717,11 +1689,11 @@
       }
 
       assert(end_idx <= _card_bm->size(),
-             err_msg("oob: end_idx=  " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
-                     end_idx, _card_bm->size()));
+             "oob: end_idx=  " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
+             end_idx, _card_bm->size());
       assert(start_idx < _card_bm->size(),
-             err_msg("oob: start_idx=  " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
-                     start_idx, _card_bm->size()));
+             "oob: start_idx=  " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
+             start_idx, _card_bm->size());
 
       _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
     }
@@ -2391,8 +2363,7 @@
                                           &g1_keep_alive,
                                           &g1_drain_mark_stack,
                                           executor,
-                                          g1h->gc_timer_cm(),
-                                          concurrent_gc_id());
+                                          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
@@ -2471,7 +2442,7 @@
       // object; it could instead have been a stale reference.
       oop obj = static_cast<oop>(entry);
       assert(obj->is_oop(true /* ignore mark word */),
-             err_msg("Invalid oop in SATB buffer: " PTR_FORMAT, p2i(obj)));
+             "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(obj));
       _task->make_reference_grey(obj, hr);
     }
   }
@@ -2588,9 +2559,9 @@
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
   guarantee(has_overflown() ||
             satb_mq_set.completed_buffers_num() == 0,
-            err_msg("Invariant: has_overflown = %s, num buffers = %d",
-                    BOOL_TO_STR(has_overflown()),
-                    satb_mq_set.completed_buffers_num()));
+            "Invariant: has_overflown = %s, num buffers = %d",
+            BOOL_TO_STR(has_overflown()),
+            satb_mq_set.completed_buffers_num());
 
   print_stats();
 }
@@ -2724,11 +2695,11 @@
 
   void operator()(oop obj) const {
     guarantee(obj->is_oop(),
-              err_msg("Non-oop " PTR_FORMAT ", phase: %s, info: %d",
-                      p2i(obj), _phase, _info));
+              "Non-oop " PTR_FORMAT ", phase: %s, info: %d",
+              p2i(obj), _phase, _info);
     guarantee(!_g1h->obj_in_cs(obj),
-              err_msg("obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
-                      p2i(obj), _phase, _info));
+              "obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
+              p2i(obj), _phase, _info);
   }
 };
 
@@ -2761,8 +2732,8 @@
     // here.
     HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
     guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
-              err_msg("global finger: " PTR_FORMAT " region: " HR_FORMAT,
-                      p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
+              "global finger: " PTR_FORMAT " region: " HR_FORMAT,
+              p2i(global_finger), HR_FORMAT_PARAMS(global_hr));
   }
 
   // Verify the task fingers
@@ -2775,8 +2746,8 @@
       HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
       guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
                 !task_hr->in_collection_set(),
-                err_msg("task finger: " PTR_FORMAT " region: " HR_FORMAT,
-                        p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
+                "task finger: " PTR_FORMAT " region: " HR_FORMAT,
+                p2i(task_finger), HR_FORMAT_PARAMS(task_hr));
     }
   }
 }
@@ -2816,10 +2787,10 @@
     HeapWord* end = hr->end();
 
     assert(start <= limit && limit <= hr->top() && hr->top() <= hr->end(),
-           err_msg("Preconditions not met - "
-                   "start: " PTR_FORMAT ", limit: " PTR_FORMAT ", "
-                   "top: " PTR_FORMAT ", end: " PTR_FORMAT,
-                   p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end())));
+           "Preconditions not met - "
+           "start: " PTR_FORMAT ", limit: " PTR_FORMAT ", "
+           "top: " PTR_FORMAT ", end: " PTR_FORMAT,
+           p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end()));
 
     assert(hr->next_marked_bytes() == 0, "Precondition");
 
@@ -2988,8 +2959,6 @@
   }
   _first_overflow_barrier_sync.abort();
   _second_overflow_barrier_sync.abort();
-  _aborted_gc_id = _g1h->gc_tracer_cm()->gc_id();
-  assert(!_aborted_gc_id.is_undefined(), "ConcurrentMark::abort() executed more than once?");
   _has_aborted = true;
 
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
@@ -3004,13 +2973,6 @@
   _g1h->register_concurrent_cycle_end();
 }
 
-const GCId& ConcurrentMark::concurrent_gc_id() {
-  if (has_aborted()) {
-    return _aborted_gc_id;
-  }
-  return _g1h->gc_tracer_cm()->gc_id();
-}
-
 static void print_ms_time_info(const char* prefix, const char* name,
                                NumberSeq& ns) {
   gclog_or_tty->print_cr("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).",
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -28,7 +28,6 @@
 #include "classfile/javaClasses.hpp"
 #include "gc/g1/g1RegionToSpaceMapper.hpp"
 #include "gc/g1/heapRegionSet.hpp"
-#include "gc/shared/gcId.hpp"
 #include "gc/shared/taskqueue.hpp"
 
 class G1CollectedHeap;
@@ -183,15 +182,6 @@
 
   bool  _overflow;
   bool  _should_expand;
-  DEBUG_ONLY(bool _drain_in_progress;)
-  DEBUG_ONLY(bool _drain_in_progress_yields;)
-
-  oop pop() {
-    if (!isEmpty()) {
-      return _base[--_index] ;
-    }
-    return NULL;
-  }
 
  public:
   CMMarkStack(ConcurrentMark* cm);
@@ -213,17 +203,6 @@
   // operations, which use the same locking strategy.
   bool par_pop_arr(oop* ptr_arr, int max, int* n);
 
-  // Drain the mark stack, applying the given closure to all fields of
-  // objects on the stack.  (That is, continue until the stack is empty,
-  // even if closure applications add entries to the stack.)  The "bm"
-  // argument, if non-null, may be used to verify that only marked objects
-  // are on the mark stack.  If "yield_after" is "true", then the
-  // concurrent marker performing the drain offers to yield after
-  // processing each object.  If a yield occurs, stops the drain operation
-  // and returns false.  Otherwise, returns true.
-  template<class OopClosureClass>
-  bool drain(OopClosureClass* cl, CMBitMap* bm, bool yield_after = false);
-
   bool isEmpty()    { return _index == 0; }
   int  maxElems()   { return _capacity; }
 
@@ -425,7 +404,6 @@
   volatile bool           _concurrent;
   // Set at the end of a Full GC so that marking aborts
   volatile bool           _has_aborted;
-  GCId                    _aborted_gc_id;
 
   // Used when remark aborts due to an overflow to indicate that
   // another concurrent marking phase should start
@@ -768,8 +746,6 @@
 
   bool has_aborted()      { return _has_aborted; }
 
-  const GCId& concurrent_gc_id();
-
   // This prints the global/local fingers. It is used for debugging.
   NOT_PRODUCT(void print_finger();)
 
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -197,9 +197,9 @@
   assert(_bmStartWord <= (addr) && (addr) < (_bmStartWord + _bmWordSize),      \
          "outside underlying space?");                                         \
   assert(G1CollectedHeap::heap()->is_in_exact(addr),                           \
-         err_msg("Trying to access not available bitmap " PTR_FORMAT           \
-                 " corresponding to " PTR_FORMAT " (%u)",                      \
-                 p2i(this), p2i(addr), G1CollectedHeap::heap()->addr_to_region(addr)));
+         "Trying to access not available bitmap " PTR_FORMAT                   \
+         " corresponding to " PTR_FORMAT " (%u)",                              \
+         p2i(this), p2i(addr), G1CollectedHeap::heap()->addr_to_region(addr));
 
 inline void CMBitMap::mark(HeapWord* addr) {
   check_mark(addr);
@@ -225,8 +225,7 @@
 
 template<typename Fn>
 inline void CMMarkStack::iterate(Fn fn) {
-  assert(_saved_index == _index,
-         err_msg("saved index: %d index: %d", _saved_index, _index));
+  assert(_saved_index == _index, "saved index: %d index: %d", _saved_index, _index);
   for (int i = 0; i < _index; ++i) {
     fn(_base[i]);
   }
@@ -385,7 +384,7 @@
   increment_refs_reached();
 
   HeapWord* objAddr = (HeapWord*) obj;
-  assert(obj->is_oop_or_null(true /* ignore mark word */), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(obj)));
+  assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
   if (_g1h->is_in_g1_reserved(objAddr)) {
     assert(obj != NULL, "null check is implicit");
     if (!_nextMarkBitMap->isMarked(objAddr)) {
@@ -427,9 +426,9 @@
   // assert that word_size is under an upper bound which is its
   // containing region's capacity.
   assert(word_size * HeapWordSize <= hr->capacity(),
-         err_msg("size: " SIZE_FORMAT " capacity: " SIZE_FORMAT " " HR_FORMAT,
-                 word_size * HeapWordSize, hr->capacity(),
-                 HR_FORMAT_PARAMS(hr)));
+         "size: " SIZE_FORMAT " capacity: " SIZE_FORMAT " " HR_FORMAT,
+         word_size * HeapWordSize, hr->capacity(),
+         HR_FORMAT_PARAMS(hr));
 
   if (addr < hr->next_top_at_mark_start()) {
     if (!_nextMarkBitMap->isMarked(addr)) {
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,6 +30,7 @@
 #include "gc/g1/g1MMUTracker.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
 #include "gc/g1/vm_operations_g1.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcTrace.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/vmThread.hpp"
@@ -85,7 +86,7 @@
     SuspendibleThreadSetJoiner sts_joiner(join_sts);
     va_list args;
     va_start(args, fmt);
-    gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+    gclog_or_tty->gclog_stamp();
     gclog_or_tty->vprint_cr(fmt, args);
     va_end(args);
   }
@@ -108,6 +109,7 @@
       break;
     }
 
+    assert(GCId::current() != GCId::undefined(), "GC id should have been set up by the initial mark GC.");
     {
       ResourceMark rm;
       HandleMark   hm;
@@ -194,7 +196,7 @@
         // reclaimed by cleanup.
 
         double cleanup_start_sec = os::elapsedTime();
-        cm_log(G1Log::fine(), true, "[GC concurrent-cleanup-start]");
+        cm_log(G1Log::fine(), false, "[GC concurrent-cleanup-start]");
 
         // Now do the concurrent cleanup operation.
         _cm->completeCleanup();
--- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -91,7 +91,7 @@
 }
 
 size_t G1AllocRegion::retire(bool fill_up) {
-  assert(_alloc_region != NULL, ar_ext_msg(this, "not initialized properly"));
+  assert_alloc_region(_alloc_region != NULL, "not initialized properly");
 
   size_t result = 0;
 
@@ -101,15 +101,14 @@
     // We never have to check whether the active region is empty or not,
     // and potentially free it if it is, given that it's guaranteed that
     // it will never be empty.
-    assert(!alloc_region->is_empty(),
-           ar_ext_msg(this, "the alloc region should never be empty"));
+    assert_alloc_region(!alloc_region->is_empty(),
+                           "the alloc region should never be empty");
 
     if (fill_up) {
       result = fill_up_remaining_space(alloc_region, _bot_updates);
     }
 
-    assert(alloc_region->used() >= _used_bytes_before,
-           ar_ext_msg(this, "invariant"));
+    assert_alloc_region(alloc_region->used() >= _used_bytes_before, "invariant");
     size_t allocated_bytes = alloc_region->used() - _used_bytes_before;
     retire_region(alloc_region, allocated_bytes);
     _used_bytes_before = 0;
@@ -122,8 +121,8 @@
 
 HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size,
                                                        bool force) {
-  assert(_alloc_region == _dummy_region, ar_ext_msg(this, "pre-condition"));
-  assert(_used_bytes_before == 0, ar_ext_msg(this, "pre-condition"));
+  assert_alloc_region(_alloc_region == _dummy_region, "pre-condition");
+  assert_alloc_region(_used_bytes_before == 0, "pre-condition");
 
   trace("attempting region allocation");
   HeapRegion* new_alloc_region = allocate_new_region(word_size, force);
@@ -132,7 +131,7 @@
     // Need to do this before the allocation
     _used_bytes_before = new_alloc_region->used();
     HeapWord* result = allocate(new_alloc_region, word_size, _bot_updates);
-    assert(result != NULL, ar_ext_msg(this, "the allocation should succeeded"));
+    assert_alloc_region(result != NULL, "the allocation should succeeded");
 
     OrderAccess::storestore();
     // Note that we first perform the allocation and then we store the
@@ -148,17 +147,10 @@
   ShouldNotReachHere();
 }
 
-void G1AllocRegion::fill_in_ext_msg(ar_ext_msg* msg, const char* message) {
-  msg->append("[%s] %s c: %u b: %s r: " PTR_FORMAT " u: " SIZE_FORMAT,
-              _name, message, _count, BOOL_TO_STR(_bot_updates),
-              p2i(_alloc_region), _used_bytes_before);
-}
-
 void G1AllocRegion::init() {
   trace("initializing");
-  assert(_alloc_region == NULL && _used_bytes_before == 0,
-         ar_ext_msg(this, "pre-condition"));
-  assert(_dummy_region != NULL, ar_ext_msg(this, "should have been set"));
+  assert_alloc_region(_alloc_region == NULL && _used_bytes_before == 0, "pre-condition");
+  assert_alloc_region(_dummy_region != NULL, "should have been set");
   _alloc_region = _dummy_region;
   _count = 0;
   trace("initialized");
@@ -168,11 +160,10 @@
   trace("setting");
   // We explicitly check that the region is not empty to make sure we
   // maintain the "the alloc region cannot be empty" invariant.
-  assert(alloc_region != NULL && !alloc_region->is_empty(),
-         ar_ext_msg(this, "pre-condition"));
-  assert(_alloc_region == _dummy_region &&
-         _used_bytes_before == 0 && _count == 0,
-         ar_ext_msg(this, "pre-condition"));
+  assert_alloc_region(alloc_region != NULL && !alloc_region->is_empty(), "pre-condition");
+  assert_alloc_region(_alloc_region == _dummy_region &&
+                         _used_bytes_before == 0 && _count == 0,
+                         "pre-condition");
 
   _used_bytes_before = alloc_region->used();
   _alloc_region = alloc_region;
@@ -184,8 +175,7 @@
   trace("update");
   // We explicitly check that the region is not empty to make sure we
   // maintain the "the alloc region cannot be empty" invariant.
-  assert(alloc_region != NULL && !alloc_region->is_empty(),
-         ar_ext_msg(this, "pre-condition"));
+  assert_alloc_region(alloc_region != NULL && !alloc_region->is_empty(), "pre-condition");
 
   _alloc_region = alloc_region;
   _alloc_region->set_allocation_context(allocation_context());
@@ -197,8 +187,7 @@
   trace("releasing");
   HeapRegion* alloc_region = _alloc_region;
   retire(false /* fill_up */);
-  assert(_alloc_region == _dummy_region,
-         ar_ext_msg(this, "post-condition of retire()"));
+  assert_alloc_region(_alloc_region == _dummy_region, "post-condition of retire()");
   _alloc_region = NULL;
   trace("released");
   return (alloc_region == _dummy_region) ? NULL : alloc_region;
--- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -34,8 +34,6 @@
 // 0 -> no tracing, 1 -> basic tracing, 2 -> basic + allocation tracing
 #define G1_ALLOC_REGION_TRACING 0
 
-class ar_ext_msg;
-
 // A class that holds a region that is active in satisfying allocation
 // requests, potentially issued in parallel. When the active region is
 // full it will be retired and replaced with a new one. The
@@ -44,7 +42,6 @@
 // replaced.
 
 class G1AllocRegion VALUE_OBJ_CLASS_SPEC {
-  friend class ar_ext_msg;
 
 private:
   // The active allocating region we are currently allocating out
@@ -131,8 +128,6 @@
   // to allocate a new region even if the max has been reached.
   HeapWord* new_alloc_region_and_allocate(size_t word_size, bool force);
 
-  void fill_in_ext_msg(ar_ext_msg* msg, const char* message);
-
 protected:
   // Retire the active allocating region. If fill_up is true then make
   // sure that the region is full before we retire it so that no one
@@ -278,11 +273,4 @@
   virtual HeapRegion* release();
 };
 
-class ar_ext_msg : public err_msg {
-public:
-  ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("%s", "") {
-    alloc_region->fill_in_ext_msg(this, message);
-  }
-};
-
 #endif // SHARE_VM_GC_G1_G1ALLOCREGION_HPP
--- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -28,10 +28,18 @@
 #include "gc/g1/g1AllocRegion.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 
+#define assert_alloc_region(p, message)                                  \
+  do {                                                                   \
+    assert((p), "[%s] %s c: %u b: %s r: " PTR_FORMAT " u: " SIZE_FORMAT, \
+           _name, (message), _count, BOOL_TO_STR(_bot_updates),          \
+           p2i(_alloc_region), _used_bytes_before);                      \
+  } while (0)
+
+
 inline HeapWord* G1AllocRegion::allocate(HeapRegion* alloc_region,
                                          size_t word_size,
                                          bool bot_updates) {
-  assert(alloc_region != NULL, err_msg("pre-condition"));
+  assert(alloc_region != NULL, "pre-condition");
 
   if (!bot_updates) {
     return alloc_region->allocate_no_bot_updates(word_size);
@@ -50,8 +58,8 @@
                                              size_t desired_word_size,
                                              size_t* actual_word_size,
                                              bool bot_updates) {
-  assert(alloc_region != NULL, err_msg("pre-condition"));
-  assert(!alloc_region->is_empty(), err_msg("pre-condition"));
+  assert(alloc_region != NULL, "pre-condition");
+  assert(!alloc_region->is_empty(), "pre-condition");
 
   if (!bot_updates) {
     return alloc_region->par_allocate_no_bot_updates(min_word_size, desired_word_size, actual_word_size);
@@ -69,10 +77,10 @@
                                                    size_t desired_word_size,
                                                    size_t* actual_word_size,
                                                    bool bot_updates) {
-  assert(bot_updates == _bot_updates, ar_ext_msg(this, "pre-condition"));
+  assert_alloc_region(bot_updates == _bot_updates, "pre-condition");
 
   HeapRegion* alloc_region = _alloc_region;
-  assert(alloc_region != NULL, ar_ext_msg(this, "not initialized properly"));
+  assert_alloc_region(alloc_region != NULL, "not initialized properly");
 
   HeapWord* result = par_allocate(alloc_region, min_word_size, desired_word_size, actual_word_size, bot_updates);
   if (result != NULL) {
@@ -113,8 +121,8 @@
 
 inline HeapWord* G1AllocRegion::attempt_allocation_force(size_t word_size,
                                                          bool bot_updates) {
-  assert(bot_updates == _bot_updates, ar_ext_msg(this, "pre-condition"));
-  assert(_alloc_region != NULL, ar_ext_msg(this, "not initialized properly"));
+  assert_alloc_region(bot_updates == _bot_updates, "pre-condition");
+  assert_alloc_region(_alloc_region != NULL, "not initialized properly");
 
   trace("forcing alloc", word_size, word_size);
   HeapWord* result = new_alloc_region_and_allocate(word_size, true /* force */);
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -54,7 +54,7 @@
   HeapRegion* retained_region = *retained_old;
   *retained_old = NULL;
   assert(retained_region == NULL || !retained_region->is_archive(),
-         err_msg("Archive region should not be alloc region (index %u)", retained_region->hrm_index()));
+         "Archive region should not be alloc region (index %u)", retained_region->hrm_index());
 
   // We will discard the current GC alloc region if:
   // a) it's in the collection set (it can happen!),
@@ -147,8 +147,8 @@
   size_t temp = 0;
   HeapWord* result = par_allocate_during_gc(dest, word_size, word_size, &temp, context);
   assert(result == NULL || temp == word_size,
-         err_msg("Requested " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
-                 word_size, temp, p2i(result)));
+         "Requested " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
+         word_size, temp, p2i(result));
   return result;
 }
 
@@ -276,16 +276,16 @@
                                                        context);
 
     assert(buf == NULL || ((actual_plab_size >= required_in_plab) && (actual_plab_size <= plab_word_size)),
-           err_msg("Requested at minimum " SIZE_FORMAT ", desired " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
-                   required_in_plab, plab_word_size, actual_plab_size, p2i(buf)));
+           "Requested at minimum " SIZE_FORMAT ", desired " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
+           required_in_plab, plab_word_size, actual_plab_size, p2i(buf));
 
     if (buf != NULL) {
       alloc_buf->set_buf(buf, actual_plab_size);
 
       HeapWord* const obj = alloc_buf->allocate(word_sz);
-      assert(obj != NULL, err_msg("PLAB should have been big enough, tried to allocate "
-                                  SIZE_FORMAT " requiring " SIZE_FORMAT " PLAB size " SIZE_FORMAT,
-                                  word_sz, required_in_plab, plab_word_size));
+      assert(obj != NULL, "PLAB should have been big enough, tried to allocate "
+                          SIZE_FORMAT " requiring " SIZE_FORMAT " PLAB size " SIZE_FORMAT,
+                          word_sz, required_in_plab, plab_word_size);
       return obj;
     }
     // Otherwise.
@@ -354,7 +354,7 @@
   if (hr == NULL) {
     return false;
   }
-  assert(hr->is_empty(), err_msg("expected empty region (index %u)", hr->hrm_index()));
+  assert(hr->is_empty(), "expected empty region (index %u)", hr->hrm_index());
   hr->set_archive();
   _g1h->old_set_add(hr);
   _g1h->hr_printer()->alloc(hr, G1HRPrinter::Archive);
@@ -383,15 +383,15 @@
   }
   HeapWord* old_top = _allocation_region->top();
   assert(_bottom >= _allocation_region->bottom(),
-         err_msg("inconsistent allocation state: " PTR_FORMAT " < " PTR_FORMAT,
-                 p2i(_bottom), p2i(_allocation_region->bottom())));
+         "inconsistent allocation state: " PTR_FORMAT " < " PTR_FORMAT,
+         p2i(_bottom), p2i(_allocation_region->bottom()));
   assert(_max <= _allocation_region->end(),
-         err_msg("inconsistent allocation state: " PTR_FORMAT " > " PTR_FORMAT,
-                 p2i(_max), p2i(_allocation_region->end())));
+         "inconsistent allocation state: " PTR_FORMAT " > " PTR_FORMAT,
+         p2i(_max), p2i(_allocation_region->end()));
   assert(_bottom <= old_top && old_top <= _max,
-         err_msg("inconsistent allocation state: expected "
-                 PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT,
-                 p2i(_bottom), p2i(old_top), p2i(_max)));
+         "inconsistent allocation state: expected "
+         PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT,
+         p2i(_bottom), p2i(old_top), p2i(_max));
 
   // Allocate the next word_size words in the current allocation chunk.
   // If allocation would cross the _max boundary, insert a filler and begin
@@ -430,9 +430,9 @@
 void G1ArchiveAllocator::complete_archive(GrowableArray<MemRegion>* ranges,
                                           size_t end_alignment_in_bytes) {
   assert((end_alignment_in_bytes >> LogHeapWordSize) < HeapRegion::min_region_size_in_words(),
-          err_msg("alignment " SIZE_FORMAT " too large", end_alignment_in_bytes));
+         "alignment " SIZE_FORMAT " too large", end_alignment_in_bytes);
   assert(is_size_aligned(end_alignment_in_bytes, HeapWordSize),
-         err_msg("alignment " SIZE_FORMAT " is not HeapWord (%u) aligned", end_alignment_in_bytes, HeapWordSize));
+         "alignment " SIZE_FORMAT " is not HeapWord (%u) aligned", end_alignment_in_bytes, HeapWordSize);
 
   // If we've allocated nothing, simply return.
   if (_allocation_region == NULL) {
@@ -465,8 +465,8 @@
   // MemRegions to the GrowableArray provided by the caller.
   int index = _allocated_regions.length() - 1;
   assert(_allocated_regions.at(index) == _allocation_region,
-         err_msg("expected region %u at end of array, found %u",
-                 _allocation_region->hrm_index(), _allocated_regions.at(index)->hrm_index()));
+         "expected region %u at end of array, found %u",
+         _allocation_region->hrm_index(), _allocated_regions.at(index)->hrm_index());
   HeapWord* base_address = _allocation_region->bottom();
   HeapWord* top = base_address;
 
@@ -482,7 +482,7 @@
     index = index - 1;
   }
 
-  assert(top != base_address, err_msg("zero-sized range, address " PTR_FORMAT, p2i(base_address)));
+  assert(top != base_address, "zero-sized range, address " PTR_FORMAT, p2i(base_address));
   ranges->append(MemRegion(base_address, pointer_delta(top, base_address)));
   _allocated_regions.clear();
   _allocation_region = NULL;
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -295,9 +295,9 @@
 
   virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
     assert(dest.is_valid(),
-           err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
+           "Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value());
     assert(_alloc_buffers[dest.value()] != NULL,
-           err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value()));
+           "Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value());
     return _alloc_buffers[dest.value()];
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,7 +36,7 @@
 HeapWord* G1Allocator::attempt_allocation_locked(size_t word_size, AllocationContext_t context) {
   HeapWord* result = mutator_alloc_region(context)->attempt_allocation_locked(word_size, false /* bot_updates */);
   assert(result != NULL || mutator_alloc_region(context)->get() == NULL,
-         err_msg("Must not have a mutator alloc region if there is no memory, but is " PTR_FORMAT, p2i(mutator_alloc_region(context)->get())));
+         "Must not have a mutator alloc region if there is no memory, but is " PTR_FORMAT, p2i(mutator_alloc_region(context)->get()));
   return result;
 }
 
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,19 +36,21 @@
 #ifndef PRODUCT
 void G1BiasedMappedArrayBase::verify_index(idx_t index) const {
   guarantee(_base != NULL, "Array not initialized");
-  guarantee(index < length(), err_msg("Index out of bounds index: " SIZE_FORMAT " length: " SIZE_FORMAT, index, length()));
+  guarantee(index < length(), "Index out of bounds index: " SIZE_FORMAT " length: " SIZE_FORMAT, index, length());
 }
 
 void G1BiasedMappedArrayBase::verify_biased_index(idx_t biased_index) const {
   guarantee(_biased_base != NULL, "Array not initialized");
   guarantee(biased_index >= bias() && biased_index < (bias() + length()),
-    err_msg("Biased index out of bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT, biased_index, bias(), length()));
+            "Biased index out of bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT,
+            biased_index, bias(), length());
 }
 
 void G1BiasedMappedArrayBase::verify_biased_index_inclusive_end(idx_t biased_index) const {
   guarantee(_biased_base != NULL, "Array not initialized");
   guarantee(biased_index >= bias() && biased_index <= (bias() + length()),
-    err_msg("Biased index out of inclusive bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT, biased_index, bias(), length()));
+            "Biased index out of inclusive bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT,
+            biased_index, bias(), length());
 }
 
 class TestMappedArray : public G1BiasedMappedArray<int> {
@@ -65,7 +67,7 @@
             REGION_SIZE_IN_WORDS * HeapWordSize);
     // Check address calculation (bounds)
     assert(array.bottom_address_mapped() == fake_heap,
-      err_msg("bottom mapped address should be " PTR_FORMAT ", but is " PTR_FORMAT, p2i(fake_heap), p2i(array.bottom_address_mapped())));
+           "bottom mapped address should be " PTR_FORMAT ", but is " PTR_FORMAT, p2i(fake_heap), p2i(array.bottom_address_mapped()));
     assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be");
 
     int* bottom = array.address_mapped_to(fake_heap);
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -56,7 +56,7 @@
   void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) {
     assert(base != NULL, "just checking");
     assert(length > 0, "just checking");
-    assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %u, larger than word size?", shift_by));
+    assert(shift_by < sizeof(uintptr_t) * 8, "Shifting by %u, larger than word size?", shift_by);
     _base = base;
     _length = length;
     _biased_base = base - (bias * elem_size);
@@ -69,13 +69,13 @@
   void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) {
     assert(mapping_granularity_in_bytes > 0, "just checking");
     assert(is_power_of_2(mapping_granularity_in_bytes),
-      err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes));
+           "mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes);
     assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0,
-      err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is  " PTR_FORMAT,
-        mapping_granularity_in_bytes, p2i(bottom)));
+           "bottom mapping area address must be a multiple of mapping granularity %zd, is  " PTR_FORMAT,
+           mapping_granularity_in_bytes, p2i(bottom));
     assert((uintptr_t)end % mapping_granularity_in_bytes == 0,
-      err_msg("end mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT,
-        mapping_granularity_in_bytes, p2i(end)));
+           "end mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT,
+           mapping_granularity_in_bytes, p2i(end));
     size_t num_target_elems = pointer_delta(end, bottom, mapping_granularity_in_bytes);
     idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes;
     address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes);
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -69,14 +69,14 @@
 #ifdef ASSERT
 void G1BlockOffsetSharedArray::check_index(size_t index, const char* msg) const {
   assert((index) < (_reserved.word_size() >> LogN_words),
-         err_msg("%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
-                 msg, (index), (_reserved.word_size() >> LogN_words)));
+         "%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
+         msg, (index), (_reserved.word_size() >> LogN_words));
   assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)),
-         err_msg("Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
-                 " (%u) is not in committed area.",
-                 (index),
-                 p2i(address_for_index_raw(index)),
-                 G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index))));
+         "Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
+         " (%u) is not in committed area.",
+         (index),
+         p2i(address_for_index_raw(index)),
+         G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index)));
 }
 #endif // ASSERT
 
@@ -192,27 +192,27 @@
     u_char entry = _array->offset_array(c);
     if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
       guarantee(entry > N_words,
-                err_msg("Should be in logarithmic region - "
-                        "entry: %u, "
-                        "_array->offset_array(c): %u, "
-                        "N_words: %u",
-                        (uint)entry, (uint)_array->offset_array(c), (uint)N_words));
+                "Should be in logarithmic region - "
+                "entry: %u, "
+                "_array->offset_array(c): %u, "
+                "N_words: %u",
+                (uint)entry, (uint)_array->offset_array(c), (uint)N_words);
     }
     size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
     size_t landing_card = c - backskip;
     guarantee(landing_card >= (start_card - 1), "Inv");
     if (landing_card >= start_card) {
       guarantee(_array->offset_array(landing_card) <= entry,
-                err_msg("Monotonicity - landing_card offset: %u, "
-                        "entry: %u",
-                        (uint)_array->offset_array(landing_card), (uint)entry));
+                "Monotonicity - landing_card offset: %u, "
+                "entry: %u",
+                (uint)_array->offset_array(landing_card), (uint)entry);
     } else {
       guarantee(landing_card == start_card - 1, "Tautology");
       // Note that N_words is the maximum offset value
       guarantee(_array->offset_array(landing_card) <= N_words,
-                err_msg("landing card offset: %u, "
-                        "N_words: %u",
-                        (uint)_array->offset_array(landing_card), (uint)N_words));
+                "landing card offset: %u, "
+                "N_words: %u",
+                (uint)_array->offset_array(landing_card), (uint)N_words);
     }
   }
 }
@@ -271,9 +271,9 @@
   HeapWord* next_boundary = _array->address_for_index(n_index) +
                             (n_index == next_index ? 0 : N_words);
   assert(next_boundary <= _array->_end,
-         err_msg("next_boundary is beyond the end of the covered region "
-                 " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
-                 p2i(next_boundary), p2i(_array->_end)));
+         "next_boundary is beyond the end of the covered region "
+         " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
+         p2i(next_boundary), p2i(_array->_end));
   if (addr >= gsp()->top()) return gsp()->top();
   while (next_boundary < addr) {
     while (n <= next_boundary) {
@@ -361,25 +361,23 @@
   // is checked by an assertion above.
   size_t start_index = _array->index_for(blk_start);
   HeapWord* boundary = _array->address_for_index(start_index);
-  assert((_array->offset_array(orig_index) == 0 &&
-          blk_start == boundary) ||
-          (_array->offset_array(orig_index) > 0 &&
-         _array->offset_array(orig_index) <= N_words),
-         err_msg("offset array should have been set - "
-                  "orig_index offset: %u, "
-                  "blk_start: " PTR_FORMAT ", "
-                  "boundary: " PTR_FORMAT,
-                  (uint)_array->offset_array(orig_index),
-                  p2i(blk_start), p2i(boundary)));
+  assert((_array->offset_array(orig_index) == 0 && blk_start == boundary) ||
+         (_array->offset_array(orig_index) > 0 && _array->offset_array(orig_index) <= N_words),
+         "offset array should have been set - "
+         "orig_index offset: %u, "
+         "blk_start: " PTR_FORMAT ", "
+         "boundary: " PTR_FORMAT,
+         (uint)_array->offset_array(orig_index),
+         p2i(blk_start), p2i(boundary));
   for (size_t j = orig_index + 1; j <= end_index; j++) {
     assert(_array->offset_array(j) > 0 &&
            _array->offset_array(j) <=
              (u_char) (N_words+BlockOffsetArray::N_powers-1),
-           err_msg("offset array should have been set - "
-                   "%u not > 0 OR %u not <= %u",
-                   (uint) _array->offset_array(j),
-                   (uint) _array->offset_array(j),
-                   (uint) (N_words+BlockOffsetArray::N_powers-1)));
+           "offset array should have been set - "
+           "%u not > 0 OR %u not <= %u",
+           (uint) _array->offset_array(j),
+           (uint) _array->offset_array(j),
+           (uint) (N_words+BlockOffsetArray::N_powers-1));
   }
 #endif
 }
@@ -402,8 +400,8 @@
         size_t obj_size = block_size(obj);
         obj_end = obj + obj_size;
         guarantee(obj_end > obj && obj_end <= gsp()->top(),
-            err_msg("Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT,
-                p2i(obj), obj_size, p2i(obj_end), p2i(gsp()->top())));
+                  "Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT,
+                  p2i(obj), obj_size, p2i(obj_end), p2i(gsp()->top()));
       }
     } else {
       // Because we refine the BOT based on which cards are dirty there is not much we can verify here.
@@ -414,13 +412,13 @@
 
       size_t max_backskip = current_card - start_card;
       guarantee(backskip <= max_backskip,
-          err_msg("Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
-              start_card, current_card, backskip));
+                "Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
+                start_card, current_card, backskip);
 
       HeapWord* backskip_address = _array->address_for_index(current_card - backskip);
       guarantee(backskip_address >= gsp()->bottom(),
-          err_msg("Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
-              p2i(gsp()->bottom()), p2i(backskip_address)));
+                "Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
+                p2i(gsp()->bottom()), p2i(backskip_address));
     }
   }
 }
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -80,8 +80,8 @@
 
   virtual void set_bottom(HeapWord* new_bottom) {
     assert(new_bottom <= _end,
-           err_msg("new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")",
-                   p2i(new_bottom), p2i(_end)));
+           "new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")",
+           p2i(new_bottom), p2i(_end));
     _bottom = new_bottom;
     resize(pointer_delta(_end, _bottom));
   }
@@ -149,9 +149,8 @@
 
   void check_offset(size_t offset, const char* msg) const {
     assert(offset <= N_words,
-           err_msg("%s - "
-                   "offset: " SIZE_FORMAT ", N_words: %u",
-                   msg, offset, (uint)N_words));
+           "%s - offset: " SIZE_FORMAT ", N_words: %u",
+           msg, offset, (uint)N_words);
   }
 
   // Bounds checking accessors:
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -81,8 +81,8 @@
   char* pc = (char*)p;
   assert(pc >= (char*)_reserved.start() &&
          pc <  (char*)_reserved.end(),
-         err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")",
-                 p2i(p), p2i(_reserved.start()), p2i(_reserved.end())));
+         "p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")",
+         p2i(p), p2i(_reserved.start()), p2i(_reserved.end()));
   size_t result = index_for_raw(p);
   check_index(result, "bad index from address");
   return result;
@@ -93,10 +93,9 @@
   check_index(index, "index out of range");
   HeapWord* result = address_for_index_raw(index);
   assert(result >= _reserved.start() && result < _reserved.end(),
-         err_msg("bad address from index result " PTR_FORMAT
-                 " _reserved.start() " PTR_FORMAT " _reserved.end() "
-                 PTR_FORMAT,
-                 p2i(result), p2i(_reserved.start()), p2i(_reserved.end())));
+         "bad address from index result " PTR_FORMAT
+         " _reserved.start() " PTR_FORMAT " _reserved.end() " PTR_FORMAT,
+         p2i(result), p2i(_reserved.start()), p2i(_reserved.end()));
   return result;
 }
 
--- a/hotspot/src/share/vm/gc/g1/g1CardCounts.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CardCounts.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -53,8 +53,8 @@
 void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
   if (has_count_table()) {
     assert(from_card_num < to_card_num,
-           err_msg("Wrong order? from: " SIZE_FORMAT ", to: " SIZE_FORMAT,
-                   from_card_num, to_card_num));
+           "Wrong order? from: " SIZE_FORMAT ", to: " SIZE_FORMAT,
+           from_card_num, to_card_num);
     Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num));
   }
 }
@@ -96,8 +96,8 @@
   if (has_count_table()) {
     size_t card_num = ptr_2_card_num(card_ptr);
     assert(card_num < _reserved_max_card_num,
-           err_msg("Card " SIZE_FORMAT " outside of card counts table (max size " SIZE_FORMAT ")",
-                   card_num, _reserved_max_card_num));
+           "Card " SIZE_FORMAT " outside of card counts table (max size " SIZE_FORMAT ")",
+           card_num, _reserved_max_card_num);
     count = (uint) _card_counts[card_num];
     if (count < G1ConcRSHotCardLimit) {
       _card_counts[card_num] =
--- a/hotspot/src/share/vm/gc/g1/g1CardCounts.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CardCounts.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -79,19 +79,19 @@
 
   size_t ptr_2_card_num(const jbyte* card_ptr) {
     assert(card_ptr >= _ct_bot,
-           err_msg("Invalid card pointer: "
-                   "card_ptr: " PTR_FORMAT ", "
-                   "_ct_bot: " PTR_FORMAT,
-                   p2i(card_ptr), p2i(_ct_bot)));
+           "Invalid card pointer: "
+           "card_ptr: " PTR_FORMAT ", "
+           "_ct_bot: " PTR_FORMAT,
+           p2i(card_ptr), p2i(_ct_bot));
     size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte));
     assert(card_num < _reserved_max_card_num,
-           err_msg("card pointer out of range: " PTR_FORMAT, p2i(card_ptr)));
+           "card pointer out of range: " PTR_FORMAT, p2i(card_ptr));
     return card_num;
   }
 
   jbyte* card_num_2_ptr(size_t card_num) {
     assert(card_num < _reserved_max_card_num,
-           err_msg("card num out of range: " SIZE_FORMAT, card_num));
+           "card num out of range: " SIZE_FORMAT, card_num);
     return (jbyte*) (_ct_bot + card_num);
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -197,7 +197,9 @@
 }
 
 void G1CodeRootSet::allocate_small_table() {
-  _table = new CodeRootSetTable(SmallSize);
+  CodeRootSetTable* temp = new CodeRootSetTable(SmallSize);
+
+  OrderAccess::release_store_ptr(&_table, temp);
 }
 
 void CodeRootSetTable::purge_list_append(CodeRootSetTable* table) {
@@ -350,11 +352,11 @@
       assert(set1.is_empty(), "Code root set must be initially empty but is not.");
 
       assert(G1CodeRootSet::static_mem_size() == sizeof(void*),
-          err_msg("The code root set's static memory usage is incorrect, " SIZE_FORMAT " bytes", G1CodeRootSet::static_mem_size()));
+             "The code root set's static memory usage is incorrect, " SIZE_FORMAT " bytes", G1CodeRootSet::static_mem_size());
 
       set1.add((nmethod*)1);
-      assert(set1.length() == 1, err_msg("Added exactly one element, but set contains "
-          SIZE_FORMAT " elements", set1.length()));
+      assert(set1.length() == 1, "Added exactly one element, but set contains "
+             SIZE_FORMAT " elements", set1.length());
 
       const size_t num_to_add = (size_t)G1CodeRootSet::Threshold + 1;
 
@@ -362,16 +364,16 @@
         set1.add((nmethod*)1);
       }
       assert(set1.length() == 1,
-          err_msg("Duplicate detection should not have increased the set size but "
-              "is " SIZE_FORMAT, set1.length()));
+             "Duplicate detection should not have increased the set size but "
+             "is " SIZE_FORMAT, set1.length());
 
       for (size_t i = 2; i <= num_to_add; i++) {
         set1.add((nmethod*)(uintptr_t)(i));
       }
       assert(set1.length() == num_to_add,
-          err_msg("After adding in total " SIZE_FORMAT " distinct code roots, they "
-              "need to be in the set, but there are only " SIZE_FORMAT,
-              num_to_add, set1.length()));
+             "After adding in total " SIZE_FORMAT " distinct code roots, they "
+             "need to be in the set, but there are only " SIZE_FORMAT,
+             num_to_add, set1.length());
 
       assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
 
@@ -385,8 +387,8 @@
         }
       }
       assert(num_popped == num_to_add,
-          err_msg("Managed to pop " SIZE_FORMAT " code roots, but only " SIZE_FORMAT " "
-              "were added", num_popped, num_to_add));
+             "Managed to pop " SIZE_FORMAT " code roots, but only " SIZE_FORMAT " "
+             "were added", num_popped, num_to_add);
       assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
 
       G1CodeRootSet::purge();
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -53,6 +53,7 @@
 #include "gc/g1/suspendibleThreadSet.hpp"
 #include "gc/g1/vm_operations_g1.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
@@ -971,11 +972,11 @@
     size_t commits = 0;
 
     guarantee(reserved.contains(start_address) && reserved.contains(last_address),
-              err_msg("MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]",
-              p2i(start_address), p2i(last_address)));
+              "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]",
+              p2i(start_address), p2i(last_address));
     guarantee(start_address > prev_last_addr,
-              err_msg("Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT ,
-              p2i(start_address), p2i(prev_last_addr)));
+              "Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT ,
+              p2i(start_address), p2i(prev_last_addr));
     prev_last_addr = last_address;
 
     // Check for ranges that start in the same G1 region in which the previous
@@ -1017,7 +1018,7 @@
 
     while (curr_region != NULL) {
       assert(curr_region->is_empty() && !curr_region->is_pinned(),
-             err_msg("Region already in use (index %u)", curr_region->hrm_index()));
+             "Region already in use (index %u)", curr_region->hrm_index());
       _hr_printer.alloc(curr_region, G1HRPrinter::Archive);
       curr_region->set_allocation_context(AllocationContext::system());
       curr_region->set_archive();
@@ -1055,11 +1056,11 @@
     HeapWord* last_address = ranges[i].last();
 
     assert(reserved.contains(start_address) && reserved.contains(last_address),
-           err_msg("MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]",
-                   p2i(start_address), p2i(last_address)));
+           "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]",
+           p2i(start_address), p2i(last_address));
     assert(start_address > prev_last_addr,
-           err_msg("Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT ,
-                   p2i(start_address), p2i(prev_last_addr)));
+           "Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT ,
+           p2i(start_address), p2i(prev_last_addr));
 
     HeapRegion* start_region = _hrm.addr_to_region(start_address);
     HeapRegion* last_region = _hrm.addr_to_region(last_address);
@@ -1076,7 +1077,7 @@
     HeapRegion* curr_region = start_region;
     while (curr_region != NULL) {
       guarantee(curr_region->is_archive(),
-                err_msg("Expected archive region at index %u", curr_region->hrm_index()));
+                "Expected archive region at index %u", curr_region->hrm_index());
       if (curr_region != last_region) {
         curr_region = _hrm.next_region_in_heap(curr_region);
       } else {
@@ -1139,11 +1140,11 @@
     HeapWord* last_address = ranges[i].last();
 
     assert(reserved.contains(start_address) && reserved.contains(last_address),
-           err_msg("MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]",
-                   p2i(start_address), p2i(last_address)));
+           "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]",
+           p2i(start_address), p2i(last_address));
     assert(start_address > prev_last_addr,
-           err_msg("Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT ,
-                   p2i(start_address), p2i(prev_last_addr)));
+           "Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT ,
+           p2i(start_address), p2i(prev_last_addr));
     size_used += ranges[i].byte_size();
     prev_last_addr = last_address;
 
@@ -1168,7 +1169,7 @@
     HeapRegion* curr_region = start_region;
     while (curr_region != NULL) {
       guarantee(curr_region->is_archive(),
-                err_msg("Expected archive region at index %u", curr_region->hrm_index()));
+                "Expected archive region at index %u", curr_region->hrm_index());
       uint curr_index = curr_region->hrm_index();
       _old_set.remove(curr_region);
       curr_region->set_free();
@@ -1450,6 +1451,7 @@
   gc_timer->register_gc_start();
 
   SerialOldTracer* gc_tracer = G1MarkSweep::gc_tracer();
+  GCIdMark gc_id_mark;
   gc_tracer->report_gc_start(gc_cause(), gc_timer->gc_start());
 
   SvcGCMarker sgcm(SvcGCMarker::FULL);
@@ -1476,7 +1478,7 @@
     TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
     {
-      GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL, gc_tracer->gc_id());
+      GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL);
       TraceCollectorStats tcs(g1mm()->full_collection_counters());
       TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
 
@@ -1507,7 +1509,9 @@
       check_bitmaps("Full GC Start");
       pre_full_gc_dump(gc_timer);
 
-      COMPILER2_PRESENT(DerivedPointerTable::clear());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+      DerivedPointerTable::clear();
+#endif
 
       // Disable discovery and empty the discovered lists
       // for the CM ref processor.
@@ -1567,7 +1571,9 @@
       // not been removed from the discovered lists.
       ref_processor_stw()->enqueue_discovered_references();
 
-      COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+      DerivedPointerTable::update_pointers();
+#endif
 
       MemoryService::track_memory_usage();
 
@@ -1755,9 +1761,9 @@
   // This assert only makes sense here, before we adjust them
   // with respect to the min and max heap size.
   assert(minimum_desired_capacity <= maximum_desired_capacity,
-         err_msg("minimum_desired_capacity = " SIZE_FORMAT ", "
-                 "maximum_desired_capacity = " SIZE_FORMAT,
-                 minimum_desired_capacity, maximum_desired_capacity));
+         "minimum_desired_capacity = " SIZE_FORMAT ", "
+         "maximum_desired_capacity = " SIZE_FORMAT,
+         minimum_desired_capacity, maximum_desired_capacity);
 
   // Should not be greater than the heap max size. No need to adjust
   // it with respect to the heap min size as it's a lower bound (i.e.,
@@ -1799,21 +1805,20 @@
   }
 }
 
-
-HeapWord*
-G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
-                                           AllocationContext_t context,
-                                           bool* succeeded) {
-  assert_at_safepoint(true /* should_be_vm_thread */);
-
-  *succeeded = true;
+HeapWord* G1CollectedHeap::satisfy_failed_allocation_helper(size_t word_size,
+                                                            AllocationContext_t context,
+                                                            bool do_gc,
+                                                            bool clear_all_soft_refs,
+                                                            bool expect_null_mutator_alloc_region,
+                                                            bool* gc_succeeded) {
+  *gc_succeeded = true;
   // Let's attempt the allocation first.
   HeapWord* result =
     attempt_allocation_at_safepoint(word_size,
                                     context,
-                                    false /* expect_null_mutator_alloc_region */);
+                                    expect_null_mutator_alloc_region);
   if (result != NULL) {
-    assert(*succeeded, "sanity");
+    assert(*gc_succeeded, "sanity");
     return result;
   }
 
@@ -1823,41 +1828,58 @@
   // do something smarter than full collection to satisfy a failed alloc.)
   result = expand_and_allocate(word_size, context);
   if (result != NULL) {
-    assert(*succeeded, "sanity");
+    assert(*gc_succeeded, "sanity");
     return result;
   }
 
-  // Expansion didn't work, we'll try to do a Full GC.
-  bool gc_succeeded = do_collection(false, /* explicit_gc */
-                                    false, /* clear_all_soft_refs */
-                                    word_size);
-  if (!gc_succeeded) {
-    *succeeded = false;
-    return NULL;
-  }
-
-  // Retry the allocation
-  result = attempt_allocation_at_safepoint(word_size,
-                                           context,
-                                           true /* expect_null_mutator_alloc_region */);
-  if (result != NULL) {
-    assert(*succeeded, "sanity");
+  if (do_gc) {
+    // Expansion didn't work, we'll try to do a Full GC.
+    *gc_succeeded = do_collection(false, /* explicit_gc */
+                                  clear_all_soft_refs,
+                                  word_size);
+  }
+
+  return NULL;
+}
+
+HeapWord* G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
+                                                     AllocationContext_t context,
+                                                     bool* succeeded) {
+  assert_at_safepoint(true /* should_be_vm_thread */);
+
+  // Attempts to allocate followed by Full GC.
+  HeapWord* result =
+    satisfy_failed_allocation_helper(word_size,
+                                     context,
+                                     true,  /* do_gc */
+                                     false, /* clear_all_soft_refs */
+                                     false, /* expect_null_mutator_alloc_region */
+                                     succeeded);
+
+  if (result != NULL || !*succeeded) {
     return result;
   }
 
-  // Then, try a Full GC that will collect all soft references.
-  gc_succeeded = do_collection(false, /* explicit_gc */
-                               true,  /* clear_all_soft_refs */
-                               word_size);
-  if (!gc_succeeded) {
-    *succeeded = false;
-    return NULL;
-  }
-
-  // Retry the allocation once more
-  result = attempt_allocation_at_safepoint(word_size,
-                                           context,
-                                           true /* expect_null_mutator_alloc_region */);
+  // Attempts to allocate followed by Full GC that will collect all soft references.
+  result = satisfy_failed_allocation_helper(word_size,
+                                            context,
+                                            true, /* do_gc */
+                                            true, /* clear_all_soft_refs */
+                                            true, /* expect_null_mutator_alloc_region */
+                                            succeeded);
+
+  if (result != NULL || !*succeeded) {
+    return result;
+  }
+
+  // Attempts to allocate, no GC
+  result = satisfy_failed_allocation_helper(word_size,
+                                            context,
+                                            false, /* do_gc */
+                                            false, /* clear_all_soft_refs */
+                                            true,  /* expect_null_mutator_alloc_region */
+                                            succeeded);
+
   if (result != NULL) {
     assert(*succeeded, "sanity");
     return result;
@@ -2538,9 +2560,9 @@
 
 void G1CollectedHeap::increment_old_marking_cycles_started() {
   assert(_old_marking_cycles_started == _old_marking_cycles_completed ||
-    _old_marking_cycles_started == _old_marking_cycles_completed + 1,
-    err_msg("Wrong marking cycle count (started: %d, completed: %d)",
-    _old_marking_cycles_started, _old_marking_cycles_completed));
+         _old_marking_cycles_started == _old_marking_cycles_completed + 1,
+         "Wrong marking cycle count (started: %d, completed: %d)",
+         _old_marking_cycles_started, _old_marking_cycles_completed);
 
   _old_marking_cycles_started++;
 }
@@ -2564,17 +2586,17 @@
   assert(concurrent ||
          (_old_marking_cycles_started == _old_marking_cycles_completed + 1) ||
          (_old_marking_cycles_started == _old_marking_cycles_completed + 2),
-         err_msg("for inner caller (Full GC): _old_marking_cycles_started = %u "
-                 "is inconsistent with _old_marking_cycles_completed = %u",
-                 _old_marking_cycles_started, _old_marking_cycles_completed));
+         "for inner caller (Full GC): _old_marking_cycles_started = %u "
+         "is inconsistent with _old_marking_cycles_completed = %u",
+         _old_marking_cycles_started, _old_marking_cycles_completed);
 
   // This is the case for the outer caller, i.e. the concurrent cycle.
   assert(!concurrent ||
          (_old_marking_cycles_started == _old_marking_cycles_completed + 1),
-         err_msg("for outer caller (concurrent cycle): "
-                 "_old_marking_cycles_started = %u "
-                 "is inconsistent with _old_marking_cycles_completed = %u",
-                 _old_marking_cycles_started, _old_marking_cycles_completed));
+         "for outer caller (concurrent cycle): "
+         "_old_marking_cycles_started = %u "
+         "is inconsistent with _old_marking_cycles_completed = %u",
+         _old_marking_cycles_started, _old_marking_cycles_completed);
 
   _old_marking_cycles_completed += 1;
 
@@ -2594,15 +2616,18 @@
 }
 
 void G1CollectedHeap::register_concurrent_cycle_start(const Ticks& start_time) {
+  GCIdMarkAndRestore conc_gc_id_mark;
   collector_state()->set_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);
+  _cmThread->set_gc_id(GCId::current());
 }
 
 void G1CollectedHeap::register_concurrent_cycle_end() {
   if (collector_state()->concurrent_cycle_started()) {
+    GCIdMarkAndRestore conc_gc_id_mark(_cmThread->gc_id());
     if (_cm->has_aborted()) {
       _gc_tracer_cm->report_concurrent_mode_failure();
     }
@@ -2625,6 +2650,7 @@
     //   but before the concurrent cycle end has been registered.
     // Make sure that we only send the heap information once.
     if (!_heap_summary_sent) {
+      GCIdMarkAndRestore conc_gc_id_mark(_cmThread->gc_id());
       trace_heap_after_gc(_gc_tracer_cm);
       _heap_summary_sent = true;
     }
@@ -3124,7 +3150,7 @@
     _young_ref_counter_closure.reset_count();
     k->oops_do(&_young_ref_counter_closure);
     if (_young_ref_counter_closure.count() > 0) {
-      guarantee(k->has_modified_oops(), err_msg("Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k)));
+      guarantee(k->has_modified_oops(), "Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k));
     }
   }
 };
@@ -3194,8 +3220,8 @@
   template <class T> void do_oop_work(T *p) {
     oop obj = oopDesc::load_decode_heap_oop(p);
     guarantee(obj == NULL || G1MarkSweep::in_archive_range(obj),
-              err_msg("Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT,
-                      p2i(p), p2i(obj)));
+              "Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT,
+              p2i(p), p2i(obj));
   }
 };
 
@@ -3630,8 +3656,9 @@
   // FIXME: what is this about?
   // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
   // is set.
-  COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(),
-                        "derived pointer present"));
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  assert(DerivedPointerTable::is_empty(), "derived pointer present");
+#endif
   // always_do_update_barrier = true;
 
   resize_all_tlabs();
@@ -3894,7 +3921,7 @@
     return;
   }
 
-  gclog_or_tty->gclog_stamp(_gc_tracer_stw->gc_id());
+  gclog_or_tty->gclog_stamp();
 
   GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause())
     .append(collector_state()->gcs_are_young() ? "(young)" : "(mixed)")
@@ -3952,6 +3979,7 @@
 
   _gc_timer_stw->register_gc_start();
 
+  GCIdMark gc_id_mark;
   _gc_tracer_stw->report_gc_start(gc_cause(), _gc_timer_stw->gc_start());
 
   SvcGCMarker sgcm(SvcGCMarker::MINOR);
@@ -4037,7 +4065,9 @@
 
       check_bitmaps("GC Start");
 
-      COMPILER2_PRESENT(DerivedPointerTable::clear());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+      DerivedPointerTable::clear();
+#endif
 
       // Please see comment in g1CollectedHeap.hpp and
       // G1CollectedHeap::ref_processing_init() to see how
@@ -4709,11 +4739,11 @@
 
   ~G1StringSymbolTableUnlinkTask() {
     guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size,
-              err_msg("claim value %d after unlink less than initial string table size %d",
-                      StringTable::parallel_claimed_index(), _initial_string_table_size));
+              "claim value %d after unlink less than initial string table size %d",
+              StringTable::parallel_claimed_index(), _initial_string_table_size);
     guarantee(!_process_symbols || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
-              err_msg("claim value %d after unlink less than initial symbol table size %d",
-                      SymbolTable::parallel_claimed_index(), _initial_symbol_table_size));
+              "claim value %d after unlink less than initial symbol table size %d",
+              SymbolTable::parallel_claimed_index(), _initial_symbol_table_size);
 
     if (G1TraceStringSymbolTableScrubbing) {
       gclog_or_tty->print_cr("Cleaned string and symbol table, "
@@ -5113,7 +5143,7 @@
     } else {
       assert(!obj->is_forwarded(), "invariant" );
       assert(cset_state.is_humongous(),
-             err_msg("Only allowed InCSet state is IsHumongous, but is %d", cset_state.value()));
+             "Only allowed InCSet state is IsHumongous, but is %d", cset_state.value());
       _g1->set_humongous_is_live(obj);
     }
   }
@@ -5167,7 +5197,7 @@
         _par_scan_state->push_on_queue(p);
       } else {
         assert(!Metaspace::contains((const void*)p),
-               err_msg("Unexpectedly found a pointer from metadata: " PTR_FORMAT, p2i(p)));
+               "Unexpectedly found a pointer from metadata: " PTR_FORMAT, p2i(p));
         _copy_non_heap_obj_cl->do_oop(p);
       }
     }
@@ -5501,8 +5531,7 @@
                                               &keep_alive,
                                               &drain_queue,
                                               NULL,
-                                              _gc_timer_stw,
-                                              _gc_tracer_stw->gc_id());
+                                              _gc_timer_stw);
   } else {
     // Parallel reference processing
     assert(rp->num_q() == no_of_gc_workers, "sanity");
@@ -5513,8 +5542,7 @@
                                               &keep_alive,
                                               &drain_queue,
                                               &par_task_executor,
-                                              _gc_timer_stw,
-                                              _gc_tracer_stw->gc_id());
+                                              _gc_timer_stw);
   }
 
   _gc_tracer_stw->report_gc_reference_stats(stats);
@@ -5666,7 +5694,9 @@
   enqueue_discovered_references(per_thread_states);
 
   redirty_logged_cards();
-  COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  DerivedPointerTable::update_pointers();
+#endif
 }
 
 void G1CollectedHeap::record_obj_copy_mem_stats() {
@@ -5823,7 +5853,7 @@
 bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
                                                HeapWord* tams, HeapWord* end) {
   guarantee(tams <= end,
-            err_msg("tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end)));
+            "tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end));
   HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
   if (result < end) {
     gclog_or_tty->cr();
@@ -6174,9 +6204,8 @@
     }
 
     guarantee(obj->is_typeArray(),
-              err_msg("Only eagerly reclaiming type arrays is supported, but the object "
-                      PTR_FORMAT " is not.",
-                      p2i(r->bottom())));
+              "Only eagerly reclaiming type arrays is supported, but the object "
+              PTR_FORMAT " is not.", p2i(r->bottom()));
 
     if (G1TraceEagerReclaimHumongousObjects) {
       gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
@@ -6405,8 +6434,8 @@
 
 void G1CollectedHeap::decrease_used(size_t bytes) {
   assert(_summary_bytes_used >= bytes,
-         err_msg("invariant: _summary_bytes_used: " SIZE_FORMAT " should be >= bytes: " SIZE_FORMAT,
-                 _summary_bytes_used, bytes));
+         "invariant: _summary_bytes_used: " SIZE_FORMAT " should be >= bytes: " SIZE_FORMAT,
+         _summary_bytes_used, bytes);
   _summary_bytes_used -= bytes;
 }
 
@@ -6488,9 +6517,9 @@
     }
   }
   assert(used_unlocked() == recalculate_used(),
-         err_msg("inconsistent used_unlocked(), "
-                 "value: " SIZE_FORMAT " recalculated: " SIZE_FORMAT,
-                 used_unlocked(), recalculate_used()));
+         "inconsistent used_unlocked(), "
+         "value: " SIZE_FORMAT " recalculated: " SIZE_FORMAT,
+         used_unlocked(), recalculate_used());
 }
 
 void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) {
@@ -6631,35 +6660,35 @@
     if (hr->is_young()) {
       // TODO
     } else if (hr->is_starts_humongous()) {
-      assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrm_index()));
+      assert(hr->containing_set() == _humongous_set, "Heap region %u is starts humongous but not in humongous set.", hr->hrm_index());
       _humongous_count.increment(1u, hr->capacity());
     } else if (hr->is_empty()) {
-      assert(_hrm->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrm_index()));
+      assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index());
       _free_count.increment(1u, hr->capacity());
     } else if (hr->is_old()) {
-      assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrm_index()));
+      assert(hr->containing_set() == _old_set, "Heap region %u is old but not in the old set.", hr->hrm_index());
       _old_count.increment(1u, hr->capacity());
     } else {
       // There are no other valid region types. Check for one invalid
       // one we can identify: pinned without old or humongous set.
-      assert(!hr->is_pinned(), err_msg("Heap region %u is pinned but not old (archive) or humongous.", hr->hrm_index()));
+      assert(!hr->is_pinned(), "Heap region %u is pinned but not old (archive) or humongous.", hr->hrm_index());
       ShouldNotReachHere();
     }
     return false;
   }
 
   void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
-    guarantee(old_set->length() == _old_count.length(), err_msg("Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length()));
-    guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), err_msg("Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-        old_set->total_capacity_bytes(), _old_count.capacity()));
-
-    guarantee(humongous_set->length() == _humongous_count.length(), err_msg("Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count.length()));
-    guarantee(humongous_set->total_capacity_bytes() == _humongous_count.capacity(), err_msg("Hum set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-        humongous_set->total_capacity_bytes(), _humongous_count.capacity()));
-
-    guarantee(free_list->num_free_regions() == _free_count.length(), err_msg("Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count.length()));
-    guarantee(free_list->total_capacity_bytes() == _free_count.capacity(), err_msg("Free list capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-        free_list->total_capacity_bytes(), _free_count.capacity()));
+    guarantee(old_set->length() == _old_count.length(), "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length());
+    guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), "Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+              old_set->total_capacity_bytes(), _old_count.capacity());
+
+    guarantee(humongous_set->length() == _humongous_count.length(), "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count.length());
+    guarantee(humongous_set->total_capacity_bytes() == _humongous_count.capacity(), "Hum set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+              humongous_set->total_capacity_bytes(), _humongous_count.capacity());
+
+    guarantee(free_list->num_free_regions() == _free_count.length(), "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count.length());
+    guarantee(free_list->total_capacity_bytes() == _free_count.capacity(), "Free list capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+              free_list->total_capacity_bytes(), _free_count.capacity());
   }
 };
 
@@ -6715,9 +6744,9 @@
       oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
       HeapRegion* hr = _g1h->heap_region_containing(obj);
       assert(!hr->is_continues_humongous(),
-             err_msg("trying to add code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
-                     " starting at " HR_FORMAT,
-                     p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+             "trying to add code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
+             " starting at " HR_FORMAT,
+             p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()));
 
       // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries.
       hr->add_strong_code_root_locked(_nm);
@@ -6742,9 +6771,9 @@
       oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
       HeapRegion* hr = _g1h->heap_region_containing(obj);
       assert(!hr->is_continues_humongous(),
-             err_msg("trying to remove code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
-                     " starting at " HR_FORMAT,
-                     p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+             "trying to remove code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
+             " starting at " HR_FORMAT,
+             p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()));
 
       hr->remove_strong_code_root(_nm);
     }
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -368,17 +368,17 @@
   // These are macros so that, if the assert fires, we get the correct
   // line number, file, etc.
 
-#define heap_locking_asserts_err_msg(_extra_message_)                         \
-  err_msg("%s : Heap_lock locked: %s, at safepoint: %s, is VM thread: %s",    \
-          (_extra_message_),                                                  \
-          BOOL_TO_STR(Heap_lock->owned_by_self()),                            \
-          BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()),               \
-          BOOL_TO_STR(Thread::current()->is_VM_thread()))
+#define heap_locking_asserts_params(_extra_message_)                          \
+  "%s : Heap_lock locked: %s, at safepoint: %s, is VM thread: %s",            \
+  (_extra_message_),                                                          \
+  BOOL_TO_STR(Heap_lock->owned_by_self()),                                    \
+  BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()),                       \
+  BOOL_TO_STR(Thread::current()->is_VM_thread())
 
 #define assert_heap_locked()                                                  \
   do {                                                                        \
     assert(Heap_lock->owned_by_self(),                                        \
-           heap_locking_asserts_err_msg("should be holding the Heap_lock"));  \
+           heap_locking_asserts_params("should be holding the Heap_lock"));   \
   } while (0)
 
 #define assert_heap_locked_or_at_safepoint(_should_be_vm_thread_)             \
@@ -386,7 +386,7 @@
     assert(Heap_lock->owned_by_self() ||                                      \
            (SafepointSynchronize::is_at_safepoint() &&                        \
              ((_should_be_vm_thread_) == Thread::current()->is_VM_thread())), \
-           heap_locking_asserts_err_msg("should be holding the Heap_lock or " \
+           heap_locking_asserts_params("should be holding the Heap_lock or "  \
                                         "should be at a safepoint"));         \
   } while (0)
 
@@ -394,21 +394,21 @@
   do {                                                                        \
     assert(Heap_lock->owned_by_self() &&                                      \
                                     !SafepointSynchronize::is_at_safepoint(), \
-          heap_locking_asserts_err_msg("should be holding the Heap_lock and " \
+          heap_locking_asserts_params("should be holding the Heap_lock and "  \
                                        "should not be at a safepoint"));      \
   } while (0)
 
 #define assert_heap_not_locked()                                              \
   do {                                                                        \
     assert(!Heap_lock->owned_by_self(),                                       \
-        heap_locking_asserts_err_msg("should not be holding the Heap_lock")); \
+        heap_locking_asserts_params("should not be holding the Heap_lock"));  \
   } while (0)
 
 #define assert_heap_not_locked_and_not_at_safepoint()                         \
   do {                                                                        \
     assert(!Heap_lock->owned_by_self() &&                                     \
                                     !SafepointSynchronize::is_at_safepoint(), \
-      heap_locking_asserts_err_msg("should not be holding the Heap_lock and " \
+      heap_locking_asserts_params("should not be holding the Heap_lock and "  \
                                    "should not be at a safepoint"));          \
   } while (0)
 
@@ -416,13 +416,13 @@
   do {                                                                        \
     assert(SafepointSynchronize::is_at_safepoint() &&                         \
               ((_should_be_vm_thread_) == Thread::current()->is_VM_thread()), \
-           heap_locking_asserts_err_msg("should be at a safepoint"));         \
+           heap_locking_asserts_params("should be at a safepoint"));          \
   } while (0)
 
 #define assert_not_at_safepoint()                                             \
   do {                                                                        \
     assert(!SafepointSynchronize::is_at_safepoint(),                          \
-           heap_locking_asserts_err_msg("should not be at a safepoint"));     \
+           heap_locking_asserts_params("should not be at a safepoint"));      \
   } while (0)
 
 protected:
@@ -571,7 +571,16 @@
   HeapWord* satisfy_failed_allocation(size_t word_size,
                                       AllocationContext_t context,
                                       bool* succeeded);
+private:
+  // Helper method for satisfy_failed_allocation()
+  HeapWord* satisfy_failed_allocation_helper(size_t word_size,
+                                             AllocationContext_t context,
+                                             bool do_gc,
+                                             bool clear_all_soft_refs,
+                                             bool expect_null_mutator_alloc_region,
+                                             bool* gc_succeeded);
 
+protected:
   // Attempting to expand the heap sufficiently
   // to support an allocation of the given "word_size".  If
   // successful, perform the allocation and return the address of the
@@ -1045,6 +1054,7 @@
     return CollectedHeap::G1CollectedHeap;
   }
 
+  const G1CollectorState* collector_state() const { return &_collector_state; }
   G1CollectorState* collector_state() { return &_collector_state; }
 
   // The current policy object for the collector.
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -67,8 +67,8 @@
 
 inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const {
   assert(is_in_reserved(addr),
-         err_msg("Cannot calculate region index for address " PTR_FORMAT " that is outside of the heap [" PTR_FORMAT ", " PTR_FORMAT ")",
-                 p2i(addr), p2i(reserved_region().start()), p2i(reserved_region().end())));
+         "Cannot calculate region index for address " PTR_FORMAT " that is outside of the heap [" PTR_FORMAT ", " PTR_FORMAT ")",
+         p2i(addr), p2i(reserved_region().start()), p2i(reserved_region().end()));
   return (uint)(pointer_delta(addr, reserved_region().start(), sizeof(uint8_t)) >> HeapRegion::LogOfHRGrainBytes);
 }
 
@@ -80,8 +80,8 @@
 inline HeapRegion* G1CollectedHeap::heap_region_containing_raw(const T addr) const {
   assert(addr != NULL, "invariant");
   assert(is_in_g1_reserved((const void*) addr),
-      err_msg("Address " PTR_FORMAT " is outside of the heap ranging from [" PTR_FORMAT " to " PTR_FORMAT ")",
-          p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end())));
+         "Address " PTR_FORMAT " is outside of the heap ranging from [" PTR_FORMAT " to " PTR_FORMAT ")",
+         p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end()));
   return _hrm.addr_to_region((HeapWord*) addr);
 }
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -112,6 +112,8 @@
                                 new TruncatedSeq(NumPrevPausesForHeuristics)),
 
   _recent_avg_pause_time_ratio(0.0),
+  _rs_lengths_prediction(0),
+  _max_survivor_regions(0),
 
   _eden_used_bytes_before_gc(0),
   _survivor_used_bytes_before_gc(0),
@@ -264,9 +266,6 @@
   _concurrent_mark_remark_times_ms->add(0.05);
   _concurrent_mark_cleanup_times_ms->add(0.20);
   _tenuring_threshold = MaxTenuringThreshold;
-  // _max_survivor_regions will be calculated by
-  // update_young_list_target_length() during initialization.
-  _max_survivor_regions = 0;
 
   assert(GCTimeRatio > 0,
          "we should have set it to a default value set_g1_gc_flags() "
@@ -315,6 +314,7 @@
   }
 }
 
+const G1CollectorState* G1CollectorPolicy::collector_state() const { return _g1->collector_state(); }
 G1CollectorState* G1CollectorPolicy::collector_state() { return _g1->collector_state(); }
 
 G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true),
@@ -441,7 +441,7 @@
 bool G1CollectorPolicy::predict_will_fit(uint young_length,
                                          double base_time_ms,
                                          uint base_free_regions,
-                                         double target_pause_time_ms) {
+                                         double target_pause_time_ms) const {
   if (young_length >= base_free_regions) {
     // end condition 1: not enough space for the young regions
     return false;
@@ -480,7 +480,7 @@
 }
 
 uint G1CollectorPolicy::calculate_young_list_desired_min_length(
-                                                       uint base_min_length) {
+                                                       uint base_min_length) const {
   uint desired_min_length = 0;
   if (adaptive_young_list_length()) {
     if (_alloc_rate_ms_seq->num() > 3) {
@@ -497,7 +497,7 @@
   return MAX2(_young_gen_sizer->min_desired_young_length(), desired_min_length);
 }
 
-uint G1CollectorPolicy::calculate_young_list_desired_max_length() {
+uint G1CollectorPolicy::calculate_young_list_desired_max_length() const {
   // Here, we might want to also take into account any additional
   // constraints (i.e., user-defined minimum bound). Currently, we
   // effectively don't set this bound.
@@ -575,7 +575,7 @@
 G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths,
                                                      uint base_min_length,
                                                      uint desired_min_length,
-                                                     uint desired_max_length) {
+                                                     uint desired_max_length) const {
   assert(adaptive_young_list_length(), "pre-condition");
   assert(collector_state()->gcs_are_young(), "only call this for young GCs");
 
@@ -675,7 +675,7 @@
   return base_min_length + min_young_length;
 }
 
-double G1CollectorPolicy::predict_survivor_regions_evac_time() {
+double G1CollectorPolicy::predict_survivor_regions_evac_time() const {
   double survivor_regions_evac_time = 0.0;
   for (HeapRegion * r = _recorded_survivor_head;
        r != NULL && r != _recorded_survivor_tail->get_next_young_region();
@@ -813,8 +813,8 @@
   update_survivors_policy();
 
   assert(_g1->used() == _g1->recalculate_used(),
-         err_msg("sanity, used: " SIZE_FORMAT " recalculate_used: " SIZE_FORMAT,
-                 _g1->used(), _g1->recalculate_used()));
+         "sanity, used: " SIZE_FORMAT " recalculate_used: " SIZE_FORMAT,
+         _g1->used(), _g1->recalculate_used());
 
   double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
   _trace_young_gen_time_data.record_start_collection(s_w_t_ms);
@@ -857,7 +857,7 @@
   _cur_mark_stop_world_time_ms += elapsed_time_ms;
   _prev_collection_pause_end_ms += elapsed_time_ms;
 
-  _mmu_tracker->add_pause(_mark_remark_start_sec, end_time_sec, _g1->gc_tracer_cm()->gc_id());
+  _mmu_tracker->add_pause(_mark_remark_start_sec, end_time_sec);
 }
 
 void G1CollectorPolicy::record_concurrent_mark_cleanup_start() {
@@ -952,8 +952,7 @@
     collector_state()->set_initiate_conc_mark_if_possible(true);
   }
 
-  _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
-                          end_time_sec, _g1->gc_tracer_stw()->gc_id());
+  _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0, end_time_sec);
 
   if (update_stats) {
     _trace_young_gen_time_data.record_end_collection(pause_time_ms, phase_times());
@@ -1174,7 +1173,7 @@
   }
 }
 
-void G1CollectorPolicy::print_heap_transition(size_t bytes_before) {
+void G1CollectorPolicy::print_heap_transition(size_t bytes_before) const {
   size_t bytes_after = _g1->used();
   size_t capacity = _g1->capacity();
 
@@ -1187,11 +1186,11 @@
       proper_unit_for_byte_size(capacity));
 }
 
-void G1CollectorPolicy::print_heap_transition() {
+void G1CollectorPolicy::print_heap_transition() const {
   print_heap_transition(_heap_used_bytes_before_gc);
 }
 
-void G1CollectorPolicy::print_detailed_heap_transition(bool full) {
+void G1CollectorPolicy::print_detailed_heap_transition(bool full) const {
   YoungList* young_list = _g1->young_list();
 
   size_t eden_used_bytes_after_gc = young_list->eden_used_bytes();
@@ -1268,7 +1267,7 @@
 
 double
 G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
-                                                size_t scanned_cards) {
+                                                size_t scanned_cards) const {
   return
     predict_rs_update_time_ms(pending_cards) +
     predict_rs_scan_time_ms(scanned_cards) +
@@ -1276,7 +1275,7 @@
 }
 
 double
-G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards) {
+G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards) const {
   size_t rs_length = predict_rs_length_diff();
   size_t card_num;
   if (collector_state()->gcs_are_young()) {
@@ -1287,7 +1286,7 @@
   return predict_base_elapsed_time_ms(pending_cards, card_num);
 }
 
-size_t G1CollectorPolicy::predict_bytes_to_copy(HeapRegion* hr) {
+size_t G1CollectorPolicy::predict_bytes_to_copy(HeapRegion* hr) const {
   size_t bytes_to_copy;
   if (hr->is_marked())
     bytes_to_copy = hr->max_live_bytes();
@@ -1302,7 +1301,7 @@
 
 double
 G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
-                                                  bool for_young_gc) {
+                                                  bool for_young_gc) const {
   size_t rs_length = hr->rem_set()->occupied();
   size_t card_num;
 
@@ -1348,7 +1347,7 @@
   _prev_collection_pause_end_ms = end_time_sec * 1000.0;
 }
 
-size_t G1CollectorPolicy::expansion_amount() {
+size_t G1CollectorPolicy::expansion_amount() const {
   double recent_gc_overhead = recent_avg_pause_time_ratio() * 100.0;
   double threshold = _gc_overhead_perc;
   if (recent_gc_overhead > threshold) {
@@ -1397,13 +1396,13 @@
 #endif // PRODUCT
 }
 
-bool G1CollectorPolicy::is_young_list_full() {
+bool G1CollectorPolicy::is_young_list_full() const {
   uint young_list_length = _g1->young_list()->length();
   uint young_list_target_length = _young_list_target_length;
   return young_list_length >= young_list_target_length;
 }
 
-bool G1CollectorPolicy::can_expand_young_list() {
+bool G1CollectorPolicy::can_expand_young_list() const {
   uint young_list_length = _g1->young_list()->length();
   uint young_list_max_length = _young_list_max_length;
   return young_list_length < young_list_max_length;
@@ -1557,7 +1556,7 @@
   }
 };
 
-uint G1CollectorPolicy::calculate_parallel_work_chunk_size(uint n_workers, uint n_regions) {
+uint G1CollectorPolicy::calculate_parallel_work_chunk_size(uint n_workers, uint n_regions) const {
   assert(n_workers > 0, "Active gc workers should be greater than 0");
   const uint overpartition_factor = 4;
   const uint min_chunk_size = MAX2(n_regions / n_workers, 1U);
@@ -1584,7 +1583,7 @@
   _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
   _cur_mark_stop_world_time_ms += elapsed_time_ms;
   _prev_collection_pause_end_ms += elapsed_time_ms;
-  _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, _g1->gc_tracer_cm()->gc_id());
+  _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec);
 }
 
 // Add the heap region at the head of the non-incremental collection set
@@ -1783,7 +1782,7 @@
 }
 #endif // !PRODUCT
 
-double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) {
+double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) const {
   // Returns the given amount of reclaimable bytes (that represents
   // the amount of reclaimable space still to be collected) as a
   // percentage of the current heap capacity.
@@ -1792,7 +1791,7 @@
 }
 
 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
-                                                const char* false_action_str) {
+                                                const char* false_action_str) const {
   CollectionSetChooser* cset_chooser = _collectionSetChooser;
   if (cset_chooser->is_empty()) {
     ergo_verbose0(ErgoMixedGCs,
@@ -1830,7 +1829,7 @@
   return true;
 }
 
-uint G1CollectorPolicy::calc_min_old_cset_length() {
+uint G1CollectorPolicy::calc_min_old_cset_length() const {
   // The min old CSet region bound is based on the maximum desired
   // number of mixed GCs after a cycle. I.e., even if some old regions
   // look expensive, we should add them to the CSet anyway to make
@@ -1851,13 +1850,13 @@
   return (uint) result;
 }
 
-uint G1CollectorPolicy::calc_max_old_cset_length() {
+uint G1CollectorPolicy::calc_max_old_cset_length() const {
   // The max old CSet region bound is based on the threshold expressed
   // as a percentage of the heap size. I.e., it should bound the
   // number of old regions added to the CSet irrespective of how many
   // of them are available.
 
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  const G1CollectedHeap* g1h = G1CollectedHeap::heap();
   const size_t region_num = g1h->num_regions();
   const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
   size_t result = region_num * perc / 100;
@@ -1876,8 +1875,7 @@
   finalize_incremental_cset_building();
 
   guarantee(target_pause_time_ms > 0.0,
-            err_msg("target_pause_time_ms = %1.6lf should be positive",
-                    target_pause_time_ms));
+            "target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
   guarantee(_collection_set == NULL, "Precondition");
 
   double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -155,7 +155,7 @@
   uint max_desired_young_length() {
     return _max_desired_young_length;
   }
-  bool adaptive_young_list_length() {
+  bool adaptive_young_list_length() const {
     return _adaptive_size;
   }
 };
@@ -242,9 +242,9 @@
   void init_cset_region_lengths(uint eden_cset_region_length,
                                 uint survivor_cset_region_length);
 
-  uint eden_cset_region_length()     { return _eden_cset_region_length;     }
-  uint survivor_cset_region_length() { return _survivor_cset_region_length; }
-  uint old_cset_region_length()      { return _old_cset_region_length;      }
+  uint eden_cset_region_length() const     { return _eden_cset_region_length;     }
+  uint survivor_cset_region_length() const { return _survivor_cset_region_length; }
+  uint old_cset_region_length() const      { return _old_cset_region_length;      }
 
   uint _free_regions_at_end_of_collection;
 
@@ -254,13 +254,13 @@
 
   size_t _rs_lengths_prediction;
 
-  double sigma() { return _sigma; }
+  double sigma() const { return _sigma; }
 
   // A function that prevents us putting too much stock in small sample
   // sets.  Returns a number between 2.0 and 1.0, depending on the number
   // of samples.  5 or more samples yields one; fewer scales linearly from
   // 2.0 at 1 sample to 1.0 at 5.
-  double confidence_factor(int samples) {
+  double confidence_factor(int samples) const {
     if (samples > 4) return 1.0;
     else return  1.0 + sigma() * ((double)(5 - samples))/2.0;
   }
@@ -303,7 +303,7 @@
   bool verify_young_ages();
 #endif // PRODUCT
 
-  double get_new_prediction(TruncatedSeq* seq) {
+  double get_new_prediction(TruncatedSeq* seq) const {
     return MAX2(seq->davg() + sigma() * seq->dsd(),
                 seq->davg() * confidence_factor(seq->num()));
   }
@@ -312,27 +312,27 @@
     _max_rs_lengths = rs_lengths;
   }
 
-  size_t predict_rs_length_diff() {
+  size_t predict_rs_length_diff() const {
     return (size_t) get_new_prediction(_rs_length_diff_seq);
   }
 
-  double predict_alloc_rate_ms() {
+  double predict_alloc_rate_ms() const {
     return get_new_prediction(_alloc_rate_ms_seq);
   }
 
-  double predict_cost_per_card_ms() {
+  double predict_cost_per_card_ms() const {
     return get_new_prediction(_cost_per_card_ms_seq);
   }
 
-  double predict_rs_update_time_ms(size_t pending_cards) {
+  double predict_rs_update_time_ms(size_t pending_cards) const {
     return (double) pending_cards * predict_cost_per_card_ms();
   }
 
-  double predict_young_cards_per_entry_ratio() {
+  double predict_young_cards_per_entry_ratio() const {
     return get_new_prediction(_young_cards_per_entry_ratio_seq);
   }
 
-  double predict_mixed_cards_per_entry_ratio() {
+  double predict_mixed_cards_per_entry_ratio() const {
     if (_mixed_cards_per_entry_ratio_seq->num() < 2) {
       return predict_young_cards_per_entry_ratio();
     } else {
@@ -340,17 +340,17 @@
     }
   }
 
-  size_t predict_young_card_num(size_t rs_length) {
+  size_t predict_young_card_num(size_t rs_length) const {
     return (size_t) ((double) rs_length *
                      predict_young_cards_per_entry_ratio());
   }
 
-  size_t predict_non_young_card_num(size_t rs_length) {
+  size_t predict_non_young_card_num(size_t rs_length) const {
     return (size_t) ((double) rs_length *
                      predict_mixed_cards_per_entry_ratio());
   }
 
-  double predict_rs_scan_time_ms(size_t card_num) {
+  double predict_rs_scan_time_ms(size_t card_num) const {
     if (collector_state()->gcs_are_young()) {
       return (double) card_num * get_new_prediction(_cost_per_entry_ms_seq);
     } else {
@@ -358,7 +358,7 @@
     }
   }
 
-  double predict_mixed_rs_scan_time_ms(size_t card_num) {
+  double predict_mixed_rs_scan_time_ms(size_t card_num) const {
     if (_mixed_cost_per_entry_ms_seq->num() < 3) {
       return (double) card_num * get_new_prediction(_cost_per_entry_ms_seq);
     } else {
@@ -367,7 +367,7 @@
     }
   }
 
-  double predict_object_copy_time_ms_during_cm(size_t bytes_to_copy) {
+  double predict_object_copy_time_ms_during_cm(size_t bytes_to_copy) const {
     if (_cost_per_byte_ms_during_cm_seq->num() < 3) {
       return (1.1 * (double) bytes_to_copy) *
               get_new_prediction(_cost_per_byte_ms_seq);
@@ -377,7 +377,7 @@
     }
   }
 
-  double predict_object_copy_time_ms(size_t bytes_to_copy) {
+  double predict_object_copy_time_ms(size_t bytes_to_copy) const {
     if (collector_state()->during_concurrent_mark()) {
       return predict_object_copy_time_ms_during_cm(bytes_to_copy);
     } else {
@@ -386,34 +386,34 @@
     }
   }
 
-  double predict_constant_other_time_ms() {
+  double predict_constant_other_time_ms() const {
     return get_new_prediction(_constant_other_time_ms_seq);
   }
 
-  double predict_young_other_time_ms(size_t young_num) {
+  double predict_young_other_time_ms(size_t young_num) const {
     return (double) young_num *
            get_new_prediction(_young_other_cost_per_region_ms_seq);
   }
 
-  double predict_non_young_other_time_ms(size_t non_young_num) {
+  double predict_non_young_other_time_ms(size_t non_young_num) const {
     return (double) non_young_num *
            get_new_prediction(_non_young_other_cost_per_region_ms_seq);
   }
 
-  double predict_base_elapsed_time_ms(size_t pending_cards);
+  double predict_base_elapsed_time_ms(size_t pending_cards) const;
   double predict_base_elapsed_time_ms(size_t pending_cards,
-                                      size_t scanned_cards);
-  size_t predict_bytes_to_copy(HeapRegion* hr);
-  double predict_region_elapsed_time_ms(HeapRegion* hr, bool for_young_gc);
+                                      size_t scanned_cards) const;
+  size_t predict_bytes_to_copy(HeapRegion* hr) const;
+  double predict_region_elapsed_time_ms(HeapRegion* hr, bool for_young_gc) const;
 
   void set_recorded_rs_lengths(size_t rs_lengths);
 
-  uint cset_region_length()       { return young_cset_region_length() +
+  uint cset_region_length() const       { return young_cset_region_length() +
                                            old_cset_region_length(); }
-  uint young_cset_region_length() { return eden_cset_region_length() +
+  uint young_cset_region_length() const { return eden_cset_region_length() +
                                            survivor_cset_region_length(); }
 
-  double predict_survivor_regions_evac_time();
+  double predict_survivor_regions_evac_time() const;
 
   void cset_regions_freed() {
     bool propagate = collector_state()->should_propagate();
@@ -426,21 +426,25 @@
     return _mmu_tracker;
   }
 
-  double max_pause_time_ms() {
+  const G1MMUTracker* mmu_tracker() const {
+    return _mmu_tracker;
+  }
+
+  double max_pause_time_ms() const {
     return _mmu_tracker->max_gc_time() * 1000.0;
   }
 
-  double predict_remark_time_ms() {
+  double predict_remark_time_ms() const {
     return get_new_prediction(_concurrent_mark_remark_times_ms);
   }
 
-  double predict_cleanup_time_ms() {
+  double predict_cleanup_time_ms() const {
     return get_new_prediction(_concurrent_mark_cleanup_times_ms);
   }
 
   // Returns an estimate of the survival rate of the region at yg-age
   // "yg_age".
-  double predict_yg_surv_rate(int age, SurvRateGroup* surv_rate_group) {
+  double predict_yg_surv_rate(int age, SurvRateGroup* surv_rate_group) const {
     TruncatedSeq* seq = surv_rate_group->get_seq(age);
     if (seq->num() == 0)
       gclog_or_tty->print("BARF! age is %d", age);
@@ -451,11 +455,11 @@
     return pred;
   }
 
-  double predict_yg_surv_rate(int age) {
+  double predict_yg_surv_rate(int age) const {
     return predict_yg_surv_rate(age, _short_lived_surv_rate_group);
   }
 
-  double accum_yg_surv_rate_pred(int age) {
+  double accum_yg_surv_rate_pred(int age) const {
     return _short_lived_surv_rate_group->accum_surv_rate_pred(age);
   }
 
@@ -536,7 +540,7 @@
   // The ratio of gc time to elapsed time, computed over recent pauses.
   double _recent_avg_pause_time_ratio;
 
-  double recent_avg_pause_time_ratio() {
+  double recent_avg_pause_time_ratio() const {
     return _recent_avg_pause_time_ratio;
   }
 
@@ -556,12 +560,12 @@
   // Calculate and return the minimum desired young list target
   // length. This is the minimum desired young list length according
   // to the user's inputs.
-  uint calculate_young_list_desired_min_length(uint base_min_length);
+  uint calculate_young_list_desired_min_length(uint base_min_length) const;
 
   // Calculate and return the maximum desired young list target
   // length. This is the maximum desired young list length according
   // to the user's inputs.
-  uint calculate_young_list_desired_max_length();
+  uint calculate_young_list_desired_max_length() const;
 
   // Calculate and return the maximum young list target length that
   // can fit into the pause time goal. The parameters are: rs_lengths
@@ -572,11 +576,11 @@
   uint calculate_young_list_target_length(size_t rs_lengths,
                                           uint base_min_length,
                                           uint desired_min_length,
-                                          uint desired_max_length);
+                                          uint desired_max_length) const;
 
   // Calculate and return chunk size (in number of regions) for parallel
   // concurrent mark cleanup.
-  uint calculate_parallel_work_chunk_size(uint n_workers, uint n_regions);
+  uint calculate_parallel_work_chunk_size(uint n_workers, uint n_regions) const;
 
   // Check whether a given young length (young_length) fits into the
   // given target pause time and whether the prediction for the amount
@@ -584,19 +588,19 @@
   // given free space (expressed by base_free_regions).  It is used by
   // calculate_young_list_target_length().
   bool predict_will_fit(uint young_length, double base_time_ms,
-                        uint base_free_regions, double target_pause_time_ms);
+                        uint base_free_regions, double target_pause_time_ms) const;
 
   // Calculate the minimum number of old regions we'll add to the CSet
   // during a mixed GC.
-  uint calc_min_old_cset_length();
+  uint calc_min_old_cset_length() const;
 
   // Calculate the maximum number of old regions we'll add to the CSet
   // during a mixed GC.
-  uint calc_max_old_cset_length();
+  uint calc_max_old_cset_length() const;
 
   // Returns the given amount of uncollected reclaimable space
   // as a percentage of the current heap capacity.
-  double reclaimable_bytes_perc(size_t reclaimable_bytes);
+  double reclaimable_bytes_perc(size_t reclaimable_bytes) const;
 
 public:
 
@@ -604,6 +608,7 @@
 
   virtual G1CollectorPolicy* as_g1_policy() { return this; }
 
+  const G1CollectorState* collector_state() const;
   G1CollectorState* collector_state();
 
   G1GCPhaseTimes* phase_times() const { return _phase_times; }
@@ -658,9 +663,9 @@
 
   // Print heap sizing transition (with less and more detail).
 
-  void print_heap_transition(size_t bytes_before);
-  void print_heap_transition();
-  void print_detailed_heap_transition(bool full = false);
+  void print_heap_transition(size_t bytes_before) const;
+  void print_heap_transition() const;
+  void print_detailed_heap_transition(bool full = false) const;
 
   void record_stop_world_start();
   void record_concurrent_pause();
@@ -672,7 +677,7 @@
   }
 
   // The amount of space we copied during a GC.
-  size_t bytes_copied_during_gc() {
+  size_t bytes_copied_during_gc() const {
     return _bytes_copied_during_gc;
   }
 
@@ -684,7 +689,7 @@
   // next GC should be mixed. The two action strings are used
   // in the ergo output when the method returns true or false.
   bool next_gc_should_be_mixed(const char* true_action_str,
-                               const char* false_action_str);
+                               const char* false_action_str) const;
 
   // Choose a new collection set.  Marks the chosen regions as being
   // "in_collection_set", and links them together.  The head and number of
@@ -764,7 +769,7 @@
 
   // If an expansion would be appropriate, because recent GC overhead had
   // exceeded the desired limit, return an amount to expand by.
-  virtual size_t expansion_amount();
+  virtual size_t expansion_amount() const;
 
   // Print tracing information.
   void print_tracing_info() const;
@@ -783,15 +788,15 @@
 
   size_t young_list_target_length() const { return _young_list_target_length; }
 
-  bool is_young_list_full();
+  bool is_young_list_full() const;
 
-  bool can_expand_young_list();
+  bool can_expand_young_list() const;
 
-  uint young_list_max_length() {
+  uint young_list_max_length() const {
     return _young_list_max_length;
   }
 
-  bool adaptive_young_list_length() {
+  bool adaptive_young_list_length() const {
     return _young_gen_sizer->adaptive_young_list_length();
   }
 
@@ -832,14 +837,14 @@
 
   static const uint REGIONS_UNLIMITED = (uint) -1;
 
-  uint max_regions(InCSetState dest) {
+  uint max_regions(InCSetState dest) const {
     switch (dest.value()) {
       case InCSetState::Young:
         return _max_survivor_regions;
       case InCSetState::Old:
         return REGIONS_UNLIMITED;
       default:
-        assert(false, err_msg("Unknown dest state: " CSETSTATE_FORMAT, dest.value()));
+        assert(false, "Unknown dest state: " CSETSTATE_FORMAT, dest.value());
         break;
     }
     // keep some compilers happy
@@ -862,7 +867,7 @@
     _recorded_survivor_tail    = tail;
   }
 
-  uint recorded_survivor_regions() {
+  uint recorded_survivor_regions() const {
     return _recorded_survivor_regions;
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectorState.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorState.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -104,24 +104,24 @@
   void set_full_collection(bool v) { _full_collection = v; }
 
   // Getters
-  bool gcs_are_young() { return _gcs_are_young; }
-  bool last_gc_was_young() { return _last_gc_was_young; }
-  bool last_young_gc() { return _last_young_gc; }
-  bool during_initial_mark_pause() { return _during_initial_mark_pause; }
-  bool initiate_conc_mark_if_possible() { return _initiate_conc_mark_if_possible; }
-  bool during_marking() { return _during_marking; }
-  bool mark_in_progress() { return _mark_in_progress; }
-  bool in_marking_window() { return _in_marking_window; }
-  bool in_marking_window_im() { return _in_marking_window_im; }
-  bool concurrent_cycle_started() { return _concurrent_cycle_started; }
-  bool full_collection() { return _full_collection; }
+  bool gcs_are_young() const { return _gcs_are_young; }
+  bool last_gc_was_young() const { return _last_gc_was_young; }
+  bool last_young_gc() const { return _last_young_gc; }
+  bool during_initial_mark_pause() const { return _during_initial_mark_pause; }
+  bool initiate_conc_mark_if_possible() const { return _initiate_conc_mark_if_possible; }
+  bool during_marking() const { return _during_marking; }
+  bool mark_in_progress() const { return _mark_in_progress; }
+  bool in_marking_window() const { return _in_marking_window; }
+  bool in_marking_window_im() const { return _in_marking_window_im; }
+  bool concurrent_cycle_started() const { return _concurrent_cycle_started; }
+  bool full_collection() const { return _full_collection; }
 
   // Composite booleans (clients worry about flickering)
-  bool during_concurrent_mark() {
+  bool during_concurrent_mark() const {
     return (_in_marking_window && !_in_marking_window_im);
   }
 
-  bool should_propagate() { // XXX should have a more suitable state name or abstraction for this
+  bool should_propagate() const { // XXX should have a more suitable state name or abstraction for this
     return (_last_young_gc && !_in_marking_window);
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -165,9 +165,9 @@
         size_t size_second_obj = ((oop)end_first_obj)->size();
         HeapWord* end_of_second_obj = end_first_obj + size_second_obj;
         assert(end == end_of_second_obj,
-               err_msg("More than two objects were used to fill the area from " PTR_FORMAT " to " PTR_FORMAT ", "
-                       "second objects size " SIZE_FORMAT " ends at " PTR_FORMAT,
-                       p2i(start), p2i(end), size_second_obj, p2i(end_of_second_obj)));
+               "More than two objects were used to fill the area from " PTR_FORMAT " to " PTR_FORMAT ", "
+               "second objects size " SIZE_FORMAT " ends at " PTR_FORMAT,
+               p2i(start), p2i(end), size_second_obj, p2i(end_of_second_obj));
 #endif
       }
     }
@@ -215,7 +215,7 @@
     bool during_initial_mark = _g1h->collector_state()->during_initial_mark_pause();
     bool during_conc_mark = _g1h->collector_state()->mark_in_progress();
 
-    assert(!hr->is_pinned(), err_msg("Unexpected pinned region at index %u", hr->hrm_index()));
+    assert(!hr->is_pinned(), "Unexpected pinned region at index %u", hr->hrm_index());
     assert(hr->in_collection_set(), "bad CS");
 
     if (_hrclaimer->claim_region(hr->hrm_index())) {
--- a/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -45,13 +45,13 @@
 
     if (_allocated == 0) {
       assert((_unused == 0),
-             err_msg("Inconsistency in PLAB stats: "
-                     "_allocated: " SIZE_FORMAT ", "
-                     "_wasted: " SIZE_FORMAT ", "
-                     "_region_end_waste: " SIZE_FORMAT ", "
-                     "_unused: " SIZE_FORMAT ", "
-                     "_used  : " SIZE_FORMAT,
-                     _allocated, _wasted, _region_end_waste, _unused, used()));
+             "Inconsistency in PLAB stats: "
+             "_allocated: " SIZE_FORMAT ", "
+             "_wasted: " SIZE_FORMAT ", "
+             "_region_end_waste: " SIZE_FORMAT ", "
+             "_unused: " SIZE_FORMAT ", "
+             "_used  : " SIZE_FORMAT,
+             _allocated, _wasted, _region_end_waste, _unused, used());
       _allocated = 1;
     }
     // The size of the PLAB caps the amount of space that can be wasted at the
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -130,8 +130,8 @@
   WorkerDataArray<size_t>* thread_work_items() { return _thread_work_items; }
 
   void set(uint worker_i, T value) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), err_msg("Overwriting data for worker %d in %s", worker_i, _title));
+    assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
+    assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), "Overwriting data for worker %d in %s", worker_i, _title);
     _data[worker_i] = value;
     _has_new_data = true;
   }
@@ -142,14 +142,14 @@
   }
 
   T get(uint worker_i) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data added for worker %d", worker_i));
+    assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
+    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), "No data added for worker %d", worker_i);
     return _data[worker_i];
   }
 
   void add(uint worker_i, T value) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data to add to for worker %d", worker_i));
+    assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
+    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), "No data to add to for worker %d", worker_i);
     _data[worker_i] += value;
     _has_new_data = true;
   }
@@ -235,7 +235,7 @@
   assert(active_threads <= _length, "Wrong number of active threads");
   for (uint i = 0; i < active_threads; i++) {
     assert(_data[i] != WorkerDataArray<T>::uninitialized(),
-        err_msg("Invalid data for worker %u in '%s'", i, _title));
+           "Invalid data for worker %u in '%s'", i, _title);
   }
   if (_thread_work_items != NULL) {
     _thread_work_items->verify(active_threads);
@@ -479,7 +479,7 @@
       print_count_values(buf, phase_id, thread_work_items);
     }
 
-    assert(thread_work_items->_print_sum, err_msg("%s does not have print sum true even though it is a count", thread_work_items->_title));
+    assert(thread_work_items->_print_sum, "%s does not have print sum true even though it is a count", thread_work_items->_title);
 
     buf.append_and_print_cr(" Min: " SIZE_FORMAT ", Avg: %.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT "]",
         _phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id),
--- a/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -112,8 +112,7 @@
           // RSet updating while within an evacuation pause.
           // In this case worker_i should be the id of a GC worker thread
           assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
-          assert(worker_i < ParallelGCThreads,
-                 err_msg("incorrect worker id: %u", worker_i));
+          assert(worker_i < ParallelGCThreads, "incorrect worker id: %u", worker_i);
 
           into_cset_dcq->enqueue(card_ptr);
         }
--- a/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -67,7 +67,7 @@
   };
 
   InCSetState(in_cset_state_t value = NotInCSet) : _value(value) {
-    assert(is_valid(), err_msg("Invalid state %d", _value));
+    assert(is_valid(), "Invalid state %d", _value);
   }
 
   in_cset_state_t value() const        { return _value; }
@@ -104,7 +104,7 @@
  public:
   void set_humongous(uintptr_t index) {
     assert(get_by_index(index).is_default(),
-           err_msg("State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
+           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
     set_by_index(index, InCSetState::Humongous);
   }
 
@@ -114,13 +114,13 @@
 
   void set_in_young(uintptr_t index) {
     assert(get_by_index(index).is_default(),
-           err_msg("State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
+           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
     set_by_index(index, InCSetState::Young);
   }
 
   void set_in_old(uintptr_t index) {
     assert(get_by_index(index).is_default(),
-           err_msg("State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
+           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
     set_by_index(index, InCSetState::Old);
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1MMUTracker.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1MMUTracker.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -76,7 +76,7 @@
   return gc_time;
 }
 
-void G1MMUTrackerQueue::add_pause(double start, double end, const GCId& gcId) {
+void G1MMUTrackerQueue::add_pause(double start, double end) {
   double duration = end - start;
 
   remove_expired_entries(end);
@@ -106,7 +106,7 @@
 
   // Current entry needs to be added before calculating the value
   double slice_time = calculate_gc_time(end);
-  G1MMUTracer::report_mmu(gcId, _time_slice, slice_time, _max_gc_time);
+  G1MMUTracer::report_mmu(_time_slice, slice_time, _max_gc_time);
 }
 
 // basically the _internal call does not remove expired entries
--- a/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,10 +43,10 @@
 public:
   G1MMUTracker(double time_slice, double max_gc_time);
 
-  virtual void add_pause(double start, double end, const GCId& gcId) = 0;
+  virtual void add_pause(double start, double end) = 0;
   virtual double when_sec(double current_time, double pause_time) = 0;
 
-  double max_gc_time() {
+  double max_gc_time() const {
     return _max_gc_time;
   }
 
@@ -127,7 +127,7 @@
 public:
   G1MMUTrackerQueue(double time_slice, double max_gc_time);
 
-  virtual void add_pause(double start, double end, const GCId& gcId);
+  virtual void add_pause(double start, double end);
 
   virtual double when_sec(double current_time, double pause_time);
 };
--- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -93,8 +93,10 @@
 
   mark_sweep_phase2();
 
+#if defined(COMPILER2) || INCLUDE_JVMCI
   // Don't add any more derived pointers during phase3
-  COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
+  DerivedPointerTable::set_active(false);
+#endif
 
   mark_sweep_phase3();
 
@@ -121,7 +123,7 @@
 void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
                                     bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+  GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer());
 
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
@@ -146,8 +148,7 @@
                                       &GenMarkSweep::keep_alive,
                                       &GenMarkSweep::follow_stack_closure,
                                       NULL,
-                                      gc_timer(),
-                                      gc_tracer()->gc_id());
+                                      gc_timer());
   gc_tracer()->report_gc_reference_stats(stats);
 
 
@@ -168,7 +169,9 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTableDeactivate dpt_deact;
+#endif
     g1h->prepare_for_verify();
     // Note: we can verify only the heap here. When an object is
     // marked, the previous value of the mark word (including
@@ -200,7 +203,7 @@
   // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
   // tracking expects us to do so. See comment under phase4.
 
-  GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+  GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer());
 
   prepare_compaction();
 }
@@ -233,7 +236,7 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+  GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer());
 
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -294,7 +297,7 @@
   // to use a higher index (saved from phase2) when verifying perm_gen.
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-  GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+  GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer());
 
   G1SpaceCompactClosure blk;
   g1h->heap_region_iterate(&blk);
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -55,7 +55,7 @@
   _worker_id = par_scan_state->worker_id();
 
   assert(_worker_id < ParallelGCThreads,
-         err_msg("The given worker id %u must be less than the number of threads %u", _worker_id, ParallelGCThreads));
+         "The given worker id %u must be less than the number of threads %u", _worker_id, ParallelGCThreads);
 }
 
 // Generate G1 specialized oop_oop_iterate functions.
--- a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -57,13 +57,13 @@
   vmassert(page_size > 0, "Page size must be non-zero.");
 
   guarantee(is_ptr_aligned(rs.base(), page_size),
-            err_msg("Reserved space base " PTR_FORMAT " is not aligned to requested page size " SIZE_FORMAT, p2i(rs.base()), page_size));
+            "Reserved space base " PTR_FORMAT " is not aligned to requested page size " SIZE_FORMAT, p2i(rs.base()), page_size);
   guarantee(is_size_aligned(used_size, os::vm_page_size()),
-            err_msg("Given used reserved space size needs to be OS page size aligned (%d bytes) but is " SIZE_FORMAT, os::vm_page_size(), used_size));
+            "Given used reserved space size needs to be OS page size aligned (%d bytes) but is " SIZE_FORMAT, os::vm_page_size(), used_size);
   guarantee(used_size <= rs.size(),
-            err_msg("Used size of reserved space " SIZE_FORMAT " bytes is smaller than reservation at " SIZE_FORMAT " bytes", used_size, rs.size()));
+            "Used size of reserved space " SIZE_FORMAT " bytes is smaller than reservation at " SIZE_FORMAT " bytes", used_size, rs.size());
   guarantee(is_size_aligned(rs.size(), page_size),
-            err_msg("Expected that the virtual space is size aligned, but " SIZE_FORMAT " is not aligned to page size " SIZE_FORMAT, rs.size(), page_size));
+            "Expected that the virtual space is size aligned, but " SIZE_FORMAT " is not aligned to page size " SIZE_FORMAT, rs.size(), page_size);
 
   _low_boundary  = rs.base();
   _high_boundary = _low_boundary + used_size;
@@ -137,23 +137,23 @@
 
 bool G1PageBasedVirtualSpace::is_after_last_page(size_t index) const {
   guarantee(index <= _committed.size(),
-            err_msg("Given boundary page " SIZE_FORMAT " is beyond managed page count " SIZE_FORMAT, index, _committed.size()));
+            "Given boundary page " SIZE_FORMAT " is beyond managed page count " SIZE_FORMAT, index, _committed.size());
   return index == _committed.size();
 }
 
 void G1PageBasedVirtualSpace::commit_preferred_pages(size_t start, size_t num_pages) {
   vmassert(num_pages > 0, "No full pages to commit");
   vmassert(start + num_pages <= _committed.size(),
-           err_msg("Tried to commit area from page " SIZE_FORMAT " to page " SIZE_FORMAT " "
-                   "that is outside of managed space of " SIZE_FORMAT " pages",
-                   start, start + num_pages, _committed.size()));
+           "Tried to commit area from page " SIZE_FORMAT " to page " SIZE_FORMAT " "
+           "that is outside of managed space of " SIZE_FORMAT " pages",
+           start, start + num_pages, _committed.size());
 
   char* start_addr = page_start(start);
   size_t size = num_pages * _page_size;
 
   os::commit_memory_or_exit(start_addr, size, _page_size, _executable,
                             err_msg("Failed to commit area from " PTR_FORMAT " to " PTR_FORMAT " of length " SIZE_FORMAT ".",
-                                    p2i(start_addr), p2i(start_addr + size), size));
+                            p2i(start_addr), p2i(start_addr + size), size));
 }
 
 void G1PageBasedVirtualSpace::commit_tail() {
@@ -162,14 +162,14 @@
   char* const aligned_end_address = (char*)align_ptr_down(_high_boundary, _page_size);
   os::commit_memory_or_exit(aligned_end_address, _tail_size, os::vm_page_size(), _executable,
                             err_msg("Failed to commit tail area from " PTR_FORMAT " to " PTR_FORMAT " of length " SIZE_FORMAT ".",
-                                    p2i(aligned_end_address), p2i(_high_boundary), _tail_size));
+                            p2i(aligned_end_address), p2i(_high_boundary), _tail_size));
 }
 
 void G1PageBasedVirtualSpace::commit_internal(size_t start_page, size_t end_page) {
   guarantee(start_page < end_page,
-            err_msg("Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page));
+            "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page);
   guarantee(end_page <= _committed.size(),
-            err_msg("Given end page " SIZE_FORMAT " is beyond end of managed page amount of " SIZE_FORMAT, end_page, _committed.size()));
+            "Given end page " SIZE_FORMAT " is beyond end of managed page amount of " SIZE_FORMAT, end_page, _committed.size());
 
   size_t pages = end_page - start_page;
   bool need_to_commit_tail = is_after_last_page(end_page) && is_last_page_partial();
@@ -195,7 +195,7 @@
 
 void G1PageBasedVirtualSpace::pretouch_internal(size_t start_page, size_t end_page) {
   guarantee(start_page < end_page,
-            err_msg("Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page));
+            "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page);
 
   os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page));
 }
@@ -226,7 +226,7 @@
 
 void G1PageBasedVirtualSpace::uncommit_internal(size_t start_page, size_t end_page) {
   guarantee(start_page < end_page,
-            err_msg("Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page));
+            "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page);
 
   char* start_addr = page_start(start_page);
   os::uncommit_memory(start_addr, pointer_delta(bounded_end_addr(end_page), start_addr, sizeof(char)));
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -97,10 +97,10 @@
 bool G1ParScanThreadState::verify_ref(narrowOop* ref) const {
   assert(ref != NULL, "invariant");
   assert(UseCompressedOops, "sanity");
-  assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, p2i(ref)));
+  assert(!has_partial_array_mask(ref), "ref=" PTR_FORMAT, p2i(ref));
   oop p = oopDesc::load_decode_heap_oop(ref);
   assert(_g1h->is_in_g1_reserved(p),
-         err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)));
+         "ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p));
   return true;
 }
 
@@ -110,11 +110,11 @@
     // Must be in the collection set--it's already been copied.
     oop p = clear_partial_array_mask(ref);
     assert(_g1h->obj_in_cs(p),
-           err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)));
+           "ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p));
   } else {
     oop p = oopDesc::load_decode_heap_oop(ref);
     assert(_g1h->is_in_g1_reserved(p),
-           err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)));
+           "ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p));
   }
   return true;
 }
@@ -147,8 +147,8 @@
                                                       size_t word_sz,
                                                       AllocationContext_t const context,
                                                       bool previous_plab_refill_failed) {
-  assert(state.is_in_cset_or_humongous(), err_msg("Unexpected state: " CSETSTATE_FORMAT, state.value()));
-  assert(dest->is_in_cset_or_humongous(), err_msg("Unexpected dest: " CSETSTATE_FORMAT, dest->value()));
+  assert(state.is_in_cset_or_humongous(), "Unexpected state: " CSETSTATE_FORMAT, state.value());
+  assert(dest->is_in_cset_or_humongous(), "Unexpected dest: " CSETSTATE_FORMAT, dest->value());
 
   // Right now we only have two types of regions (young / old) so
   // let's keep the logic here simple. We can generalize it when necessary.
@@ -177,7 +177,7 @@
     return obj_ptr;
   } else {
     _old_gen_is_full = previous_plab_refill_failed;
-    assert(dest->is_old(), err_msg("Unexpected dest: " CSETSTATE_FORMAT, dest->value()));
+    assert(dest->is_old(), "Unexpected dest: " CSETSTATE_FORMAT, dest->value());
     // no other space to try.
     return NULL;
   }
@@ -359,8 +359,7 @@
 }
 
 oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markOop m) {
-  assert(_g1h->obj_in_cs(old),
-         err_msg("Object " PTR_FORMAT " should be in the CSet", p2i(old)));
+  assert(_g1h->obj_in_cs(old), "Object " PTR_FORMAT " should be in the CSet", p2i(old));
 
   oop forward_ptr = old->forward_to_atomic(old);
   if (forward_ptr == NULL) {
@@ -383,9 +382,9 @@
     // space for this object (old != forward_ptr) or they beat us in
     // self-forwarding it (old == forward_ptr).
     assert(old == forward_ptr || !_g1h->obj_in_cs(forward_ptr),
-           err_msg("Object " PTR_FORMAT " forwarded to: " PTR_FORMAT " "
-                   "should not be in the CSet",
-                   p2i(old), p2i(forward_ptr)));
+           "Object " PTR_FORMAT " forwarded to: " PTR_FORMAT " "
+           "should not be in the CSet",
+           p2i(old), p2i(forward_ptr));
     return forward_ptr;
   }
 }
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -75,9 +75,9 @@
 
   InCSetState dest(InCSetState original) const {
     assert(original.is_valid(),
-           err_msg("Original state invalid: " CSETSTATE_FORMAT, original.value()));
+           "Original state invalid: " CSETSTATE_FORMAT, original.value());
     assert(_dest[original.value()].is_valid_gen(),
-           err_msg("Dest state is invalid: " CSETSTATE_FORMAT, _dest[original.value()].value()));
+           "Dest state is invalid: " CSETSTATE_FORMAT, _dest[original.value()].value());
     return _dest[original.value()];
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -52,7 +52,7 @@
     _g1h->set_humongous_is_live(obj);
   } else {
     assert(!in_cset_state.is_in_cset_or_humongous(),
-           err_msg("In_cset_state must be NotInCSet here, but is " CSETSTATE_FORMAT, in_cset_state.value()));
+           "In_cset_state must be NotInCSet here, but is " CSETSTATE_FORMAT, in_cset_state.value());
   }
 
   assert(obj != NULL, "Must be");
@@ -82,7 +82,7 @@
   // to-space object.
   int next_index             = to_obj_array->length();
   assert(0 <= next_index && next_index < length,
-         err_msg("invariant, next index: %d, length: %d", next_index, length));
+         "invariant, next index: %d, length: %d", next_index, length);
 
   int start                  = next_index;
   int end                    = length;
--- a/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -113,7 +113,7 @@
 
   virtual void commit_regions(uint start_idx, size_t num_regions) {
     for (uint i = start_idx; i < start_idx + num_regions; i++) {
-      assert(!_commit_map.at(i), err_msg("Trying to commit storage at region %u that is already committed", i));
+      assert(!_commit_map.at(i), "Trying to commit storage at region %u that is already committed", i);
       size_t idx = region_idx_to_page_idx(i);
       uint old_refcount = _refcounts.get_by_index(idx);
       bool zero_filled = false;
@@ -128,7 +128,7 @@
 
   virtual void uncommit_regions(uint start_idx, size_t num_regions) {
     for (uint i = start_idx; i < start_idx + num_regions; i++) {
-      assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region %u that is not committed", i));
+      assert(_commit_map.at(i), "Trying to uncommit storage at region %u that is not committed", i);
       size_t idx = region_idx_to_page_idx(i);
       uint old_refcount = _refcounts.get_by_index(idx);
       assert(old_refcount > 0, "must be");
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -413,11 +413,11 @@
 bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i,
                            bool check_for_refs_into_cset) {
   assert(_g1->is_in_exact(_ct_bs->addr_for(card_ptr)),
-         err_msg("Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
-                 p2i(card_ptr),
-                 _ct_bs->index_for(_ct_bs->addr_for(card_ptr)),
-                 p2i(_ct_bs->addr_for(card_ptr)),
-                 _g1->addr_to_region(_ct_bs->addr_for(card_ptr))));
+         "Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
+         p2i(card_ptr),
+         _ct_bs->index_for(_ct_bs->addr_for(card_ptr)),
+         p2i(_ct_bs->addr_for(card_ptr)),
+         _g1->addr_to_region(_ct_bs->addr_for(card_ptr)));
 
   // If the card is no longer dirty, nothing to do.
   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
--- a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -247,3 +247,52 @@
     }
   }
 }
+
+void G1SATBCardTableModRefBS::write_ref_nmethod_post(oop* dst, nmethod* nm) {
+  oop obj = oopDesc::load_heap_oop(dst);
+  if (obj != NULL) {
+    G1CollectedHeap* g1h = G1CollectedHeap::heap();
+    HeapRegion* hr = g1h->heap_region_containing(obj);
+    hr->add_strong_code_root(nm);
+  }
+}
+
+class G1EnsureLastRefToRegion : public OopClosure {
+  G1CollectedHeap* _g1h;
+  HeapRegion* _hr;
+  oop* _dst;
+
+  bool _value;
+public:
+  G1EnsureLastRefToRegion(G1CollectedHeap* g1h, HeapRegion* hr, oop* dst) :
+    _g1h(g1h), _hr(hr), _dst(dst), _value(true) {}
+
+  void do_oop(oop* p) {
+    if (_value && p != _dst) {
+      oop obj = oopDesc::load_heap_oop(p);
+      if (obj != NULL) {
+        HeapRegion* hr = _g1h->heap_region_containing(obj);
+        if (hr == _hr) {
+          // Another reference to the same region.
+          _value = false;
+        }
+      }
+    }
+  }
+  void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+  bool value() const        { return _value;  }
+};
+
+void G1SATBCardTableModRefBS::write_ref_nmethod_pre(oop* dst, nmethod* nm) {
+  oop obj = oopDesc::load_heap_oop(dst);
+  if (obj != NULL) {
+    G1CollectedHeap* g1h = G1CollectedHeap::heap();
+    HeapRegion* hr = g1h->heap_region_containing(obj);
+    G1EnsureLastRefToRegion ensure_last_ref(g1h, hr, dst);
+    nm->oops_do(&ensure_last_ref);
+    if (ensure_last_ref.value()) {
+      // Last reference to this region, remove the nmethod from the rset.
+      hr->remove_strong_code_root(nm);
+    }
+  }
+}
--- a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,6 +38,7 @@
 // snapshot-at-the-beginning marking.
 
 class G1SATBCardTableModRefBS: public CardTableModRefBS {
+  friend class VMStructs;
 protected:
   enum G1CardValues {
     g1_young_gen = CT_MR_BS_last_reserved << 1
@@ -122,6 +123,9 @@
     jbyte val = _byte_map[card_index];
     return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
   }
+  virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm);
+  virtual void write_ref_nmethod_post(oop* dst, nmethod* nm);
+
 };
 
 template<>
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_G1_G1_GLOBALS_HPP
 
 #include "runtime/globals.hpp"
+#include <float.h> // for DBL_MAX
 //
 // Defines all globals flags used by the garbage-first compiler.
 //
@@ -61,6 +62,7 @@
           "update buffer processing info "                                  \
           "(0 means do not periodically generate this info); "              \
           "it also requires -XX:+G1SummarizeRSetStats")                     \
+          range(0, max_intx)                                                \
                                                                             \
   diagnostic(bool, G1TraceConcRefinement, false,                            \
           "Trace G1 concurrent refinement")                                 \
@@ -71,7 +73,7 @@
   product(double, G1ConcMarkStepDurationMillis, 10.0,                       \
           "Target duration of individual concurrent marking steps "         \
           "in milliseconds.")                                               \
-          range(1.0, (double)max_uintx)                                     \
+          range(1.0, DBL_MAX)                                               \
                                                                             \
   product(intx, G1RefProcDrainInterval, 10,                                 \
           "The number of discovered reference objects to process before "   \
@@ -89,9 +91,11 @@
                                                                             \
   product(size_t, G1SATBBufferSize, 1*K,                                    \
           "Number of entries in an SATB log buffer.")                       \
+          range(1, max_uintx)                                               \
                                                                             \
   develop(intx, G1SATBProcessCompletedThreshold, 20,                        \
           "Number of completed buffers that triggers log processing.")      \
+          range(0, max_jint)                                                \
                                                                             \
   product(uintx, G1SATBBufferEnqueueingThresholdPercent, 60,                \
           "Before enqueueing them, each mutator thread tries to do some "   \
@@ -114,26 +118,31 @@
                                                                             \
   product(size_t, G1UpdateBufferSize, 256,                                  \
           "Size of an update buffer")                                       \
+          range(1, NOT_LP64(32*M) LP64_ONLY(1*G))                           \
                                                                             \
   product(intx, G1ConcRefinementYellowZone, 0,                              \
           "Number of enqueued update buffers that will "                    \
           "trigger concurrent processing. Will be selected ergonomically "  \
           "by default.")                                                    \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, G1ConcRefinementRedZone, 0,                                 \
           "Maximum number of enqueued update buffers before mutator "       \
           "threads start processing new ones instead of enqueueing them. "  \
           "Will be selected ergonomically by default. Zero will disable "   \
           "concurrent processing.")                                         \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, G1ConcRefinementGreenZone, 0,                               \
           "The number of update buffers that are left in the queue by the " \
           "concurrent processing threads. Will be selected ergonomically "  \
           "by default.")                                                    \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, G1ConcRefinementServiceIntervalMillis, 300,                 \
           "The last concurrent refinement thread wakes up every "           \
           "specified number of milliseconds to do miscellaneous work.")     \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, G1ConcRefinementThresholdStep, 0,                           \
           "Each time the rset update queue increases by this amount "       \
@@ -143,6 +152,7 @@
   product(intx, G1RSetUpdatingPauseTimePercent, 10,                         \
           "A target percentage of time that is allowed to be spend on "     \
           "process RS update buffers during the collection pause.")         \
+          range(0, 100)                                                     \
                                                                             \
   product(bool, G1UseAdaptiveConcRefinement, true,                          \
           "Select green, yellow and red zones adaptively to meet the "      \
@@ -158,18 +168,24 @@
                                                                             \
   develop(intx, G1RSetRegionEntriesBase, 256,                               \
           "Max number of regions in a fine-grain table per MB.")            \
+          range(1, max_jint/wordSize)                                       \
                                                                             \
   product(intx, G1RSetRegionEntries, 0,                                     \
           "Max number of regions for which we keep bitmaps."                \
           "Will be set ergonomically by default")                           \
+          range(0, max_jint/wordSize)                                       \
+          constraint(G1RSetRegionEntriesConstraintFunc,AfterErgo)           \
                                                                             \
   develop(intx, G1RSetSparseRegionEntriesBase, 4,                           \
           "Max number of entries per region in a sparse table "             \
           "per MB.")                                                        \
+          range(1, max_jint/wordSize)                                       \
                                                                             \
   product(intx, G1RSetSparseRegionEntries, 0,                               \
           "Max number of entries per region in a sparse table."             \
           "Will be set ergonomically by default.")                          \
+          range(0, max_jint/wordSize)                                       \
+          constraint(G1RSetSparseRegionEntriesConstraintFunc,AfterErgo)     \
                                                                             \
   develop(bool, G1RecordHRRSOops, false,                                    \
           "When true, record recent calls to rem set operations.")          \
@@ -180,6 +196,7 @@
   develop(intx, G1MaxVerifyFailures, -1,                                    \
           "The maximum number of verification failures to print.  "         \
           "-1 means print all.")                                            \
+          range(-1, max_jint)                                               \
                                                                             \
   develop(bool, G1ScrubRemSets, true,                                       \
           "When true, do RS scrubbing after cleanup.")                      \
@@ -193,11 +210,13 @@
   develop(intx, G1YoungSurvRateNumRegionsSummary, 0,                        \
           "the number of regions for which we'll print a surv rate "        \
           "summary.")                                                       \
+          range(0, max_intx)                                                \
+          constraint(G1YoungSurvRateNumRegionsSummaryConstraintFunc,AfterErgo)\
                                                                             \
   product(uintx, G1ReservePercent, 10,                                      \
           "It determines the minimum reserve we should have in the heap "   \
           "to minimize the probability of promotion failure.")              \
-          range(0, 100)                                                     \
+          range(0, 50)                                                      \
                                                                             \
   diagnostic(bool, G1PrintHeapRegions, false,                               \
           "If set G1 will print information on which regions are being "    \
@@ -215,10 +234,13 @@
                                                                             \
   product(size_t, G1HeapRegionSize, 0,                                      \
           "Size of the G1 regions.")                                        \
+          range(0, 32*M)                                                    \
+          constraint(G1HeapRegionSizeConstraintFunc,AfterMemoryInit)        \
                                                                             \
   product(uintx, G1ConcRefinementThreads, 0,                                \
           "If non-0 is the number of parallel rem set update threads, "     \
           "otherwise the value is determined ergonomically.")               \
+          range(0, (max_jint-1)/wordSize)                                   \
                                                                             \
   develop(bool, G1VerifyCTCleanup, false,                                   \
           "Verify card table cleanup.")                                     \
@@ -226,6 +248,7 @@
   product(size_t, G1RSetScanBlockSize, 64,                                  \
           "Size of a work unit of cards claimed by a worker thread"         \
           "during RSet scanning.")                                          \
+          range(1, max_uintx)                                               \
                                                                             \
   develop(uintx, G1SecondaryFreeListAppendLength, 5,                        \
           "The number of regions we will add to the secondary free list "   \
@@ -262,6 +285,7 @@
   experimental(uintx, G1NewSizePercent, 5,                                  \
           "Percentage (0-100) of the heap size to use as default "          \
           "minimum young gen size.")                                        \
+          range(0, 100)                                                     \
           constraint(G1NewSizePercentConstraintFunc,AfterErgo)              \
                                                                             \
   experimental(uintx, G1MixedGCLiveThresholdPercent, 85,                    \
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -165,7 +165,7 @@
   assert(_end == orig_end(),
          "we should have already filtered out humongous regions");
   assert(!in_collection_set(),
-         err_msg("Should not clear heap region %u in the collection set", hrm_index()));
+         "Should not clear heap region %u in the collection set", hrm_index());
 
   set_allocation_context(AllocationContext::system());
   set_young_index_in_cset(-1);
@@ -292,9 +292,9 @@
   record_timestamp();
 
   assert(mr.end() == orig_end(),
-         err_msg("Given region end address " PTR_FORMAT " should match exactly "
-                 "bottom plus one region size, i.e. " PTR_FORMAT,
-                 p2i(mr.end()), p2i(orig_end())));
+         "Given region end address " PTR_FORMAT " should match exactly "
+         "bottom plus one region size, i.e. " PTR_FORMAT,
+         p2i(mr.end()), p2i(orig_end()));
 }
 
 CompactibleSpace* HeapRegion::next_compaction_space() const {
@@ -327,7 +327,7 @@
                                                   bool during_conc_mark,
                                                   size_t marked_bytes) {
   assert(marked_bytes <= used(),
-         err_msg("marked: " SIZE_FORMAT " used: " SIZE_FORMAT, marked_bytes, used()));
+         "marked: " SIZE_FORMAT " used: " SIZE_FORMAT, marked_bytes, used());
   _prev_top_at_mark_start = top();
   _prev_marked_bytes = marked_bytes;
 }
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -542,9 +542,9 @@
   void set_containing_set(HeapRegionSetBase* containing_set) {
     assert((containing_set == NULL && _containing_set != NULL) ||
            (containing_set != NULL && _containing_set == NULL),
-           err_msg("containing_set: " PTR_FORMAT " "
-                   "_containing_set: " PTR_FORMAT,
-                   p2i(containing_set), p2i(_containing_set)));
+           "containing_set: " PTR_FORMAT " "
+           "_containing_set: " PTR_FORMAT,
+           p2i(containing_set), p2i(_containing_set));
 
     _containing_set = containing_set;
   }
--- a/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -132,10 +132,10 @@
   }
 
   assert(ClassUnloadingWithConcurrentMark,
-      err_msg("All blocks should be objects if G1 Class Unloading isn't used. "
-              "HR: [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ") "
-              "addr: " PTR_FORMAT,
-              p2i(bottom()), p2i(top()), p2i(end()), p2i(addr)));
+         "All blocks should be objects if G1 Class Unloading isn't used. "
+         "HR: [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ") "
+         "addr: " PTR_FORMAT,
+         p2i(bottom()), p2i(top()), p2i(end()), p2i(addr));
 
   // Old regions' dead objects may have dead classes
   // We need to find the next live object in some other
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -92,7 +92,7 @@
 }
 
 void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
-  guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start));
+  guarantee(num_regions >= 1, "Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start);
   guarantee(_num_committed >= num_regions, "pre-condition");
 
   // Print before uncommitting.
@@ -132,7 +132,7 @@
   _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range);
 
   for (uint i = start; i < start + num_regions; i++) {
-    assert(is_available(i), err_msg("Just made region %u available but is apparently not.", i));
+    assert(is_available(i), "Just made region %u available but is apparently not.", i);
     HeapRegion* hr = at(i);
     if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
       G1CollectedHeap::heap()->hr_printer()->commit(hr->bottom(), hr->end());
@@ -213,8 +213,8 @@
       HeapRegion* hr = _regions.get_by_index(i);
       // sanity check
       guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()),
-                err_msg("Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
-                        " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr)));
+                "Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
+                " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr));
     }
     return found;
   } else {
@@ -224,7 +224,7 @@
 
 HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const {
   guarantee(r != NULL, "Start region must be a valid region");
-  guarantee(is_available(r->hrm_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrm_index()));
+  guarantee(is_available(r->hrm_index()), "Trying to iterate starting from region %u which is not in the heap", r->hrm_index());
   for (uint i = r->hrm_index() + 1; i < _allocated_heapregions_length; i++) {
     HeapRegion* hr = _regions.get_by_index(i);
     if (is_available(i)) {
@@ -241,7 +241,7 @@
     if (!is_available(i)) {
       continue;
     }
-    guarantee(at(i) != NULL, err_msg("Tried to access region %u that has a NULL HeapRegion*", i));
+    guarantee(at(i) != NULL, "Tried to access region %u that has a NULL HeapRegion*", i);
     bool res = blk->doHeapRegion(at(i));
     if (res) {
       blk->incomplete();
@@ -273,7 +273,7 @@
     assert(!is_available(i), "just checking");
   }
   assert(cur == max_length() || num_regions == 0 || is_available(cur),
-         err_msg("The region at the current position %u must be available or at the end of the heap.", cur));
+         "The region at the current position %u must be available or at the end of the heap.", cur);
 #endif
   return num_regions;
 }
@@ -374,8 +374,8 @@
 
         assert(chr->is_continues_humongous(), "Must be humongous region");
         assert(chr->humongous_start_region() == r,
-               err_msg("Must work on humongous continuation of the original start region "
-                       PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr)));
+               "Must work on humongous continuation of the original start region "
+               PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr));
         assert(!hrclaimer->is_region_claimed(ch_index),
                "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
 
@@ -440,9 +440,9 @@
 void HeapRegionManager::shrink_at(uint index, size_t num_regions) {
 #ifdef ASSERT
   for (uint i = index; i < (index + num_regions); i++) {
-    assert(is_available(i), err_msg("Expected available region at index %u", i));
-    assert(at(i)->is_empty(), err_msg("Expected empty region at index %u", i));
-    assert(at(i)->is_free(), err_msg("Expected free region at index %u", i));
+    assert(is_available(i), "Expected available region at index %u", i);
+    assert(at(i)->is_empty(), "Expected empty region at index %u", i);
+    assert(at(i)->is_free(), "Expected free region at index %u", i);
   }
 #endif
   uncommit_regions(index, num_regions);
@@ -479,11 +479,11 @@
 
 void HeapRegionManager::verify() {
   guarantee(length() <= _allocated_heapregions_length,
-            err_msg("invariant: _length: %u _allocated_length: %u",
-                    length(), _allocated_heapregions_length));
+            "invariant: _length: %u _allocated_length: %u",
+            length(), _allocated_heapregions_length);
   guarantee(_allocated_heapregions_length <= max_length(),
-            err_msg("invariant: _allocated_length: %u _max_length: %u",
-                    _allocated_heapregions_length, max_length()));
+            "invariant: _allocated_length: %u _max_length: %u",
+            _allocated_heapregions_length, max_length());
 
   bool prev_committed = true;
   uint num_committed = 0;
@@ -495,12 +495,12 @@
     }
     num_committed++;
     HeapRegion* hr = _regions.get_by_index(i);
-    guarantee(hr != NULL, err_msg("invariant: i: %u", i));
+    guarantee(hr != NULL, "invariant: i: %u", i);
     guarantee(!prev_committed || hr->bottom() == prev_end,
-              err_msg("invariant i: %u " HR_FORMAT " prev_end: " PTR_FORMAT,
-                      i, HR_FORMAT_PARAMS(hr), p2i(prev_end)));
+              "invariant i: %u " HR_FORMAT " prev_end: " PTR_FORMAT,
+              i, HR_FORMAT_PARAMS(hr), p2i(prev_end));
     guarantee(hr->hrm_index() == i,
-              err_msg("invariant: i: %u hrm_index(): %u", i, hr->hrm_index()));
+              "invariant: i: %u hrm_index(): %u", i, hr->hrm_index());
     // Asserts will fire if i is >= _length
     HeapWord* addr = hr->bottom();
     guarantee(addr_to_region(addr) == hr, "sanity");
@@ -515,10 +515,10 @@
     }
   }
   for (uint i = _allocated_heapregions_length; i < max_length(); i++) {
-    guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i));
+    guarantee(_regions.get_by_index(i) == NULL, "invariant i: %u", i);
   }
 
-  guarantee(num_committed == _num_committed, err_msg("Found %u committed regions, but should be %u", num_committed, _num_committed));
+  guarantee(num_committed == _num_committed, "Found %u committed regions, but should be %u", num_committed, _num_committed);
   _free_list.verify();
 }
 
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,9 +31,9 @@
 
 inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const {
   assert(addr < heap_end(),
-        err_msg("addr: " PTR_FORMAT " end: " PTR_FORMAT, p2i(addr), p2i(heap_end())));
+        "addr: " PTR_FORMAT " end: " PTR_FORMAT, p2i(addr), p2i(heap_end()));
   assert(addr >= heap_bottom(),
-        err_msg("addr: " PTR_FORMAT " bottom: " PTR_FORMAT, p2i(addr), p2i(heap_bottom())));
+        "addr: " PTR_FORMAT " bottom: " PTR_FORMAT, p2i(addr), p2i(heap_bottom()));
 
   HeapRegion* hr = _regions.get_by_address(addr);
   return hr;
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -376,8 +376,8 @@
 
 void FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {
   guarantee((size_t)start_idx + new_num_regions <= max_uintx,
-            err_msg("Trying to invalidate beyond maximum region, from %u size " SIZE_FORMAT,
-                    start_idx, new_num_regions));
+            "Trying to invalidate beyond maximum region, from %u size " SIZE_FORMAT,
+            start_idx, new_num_regions);
   for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
     uint end_idx = (start_idx + (uint)new_num_regions);
     assert(end_idx <= _max_regions, "Must be within max.");
@@ -1013,7 +1013,7 @@
 
   card_index = _cur_region_card_offset + _cur_card_in_prt;
   guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
-            err_msg("Card index " SIZE_FORMAT " must be within the region", _cur_card_in_prt));
+            "Card index " SIZE_FORMAT " must be within the region", _cur_card_in_prt);
   return true;
 }
 
@@ -1182,8 +1182,8 @@
 
   size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize;
   assert(dummy->mem_size() > min_prt_size,
-         err_msg("PerRegionTable memory usage is suspiciously small, only has " SIZE_FORMAT " bytes. "
-                 "Should be at least " SIZE_FORMAT " bytes.", dummy->mem_size(), min_prt_size));
+         "PerRegionTable memory usage is suspiciously small, only has " SIZE_FORMAT " bytes. "
+         "Should be at least " SIZE_FORMAT " bytes.", dummy->mem_size(), min_prt_size);
   free(dummy);
   guarantee(dummy->mem_size() == fl_mem_size(), "fl_mem_size() does not return the correct element size");
   // try to reset the state
--- a/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,14 +37,14 @@
 
 #ifndef PRODUCT
 void HeapRegionSetBase::verify_region(HeapRegion* hr) {
-  assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrm_index()));
-  assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrm_index())); // currently we don't use these sets for young regions
-  assert(hr->is_humongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrm_index(), name()));
-  assert(hr->is_free() == regions_free(), err_msg("Wrong free state for region %u and set %s", hr->hrm_index(), name()));
-  assert(!hr->is_free() || hr->is_empty(), err_msg("Free region %u is not empty for set %s", hr->hrm_index(), name()));
+  assert(hr->containing_set() == this, "Inconsistent containing set for %u", hr->hrm_index());
+  assert(!hr->is_young(), "Adding young region %u", hr->hrm_index()); // currently we don't use these sets for young regions
+  assert(hr->is_humongous() == regions_humongous(), "Wrong humongous state for region %u and set %s", hr->hrm_index(), name());
+  assert(hr->is_free() == regions_free(), "Wrong free state for region %u and set %s", hr->hrm_index(), name());
+  assert(!hr->is_free() || hr->is_empty(), "Free region %u is not empty for set %s", hr->hrm_index(), name());
   assert(!hr->is_empty() || hr->is_free() || hr->is_archive(),
-         err_msg("Empty region %u is not free or archive for set %s", hr->hrm_index(), name()));
-  assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrm_index()));
+         "Empty region %u is not free or archive for set %s", hr->hrm_index(), name());
+  assert(hr->rem_set()->verify_ready_for_par_iteration(), "Wrong iteration state %u", hr->hrm_index());
 }
 #endif
 
@@ -57,14 +57,14 @@
 
   guarantee(( is_empty() && length() == 0 && total_capacity_bytes() == 0) ||
             (!is_empty() && length() > 0  && total_capacity_bytes() > 0) ,
-            hrs_ext_msg(this, "invariant"));
+            "%s", hrs_ext_msg(this, "invariant").buffer());
 }
 
 void HeapRegionSetBase::verify_start() {
   // See comment in verify() about MT safety and verification.
   check_mt_safety();
   assert(!_verify_in_progress,
-         hrs_ext_msg(this, "verification should not be in progress"));
+         "%s", hrs_ext_msg(this, "verification should not be in progress").buffer());
 
   // Do the basic verification first before we do the checks over the regions.
   HeapRegionSetBase::verify();
@@ -76,7 +76,7 @@
   // See comment in verify() about MT safety and verification.
   check_mt_safety();
   assert(_verify_in_progress,
-         hrs_ext_msg(this, "verification should be in progress"));
+         "%s", hrs_ext_msg(this, "verification should be in progress").buffer());
 
   _verify_in_progress = false;
 }
@@ -151,7 +151,7 @@
   #endif // ASSERT
 
   if (is_empty()) {
-    assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant"));
+    assert(length() == 0 && _tail == NULL, "%s", hrs_ext_msg(this, "invariant").buffer());
     _head = from_list->_head;
     _tail = from_list->_tail;
   } else {
@@ -198,8 +198,8 @@
 
 void FreeRegionList::remove_starting_at(HeapRegion* first, uint num_regions) {
   check_mt_safety();
-  assert(num_regions >= 1, hrs_ext_msg(this, "pre-condition"));
-  assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
+  assert(num_regions >= 1, "%s", hrs_ext_msg(this, "pre-condition").buffer());
+  assert(!is_empty(), "%s", hrs_ext_msg(this, "pre-condition").buffer());
 
   verify_optional();
   DEBUG_ONLY(uint old_length = length();)
@@ -212,22 +212,22 @@
     HeapRegion* prev = curr->prev();
 
     assert(count < num_regions,
-           hrs_err_msg("[%s] should not come across more regions "
-                       "pending for removal than num_regions: %u",
-                       name(), num_regions));
+           "%s", hrs_err_msg("[%s] should not come across more regions "
+                             "pending for removal than num_regions: %u",
+                             name(), num_regions).buffer());
 
     if (prev == NULL) {
-      assert(_head == curr, hrs_ext_msg(this, "invariant"));
+      assert(_head == curr, "%s", hrs_ext_msg(this, "invariant").buffer());
       _head = next;
     } else {
-      assert(_head != curr, hrs_ext_msg(this, "invariant"));
+      assert(_head != curr, "%s", hrs_ext_msg(this, "invariant").buffer());
       prev->set_next(next);
     }
     if (next == NULL) {
-      assert(_tail == curr, hrs_ext_msg(this, "invariant"));
+      assert(_tail == curr, "%s", hrs_ext_msg(this, "invariant").buffer());
       _tail = prev;
     } else {
-      assert(_tail != curr, hrs_ext_msg(this, "invariant"));
+      assert(_tail != curr, "%s", hrs_ext_msg(this, "invariant").buffer());
       next->set_prev(prev);
     }
     if (_last = curr) {
@@ -243,12 +243,12 @@
   }
 
   assert(count == num_regions,
-         hrs_err_msg("[%s] count: %u should be == num_regions: %u",
-                     name(), count, num_regions));
+         "%s", hrs_err_msg("[%s] count: %u should be == num_regions: %u",
+                           name(), count, num_regions).buffer());
   assert(length() + num_regions == old_length,
-         hrs_err_msg("[%s] new length should be consistent "
-                     "new length: %u old length: %u num_regions: %u",
-                     name(), length(), old_length, num_regions));
+         "%s", hrs_err_msg("[%s] new length should be consistent "
+                           "new length: %u old length: %u num_regions: %u",
+                           name(), length(), old_length, num_regions).buffer());
 
   verify_optional();
 }
@@ -305,8 +305,8 @@
 
     count++;
     guarantee(count < _unrealistically_long_length,
-        hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
-            name(), count, p2i(curr), p2i(prev0), p2i(prev1), length()));
+        "%s", hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
+              name(), count, p2i(curr), p2i(prev0), p2i(prev1), length()).buffer());
 
     if (curr->next() != NULL) {
       guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
@@ -321,11 +321,11 @@
     curr = curr->next();
   }
 
-  guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index()));
+  guarantee(_tail == prev0, "Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index());
   guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
-  guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count));
-  guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-      name(), total_capacity_bytes(), capacity));
+  guarantee(length() == count, "%s count mismatch. Expected %u, actual %u.", name(), length(), count);
+  guarantee(total_capacity_bytes() == capacity, "%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+            name(), total_capacity_bytes(), capacity);
 }
 
 // Note on the check_mt_safety() methods below:
--- a/hotspot/src/share/vm/gc/g1/heapRegionSet.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,9 +29,9 @@
 
 inline void HeapRegionSetBase::add(HeapRegion* hr) {
   check_mt_safety();
-  assert(hr->containing_set() == NULL, hrs_ext_msg(this, "should not already have a containing set %u"));
-  assert(hr->next() == NULL, hrs_ext_msg(this, "should not already be linked"));
-  assert(hr->prev() == NULL, hrs_ext_msg(this, "should not already be linked"));
+  assert(hr->containing_set() == NULL, "%s", hrs_ext_msg(this, "should not already have a containing set %u").buffer());
+  assert(hr->next() == NULL, "%s", hrs_ext_msg(this, "should not already be linked").buffer());
+  assert(hr->prev() == NULL, "%s", hrs_ext_msg(this, "should not already be linked").buffer());
 
   _count.increment(1u, hr->capacity());
   hr->set_containing_set(this);
@@ -41,18 +41,18 @@
 inline void HeapRegionSetBase::remove(HeapRegion* hr) {
   check_mt_safety();
   verify_region(hr);
-  assert(hr->next() == NULL, hrs_ext_msg(this, "should already be unlinked"));
-  assert(hr->prev() == NULL, hrs_ext_msg(this, "should already be unlinked"));
+  assert(hr->next() == NULL, "%s", hrs_ext_msg(this, "should already be unlinked").buffer());
+  assert(hr->prev() == NULL, "%s", hrs_ext_msg(this, "should already be unlinked").buffer());
 
   hr->set_containing_set(NULL);
-  assert(_count.length() > 0, hrs_ext_msg(this, "pre-condition"));
+  assert(_count.length() > 0, "%s", hrs_ext_msg(this, "pre-condition").buffer());
   _count.decrement(1u, hr->capacity());
 }
 
 inline void FreeRegionList::add_ordered(HeapRegion* hr) {
   assert((length() == 0 && _head == NULL && _tail == NULL && _last == NULL) ||
          (length() >  0 && _head != NULL && _tail != NULL),
-         hrs_ext_msg(this, "invariant"));
+         "%s", hrs_ext_msg(this, "invariant").buffer());
   // add() will verify the region and check mt safety.
   add(hr);
 
@@ -129,7 +129,7 @@
     return NULL;
   }
   assert(length() > 0 && _head != NULL && _tail != NULL,
-         hrs_ext_msg(this, "invariant"));
+         "%s", hrs_ext_msg(this, "invariant").buffer());
 
   HeapRegion* hr;
 
--- a/hotspot/src/share/vm/gc/g1/heapRegionType.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionType.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -28,7 +28,7 @@
 #include "memory/allocation.hpp"
 
 #define hrt_assert_is_valid(tag) \
-  assert(is_valid((tag)), err_msg("invalid HR type: %u", (uint) (tag)))
+  assert(is_valid((tag)), "invalid HR type: %u", (uint) (tag))
 
 class HeapRegionType VALUE_OBJ_CLASS_SPEC {
 private:
@@ -97,8 +97,7 @@
     hrt_assert_is_valid(tag);
     hrt_assert_is_valid(before);
     hrt_assert_is_valid(_tag);
-    assert(_tag == before,
-           err_msg("HR tag: %u, expected: %u new tag; %u", _tag, before, tag));
+    assert(_tag == before, "HR tag: %u, expected: %u new tag; %u", _tag, before, tag);
     _tag = tag;
   }
 
--- a/hotspot/src/share/vm/gc/g1/satbQueue.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/satbQueue.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -77,16 +77,16 @@
 inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
   // Includes rejection of NULL pointers.
   assert(heap->is_in_reserved(entry),
-         err_msg("Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry)));
+         "Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry));
 
   HeapRegion* region = heap->heap_region_containing_raw(entry);
-  assert(region != NULL, err_msg("No region for " PTR_FORMAT, p2i(entry)));
+  assert(region != NULL, "No region for " PTR_FORMAT, p2i(entry));
   if (entry >= region->next_top_at_mark_start()) {
     return false;
   }
 
   assert(((oop)entry)->is_oop(true /* ignore mark word */),
-         err_msg("Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry)));
+         "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry));
 
   return true;
 }
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #include "gc/g1/concurrentMarkThread.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/g1/g1Log.hpp"
 #include "gc/g1/vm_operations_g1.hpp"
 #include "gc/shared/gcTimer.hpp"
@@ -66,8 +67,8 @@
     _should_retry_gc(false),
     _old_marking_cycles_completed_before(0) {
   guarantee(target_pause_time_ms > 0.0,
-            err_msg("target_pause_time_ms = %1.6lf should be positive",
-                    target_pause_time_ms));
+            "target_pause_time_ms = %1.6lf should be positive",
+            target_pause_time_ms);
   _gc_cause = gc_cause;
 }
 
@@ -227,7 +228,8 @@
 void VM_CGC_Operation::doit() {
   TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  GCTraceTime t(_printGCMessage, G1Log::fine(), true, g1h->gc_timer_cm(), g1h->concurrent_mark()->concurrent_gc_id());
+  GCIdMark gc_id_mark(_gc_id);
+  GCTraceTime t(_printGCMessage, G1Log::fine(), true, g1h->gc_timer_cm());
   IsGCActiveMark x;
   _cl->do_void();
 }
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_G1_VM_OPERATIONS_G1_HPP
 
 #include "gc/g1/g1AllocationContext.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 
 // VM_operations for the G1 collector.
@@ -104,6 +105,7 @@
   VoidClosure* _cl;
   const char* _printGCMessage;
   bool _needs_pll;
+  uint _gc_id;
 
 protected:
   // java.lang.ref.Reference support
@@ -112,7 +114,7 @@
 
 public:
   VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg, bool needs_pll)
-    : _cl(cl), _printGCMessage(printGCMsg), _needs_pll(needs_pll) { }
+    : _cl(cl), _printGCMessage(printGCMsg), _needs_pll(needs_pll), _gc_id(GCId::current()) { }
   virtual VMOp_Type type() const { return VMOp_CGC_Operation; }
   virtual void doit();
   virtual bool doit_prologue();
--- a/hotspot/src/share/vm/gc/parallel/cardTableExtension.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/cardTableExtension.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -285,7 +285,7 @@
           while (p < to) {
             Prefetch::write(p, interval);
             oop m = oop(p);
-            assert(m->is_oop_or_null(), err_msg("Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m)));
+            assert(m->is_oop_or_null(), "Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m));
             pm->push_contents(m);
             p += m->size();
           }
@@ -293,7 +293,7 @@
         } else {
           while (p < to) {
             oop m = oop(p);
-            assert(m->is_oop_or_null(), err_msg("Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m)));
+            assert(m->is_oop_or_null(), "Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m));
             pm->push_contents(m);
             p += m->size();
           }
--- a/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #include "gc/parallel/gcTaskManager.hpp"
 #include "gc/parallel/gcTaskThread.hpp"
 #include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/gcId.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/mutex.hpp"
@@ -48,8 +49,8 @@
   case ordinary_task:
     result = "ordinary task";
     break;
-  case barrier_task:
-    result = "barrier task";
+  case wait_for_barrier_task:
+    result = "wait for barrier task";
     break;
   case noop_task:
     result = "noop task";
@@ -61,33 +62,24 @@
   return result;
 };
 
-GCTask::GCTask() :
-  _kind(Kind::ordinary_task),
-  _affinity(GCTaskManager::sentinel_worker()){
-  initialize();
+GCTask::GCTask() {
+  initialize(Kind::ordinary_task, GCId::current());
 }
 
-GCTask::GCTask(Kind::kind kind) :
-  _kind(kind),
-  _affinity(GCTaskManager::sentinel_worker()) {
-  initialize();
+GCTask::GCTask(Kind::kind kind) {
+  initialize(kind, GCId::current());
 }
 
-GCTask::GCTask(uint affinity) :
-  _kind(Kind::ordinary_task),
-  _affinity(affinity) {
-  initialize();
+GCTask::GCTask(Kind::kind kind, uint gc_id) {
+  initialize(kind, gc_id);
 }
 
-GCTask::GCTask(Kind::kind kind, uint affinity) :
-  _kind(kind),
-  _affinity(affinity) {
-  initialize();
-}
-
-void GCTask::initialize() {
+void GCTask::initialize(Kind::kind kind, uint gc_id) {
+  _kind = kind;
+  _affinity = GCTaskManager::sentinel_worker();
   _older = NULL;
   _newer = NULL;
+  _gc_id = gc_id;
 }
 
 void GCTask::destruct() {
@@ -378,16 +370,7 @@
 GCTaskManager::GCTaskManager(uint workers) :
   _workers(workers),
   _active_workers(0),
-  _idle_workers(0),
-  _ndc(NULL) {
-  initialize();
-}
-
-GCTaskManager::GCTaskManager(uint workers, NotifyDoneClosure* ndc) :
-  _workers(workers),
-  _active_workers(0),
-  _idle_workers(0),
-  _ndc(ndc) {
+  _idle_workers(0) {
   initialize();
 }
 
@@ -404,7 +387,6 @@
   GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap();
   _queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
   _noop_task = NoopGCTask::create_on_c_heap();
-  _idle_inactive_task = WaitForBarrierGCTask::create_on_c_heap();
   _resource_flag = NEW_C_HEAP_ARRAY(bool, workers(), mtGC);
   {
     // Set up worker threads.
@@ -437,7 +419,6 @@
   }
   reset_delivered_tasks();
   reset_completed_tasks();
-  reset_noop_tasks();
   reset_barriers();
   reset_emptied_queue();
   for (uint s = 0; s < workers(); s += 1) {
@@ -450,8 +431,6 @@
   assert(queue()->is_empty(), "still have queued work");
   NoopGCTask::destroy(_noop_task);
   _noop_task = NULL;
-  WaitForBarrierGCTask::destroy(_idle_inactive_task);
-  _idle_inactive_task = NULL;
   if (_thread != NULL) {
     for (uint i = 0; i < workers(); i += 1) {
       GCTaskThread::destroy(thread(i));
@@ -483,9 +462,9 @@
                                  Threads::number_of_non_daemon_threads());
 
   assert(!all_workers_active() || active_workers() == ParallelGCThreads,
-         err_msg("all_workers_active() is  incorrect: "
-                 "active %d  ParallelGCThreads %u", active_workers(),
-                 ParallelGCThreads));
+         "all_workers_active() is  incorrect: "
+         "active %d  ParallelGCThreads %u", active_workers(),
+         ParallelGCThreads);
   if (TraceDynamicGCThreads) {
     gclog_or_tty->print_cr("GCTaskManager::set_active_gang(): "
                            "all_workers_active()  %d  workers %d  "
@@ -507,7 +486,7 @@
       // the GCTaskManager's monitor so that the "more_inactive_workers"
       // count is correct.
       MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
-      _idle_inactive_task->set_should_wait(true);
+      _wait_helper.set_should_wait(true);
       // active_workers are a number being requested.  idle_workers
       // are the number currently idle.  If all the workers are being
       // requested to be active but some are already idle, reduce
@@ -550,7 +529,7 @@
   {
     MutexLockerEx ml(monitor(),
       Mutex::_no_safepoint_check_flag);
-    _idle_inactive_task->set_should_wait(false);
+    _wait_helper.set_should_wait(false);
     monitor()->notify_all();
   // Release monitor
   }
@@ -671,7 +650,6 @@
     // Just hand back a Noop task,
     // in case someone wanted us to release resources, or whatever.
     result = noop_task();
-    increment_noop_tasks();
   }
   assert(result != NULL, "shouldn't have null task");
   if (TraceGCTaskManager) {
@@ -706,11 +684,6 @@
     if (TraceGCTaskManager) {
       tty->print_cr("    GCTaskManager::note_completion(%u) done", which);
     }
-    // Notify client that we are done.
-    NotifyDoneClosure* ndc = notify_done_closure();
-    if (ndc != NULL) {
-      ndc->notify(this);
-    }
   }
   if (TraceGCTaskManager) {
     tty->print_cr("    GCTaskManager::note_completion(%u) (%s)->notify_all",
@@ -751,7 +724,7 @@
 }
 
 void GCTaskManager::release_all_resources() {
-  // If you want this to be done atomically, do it in a BarrierGCTask.
+  // If you want this to be done atomically, do it in a WaitForBarrierGCTask.
   for (uint i = 0; i < workers(); i += 1) {
     set_resource_flag(i, true);
   }
@@ -813,25 +786,22 @@
 // NoopGCTask
 //
 
-NoopGCTask* NoopGCTask::create() {
-  NoopGCTask* result = new NoopGCTask(false);
-  return result;
-}
-
 NoopGCTask* NoopGCTask::create_on_c_heap() {
-  NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask(true);
+  NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask();
   return result;
 }
 
 void NoopGCTask::destroy(NoopGCTask* that) {
   if (that != NULL) {
     that->destruct();
-    if (that->is_c_heap_obj()) {
-      FreeHeap(that);
-    }
+    FreeHeap(that);
   }
 }
 
+// This task should never be performing GC work that require
+// a valid GC id.
+NoopGCTask::NoopGCTask() : GCTask(GCTask::Kind::noop_task, GCId::undefined()) { }
+
 void NoopGCTask::destruct() {
   // This has to know it's superclass structure, just like the constructor.
   this->GCTask::destruct();
@@ -857,12 +827,12 @@
 }
 
 void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
-  WaitForBarrierGCTask* wait_for_task = manager->idle_inactive_task();
+  WaitHelper* wait_helper = manager->wait_helper();
   if (TraceGCTaskManager) {
     tty->print_cr("[" INTPTR_FORMAT "]"
                   " IdleGCTask:::do_it()"
       "  should_wait: %s",
-      p2i(this), wait_for_task->should_wait() ? "true" : "false");
+      p2i(this), wait_helper->should_wait() ? "true" : "false");
   }
   MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
   if (TraceDynamicGCThreads) {
@@ -871,7 +841,7 @@
   // Increment has to be done when the idle tasks are created.
   // manager->increment_idle_workers();
   manager->monitor()->notify_all();
-  while (wait_for_task->should_wait()) {
+  while (wait_helper->should_wait()) {
     if (TraceGCTaskManager) {
       tty->print_cr("[" INTPTR_FORMAT "]"
                     " IdleGCTask::do_it()"
@@ -888,7 +858,7 @@
     tty->print_cr("[" INTPTR_FORMAT "]"
                   " IdleGCTask::do_it() returns"
       "  should_wait: %s",
-      p2i(this), wait_for_task->should_wait() ? "true" : "false");
+      p2i(this), wait_helper->should_wait() ? "true" : "false");
   }
   // Release monitor().
 }
@@ -909,140 +879,52 @@
 }
 
 //
-// BarrierGCTask
+// WaitForBarrierGCTask
 //
-
-void BarrierGCTask::do_it(GCTaskManager* manager, uint which) {
-  // Wait for this to be the only busy worker.
-  // ??? I thought of having a StackObj class
-  //     whose constructor would grab the lock and come to the barrier,
-  //     and whose destructor would release the lock,
-  //     but that seems like too much mechanism for two lines of code.
-  MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
-  do_it_internal(manager, which);
-  // Release manager->lock().
+WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
+  WaitForBarrierGCTask* result = new WaitForBarrierGCTask();
+  return result;
 }
 
-void BarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
+WaitForBarrierGCTask::WaitForBarrierGCTask() : GCTask(GCTask::Kind::wait_for_barrier_task) { }
+
+void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
+  if (that != NULL) {
+    if (TraceGCTaskManager) {
+      tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destroy()", p2i(that));
+    }
+    that->destruct();
+  }
+}
+
+void WaitForBarrierGCTask::destruct() {
+  if (TraceGCTaskManager) {
+    tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destruct()", p2i(this));
+  }
+  this->GCTask::destruct();
+  // Clean up that should be in the destructor,
+  // except that ResourceMarks don't call destructors.
+  _wait_helper.release_monitor();
+}
+
+void WaitForBarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
   // Wait for this to be the only busy worker.
   assert(manager->monitor()->owned_by_self(), "don't own the lock");
   assert(manager->is_blocked(), "manager isn't blocked");
   while (manager->busy_workers() > 1) {
     if (TraceGCTaskManager) {
-      tty->print_cr("BarrierGCTask::do_it(%u) waiting on %u workers",
+      tty->print_cr("WaitForBarrierGCTask::do_it(%u) waiting on %u workers",
                     which, manager->busy_workers());
     }
     manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
   }
 }
 
-void BarrierGCTask::destruct() {
-  this->GCTask::destruct();
-  // Nothing else to do.
-}
-
-//
-// ReleasingBarrierGCTask
-//
-
-void ReleasingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
-  MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
-  do_it_internal(manager, which);
-  manager->release_all_resources();
-  // Release manager->lock().
-}
-
-void ReleasingBarrierGCTask::destruct() {
-  this->BarrierGCTask::destruct();
-  // Nothing else to do.
-}
-
-//
-// NotifyingBarrierGCTask
-//
-
-void NotifyingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
-  MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
-  do_it_internal(manager, which);
-  NotifyDoneClosure* ndc = notify_done_closure();
-  if (ndc != NULL) {
-    ndc->notify(manager);
-  }
-  // Release manager->lock().
-}
-
-void NotifyingBarrierGCTask::destruct() {
-  this->BarrierGCTask::destruct();
-  // Nothing else to do.
-}
-
-//
-// WaitForBarrierGCTask
-//
-WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
-  WaitForBarrierGCTask* result = new WaitForBarrierGCTask(false);
-  return result;
-}
-
-WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
-  WaitForBarrierGCTask* result =
-    new (ResourceObj::C_HEAP, mtGC) WaitForBarrierGCTask(true);
-  return result;
-}
-
-WaitForBarrierGCTask::WaitForBarrierGCTask(bool on_c_heap) :
-  _is_c_heap_obj(on_c_heap) {
-  _monitor = MonitorSupply::reserve();
-  set_should_wait(true);
-  if (TraceGCTaskManager) {
-    tty->print_cr("[" INTPTR_FORMAT "]"
-                  " WaitForBarrierGCTask::WaitForBarrierGCTask()"
-                  "  monitor: " INTPTR_FORMAT,
-                  p2i(this), p2i(monitor()));
-  }
-}
-
-void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
-  if (that != NULL) {
-    if (TraceGCTaskManager) {
-      tty->print_cr("[" INTPTR_FORMAT "]"
-                    " WaitForBarrierGCTask::destroy()"
-                    "  is_c_heap_obj: %s"
-                    "  monitor: " INTPTR_FORMAT,
-                    p2i(that),
-                    that->is_c_heap_obj() ? "true" : "false",
-                    p2i(that->monitor()));
-    }
-    that->destruct();
-    if (that->is_c_heap_obj()) {
-      FreeHeap(that);
-    }
-  }
-}
-
-void WaitForBarrierGCTask::destruct() {
-  assert(monitor() != NULL, "monitor should not be NULL");
-  if (TraceGCTaskManager) {
-    tty->print_cr("[" INTPTR_FORMAT "]"
-                  " WaitForBarrierGCTask::destruct()"
-                  "  monitor: " INTPTR_FORMAT,
-                  p2i(this), p2i(monitor()));
-  }
-  this->BarrierGCTask::destruct();
-  // Clean up that should be in the destructor,
-  // except that ResourceMarks don't call destructors.
-   if (monitor() != NULL) {
-     MonitorSupply::release(monitor());
-  }
-  _monitor = (Monitor*) 0xDEAD000F;
-}
-
 void WaitForBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
   if (TraceGCTaskManager) {
     tty->print_cr("[" INTPTR_FORMAT "]"
-                  " WaitForBarrierGCTask::do_it() waiting for idle"
-                  "  monitor: " INTPTR_FORMAT,
-                  p2i(this), p2i(monitor()));
+                  " WaitForBarrierGCTask::do_it() waiting for idle",
+                  p2i(this));
   }
   {
     // First, wait for the barrier to arrive.
@@ -1050,24 +932,30 @@
     do_it_internal(manager, which);
     // Release manager->lock().
   }
-  {
-    // Then notify the waiter.
-    MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
-    set_should_wait(false);
-    // Waiter doesn't miss the notify in the wait_for method
-    // since it checks the flag after grabbing the monitor.
-    if (TraceGCTaskManager) {
-      tty->print_cr("[" INTPTR_FORMAT "]"
-                    " WaitForBarrierGCTask::do_it()"
-                    "  [" INTPTR_FORMAT "] (%s)->notify_all()",
-                    p2i(this), p2i(monitor()), monitor()->name());
-    }
-    monitor()->notify_all();
-    // Release monitor().
+  // Then notify the waiter.
+  _wait_helper.notify();
+}
+
+WaitHelper::WaitHelper() : _should_wait(true), _monitor(MonitorSupply::reserve()) {
+  if (TraceGCTaskManager) {
+    tty->print_cr("[" INTPTR_FORMAT "]"
+                  " WaitHelper::WaitHelper()"
+                  "  monitor: " INTPTR_FORMAT,
+                  p2i(this), p2i(monitor()));
   }
 }
 
-void WaitForBarrierGCTask::wait_for(bool reset) {
+void WaitHelper::release_monitor() {
+  assert(_monitor != NULL, "");
+  MonitorSupply::release(_monitor);
+  _monitor = NULL;
+}
+
+WaitHelper::~WaitHelper() {
+  release_monitor();
+}
+
+void WaitHelper::wait_for(bool reset) {
   if (TraceGCTaskManager) {
     tty->print_cr("[" INTPTR_FORMAT "]"
                   " WaitForBarrierGCTask::wait_for()"
@@ -1100,6 +988,20 @@
   }
 }
 
+void WaitHelper::notify() {
+  MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
+  set_should_wait(false);
+  // Waiter doesn't miss the notify in the wait_for method
+  // since it checks the flag after grabbing the monitor.
+  if (TraceGCTaskManager) {
+    tty->print_cr("[" INTPTR_FORMAT "]"
+                  " WaitForBarrierGCTask::do_it()"
+                  "  [" INTPTR_FORMAT "] (%s)->notify_all()",
+                  p2i(this), p2i(monitor()), monitor()->name());
+  }
+  monitor()->notify_all();
+}
+
 Mutex*                   MonitorSupply::_lock     = NULL;
 GrowableArray<Monitor*>* MonitorSupply::_freelist = NULL;
 
--- a/hotspot/src/share/vm/gc/parallel/gcTaskManager.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskManager.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,12 +38,8 @@
 class GCTaskQueue;
 class SynchronizedGCTaskQueue;
 class GCTaskManager;
-class NotifyDoneClosure;
 // Some useful subclasses of GCTask.  You can also make up your own.
 class NoopGCTask;
-class BarrierGCTask;
-class ReleasingBarrierGCTask;
-class NotifyingBarrierGCTask;
 class WaitForBarrierGCTask;
 class IdleGCTask;
 // A free list of Monitor*'s.
@@ -64,7 +60,7 @@
     enum kind {
       unknown_task,
       ordinary_task,
-      barrier_task,
+      wait_for_barrier_task,
       noop_task,
       idle_task
     };
@@ -72,13 +68,16 @@
   };
 private:
   // Instance state.
-  const Kind::kind _kind;               // For runtime type checking.
-  const uint       _affinity;           // Which worker should run task.
+  Kind::kind       _kind;               // For runtime type checking.
+  uint             _affinity;           // Which worker should run task.
   GCTask*          _newer;              // Tasks are on doubly-linked ...
   GCTask*          _older;              // ... lists.
+  uint             _gc_id;              // GC Id to use for the thread that executes this task
 public:
   virtual char* name() { return (char *)"task"; }
 
+  uint gc_id() { return _gc_id; }
+
   // Abstract do_it method
   virtual void do_it(GCTaskManager* manager, uint which) = 0;
   // Accessors
@@ -105,7 +104,7 @@
     return kind()==Kind::ordinary_task;
   }
   bool is_barrier_task() const {
-    return kind()==Kind::barrier_task;
+    return kind()==Kind::wait_for_barrier_task;
   }
   bool is_noop_task() const {
     return kind()==Kind::noop_task;
@@ -120,17 +119,14 @@
   GCTask();
   //     A GCTask of a particular kind, usually barrier or noop.
   GCTask(Kind::kind kind);
-  //     An ordinary GCTask with an affinity.
-  GCTask(uint affinity);
-  //     A GCTask of a particular kind, with and affinity.
-  GCTask(Kind::kind kind, uint affinity);
+  GCTask(Kind::kind kind, uint gc_id);
   // We want a virtual destructor because virtual methods,
   // but since ResourceObj's don't have their destructors
   // called, we don't have one at all.  Instead we have
   // this method, which gets called by subclasses to clean up.
   virtual void destruct();
   // Methods.
-  void initialize();
+  void initialize(Kind::kind kind, uint gc_id);
 };
 
 // A doubly-linked list of GCTasks.
@@ -276,21 +272,26 @@
   ~SynchronizedGCTaskQueue();
 };
 
-// This is an abstract base class for getting notifications
-// when a GCTaskManager is done.
-class NotifyDoneClosure : public CHeapObj<mtGC> {
-public:
-  // The notification callback method.
-  virtual void notify(GCTaskManager* manager) = 0;
-protected:
-  // Constructor.
-  NotifyDoneClosure() {
-    // Nothing to do.
+class WaitHelper VALUE_OBJ_CLASS_SPEC {
+ private:
+  Monitor*      _monitor;
+  volatile bool _should_wait;
+ public:
+  WaitHelper();
+  ~WaitHelper();
+  void wait_for(bool reset);
+  void notify();
+  void set_should_wait(bool value) {
+    _should_wait = value;
   }
-  // Virtual destructor because virtual methods.
-  virtual ~NotifyDoneClosure() {
-    // Nothing to do.
+
+  Monitor* monitor() const {
+    return _monitor;
   }
+  bool should_wait() const {
+    return _should_wait;
+  }
+  void release_monitor();
 };
 
 // Dynamic number of GC threads
@@ -365,7 +366,6 @@
  friend class IdleGCTask;
 private:
   // Instance state.
-  NotifyDoneClosure*        _ndc;               // Notify on completion.
   const uint                _workers;           // Number of workers.
   Monitor*                  _monitor;           // Notification of changes.
   SynchronizedGCTaskQueue*  _queue;             // Queue of tasks.
@@ -379,17 +379,13 @@
   uint                      _barriers;          // Count of barrier tasks.
   uint                      _emptied_queue;     // Times we emptied the queue.
   NoopGCTask*               _noop_task;         // The NoopGCTask instance.
-  uint                      _noop_tasks;        // Count of noop tasks.
-  WaitForBarrierGCTask*     _idle_inactive_task;// Task for inactive workers
+  WaitHelper                _wait_helper;       // Used by inactive worker
   volatile uint             _idle_workers;      // Number of idled workers
 public:
   // Factory create and destroy methods.
   static GCTaskManager* create(uint workers) {
     return new GCTaskManager(workers);
   }
-  static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) {
-    return new GCTaskManager(workers, ndc);
-  }
   static void destroy(GCTaskManager* that) {
     if (that != NULL) {
       delete that;
@@ -409,8 +405,8 @@
   Monitor * lock() const {
     return _monitor;
   }
-  WaitForBarrierGCTask* idle_inactive_task() {
-    return _idle_inactive_task;
+  WaitHelper* wait_helper() {
+    return &_wait_helper;
   }
   // Methods.
   //     Add the argument task to be run.
@@ -452,8 +448,6 @@
   // Constructors.  Clients use factory, but there might be subclasses.
   //     Create a GCTaskManager with the appropriate number of workers.
   GCTaskManager(uint workers);
-  //     Create a GCTaskManager that calls back when there's no more work.
-  GCTaskManager(uint workers, NotifyDoneClosure* ndc);
   //     Make virtual if necessary.
   ~GCTaskManager();
   // Accessors.
@@ -469,9 +463,6 @@
   // Sets the number of threads that will be used in a collection
   void set_active_gang();
 
-  NotifyDoneClosure* notify_done_closure() const {
-    return _ndc;
-  }
   SynchronizedGCTaskQueue* queue() const {
     return _queue;
   }
@@ -540,17 +531,6 @@
   void reset_emptied_queue() {
     _emptied_queue = 0;
   }
-  //     Count of the number of noop tasks we've handed out,
-  //     e.g., to handle resource release requests.
-  uint noop_tasks() const {
-    return _noop_tasks;
-  }
-  void increment_noop_tasks() {
-    _noop_tasks += 1;
-  }
-  void reset_noop_tasks() {
-    _noop_tasks = 0;
-  }
   void increment_idle_workers() {
     _idle_workers++;
   }
@@ -575,11 +555,8 @@
 // A noop task that does nothing,
 // except take us around the GCTaskThread loop.
 class NoopGCTask : public GCTask {
-private:
-  const bool _is_c_heap_obj;            // Is this a CHeapObj?
 public:
   // Factory create and destroy methods.
-  static NoopGCTask* create();
   static NoopGCTask* create_on_c_heap();
   static void destroy(NoopGCTask* that);
 
@@ -590,147 +567,39 @@
   }
 protected:
   // Constructor.
-  NoopGCTask(bool on_c_heap) :
-    GCTask(GCTask::Kind::noop_task),
-    _is_c_heap_obj(on_c_heap) {
-    // Nothing to do.
-  }
-  // Destructor-like method.
-  void destruct();
-  // Accessors.
-  bool is_c_heap_obj() const {
-    return _is_c_heap_obj;
-  }
-};
-
-// A BarrierGCTask blocks other tasks from starting,
-// and waits until it is the only task running.
-class BarrierGCTask : public GCTask {
-public:
-  // Factory create and destroy methods.
-  static BarrierGCTask* create() {
-    return new BarrierGCTask();
-  }
-  static void destroy(BarrierGCTask* that) {
-    if (that != NULL) {
-      that->destruct();
-      delete that;
-    }
-  }
-  // Methods from GCTask.
-  void do_it(GCTaskManager* manager, uint which);
-protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  BarrierGCTask() :
-    GCTask(GCTask::Kind::barrier_task) {
-    // Nothing to do.
-  }
-  // Destructor-like method.
-  void destruct();
-
-  virtual char* name() { return (char *)"barrier task"; }
-  // Methods.
-  //     Wait for this to be the only task running.
-  void do_it_internal(GCTaskManager* manager, uint which);
-};
-
-// A ReleasingBarrierGCTask is a BarrierGCTask
-// that tells all the tasks to release their resource areas.
-class ReleasingBarrierGCTask : public BarrierGCTask {
-public:
-  // Factory create and destroy methods.
-  static ReleasingBarrierGCTask* create() {
-    return new ReleasingBarrierGCTask();
-  }
-  static void destroy(ReleasingBarrierGCTask* that) {
-    if (that != NULL) {
-      that->destruct();
-      delete that;
-    }
-  }
-  // Methods from GCTask.
-  void do_it(GCTaskManager* manager, uint which);
-protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  ReleasingBarrierGCTask() :
-    BarrierGCTask() {
-    // Nothing to do.
-  }
+  NoopGCTask();
   // Destructor-like method.
   void destruct();
 };
 
-// A NotifyingBarrierGCTask is a BarrierGCTask
-// that calls a notification method when it is the only task running.
-class NotifyingBarrierGCTask : public BarrierGCTask {
-private:
-  // Instance state.
-  NotifyDoneClosure* _ndc;              // The callback object.
-public:
-  // Factory create and destroy methods.
-  static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) {
-    return new NotifyingBarrierGCTask(ndc);
-  }
-  static void destroy(NotifyingBarrierGCTask* that) {
-    if (that != NULL) {
-      that->destruct();
-      delete that;
-    }
-  }
-  // Methods from GCTask.
-  void do_it(GCTaskManager* manager, uint which);
-protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  NotifyingBarrierGCTask(NotifyDoneClosure* ndc) :
-    BarrierGCTask(),
-    _ndc(ndc) {
-    assert(notify_done_closure() != NULL, "can't notify on NULL");
-  }
-  // Destructor-like method.
-  void destruct();
-  // Accessor.
-  NotifyDoneClosure* notify_done_closure() const { return _ndc; }
-};
-
-// A WaitForBarrierGCTask is a BarrierGCTask
+// A WaitForBarrierGCTask is a GCTask
 // with a method you can call to wait until
 // the BarrierGCTask is done.
-// This may cover many of the uses of NotifyingBarrierGCTasks.
-class WaitForBarrierGCTask : public BarrierGCTask {
+class WaitForBarrierGCTask : public GCTask {
   friend class GCTaskManager;
   friend class IdleGCTask;
 private:
   // Instance state.
-  Monitor*      _monitor;                  // Guard and notify changes.
-  volatile bool _should_wait;              // true=>wait, false=>proceed.
-  const bool    _is_c_heap_obj;            // Was allocated on the heap.
+  WaitHelper    _wait_helper;
+  WaitForBarrierGCTask();
 public:
   virtual char* name() { return (char *) "waitfor-barrier-task"; }
 
   // Factory create and destroy methods.
   static WaitForBarrierGCTask* create();
-  static WaitForBarrierGCTask* create_on_c_heap();
   static void destroy(WaitForBarrierGCTask* that);
   // Methods.
   void     do_it(GCTaskManager* manager, uint which);
-  void     wait_for(bool reset);
-  void set_should_wait(bool value) {
-    _should_wait = value;
-  }
 protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  WaitForBarrierGCTask(bool on_c_heap);
   // Destructor-like method.
   void destruct();
-  // Accessors.
-  Monitor* monitor() const {
-    return _monitor;
-  }
-  bool should_wait() const {
-    return _should_wait;
-  }
-  bool is_c_heap_obj() {
-    return _is_c_heap_obj;
+
+  // Methods.
+  //     Wait for this to be the only task running.
+  void do_it_internal(GCTaskManager* manager, uint which);
+
+  void wait_for(bool reset) {
+    _wait_helper.wait_for(reset);
   }
 };
 
--- a/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #include "precompiled.hpp"
 #include "gc/parallel/gcTaskManager.hpp"
 #include "gc/parallel/gcTaskThread.hpp"
+#include "gc/shared/gcId.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -124,6 +125,7 @@
     for (; /* break */; ) {
       // This will block until there is a task to be gotten.
       GCTask* task = manager()->get_task(which());
+      GCIdMark gc_id_mark(task->gc_id());
       // Record if this is an idle task for later use.
       bool is_idle_task = task->is_idle_task();
       // In case the update is costly
--- a/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -85,8 +85,8 @@
         while (words_left_to_fill > 0) {
           size_t words_to_fill = MIN2(words_left_to_fill, CollectedHeap::filler_array_max_size());
           assert(words_to_fill >= CollectedHeap::min_fill_size(),
-            err_msg("Remaining size (" SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")",
-            words_to_fill, words_left_to_fill, CollectedHeap::filler_array_max_size()));
+                 "Remaining size (" SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")",
+                 words_to_fill, words_left_to_fill, CollectedHeap::filler_array_max_size());
           CollectedHeap::fill_with_object((HeapWord*)cur_top, words_to_fill);
           if (!os::numa_has_static_binding()) {
             size_t touched_words = words_to_fill;
@@ -971,7 +971,7 @@
       break;
     }
     if (e != scan_end) {
-      assert(e < scan_end, err_msg("e: " PTR_FORMAT " scan_end: " PTR_FORMAT, p2i(e), p2i(scan_end)));
+      assert(e < scan_end, "e: " PTR_FORMAT " scan_end: " PTR_FORMAT, p2i(e), p2i(scan_end));
 
       if ((page_expected.size != page_size || page_expected.lgrp_id != lgrp_id())
           && page_expected.size != 0) {
--- a/hotspot/src/share/vm/gc/parallel/objectStartArray.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/objectStartArray.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -127,8 +127,8 @@
 bool ObjectStartArray::object_starts_in_range(HeapWord* start_addr,
                                               HeapWord* end_addr) const {
   assert(start_addr <= end_addr,
-         err_msg("Range is wrong. start_addr (" PTR_FORMAT ") is after end_addr (" PTR_FORMAT ")",
-                 p2i(start_addr), p2i(end_addr)));
+         "Range is wrong. start_addr (" PTR_FORMAT ") is after end_addr (" PTR_FORMAT ")",
+         p2i(start_addr), p2i(end_addr));
   if (start_addr > end_addr) {
     return false;
   }
--- a/hotspot/src/share/vm/gc/parallel/objectStartArray.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/objectStartArray.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -121,8 +121,8 @@
 
 #define assert_covered_region_contains(addr)                                                                 \
         assert(_covered_region.contains(addr),                                                               \
-               err_msg(#addr " (" PTR_FORMAT ") is not in covered region [" PTR_FORMAT ", " PTR_FORMAT "]",  \
-                       p2i(addr), p2i(_covered_region.start()), p2i(_covered_region.end())))
+               #addr " (" PTR_FORMAT ") is not in covered region [" PTR_FORMAT ", " PTR_FORMAT "]",          \
+               p2i(addr), p2i(_covered_region.start()), p2i(_covered_region.end()))
 
   void allocate_block(HeapWord* p) {
     assert_covered_region_contains(p);
--- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -390,9 +390,9 @@
 inline void ParMarkBitMap::verify_addr(HeapWord* addr) const {
   // Allow one past the last valid address; useful for loop bounds.
   assert(addr >= region_start(),
-      err_msg("addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, p2i(addr), p2i(region_start())));
+         "addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, p2i(addr), p2i(region_start()));
   assert(addr <= region_end(),
-      err_msg("addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, p2i(addr), p2i(region_end())));
+         "addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, p2i(addr), p2i(region_end()));
 }
 #endif  // #ifdef ASSERT
 
--- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -48,7 +48,7 @@
   // Assumes the the old gen address range is lower than that of the young gen.
   bool result = ((HeapWord*)p) >= young_gen()->reserved().start();
   assert(result == young_gen()->is_in_reserved(p),
-        err_msg("incorrect test - result=%d, p=" PTR_FORMAT, result, p2i((void*)p)));
+         "incorrect test - result=%d, p=" PTR_FORMAT, result, p2i((void*)p));
   return result;
 }
 #endif // SHARE_VM_GC_PARALLEL_PARALLELSCAVENGEHEAP_INLINE_HPP
--- a/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -53,7 +53,7 @@
   ResourceMark rm;
 
   NOT_PRODUCT(GCTraceTime tm("ThreadRootsMarkingTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
 
@@ -82,7 +82,7 @@
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
@@ -153,7 +153,7 @@
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("RefProcTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
@@ -209,7 +209,7 @@
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("StealMarkingTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
@@ -241,7 +241,7 @@
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("StealRegionCompactionTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
@@ -254,9 +254,9 @@
   if (use_all_workers) {
     which_stack_index = which;
     assert(manager->active_workers() == ParallelGCThreads,
-           err_msg("all_workers_active has been incorrectly set: "
-                   " active %d  ParallelGCThreads %u", manager->active_workers(),
-                   ParallelGCThreads));
+           "all_workers_active has been incorrectly set: "
+           " active %d  ParallelGCThreads %u", manager->active_workers(),
+           ParallelGCThreads);
   } else {
     which_stack_index = ParCompactionManager::pop_recycled_stack_index();
   }
@@ -308,7 +308,7 @@
 void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
 
   NOT_PRODUCT(GCTraceTime tm("UpdateDensePrefixTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
@@ -323,7 +323,7 @@
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("DrainStacksCompactionTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
 
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
@@ -333,9 +333,9 @@
   if (use_all_workers) {
     which_stack_index = which;
     assert(manager->active_workers() == ParallelGCThreads,
-           err_msg("all_workers_active has been incorrectly set: "
-                   " active %d  ParallelGCThreads %u", manager->active_workers(),
-                   ParallelGCThreads));
+           "all_workers_active has been incorrectly set: "
+           " active %d  ParallelGCThreads %u", manager->active_workers(),
+           ParallelGCThreads);
   } else {
     which_stack_index = stack_index();
   }
--- a/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,6 +36,7 @@
 #include "gc/serial/markSweep.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
@@ -113,6 +114,7 @@
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   GCCause::Cause gc_cause = heap->gc_cause();
 
+  GCIdMark gc_id_mark;
   _gc_timer->register_gc_start();
   _gc_tracer->report_gc_start(gc_cause, _gc_timer->gc_start());
 
@@ -165,7 +167,7 @@
     HandleMark hm;
 
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer->gc_id());
+    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -189,7 +191,9 @@
 
     allocate_stacks();
 
-    COMPILER2_PRESENT(DerivedPointerTable::clear());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTable::clear();
+#endif
 
     ref_processor()->enable_discovery();
     ref_processor()->setup_policy(clear_all_softrefs);
@@ -198,9 +202,11 @@
 
     mark_sweep_phase2();
 
+#if defined(COMPILER2) || INCLUDE_JVMCI
     // Don't add any more derived pointers during phase3
-    COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
-    COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
+    assert(DerivedPointerTable::is_active(), "Sanity");
+    DerivedPointerTable::set_active(false);
+#endif
 
     mark_sweep_phase3();
 
@@ -245,7 +251,9 @@
     CodeCache::gc_epilogue();
     JvmtiExport::gc_epilogue();
 
-    COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTable::update_pointers();
+#endif
 
     ref_processor()->enqueue_discovered_references(NULL);
 
@@ -508,7 +516,7 @@
 
 void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
@@ -541,7 +549,7 @@
     ref_processor()->setup_policy(clear_all_softrefs);
     const ReferenceProcessorStats& stats =
       ref_processor()->process_discovered_references(
-        is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer, _gc_tracer->gc_id());
+        is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer);
     gc_tracer()->report_gc_reference_stats(stats);
   }
 
@@ -567,7 +575,7 @@
 
 
 void PSMarkSweep::mark_sweep_phase2() {
-  GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer);
 
   // Now all live objects are marked, compute the new object addresses.
 
@@ -594,7 +602,7 @@
 
 void PSMarkSweep::mark_sweep_phase3() {
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
@@ -634,7 +642,7 @@
 
 void PSMarkSweep::mark_sweep_phase4() {
   EventMark m("4 compact heap");
-  GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer);
 
   // All pointers are now adjusted, move objects accordingly
 
--- a/hotspot/src/share/vm/gc/parallel/psOldGen.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psOldGen.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -65,15 +65,15 @@
     // Explictly capture current covered_region in a local
     MemRegion covered_region = this->start_array()->covered_region();
     assert(covered_region.contains(new_memregion),
-           err_msg("new region is not in covered_region [ " PTR_FORMAT ", " PTR_FORMAT " ], "
-                   "new region [ " PTR_FORMAT ", " PTR_FORMAT " ], "
-                   "object space [ " PTR_FORMAT ", " PTR_FORMAT " ]",
-                   p2i(covered_region.start()),
-                   p2i(covered_region.end()),
-                   p2i(new_memregion.start()),
-                   p2i(new_memregion.end()),
-                   p2i(this->object_space()->used_region().start()),
-                   p2i(this->object_space()->used_region().end())));
+           "new region is not in covered_region [ " PTR_FORMAT ", " PTR_FORMAT " ], "
+           "new region [ " PTR_FORMAT ", " PTR_FORMAT " ], "
+           "object space [ " PTR_FORMAT ", " PTR_FORMAT " ]",
+           p2i(covered_region.start()),
+           p2i(covered_region.end()),
+           p2i(new_memregion.start()),
+           p2i(new_memregion.end()),
+           p2i(this->object_space()->used_region().start()),
+           p2i(this->object_space()->used_region().end()));
   }
 #endif
 
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -40,6 +40,7 @@
 #include "gc/parallel/psYoungGen.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
@@ -960,7 +961,7 @@
   // at each young gen gc.  Do the update unconditionally (even though a
   // promotion failure does not swap spaces) because an unknown number of young
   // collections will have swapped the spaces an unknown number of times.
-  GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer);
   ParallelScavengeHeap* heap = ParallelScavengeHeap::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());
@@ -1003,7 +1004,7 @@
 
 void PSParallelCompact::post_compact()
 {
-  GCTraceTime tm("post compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  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.
@@ -1045,7 +1046,9 @@
   CodeCache::gc_epilogue();
   JvmtiExport::gc_epilogue();
 
-  COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  DerivedPointerTable::update_pointers();
+#endif
 
   ref_processor()->enqueue_discovered_references(NULL);
 
@@ -1824,7 +1827,7 @@
 void PSParallelCompact::summary_phase(ParCompactionManager* cm,
                                       bool maximum_compaction)
 {
-  GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer);
   // trace("2");
 
 #ifdef  ASSERT
@@ -1984,6 +1987,7 @@
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
+  GCIdMark gc_id_mark;
   _gc_timer.register_gc_start();
   _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
 
@@ -2031,7 +2035,7 @@
     gc_task_manager()->task_idle_workers();
 
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
+    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -2042,7 +2046,9 @@
 
     CodeCache::gc_prologue();
 
-    COMPILER2_PRESENT(DerivedPointerTable::clear());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTable::clear();
+#endif
 
     ref_processor()->enable_discovery();
     ref_processor()->setup_policy(maximum_heap_compaction);
@@ -2056,8 +2062,10 @@
       && GCCause::is_user_requested_gc(gc_cause);
     summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
 
-    COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
-    COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    assert(DerivedPointerTable::is_active(), "Sanity");
+    DerivedPointerTable::set_active(false);
+#endif
 
     // adjust_roots() updates Universe::_intArrayKlassObj which is
     // needed by the compaction for filling holes in the dense prefix.
@@ -2331,7 +2339,7 @@
                                       bool maximum_heap_compaction,
                                       ParallelOldTracer *gc_tracer) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
@@ -2346,7 +2354,7 @@
   ClassLoaderDataGraph::clear_claimed_marks();
 
   {
-    GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+    GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer);
 
     ParallelScavengeHeap::ParStrongRootsScope psrs;
 
@@ -2375,24 +2383,24 @@
 
   // Process reference objects found during marking
   {
-    GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+    GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer);
 
     ReferenceProcessorStats stats;
     if (ref_processor()->processing_is_mt()) {
       RefProcTaskExecutor task_executor;
       stats = ref_processor()->process_discovered_references(
         is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
-        &task_executor, &_gc_timer, _gc_tracer.gc_id());
+        &task_executor, &_gc_timer);
     } else {
       stats = ref_processor()->process_discovered_references(
         is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL,
-        &_gc_timer, _gc_tracer.gc_id());
+        &_gc_timer);
     }
 
     gc_tracer->report_gc_reference_stats(stats);
   }
 
-  GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  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");
@@ -2423,7 +2431,7 @@
 
 void PSParallelCompact::adjust_roots() {
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  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 +2467,7 @@
 void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
                                                       uint parallel_gc_threads)
 {
-  GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer);
 
   // Find the threads that are active
   unsigned int which = 0;
@@ -2533,7 +2541,7 @@
 
 void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
                                                     uint parallel_gc_threads) {
-  GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer);
 
   ParallelCompactData& sd = PSParallelCompact::summary_data();
 
@@ -2615,7 +2623,7 @@
                                      GCTaskQueue* q,
                                      ParallelTaskTerminator* terminator_ptr,
                                      uint parallel_gc_threads) {
-  GCTraceTime tm("steal task setup", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  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.
@@ -2663,7 +2671,7 @@
 
 void PSParallelCompact::compact() {
   // trace("5");
-  GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+  GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSOldGen* old_gen = heap->old_gen();
@@ -2679,7 +2687,7 @@
   enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
 
   {
-    GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+    GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer);
 
     gc_task_manager()->execute_and_wait(q);
 
@@ -2693,7 +2701,7 @@
 
   {
     // Update the deferred objects, if any.  Any compaction manager can be used.
-    GCTraceTime tm_du("deferred updates", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+    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));
@@ -2851,7 +2859,7 @@
         start_array->allocate_block(addr);
       }
       cm->update_contents(oop(addr));
-      assert(oop(addr)->is_oop_or_null(), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(oop(addr))));
+      assert(oop(addr)->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(oop(addr)));
     }
   }
 }
@@ -3400,7 +3408,7 @@
 
   oop moved_oop = (oop) destination();
   compaction_manager()->update_contents(moved_oop);
-  assert(moved_oop->is_oop_or_null(), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(moved_oop)));
+  assert(moved_oop->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(moved_oop));
 
   update_state(words);
   assert(destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity");
--- a/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,6 +36,7 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
@@ -278,6 +279,7 @@
     return false;
   }
 
+  GCIdMark gc_id_mark;
   _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
 
   bool promotion_failure_occurred = false;
@@ -322,7 +324,7 @@
     HandleMark hm;
 
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
+    GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
 
@@ -351,7 +353,9 @@
     }
     save_to_space_top_before_gc();
 
-    COMPILER2_PRESENT(DerivedPointerTable::clear());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTable::clear();
+#endif
 
     reference_processor()->enable_discovery();
     reference_processor()->setup_policy(false);
@@ -387,7 +391,7 @@
     // We'll use the promotion manager again later.
     PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
     {
-      GCTraceTime tm("Scavenge", false, false, &_gc_timer, _gc_tracer.gc_id());
+      GCTraceTime tm("Scavenge", false, false, &_gc_timer);
       ParallelScavengeHeap::ParStrongRootsScope psrs;
 
       GCTaskQueue* q = GCTaskQueue::create();
@@ -429,7 +433,7 @@
 
     // Process reference objects discovered during scavenge
     {
-      GCTraceTime tm("References", false, false, &_gc_timer, _gc_tracer.gc_id());
+      GCTraceTime tm("References", false, false, &_gc_timer);
 
       reference_processor()->setup_policy(false); // not always_clear
       reference_processor()->set_active_mt_degree(active_workers);
@@ -440,10 +444,10 @@
         PSRefProcTaskExecutor task_executor;
         stats = reference_processor()->process_discovered_references(
           &_is_alive_closure, &keep_alive, &evac_followers, &task_executor,
-          &_gc_timer, _gc_tracer.gc_id());
+          &_gc_timer);
       } else {
         stats = reference_processor()->process_discovered_references(
-          &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer, _gc_tracer.gc_id());
+          &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer);
       }
 
       _gc_tracer.report_gc_reference_stats(stats);
@@ -458,7 +462,7 @@
     }
 
     {
-      GCTraceTime tm("StringTable", false, false, &_gc_timer, _gc_tracer.gc_id());
+      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);
@@ -473,6 +477,8 @@
       }
     }
 
+    _gc_tracer.report_tenuring_threshold(tenuring_threshold());
+
     // Let the size policy know we're done.  Note that we count promotion
     // failure cleanup time as part of the collection (otherwise, we're
     // implicitly saying it's mutator time).
@@ -623,12 +629,14 @@
       assert(young_gen->to_space()->is_empty(), "to space should be empty now");
     }
 
-    COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+    DerivedPointerTable::update_pointers();
+#endif
 
     NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
 
     {
-      GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer, _gc_tracer.gc_id());
+      GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer);
 
       CodeCache::prune_scavenge_root_nmethods();
     }
@@ -672,7 +680,6 @@
 
   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();
@@ -819,7 +826,7 @@
 
   if (AlwaysTenure || NeverTenure) {
     assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markOopDesc::max_age + 1,
-        err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is %d", (int) MaxTenuringThreshold));
+           "MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is %d", (int) MaxTenuringThreshold);
     _tenuring_threshold = MaxTenuringThreshold;
   } else {
     // We want to smooth out our startup times for the AdaptiveSizePolicy
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -583,7 +583,7 @@
 
   init_assuming_no_promotion_failure();
 
-  GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, gc_tracer.gc_id());
+  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();
 
@@ -646,8 +646,9 @@
   rp->setup_policy(clear_all_soft_refs);
   const ReferenceProcessorStats& stats =
   rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers,
-                                    NULL, _gc_timer, gc_tracer.gc_id());
+                                    NULL, _gc_timer);
   gc_tracer.report_gc_reference_stats(stats);
+  gc_tracer.report_tenuring_threshold(tenuring_threshold());
 
   if (!_promotion_failed) {
     // Swap the survivor spaces.
@@ -712,7 +713,6 @@
   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();
 
--- a/hotspot/src/share/vm/gc/serial/genMarkSweep.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/serial/genMarkSweep.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -70,7 +70,7 @@
   set_ref_processor(rp);
   rp->setup_policy(clear_all_softrefs);
 
-  GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, _gc_tracer->gc_id());
+  GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
 
   gch->trace_heap_before_gc(_gc_tracer);
 
@@ -96,8 +96,10 @@
   mark_sweep_phase2();
 
   // Don't add any more derived pointers during phase3
-  COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
-  COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  assert(DerivedPointerTable::is_active(), "Sanity");
+  DerivedPointerTable::set_active(false);
+#endif
 
   mark_sweep_phase3();
 
@@ -186,7 +188,7 @@
 
 void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer);
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
@@ -217,7 +219,7 @@
     ref_processor()->setup_policy(clear_all_softrefs);
     const ReferenceProcessorStats& stats =
       ref_processor()->process_discovered_references(
-        &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer, _gc_tracer->gc_id());
+        &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer);
     gc_tracer()->report_gc_reference_stats(stats);
   }
 
@@ -259,7 +261,7 @@
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer);
 
   gch->prepare_for_compaction();
 }
@@ -275,7 +277,7 @@
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer);
 
   // Need new claim bits for the pointer adjustment tracing.
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -327,7 +329,7 @@
   // to use a higher index (saved from phase2) when verifying perm_gen.
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+  GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer);
 
   GenCompactClosure blk;
   gch->generation_iterate(&blk, true);
--- a/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -129,8 +129,8 @@
   CardGeneration::compute_new_size();
 
   assert(used() == used_after_gc && used_after_gc <= capacity(),
-         err_msg("used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT
-         " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity()));
+         "used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT
+         " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity());
 }
 
 void TenuredGeneration::update_gc_stats(Generation* current_generation,
--- a/hotspot/src/share/vm/gc/shared/ageTable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/ageTable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -78,7 +78,7 @@
 
   if (AlwaysTenure || NeverTenure) {
     assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markOopDesc::max_age + 1,
-        err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is " UINTX_FORMAT, MaxTenuringThreshold));
+           "MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is " UINTX_FORMAT, MaxTenuringThreshold);
     result = MaxTenuringThreshold;
   } else {
     size_t total = 0;
--- a/hotspot/src/share/vm/gc/shared/barrierSet.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/barrierSet.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -188,6 +188,9 @@
   static void static_write_ref_array_pre(HeapWord* start, size_t count);
   static void static_write_ref_array_post(HeapWord* start, size_t count);
 
+  virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm) {}
+  virtual void write_ref_nmethod_post(oop* dst, nmethod* nm) {}
+
 protected:
   virtual void write_ref_array_work(MemRegion mr) = 0;
 public:
--- a/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -543,11 +543,11 @@
     size_t n_cards_back = entry_to_cards_back(offset);
     q -= (N_words * n_cards_back);
     assert(q >= _sp->bottom(),
-           err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
-                   p2i(q), p2i(_sp->bottom())));
+           "q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
+           p2i(q), p2i(_sp->bottom()));
     assert(q < _sp->end(),
-           err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
-                   p2i(q), p2i(_sp->end())));
+           "q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
+           p2i(q), p2i(_sp->end()));
     index -= n_cards_back;
     offset = _array->offset_array(index);
   }
@@ -555,11 +555,11 @@
   index--;
   q -= offset;
   assert(q >= _sp->bottom(),
-         err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
-                 p2i(q), p2i(_sp->bottom())));
+         "q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
+         p2i(q), p2i(_sp->bottom()));
   assert(q < _sp->end(),
-         err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
-                 p2i(q), p2i(_sp->end())));
+         "q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
+         p2i(q), p2i(_sp->end()));
   HeapWord* n = q;
 
   while (n <= addr) {
@@ -567,17 +567,17 @@
     q = n;
     n += _sp->block_size(n);
     assert(n > q,
-           err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT ","
-                   " while querying blk_start(" PTR_FORMAT ")"
-                   " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")",
-                   p2i(n), p2i(last), p2i(addr), p2i(_sp->bottom()), p2i(_sp->end())));
+           "Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT ","
+           " while querying blk_start(" PTR_FORMAT ")"
+           " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")",
+           p2i(n), p2i(last), p2i(addr), p2i(_sp->bottom()), p2i(_sp->end()));
   }
   assert(q <= addr,
-         err_msg("wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")",
-                 p2i(q), p2i(addr)));
+         "wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")",
+         p2i(q), p2i(addr));
   assert(addr <= n,
-         err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")",
-                 p2i(addr), p2i(n)));
+         "wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")",
+         p2i(addr), p2i(n));
   return q;
 }
 
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -126,9 +126,9 @@
   // Mapping from address to card marking array entry
   jbyte* byte_for(const void* p) const {
     assert(_whole_heap.contains(p),
-           err_msg("Attempt to access p = " PTR_FORMAT " out of bounds of "
-                   " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
-                   p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())));
+           "Attempt to access p = " PTR_FORMAT " out of bounds of "
+           " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
+           p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
     jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift];
     assert(result >= _byte_map && result < _byte_map + _byte_map_size,
            "out of bounds accessor for card marking array");
@@ -294,18 +294,18 @@
     size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte));
     HeapWord* result = (HeapWord*) (delta << card_shift);
     assert(_whole_heap.contains(result),
-           err_msg("Returning result = " PTR_FORMAT " out of bounds of "
-                   " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
-                   p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end())));
+           "Returning result = " PTR_FORMAT " out of bounds of "
+           " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
+           p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
     return result;
   }
 
   // Mapping from address to card marking array index.
   size_t index_for(void* p) {
     assert(_whole_heap.contains(p),
-           err_msg("Attempt to access p = " PTR_FORMAT " out of bounds of "
-                   " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
-                   p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())));
+           "Attempt to access p = " PTR_FORMAT " out of bounds of "
+           " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
+           p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
     return byte_for(p) - _byte_map;
   }
 
--- a/hotspot/src/share/vm/gc/shared/cardTableRS.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/cardTableRS.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -278,10 +278,10 @@
   // CMS+ParNew until related bug is fixed.
   MemRegion ur    = sp->used_region();
   assert(ur.contains(urasm) || (UseConcMarkSweepGC),
-         err_msg("Did you forget to call save_marks()? "
-                 "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
-                 "[" PTR_FORMAT ", " PTR_FORMAT ")",
-                 p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end())));
+         "Did you forget to call save_marks()? "
+         "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
+         "[" PTR_FORMAT ", " PTR_FORMAT ")",
+         p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()));
   // In the case of CMS+ParNew, issue a warning
   if (!ur.contains(urasm)) {
     assert(UseConcMarkSweepGC, "Tautology: see assert above");
@@ -342,25 +342,25 @@
   template <class T> void do_oop_work(T* p) {
     HeapWord* jp = (HeapWord*)p;
     assert(jp >= _begin && jp < _end,
-           err_msg("Error: jp " PTR_FORMAT " should be within "
-                   "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")",
-                   p2i(jp), p2i(_begin), p2i(_end)));
+           "Error: jp " PTR_FORMAT " should be within "
+           "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")",
+           p2i(jp), p2i(_begin), p2i(_end));
     oop obj = oopDesc::load_decode_heap_oop(p);
     guarantee(obj == NULL || (HeapWord*)obj >= _boundary,
-              err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on "
-                      "clean card crosses boundary" PTR_FORMAT,
-                      p2i((HeapWord*)obj), p2i(jp), p2i(_boundary)));
+              "pointer " PTR_FORMAT " at " PTR_FORMAT " on "
+              "clean card crosses boundary" PTR_FORMAT,
+              p2i(obj), p2i(jp), p2i(_boundary));
   }
 
 public:
   VerifyCleanCardClosure(HeapWord* b, HeapWord* begin, HeapWord* end) :
     _boundary(b), _begin(begin), _end(end) {
     assert(b <= begin,
-           err_msg("Error: boundary " PTR_FORMAT " should be at or below begin " PTR_FORMAT,
-                   p2i(b), p2i(begin)));
+           "Error: boundary " PTR_FORMAT " should be at or below begin " PTR_FORMAT,
+           p2i(b), p2i(begin));
     assert(begin <= end,
-           err_msg("Error: begin " PTR_FORMAT " should be strictly below end " PTR_FORMAT,
-                   p2i(begin), p2i(end)));
+           "Error: begin " PTR_FORMAT " should be strictly below end " PTR_FORMAT,
+           p2i(begin), p2i(end));
   }
 
   virtual void do_oop(oop* p)       { VerifyCleanCardClosure::do_oop_work(p); }
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -231,7 +231,7 @@
 void CollectedHeap::pre_initialize() {
   // Used for ReduceInitialCardMarks (when COMPILER2 is used);
   // otherwise remains unused.
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   _defer_initial_card_mark =    ReduceInitialCardMarks && can_elide_tlab_store_barriers()
                              && (DeferInitialCardMark || card_mark_must_follow_store());
 #else
@@ -459,7 +459,7 @@
 
   const size_t payload_size = words - filler_array_hdr_size();
   const size_t len = payload_size * HeapWordSize / sizeof(jint);
-  assert((int)len >= 0, err_msg("size too large " SIZE_FORMAT " becomes %d", words, (int)len));
+  assert((int)len >= 0, "size too large " SIZE_FORMAT " becomes %d", words, (int)len);
 
   // Set the length first for concurrent GC.
   ((arrayOop)start)->set_length((int)len);
@@ -539,7 +539,7 @@
          " to threads list is doomed to failure!");
   for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
      if (use_tlab) thread->tlab().make_parsable(retire_tlabs);
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
      // The deferred store barriers must all have been flushed to the
      // card-table (or other remembered set structure) before GC starts
      // processing the card-table (or other remembered set).
@@ -573,13 +573,15 @@
 
 void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
   if (HeapDumpBeforeFullGC) {
-    GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer, GCId::create());
+    GCIdMarkAndRestore gc_id_mark;
+    GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer);
     // We are doing a full collection and a heap dump before
     // full collection has been requested.
     HeapDumper::dump_heap();
   }
   if (PrintClassHistogramBeforeFullGC) {
-    GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer, GCId::create());
+    GCIdMarkAndRestore gc_id_mark;
+    GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer);
     VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
     inspector.doit();
   }
@@ -587,11 +589,13 @@
 
 void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
   if (HeapDumpAfterFullGC) {
-    GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer, GCId::create());
+    GCIdMarkAndRestore gc_id_mark;
+    GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer);
     HeapDumper::dump_heap();
   }
   if (PrintClassHistogramAfterFullGC) {
-    GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer, GCId::create());
+    GCIdMarkAndRestore gc_id_mark;
+    GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer);
     VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
     inspector.doit();
   }
@@ -622,12 +626,12 @@
   assert(heap_start >= ((uintptr_t)NULL + epsilon), "sanity");
   void* before_heap = (void*)(heap_start - epsilon);
   assert(!heap->is_in(before_heap),
-      err_msg("before_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(before_heap)));
+         "before_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(before_heap));
 
   // Test that a pointer to after the heap end is reported as outside the heap.
   assert(heap_end <= ((uintptr_t)-1 - epsilon), "sanity");
   void* after_heap = (void*)(heap_end + epsilon);
   assert(!heap->is_in(after_heap),
-      err_msg("after_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(after_heap)));
+         "after_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(after_heap));
 }
 #endif
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -90,7 +90,8 @@
 
   GCHeapLog* _gc_heap_log;
 
-  // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2 is being used
+  // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2
+  // or INCLUDE_JVMCI is being used
   bool _defer_initial_card_mark;
 
   MemRegion _reserved;
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -244,9 +244,9 @@
   }
 
   assert(is_ptr_aligned(addr, HeapWordSize),
-    err_msg("Address " PTR_FORMAT " is not properly aligned.", p2i(addr)));
+         "Address " PTR_FORMAT " is not properly aligned.", p2i(addr));
   assert(is_size_aligned(alignment_in_bytes, HeapWordSize),
-    err_msg("Alignment size %u is incorrect.", alignment_in_bytes));
+         "Alignment size %u is incorrect.", alignment_in_bytes);
 
   HeapWord* new_addr = (HeapWord*) align_pointer_up(addr, alignment_in_bytes);
   size_t padding = pointer_delta(new_addr, addr);
@@ -258,13 +258,13 @@
   if (padding < CollectedHeap::min_fill_size()) {
     padding += alignment_in_bytes / HeapWordSize;
     assert(padding >= CollectedHeap::min_fill_size(),
-      err_msg("alignment_in_bytes %u is expect to be larger "
-      "than the minimum object size", alignment_in_bytes));
+           "alignment_in_bytes %u is expect to be larger "
+           "than the minimum object size", alignment_in_bytes);
     new_addr = addr + padding;
   }
 
-  assert(new_addr > addr, err_msg("Unexpected arithmetic overflow "
-    PTR_FORMAT " not greater than " PTR_FORMAT, p2i(new_addr), p2i(addr)));
+  assert(new_addr > addr, "Unexpected arithmetic overflow "
+         PTR_FORMAT " not greater than " PTR_FORMAT, p2i(new_addr), p2i(addr));
   if(new_addr < end) {
     CollectedHeap::fill_with_object(addr, padding);
     return new_addr;
--- a/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -78,11 +78,11 @@
   assert(_space_alignment != 0, "Space alignment not set up properly");
   assert(_heap_alignment != 0, "Heap alignment not set up properly");
   assert(_heap_alignment >= _space_alignment,
-         err_msg("heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
-                 _heap_alignment, _space_alignment));
+         "heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
+         _heap_alignment, _space_alignment);
   assert(_heap_alignment % _space_alignment == 0,
-         err_msg("heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
-                 _heap_alignment, _space_alignment));
+         "heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
+         _heap_alignment, _space_alignment);
 
   if (FLAG_IS_CMDLINE(MaxHeapSize)) {
     if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
@@ -275,14 +275,14 @@
 
   assert(_gen_alignment != 0, "Generation alignment not set up properly");
   assert(_heap_alignment >= _gen_alignment,
-         err_msg("heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,
-                 _heap_alignment, _gen_alignment));
+         "heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,
+         _heap_alignment, _gen_alignment);
   assert(_gen_alignment % _space_alignment == 0,
-         err_msg("gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
-                 _gen_alignment, _space_alignment));
+         "gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
+         _gen_alignment, _space_alignment);
   assert(_heap_alignment % _gen_alignment == 0,
-         err_msg("heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,
-                 _heap_alignment, _gen_alignment));
+         "heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,
+         _heap_alignment, _gen_alignment);
 
   // All generational heaps have a youngest gen; handle those flags here
 
@@ -1012,14 +1012,14 @@
     MarkSweepPolicy msp;
     msp.initialize_all();
 
-    assert(msp.min_young_size() <= expected, err_msg("%zu  > %zu", msp.min_young_size(), expected));
+    assert(msp.min_young_size() <= expected, "%zu  > %zu", msp.min_young_size(), expected);
   }
 
   static void verify_young_initial(size_t expected) {
     MarkSweepPolicy msp;
     msp.initialize_all();
 
-    assert(msp.initial_young_size() == expected, err_msg("%zu != %zu", msp.initial_young_size(), expected));
+    assert(msp.initial_young_size() == expected, "%zu != %zu", msp.initial_young_size(), expected);
   }
 
   static void verify_scaled_young_initial(size_t initial_heap_size) {
@@ -1033,23 +1033,23 @@
     }
 
     size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);
-    assert(msp.initial_young_size() == expected, err_msg("%zu != %zu", msp.initial_young_size(), expected));
+    assert(msp.initial_young_size() == expected, "%zu != %zu", msp.initial_young_size(), expected);
     assert(FLAG_IS_ERGO(NewSize) && NewSize == expected,
-        err_msg("NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize));
+        "NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize);
   }
 
   static void verify_old_min(size_t expected) {
     MarkSweepPolicy msp;
     msp.initialize_all();
 
-    assert(msp.min_old_size() <= expected, err_msg("%zu  > %zu", msp.min_old_size(), expected));
+    assert(msp.min_old_size() <= expected, "%zu  > %zu", msp.min_old_size(), expected);
   }
 
   static void verify_old_initial(size_t expected) {
     MarkSweepPolicy msp;
     msp.initialize_all();
 
-    assert(msp.initial_old_size() == expected, err_msg("%zu != %zu", msp.initial_old_size(), expected));
+    assert(msp.initial_old_size() == expected, "%zu != %zu", msp.initial_old_size(), expected);
   }
 
 
--- a/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -33,10 +33,6 @@
 #include "runtime/javaCalls.hpp"
 #include "runtime/os.hpp"
 
-// CopyrightVersion 1.2
-
-int  ConcurrentGCThread::_CGC_flag            = CGC_nil;
-
 ConcurrentGCThread::ConcurrentGCThread() :
   _should_terminate(false), _has_terminated(false) {
 };
--- a/hotspot/src/share/vm/gc/shared/concurrentGCThread.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/concurrentGCThread.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -35,19 +35,6 @@
   bool _should_terminate;
   bool _has_terminated;
 
-  enum CGC_flag_type {
-    CGC_nil           = 0x0,
-    CGC_dont_suspend  = 0x1,
-    CGC_CGC_safepoint = 0x2,
-    CGC_VM_safepoint  = 0x4
-  };
-
-  static int _CGC_flag;
-
-  static bool CGC_flag_is_set(int b)       { return (_CGC_flag & b) != 0; }
-  static int set_CGC_flag(int b)           { return _CGC_flag |= b; }
-  static int reset_CGC_flag(int b)         { return _CGC_flag &= ~b; }
-
   // Create and start the thread (setting it's priority high.)
   void create_and_start();
 
@@ -63,13 +50,10 @@
   void terminate();
 
 public:
-  // Constructor
-
   ConcurrentGCThread();
-  ~ConcurrentGCThread() {} // Exists to call NamedThread destructor.
 
   // Tester
-  bool is_ConcurrentGC_thread() const          { return true;       }
+  bool is_ConcurrentGC_thread() const { return true; }
 };
 
 // The SurrogateLockerThread is used by concurrent GC threads for
--- a/hotspot/src/share/vm/gc/shared/gcCause.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcCause.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -95,9 +95,9 @@
   // Causes for collection of the tenured gernation
   inline static bool is_tenured_allocation_failure_gc(GCCause::Cause cause) {
     assert(cause != GCCause::_old_generation_too_full_to_scavenge &&
-      cause != GCCause::_old_generation_expanded_on_last_scavenge,
-      err_msg("This GCCause may be correct but is not expected yet: %s",
-      to_string(cause)));
+           cause != GCCause::_old_generation_expanded_on_last_scavenge,
+           "This GCCause may be correct but is not expected yet: %s",
+           to_string(cause));
     // _tenured_generation_full or _cms_generation_full for full tenured generations
     // _adaptive_size_policy for a full collection after a young GC
     // _allocation_failure is the generic cause a collection which could result
@@ -141,14 +141,14 @@
       _position = jio_snprintf(_buffer, _length, "%s ", prefix);
      }
      assert(_position >= 0 && _position <= _length,
-       err_msg("Need to increase the buffer size in GCCauseString? %d", _position));
+            "Need to increase the buffer size in GCCauseString? %d", _position);
    }
 
    GCCauseString& append(const char* str) {
      int res = jio_snprintf(_buffer + _position, _length - _position, "%s", str);
      _position += res;
      assert(res >= 0 && _position <= _length,
-       err_msg("Need to increase the buffer size in GCCauseString? %d", res));
+            "Need to increase the buffer size in GCCauseString? %d", res);
      return *this;
    }
 
--- a/hotspot/src/share/vm/gc/shared/gcId.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcId.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -25,18 +25,50 @@
 #include "precompiled.hpp"
 #include "gc/shared/gcId.hpp"
 #include "runtime/safepoint.hpp"
+#include "runtime/thread.inline.hpp"
 
 uint GCId::_next_id = 0;
 
-const GCId GCId::create() {
-  return GCId(_next_id++);
+NamedThread* currentNamedthread() {
+  assert(Thread::current()->is_Named_thread(), "This thread must be NamedThread");
+  return (NamedThread*)Thread::current();
+}
+
+const uint GCId::create() {
+  return _next_id++;
 }
-const GCId GCId::peek() {
-  return GCId(_next_id);
+
+const uint GCId::current() {
+  assert(currentNamedthread()->gc_id() != undefined(), "Using undefined GC id.");
+  return current_raw();
+}
+
+const uint GCId::current_raw() {
+  return currentNamedthread()->gc_id();
+}
+
+GCIdMark::GCIdMark() : _gc_id(GCId::create()) {
+  currentNamedthread()->set_gc_id(_gc_id);
 }
-const GCId GCId::undefined() {
-  return GCId(UNDEFINED);
+
+GCIdMark::GCIdMark(uint gc_id) : _gc_id(gc_id) {
+  currentNamedthread()->set_gc_id(_gc_id);
+}
+
+GCIdMark::~GCIdMark() {
+  currentNamedthread()->set_gc_id(GCId::undefined());
 }
-bool GCId::is_undefined() const {
-  return _id == UNDEFINED;
+
+GCIdMarkAndRestore::GCIdMarkAndRestore() : _gc_id(GCId::create()) {
+  _previous_gc_id = GCId::current(); // will assert that the GC Id is not undefined
+  currentNamedthread()->set_gc_id(_gc_id);
 }
+
+GCIdMarkAndRestore::GCIdMarkAndRestore(uint gc_id) : _gc_id(gc_id) {
+  _previous_gc_id = GCId::current(); // will assert that the GC Id is not undefinied
+  currentNamedthread()->set_gc_id(_gc_id);
+}
+
+GCIdMarkAndRestore::~GCIdMarkAndRestore() {
+  currentNamedthread()->set_gc_id(_previous_gc_id);
+}
--- a/hotspot/src/share/vm/gc/shared/gcId.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcId.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -27,25 +27,36 @@
 
 #include "memory/allocation.hpp"
 
-class GCId VALUE_OBJ_CLASS_SPEC {
- private:
-  uint _id;
-  GCId(uint id) : _id(id) {}
-  GCId() { } // Unused
-
+class GCId : public AllStatic {
+  friend class GCIdMark;
+  friend class GCIdMarkAndRestore;
   static uint _next_id;
   static const uint UNDEFINED = (uint)-1;
+  static const uint create();
 
  public:
-  uint id() const {
-    assert(_id != UNDEFINED, "Using undefined GC ID");
-    return _id;
-  }
-  bool is_undefined() const;
+  // Returns the currently active GC id. Asserts that there is an active GC id.
+  static const uint current();
+  // Same as current() but can return undefined() if no GC id is currently active
+  static const uint current_raw();
+  static const uint undefined() { return UNDEFINED; }
+};
 
-  static const GCId create();
-  static const GCId peek();
-  static const GCId undefined();
+class GCIdMark : public StackObj {
+  uint _gc_id;
+ public:
+  GCIdMark();
+  GCIdMark(uint gc_id);
+  ~GCIdMark();
+};
+
+class GCIdMarkAndRestore : public StackObj {
+  uint _gc_id;
+  uint _previous_gc_id;
+ public:
+  GCIdMarkAndRestore();
+  GCIdMarkAndRestore(uint gc_id);
+  ~GCIdMarkAndRestore();
 };
 
 #endif // SHARE_VM_GC_SHARED_GCID_HPP
--- a/hotspot/src/share/vm/gc/shared/gcTrace.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -40,31 +40,16 @@
 #include "gc/g1/evacuationInfo.hpp"
 #endif
 
-#define assert_unset_gc_id() assert(_shared_gc_info.gc_id().is_undefined(), "GC already started?")
-#define assert_set_gc_id() assert(!_shared_gc_info.gc_id().is_undefined(), "GC not started?")
-
 void GCTracer::report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp) {
-  assert_unset_gc_id();
-
-  GCId gc_id = GCId::create();
-  _shared_gc_info.set_gc_id(gc_id);
   _shared_gc_info.set_cause(cause);
   _shared_gc_info.set_start_timestamp(timestamp);
 }
 
 void GCTracer::report_gc_start(GCCause::Cause cause, const Ticks& timestamp) {
-  assert_unset_gc_id();
-
   report_gc_start_impl(cause, timestamp);
 }
 
-bool GCTracer::has_reported_gc_start() const {
-  return !_shared_gc_info.gc_id().is_undefined();
-}
-
 void GCTracer::report_gc_end_impl(const Ticks& 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);
@@ -74,16 +59,10 @@
 }
 
 void GCTracer::report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions) {
-  assert_set_gc_id();
-
   report_gc_end_impl(timestamp, time_partitions);
-
-  _shared_gc_info.set_gc_id(GCId::undefined());
 }
 
 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());
@@ -92,14 +71,12 @@
 
 #if INCLUDE_SERVICES
 class ObjectCountEventSenderClosure : public KlassInfoClosure {
-  const GCId _gc_id;
   const double _size_threshold_percentage;
   const size_t _total_size_in_words;
   const Ticks _timestamp;
 
  public:
-  ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, const Ticks& timestamp) :
-    _gc_id(gc_id),
+  ObjectCountEventSenderClosure(size_t total_size_in_words, const Ticks& timestamp) :
     _size_threshold_percentage(ObjectCountCutOffPercent / 100),
     _total_size_in_words(total_size_in_words),
     _timestamp(timestamp)
@@ -107,7 +84,7 @@
 
   virtual void do_cinfo(KlassInfoEntry* entry) {
     if (should_send_event(entry)) {
-      ObjectCountEventSender::send(entry, _gc_id, _timestamp);
+      ObjectCountEventSender::send(entry, _timestamp);
     }
   }
 
@@ -119,7 +96,6 @@
 };
 
 void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) {
-  assert_set_gc_id();
   assert(is_alive_cl != NULL, "Must supply function to check liveness");
 
   if (ObjectCountEventSender::should_send_event()) {
@@ -129,7 +105,7 @@
     if (!cit.allocation_failed()) {
       HeapInspection hi(false, false, false, NULL);
       hi.populate_table(&cit, is_alive_cl);
-      ObjectCountEventSenderClosure event_sender(_shared_gc_info.gc_id(), cit.size_of_instances_in_words(), Ticks::now());
+      ObjectCountEventSenderClosure event_sender(cit.size_of_instances_in_words(), Ticks::now());
       cit.iterate(&event_sender);
     }
   }
@@ -137,14 +113,10 @@
 #endif // INCLUDE_SERVICES
 
 void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
-  assert_set_gc_id();
-
   send_gc_heap_summary_event(when, heap_summary);
 }
 
 void GCTracer::report_metaspace_summary(GCWhen::Type when, const MetaspaceSummary& summary) const {
-  assert_set_gc_id();
-
   send_meta_space_summary_event(when, summary);
 
   send_metaspace_chunk_free_list_summary(when, Metaspace::NonClassType, summary.metaspace_chunk_free_list_summary());
@@ -154,7 +126,6 @@
 }
 
 void YoungGCTracer::report_gc_end_impl(const Ticks& 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);
@@ -164,8 +135,6 @@
 }
 
 void YoungGCTracer::report_promotion_failed(const PromotionFailedInfo& pf_info) const {
-  assert_set_gc_id();
-
   send_promotion_failed_event(pf_info);
 }
 
@@ -189,78 +158,56 @@
 void YoungGCTracer::report_promotion_in_new_plab_event(Klass* klass, size_t obj_size,
                                                        uint age, bool tenured,
                                                        size_t plab_size) const {
-  assert_set_gc_id();
   send_promotion_in_new_plab_event(klass, obj_size, age, tenured, plab_size);
 }
 
 void YoungGCTracer::report_promotion_outside_plab_event(Klass* klass, size_t obj_size,
                                                         uint age, bool tenured) const {
-  assert_set_gc_id();
   send_promotion_outside_plab_event(klass, obj_size, age, tenured);
 }
 
 void OldGCTracer::report_gc_end_impl(const Ticks& 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(const Ticks& 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 G1MMUTracer::report_mmu(const GCId& gcId, double timeSlice, double gcTime, double maxTime) {
-  assert(!gcId.is_undefined(), "Undefined GC id");
-
-  send_g1_mmu_event(gcId, timeSlice, gcTime, maxTime);
+void G1MMUTracer::report_mmu(double timeSlice, double gcTime, double maxTime) {
+  send_g1_mmu_event(timeSlice, gcTime, maxTime);
 }
 
 void G1NewTracer::report_yc_type(G1YCType type) {
-  assert_set_gc_id();
-
   _g1_young_gc_info.set_type(type);
 }
 
 void G1NewTracer::report_gc_end_impl(const Ticks& 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();
 }
 
 void G1NewTracer::report_evacuation_statistics(const G1EvacSummary& young_summary, const G1EvacSummary& old_summary) const {
-  assert_set_gc_id();
-
   send_young_evacuation_statistics(young_summary);
   send_old_evacuation_statistics(old_summary);
 }
--- a/hotspot/src/share/vm/gc/shared/gcTrace.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -52,7 +52,6 @@
 
 class SharedGCInfo VALUE_OBJ_CLASS_SPEC {
  private:
-  GCId _gc_id;
   GCName _name;
   GCCause::Cause _cause;
   Ticks     _start_timestamp;
@@ -62,7 +61,6 @@
 
  public:
   SharedGCInfo(GCName name) :
-    _gc_id(GCId::undefined()),
     _name(name),
     _cause(GCCause::_last_gc_cause),
     _start_timestamp(),
@@ -71,9 +69,6 @@
     _longest_pause() {
   }
 
-  void set_gc_id(GCId gc_id) { _gc_id = gc_id; }
-  const GCId& gc_id() const { return _gc_id; }
-
   void set_start_timestamp(const Ticks& timestamp) { _start_timestamp = timestamp; }
   const Ticks start_timestamp() const { return _start_timestamp; }
 
@@ -128,8 +123,6 @@
   void report_metaspace_summary(GCWhen::Type when, const MetaspaceSummary& metaspace_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;
-  const GCId& gc_id() { return _shared_gc_info.gc_id(); }
 
  protected:
   GCTracer(GCName name) : _shared_gc_info(name) {}
@@ -242,10 +235,10 @@
 
 #if INCLUDE_ALL_GCS
 class G1MMUTracer : public AllStatic {
-  static void send_g1_mmu_event(const GCId& gcId, double timeSlice, double gcTime, double maxTime);
+  static void send_g1_mmu_event(double timeSlice, double gcTime, double maxTime);
 
  public:
-  static void report_mmu(const GCId& gcId, double timeSlice, double gcTime, double maxTime);
+  static void report_mmu(double timeSlice, double gcTime, double maxTime);
 };
 
 class G1NewTracer : public YoungGCTracer {
--- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -44,7 +44,7 @@
 void GCTracer::send_garbage_collection_event() const {
   EventGCGarbageCollection event(UNTIMED);
   if (event.should_commit()) {
-    event.set_gcId(_shared_gc_info.gc_id().id());
+    event.set_gcId(GCId::current());
     event.set_name(_shared_gc_info.name());
     event.set_cause((u2) _shared_gc_info.cause());
     event.set_sumOfPauses(_shared_gc_info.sum_of_pauses());
@@ -58,7 +58,7 @@
 void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const {
   EventGCReferenceStatistics e;
   if (e.should_commit()) {
-      e.set_gcId(_shared_gc_info.gc_id().id());
+      e.set_gcId(GCId::current());
       e.set_type((u1)type);
       e.set_count(count);
       e.commit();
@@ -69,7 +69,7 @@
                                                       const MetaspaceChunkFreeListSummary& summary) const {
   EventMetaspaceChunkFreeListSummary e;
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_when(when);
     e.set_metadataType(mdtype);
 
@@ -92,7 +92,7 @@
 void ParallelOldTracer::send_parallel_old_event() const {
   EventGCParallelOld e(UNTIMED);
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     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());
@@ -103,7 +103,7 @@
 void YoungGCTracer::send_young_gc_event() const {
   EventGCYoungGarbageCollection e(UNTIMED);
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_tenuringThreshold(_tenuring_threshold);
     e.set_starttime(_shared_gc_info.start_timestamp());
     e.set_endtime(_shared_gc_info.end_timestamp());
@@ -125,7 +125,7 @@
 
   EventPromoteObjectInNewPLAB event;
   if (event.should_commit()) {
-    event.set_gcId(_shared_gc_info.gc_id().id());
+    event.set_gcId(GCId::current());
     event.set_class(klass);
     event.set_objectSize(obj_size);
     event.set_tenured(tenured);
@@ -140,7 +140,7 @@
 
   EventPromoteObjectOutsidePLAB event;
   if (event.should_commit()) {
-    event.set_gcId(_shared_gc_info.gc_id().id());
+    event.set_gcId(GCId::current());
     event.set_class(klass);
     event.set_objectSize(obj_size);
     event.set_tenured(tenured);
@@ -152,7 +152,7 @@
 void OldGCTracer::send_old_gc_event() const {
   EventGCOldGarbageCollection e(UNTIMED);
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_starttime(_shared_gc_info.start_timestamp());
     e.set_endtime(_shared_gc_info.end_timestamp());
     e.commit();
@@ -171,7 +171,7 @@
 void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const {
   EventPromotionFailed e;
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_data(to_trace_struct(pf_info));
     e.set_thread(pf_info.thread()->thread_id());
     e.commit();
@@ -182,7 +182,7 @@
 void OldGCTracer::send_concurrent_mode_failure_event() {
   EventConcurrentModeFailure e;
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.commit();
   }
 }
@@ -191,7 +191,7 @@
 void G1NewTracer::send_g1_young_gc_event() {
   EventGCG1GarbageCollection e(UNTIMED);
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_type(_g1_young_gc_info.type());
     e.set_starttime(_shared_gc_info.start_timestamp());
     e.set_endtime(_shared_gc_info.end_timestamp());
@@ -199,10 +199,10 @@
   }
 }
 
-void G1MMUTracer::send_g1_mmu_event(const GCId& gcId, double timeSlice, double gcTime, double maxTime) {
+void G1MMUTracer::send_g1_mmu_event(double timeSlice, double gcTime, double maxTime) {
   EventGCG1MMU e;
   if (e.should_commit()) {
-    e.set_gcId(gcId.id());
+    e.set_gcId(GCId::current());
     e.set_timeSlice(timeSlice);
     e.set_gcTime(gcTime);
     e.set_maxGcTime(maxTime);
@@ -213,7 +213,7 @@
 void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
   EventEvacuationInfo e;
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_cSetRegions(info->collectionset_regions());
     e.set_cSetUsedBefore(info->collectionset_used_before());
     e.set_cSetUsedAfter(info->collectionset_used_after());
@@ -229,7 +229,7 @@
 void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const {
   EventEvacuationFailed e;
   if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_data(to_trace_struct(ef_info));
     e.commit();
   }
@@ -253,7 +253,7 @@
 void G1NewTracer::send_young_evacuation_statistics(const G1EvacSummary& summary) const {
   EventGCG1EvacuationYoungStatistics surv_evt;
   if (surv_evt.should_commit()) {
-    surv_evt.set_stats(create_g1_evacstats(_shared_gc_info.gc_id().id(), summary));
+    surv_evt.set_stats(create_g1_evacstats(GCId::current(), summary));
     surv_evt.commit();
   }
 }
@@ -261,7 +261,7 @@
 void G1NewTracer::send_old_evacuation_statistics(const G1EvacSummary& summary) const {
   EventGCG1EvacuationOldStatistics old_evt;
   if (old_evt.should_commit()) {
-    old_evt.set_stats(create_g1_evacstats(_shared_gc_info.gc_id().id(), summary));
+    old_evt.set_stats(create_g1_evacstats(GCId::current(), summary));
     old_evt.commit();
   }
 }
@@ -287,17 +287,16 @@
 }
 
 class GCHeapSummaryEventSender : public GCHeapSummaryVisitor {
-  GCId _gc_id;
   GCWhen::Type _when;
  public:
-  GCHeapSummaryEventSender(GCId gc_id, GCWhen::Type when) : _gc_id(gc_id), _when(when) {}
+  GCHeapSummaryEventSender(GCWhen::Type when) : _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(_gc_id.id());
+      e.set_gcId(GCId::current());
       e.set_when((u1)_when);
       e.set_heapSpace(to_trace_struct(heap_space));
       e.set_heapUsed(heap_summary->used());
@@ -310,7 +309,7 @@
 
     EventG1HeapSummary e;
     if (e.should_commit()) {
-      e.set_gcId(_gc_id.id());
+      e.set_gcId(GCId::current());
       e.set_when((u1)_when);
       e.set_edenUsedSize(g1_heap_summary->edenUsed());
       e.set_edenTotalSize(g1_heap_summary->edenCapacity());
@@ -331,7 +330,7 @@
 
     EventPSHeapSummary e;
     if (e.should_commit()) {
-      e.set_gcId(_gc_id.id());
+      e.set_gcId(GCId::current());
       e.set_when((u1)_when);
 
       e.set_oldSpace(to_trace_struct(ps_heap_summary->old()));
@@ -346,7 +345,7 @@
 };
 
 void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
-  GCHeapSummaryEventSender visitor(_shared_gc_info.gc_id(), when);
+  GCHeapSummaryEventSender visitor(when);
   heap_summary.accept(&visitor);
 }
 
@@ -363,7 +362,7 @@
 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.gc_id().id());
+    e.set_gcId(GCId::current());
     e.set_when((u1) when);
     e.set_gcThreshold(meta_space_summary.capacity_until_GC());
     e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
@@ -374,15 +373,12 @@
 }
 
 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.id());
+      event.set_gcId(GCId::current());
       event.set_name(pause->name());
       event.set_starttime(pause->start());
       event.set_endtime(pause->end());
@@ -406,7 +402,7 @@
 };
 
 void GCTracer::send_phase_events(TimePartitions* time_partitions) const {
-  PhaseSender phase_reporter(_shared_gc_info.gc_id());
+  PhaseSender phase_reporter;
 
   TimePartitionPhasesIterator iter(time_partitions);
   while (iter.has_next()) {
--- a/hotspot/src/share/vm/gc/shared/gcTraceTime.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTraceTime.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -35,7 +35,7 @@
 #include "utilities/ticks.inline.hpp"
 
 
-GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer, GCId gc_id) :
+GCTraceTimeImpl::GCTraceTimeImpl(const char* title, bool doit, bool print_cr, GCTimer* timer) :
     _title(title), _doit(doit), _print_cr(print_cr), _timer(timer), _start_counter() {
   if (_doit || _timer != NULL) {
     _start_counter.stamp();
@@ -49,17 +49,13 @@
   }
 
   if (_doit) {
-    gclog_or_tty->date_stamp(PrintGCDateStamps);
-    gclog_or_tty->stamp(PrintGCTimeStamps);
-    if (PrintGCID) {
-      gclog_or_tty->print("#%u: ", gc_id.id());
-    }
+    gclog_or_tty->gclog_stamp();
     gclog_or_tty->print("[%s", title);
     gclog_or_tty->flush();
   }
 }
 
-GCTraceTime::~GCTraceTime() {
+GCTraceTimeImpl::~GCTraceTimeImpl() {
   Ticks stop_counter;
 
   if (_doit || _timer != NULL) {
--- a/hotspot/src/share/vm/gc/shared/gcTraceTime.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTraceTime.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,12 +26,13 @@
 #define SHARE_VM_GC_SHARED_GCTRACETIME_HPP
 
 #include "gc/shared/gcTrace.hpp"
+#include "memory/allocation.hpp"
 #include "prims/jni_md.h"
 #include "utilities/ticks.hpp"
 
 class GCTimer;
 
-class GCTraceTime {
+class GCTraceTimeImpl VALUE_OBJ_CLASS_SPEC {
   const char* _title;
   bool _doit;
   bool _print_cr;
@@ -39,8 +40,16 @@
   Ticks _start_counter;
 
  public:
-  GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer, GCId gc_id);
-  ~GCTraceTime();
+  GCTraceTimeImpl(const char* title, bool doit, bool print_cr, GCTimer* timer);
+  ~GCTraceTimeImpl();
+};
+
+class GCTraceTime : public StackObj {
+  GCTraceTimeImpl _gc_trace_time_impl;
+
+ public:
+  GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) :
+    _gc_trace_time_impl(title, doit, print_cr, timer) {};
 };
 
 #endif // SHARE_VM_GC_SHARED_GCTRACETIME_HPP
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,6 +30,7 @@
 #include "code/icBuffer.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "gc/shared/collectorCounters.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTrace.hpp"
 #include "gc/shared/gcTraceTime.hpp"
@@ -162,8 +163,8 @@
                                   "the maximum representable size");
   }
   assert(total_reserved % alignment == 0,
-         err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="
-                 SIZE_FORMAT, total_reserved, alignment));
+         "Gen size; total_reserved=" SIZE_FORMAT ", alignment="
+         SIZE_FORMAT, total_reserved, alignment);
 
   *heap_rs = Universe::reserve_heap(total_reserved, alignment);
   return heap_rs->base();
@@ -315,9 +316,7 @@
                                           bool restore_marks_for_biased_locking) {
   // Timer for individual generations. Last argument is false: no CR
   // FIXME: We should try to start the timing earlier to cover more of the GC pause
-  // The PrintGCDetails logging starts before we have incremented the GC id. We will do that later
-  // so we can assume here that the next GC id is what we want.
-  GCTraceTime t1(gen->short_name(), PrintGCDetails, false, NULL, GCId::peek());
+  GCTraceTime t1(gen->short_name(), PrintGCDetails, false, NULL);
   TraceCollectorStats tcs(gen->counters());
   TraceMemoryManagerStats tmms(gen->kind(),gc_cause());
 
@@ -434,6 +433,8 @@
     return; // GC is disabled (e.g. JNI GetXXXCritical operation)
   }
 
+  GCIdMark gc_id_mark;
+
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
                           collector_policy()->should_clear_all_soft_refs();
 
@@ -449,9 +450,7 @@
     bool complete = full && (max_generation == OldGen);
     const char* gc_cause_prefix = complete ? "Full GC" : "GC";
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    // The PrintGCDetails logging starts before we have incremented the GC id. We will do that later
-    // so we can assume here that the next GC id is what we want.
-    GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL, GCId::peek());
+    GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL);
 
     gc_prologue(complete);
     increment_total_collections(complete);
@@ -489,6 +488,7 @@
     bool must_restore_marks_for_biased_locking = false;
 
     if (max_generation == OldGen && _old_gen->should_collect(full, size, is_tlab)) {
+      GCIdMarkAndRestore gc_id_mark;
       if (!complete) {
         // The full_collections increment was missed above.
         increment_total_full_collections();
@@ -891,7 +891,7 @@
 bool GenCollectedHeap::is_in_young(oop p) {
   bool result = ((HeapWord*)p) < _old_gen->reserved().start();
   assert(result == _young_gen->is_in_reserved(p),
-         err_msg("incorrect test - result=%d, p=" INTPTR_FORMAT, result, p2i((void*)p)));
+         "incorrect test - result=%d, p=" INTPTR_FORMAT, result, p2i((void*)p));
   return result;
 }
 
@@ -1224,11 +1224,11 @@
 };
 
 void GenCollectedHeap::gc_epilogue(bool full) {
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   assert(DerivedPointerTable::is_empty(), "derived pointer present");
   size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr()));
   guarantee(actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
-#endif /* COMPILER2 */
+#endif /* COMPILER2 || INCLUDE_JVMCI */
 
   resize_all_tlabs();
 
--- a/hotspot/src/share/vm/gc/shared/objectCountEventSender.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/objectCountEventSender.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -33,13 +33,13 @@
 #include "utilities/ticks.hpp"
 #if INCLUDE_SERVICES
 
-void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp) {
+void ObjectCountEventSender::send(const KlassInfoEntry* entry, const Ticks& timestamp) {
 #if INCLUDE_TRACE
   assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId),
          "Only call this method if the event is enabled");
 
   EventObjectCountAfterGC event(UNTIMED);
-  event.set_gcId(gc_id.id());
+  event.set_gcId(GCId::current());
   event.set_class(entry->klass());
   event.set_count(entry->count());
   event.set_totalSize(entry->words() * BytesPerWord);
--- a/hotspot/src/share/vm/gc/shared/objectCountEventSender.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/objectCountEventSender.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,7 +36,7 @@
 
 class ObjectCountEventSender : public AllStatic {
  public:
-  static void send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp);
+  static void send(const KlassInfoEntry* entry, const Ticks& timestamp);
   static bool should_send_event();
 };
 
--- a/hotspot/src/share/vm/gc/shared/plab.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/plab.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -45,8 +45,8 @@
   // ArrayOopDesc::header_size depends on command line initialization.
   AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
   assert(min_size() > AlignmentReserve,
-         err_msg("Minimum PLAB size " SIZE_FORMAT " must be larger than alignment reserve " SIZE_FORMAT " "
-                 "to be able to contain objects", min_size(), AlignmentReserve));
+         "Minimum PLAB size " SIZE_FORMAT " must be larger than alignment reserve " SIZE_FORMAT " "
+         "to be able to contain objects", min_size(), AlignmentReserve);
 }
 
 // If the minimum object size is greater than MinObjAlignment, we can
@@ -125,12 +125,12 @@
 
   if (_allocated == 0) {
     assert(_unused == 0,
-           err_msg("Inconsistency in PLAB stats: "
-                   "_allocated: " SIZE_FORMAT ", "
-                   "_wasted: " SIZE_FORMAT ", "
-                   "_unused: " SIZE_FORMAT ", "
-                   "_undo_wasted: " SIZE_FORMAT,
-                   _allocated, _wasted, _unused, _undo_wasted));
+           "Inconsistency in PLAB stats: "
+           "_allocated: " SIZE_FORMAT ", "
+           "_wasted: " SIZE_FORMAT ", "
+           "_unused: " SIZE_FORMAT ", "
+           "_undo_wasted: " SIZE_FORMAT,
+           _allocated, _wasted, _unused, _undo_wasted);
 
     _allocated = 1;
   }
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,6 +31,7 @@
 #include "gc/shared/gcTraceTime.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/referenceProcessor.hpp"
+#include "memory/allocation.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/jniHandles.hpp"
@@ -54,8 +55,11 @@
   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
 
   _always_clear_soft_ref_policy = new AlwaysClearPolicy();
-  _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
-                                      NOT_COMPILER2(LRUCurrentHeapPolicy());
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  _default_soft_ref_policy      = new LRUMaxHeapPolicy();
+#else
+  _default_soft_ref_policy      = new LRUCurrentHeapPolicy();
+#endif
   if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
     vm_exit_during_initialization("Could not allocate reference policy object");
   }
@@ -182,13 +186,27 @@
   return total;
 }
 
+static void log_ref_count(size_t count, bool doit) {
+  if (doit) {
+    gclog_or_tty->print(", " SIZE_FORMAT " refs", count);
+  }
+}
+
+class GCRefTraceTime : public StackObj {
+  GCTraceTimeImpl _gc_trace_time;
+ public:
+  GCRefTraceTime(const char* title, bool doit, GCTimer* timer, size_t count) :
+    _gc_trace_time(title, doit, false, timer) {
+    log_ref_count(count, doit);
+  }
+};
+
 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
   BoolObjectClosure*           is_alive,
   OopClosure*                  keep_alive,
   VoidClosure*                 complete_gc,
   AbstractRefProcTaskExecutor* task_executor,
-  GCTimer*                     gc_timer,
-  GCId                         gc_id) {
+  GCTimer*                     gc_timer) {
 
   assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
   // Stop treating discovered references specially.
@@ -206,48 +224,48 @@
 
   bool trace_time = PrintGCDetails && PrintReferenceGC;
 
+  // Include cleaners in phantom statistics.  We expect Cleaner
+  // references to be temporary, and don't want to deal with
+  // possible incompatibilities arising from making it more visible.
+  ReferenceProcessorStats stats(
+      total_count(_discoveredSoftRefs),
+      total_count(_discoveredWeakRefs),
+      total_count(_discoveredFinalRefs),
+      total_count(_discoveredPhantomRefs) + total_count(_discoveredCleanerRefs));
+
   // Soft references
-  size_t soft_count = 0;
   {
-    GCTraceTime tt("SoftReference", trace_time, false, gc_timer, gc_id);
-    soft_count =
-      process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
-                                 is_alive, keep_alive, complete_gc, task_executor);
+    GCRefTraceTime tt("SoftReference", trace_time, gc_timer, stats.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;
   {
-    GCTraceTime tt("WeakReference", trace_time, false, gc_timer, gc_id);
-    weak_count =
-      process_discovered_reflist(_discoveredWeakRefs, NULL, true,
-                                 is_alive, keep_alive, complete_gc, task_executor);
+    GCRefTraceTime tt("WeakReference", trace_time, gc_timer, stats.weak_count());
+    process_discovered_reflist(_discoveredWeakRefs, NULL, true,
+                               is_alive, keep_alive, complete_gc, task_executor);
   }
 
   // Final references
-  size_t final_count = 0;
   {
-    GCTraceTime tt("FinalReference", trace_time, false, gc_timer, gc_id);
-    final_count =
-      process_discovered_reflist(_discoveredFinalRefs, NULL, false,
-                                 is_alive, keep_alive, complete_gc, task_executor);
+    GCRefTraceTime tt("FinalReference", trace_time, gc_timer, stats.final_count());
+    process_discovered_reflist(_discoveredFinalRefs, NULL, false,
+                               is_alive, keep_alive, complete_gc, task_executor);
   }
 
   // Phantom references
-  size_t phantom_count = 0;
   {
-    GCTraceTime tt("PhantomReference", trace_time, false, gc_timer, gc_id);
-    phantom_count =
-      process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
-                                 is_alive, keep_alive, complete_gc, task_executor);
+    GCRefTraceTime tt("PhantomReference", trace_time, gc_timer, stats.phantom_count());
+    process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
+                               is_alive, keep_alive, complete_gc, task_executor);
 
-    // Process cleaners, but include them in phantom statistics.  We expect
+    // Process cleaners, but include them in phantom timing.  We expect
     // Cleaner references to be temporary, and don't want to deal with
     // possible incompatibilities arising from making it more visible.
-    phantom_count +=
-      process_discovered_reflist(_discoveredCleanerRefs, NULL, true,
+    process_discovered_reflist(_discoveredCleanerRefs, NULL, true,
                                  is_alive, keep_alive, complete_gc, task_executor);
   }
 
@@ -257,14 +275,15 @@
   // thus use JNI weak references to circumvent the phantom references and
   // resurrect a "post-mortem" object.
   {
-    GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id);
+    GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
+    NOT_PRODUCT(log_ref_count(count_jni_refs(), trace_time);)
     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);
+  return stats;
 }
 
 #ifndef PRODUCT
@@ -294,12 +313,6 @@
 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
                                           OopClosure*        keep_alive,
                                           VoidClosure*       complete_gc) {
-#ifndef PRODUCT
-  if (PrintGCDetails && PrintReferenceGC) {
-    unsigned int count = count_jni_refs();
-    gclog_or_tty->print(", %u refs", count);
-  }
-#endif
   JNIHandles::weak_oops_do(is_alive, keep_alive);
   complete_gc->do_void();
 }
@@ -437,7 +450,7 @@
   _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
   oop discovered = java_lang_ref_Reference::discovered(_ref);
   assert(_discovered_addr && discovered->is_oop_or_null(),
-         err_msg("Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)));
+         "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
   _next = discovered;
   _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
   _referent = java_lang_ref_Reference::referent(_ref);
@@ -446,9 +459,9 @@
   assert(allow_null_referent ?
              _referent->is_oop_or_null()
            : _referent->is_oop(),
-         err_msg("Expected an oop%s for referent field at " PTR_FORMAT,
-                 (allow_null_referent ? " or NULL" : ""),
-                 p2i(_referent)));
+         "Expected an oop%s for referent field at " PTR_FORMAT,
+         (allow_null_referent ? " or NULL" : ""),
+         p2i(_referent));
 }
 
 void DiscoveredListIterator::remove() {
@@ -578,7 +591,7 @@
     oop next = java_lang_ref_Reference::next(iter.obj());
     if ((iter.referent() == NULL || iter.is_referent_alive() ||
          next != NULL)) {
-      assert(next->is_oop_or_null(), err_msg("Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next)));
+      assert(next->is_oop_or_null(), "Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next));
       // Remove Reference object from list
       iter.remove();
       // Trace the cohorts
@@ -826,8 +839,7 @@
   balance_queues(_discoveredCleanerRefs);
 }
 
-size_t
-ReferenceProcessor::process_discovered_reflist(
+void ReferenceProcessor::process_discovered_reflist(
   DiscoveredList               refs_lists[],
   ReferencePolicy*             policy,
   bool                         clear_referent,
@@ -850,12 +862,6 @@
     balance_queues(refs_lists);
   }
 
-  size_t total_list_count = total_count(refs_lists);
-
-  if (PrintReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print(", " SIZE_FORMAT " refs", total_list_count);
-  }
-
   // Phase 1 (soft refs only):
   // . Traverse the list and remove any SoftReferences whose
   //   referents are not alive, but that should be kept alive for
@@ -898,8 +904,6 @@
                      is_alive, keep_alive, complete_gc);
     }
   }
-
-  return total_list_count;
 }
 
 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
@@ -993,9 +997,9 @@
   bool da = discovery_is_atomic();
   oop referent = java_lang_ref_Reference::referent(obj);
   assert(da ? referent->is_oop() : referent->is_oop_or_null(),
-         err_msg("Bad referent " INTPTR_FORMAT " found in Reference "
-                 INTPTR_FORMAT " during %satomic discovery ",
-                 p2i(referent), p2i(obj), da ? "" : "non-"));
+         "Bad referent " INTPTR_FORMAT " found in Reference "
+         INTPTR_FORMAT " during %satomic discovery ",
+         p2i(referent), p2i(obj), da ? "" : "non-");
 }
 #endif
 
@@ -1070,7 +1074,7 @@
 
   HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
   const oop  discovered = java_lang_ref_Reference::discovered(obj);
-  assert(discovered->is_oop_or_null(), err_msg("Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)));
+  assert(discovered->is_oop_or_null(), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
   if (discovered != NULL) {
     // The reference has already been discovered...
     if (TraceReferenceGC) {
@@ -1150,13 +1154,12 @@
   OopClosure* keep_alive,
   VoidClosure* complete_gc,
   YieldClosure* yield,
-  GCTimer* gc_timer,
-  GCId     gc_id) {
+  GCTimer* gc_timer) {
 
   // Soft references
   {
     GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer, gc_id);
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1169,7 +1172,7 @@
   // Weak references
   {
     GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer, gc_id);
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1182,7 +1185,7 @@
   // Final references
   {
     GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer, gc_id);
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1195,7 +1198,7 @@
   // Phantom references
   {
     GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer, gc_id);
+              false, gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -263,13 +263,13 @@
   }
 
   // Process references with a certain reachability level.
-  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_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,
@@ -331,8 +331,7 @@
                                       OopClosure*        keep_alive,
                                       VoidClosure*       complete_gc,
                                       YieldClosure*      yield,
-                                      GCTimer*           gc_timer,
-                                      GCId               gc_id);
+                                      GCTimer*           gc_timer);
 
   // Returns the name of the discovered reference list
   // occupying the i / _num_q slot.
@@ -441,8 +440,7 @@
                                 OopClosure*                  keep_alive,
                                 VoidClosure*                 complete_gc,
                                 AbstractRefProcTaskExecutor* task_executor,
-                                GCTimer *gc_timer,
-                                GCId    gc_id);
+                                GCTimer *gc_timer);
 
   // Enqueue references at end of GC (called by the garbage collector)
   bool enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
--- a/hotspot/src/share/vm/gc/shared/space.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -592,8 +592,8 @@
 // Very general, slow implementation.
 HeapWord* ContiguousSpace::block_start_const(const void* p) const {
   assert(MemRegion(bottom(), end()).contains(p),
-         err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
-                  p2i(p), p2i(bottom()), p2i(end())));
+         "p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
+         p2i(p), p2i(bottom()), p2i(end()));
   if (p >= top()) {
     return top();
   } else {
@@ -603,24 +603,23 @@
       last = cur;
       cur += oop(cur)->size();
     }
-    assert(oop(last)->is_oop(),
-           err_msg(PTR_FORMAT " should be an object start", p2i(last)));
+    assert(oop(last)->is_oop(), PTR_FORMAT " should be an object start", p2i(last));
     return last;
   }
 }
 
 size_t ContiguousSpace::block_size(const HeapWord* p) const {
   assert(MemRegion(bottom(), end()).contains(p),
-         err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
-                  p2i(p), p2i(bottom()), p2i(end())));
+         "p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
+         p2i(p), p2i(bottom()), p2i(end()));
   HeapWord* current_top = top();
   assert(p <= current_top,
-         err_msg("p > current top - p: " PTR_FORMAT ", current top: " PTR_FORMAT,
-                  p2i(p), p2i(current_top)));
+         "p > current top - p: " PTR_FORMAT ", current top: " PTR_FORMAT,
+         p2i(p), p2i(current_top));
   assert(p == current_top || oop(p)->is_oop(),
-         err_msg("p (" PTR_FORMAT ") is not a block start - "
-                 "current_top: " PTR_FORMAT ", is_oop: %s",
-                 p2i(p), p2i(current_top), BOOL_TO_STR(oop(p)->is_oop())));
+         "p (" PTR_FORMAT ") is not a block start - "
+         "current_top: " PTR_FORMAT ", is_oop: %s",
+         p2i(p), p2i(current_top), BOOL_TO_STR(oop(p)->is_oop()));
   if (p < current_top) {
     return oop(p)->size();
   } else {
--- a/hotspot/src/share/vm/gc/shared/taskqueue.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/taskqueue.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -92,20 +92,20 @@
 void TaskQueueStats::verify() const
 {
   assert(get(push) == get(pop) + get(steal),
-         err_msg("push=" SIZE_FORMAT " pop=" SIZE_FORMAT " steal=" SIZE_FORMAT,
-                 get(push), get(pop), get(steal)));
+         "push=" SIZE_FORMAT " pop=" SIZE_FORMAT " steal=" SIZE_FORMAT,
+         get(push), get(pop), get(steal));
   assert(get(pop_slow) <= get(pop),
-         err_msg("pop_slow=" SIZE_FORMAT " pop=" SIZE_FORMAT,
-                 get(pop_slow), get(pop)));
+         "pop_slow=" SIZE_FORMAT " pop=" SIZE_FORMAT,
+         get(pop_slow), get(pop));
   assert(get(steal) <= get(steal_attempt),
-         err_msg("steal=" SIZE_FORMAT " steal_attempt=" SIZE_FORMAT,
-                 get(steal), get(steal_attempt)));
+         "steal=" SIZE_FORMAT " steal_attempt=" SIZE_FORMAT,
+         get(steal), get(steal_attempt));
   assert(get(overflow) == 0 || get(push) != 0,
-         err_msg("overflow=" SIZE_FORMAT " push=" SIZE_FORMAT,
-                 get(overflow), get(push)));
+         "overflow=" SIZE_FORMAT " push=" SIZE_FORMAT,
+         get(overflow), get(push));
   assert(get(overflow_max_len) == 0 || get(overflow) != 0,
-         err_msg("overflow_max_len=" SIZE_FORMAT " overflow=" SIZE_FORMAT,
-                 get(overflow_max_len), get(overflow)));
+         "overflow_max_len=" SIZE_FORMAT " overflow=" SIZE_FORMAT,
+         get(overflow_max_len), get(overflow));
 }
 #endif // ASSERT
 #endif // TASKQUEUE_STATS
--- a/hotspot/src/share/vm/gc/shared/workgroup.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
@@ -140,7 +141,7 @@
     _end_semaphore->wait();
 
     // No workers are allowed to read the state variables after the coordinator has been signaled.
-    assert(_not_finished == 0, err_msg("%d not finished workers?", _not_finished));
+    assert(_not_finished == 0, "%d not finished workers?", _not_finished);
     _task    = NULL;
     _started = 0;
 
@@ -328,6 +329,7 @@
 void GangWorker::run_task(WorkData data) {
   print_task_started(data);
 
+  GCIdMark gc_id_mark(data._task->gc_id());
   data._task->work(data._worker_id);
 
   print_task_done(data);
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -28,6 +28,7 @@
 #include "memory/allocation.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/thread.hpp"
+#include "gc/shared/gcId.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -54,9 +55,13 @@
 // You subclass this to supply your own work() method
 class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
   const char* _name;
+  const uint _gc_id;
 
  public:
-  AbstractGangTask(const char* name) : _name(name) {}
+  AbstractGangTask(const char* name) :
+    _name(name),
+    _gc_id(GCId::current_raw())
+ {}
 
   // The abstract work method.
   // The argument tells you which member of the gang you are.
@@ -64,6 +69,7 @@
 
   // Debugging accessor for the name.
   const char* name() const { return _name; }
+  const uint gc_id() const { return _gc_id; }
 };
 
 struct WorkData {
@@ -132,7 +138,7 @@
 
   virtual uint active_workers() const {
     assert(_active_workers <= _total_workers,
-           err_msg("_active_workers: %u > _total_workers: %u", _active_workers, _total_workers));
+           "_active_workers: %u > _total_workers: %u", _active_workers, _total_workers);
     assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
            "Unless dynamic should use total workers");
     return _active_workers;
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -90,6 +90,8 @@
     java_util_zip_CRC32_update,                                 // implementation of java.util.zip.CRC32.update()
     java_util_zip_CRC32_updateBytes,                            // implementation of java.util.zip.CRC32.updateBytes()
     java_util_zip_CRC32_updateByteBuffer,                       // implementation of java.util.zip.CRC32.updateByteBuffer()
+    java_util_zip_CRC32C_updateBytes,                           // implementation of java.util.zip.CRC32C.updateBytes(crc, b[], off, end)
+    java_util_zip_CRC32C_updateDirectByteBuffer,                // implementation of java.util.zip.CRC32C.updateDirectByteBuffer(crc, address, off, end)
     java_lang_Float_intBitsToFloat,                             // implementation of java.lang.Float.intBitsToFloat()
     java_lang_Float_floatToRawIntBits,                          // implementation of java.lang.Float.floatToRawIntBits()
     java_lang_Double_longBitsToDouble,                          // implementation of java.lang.Double.longBitsToDouble()
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -2734,8 +2734,8 @@
       }
 
       DEFAULT:
-          fatal(err_msg("Unimplemented opcode %d = %s", opcode,
-                        Bytecodes::name((Bytecodes::Code)opcode)));
+          fatal("Unimplemented opcode %d = %s", opcode,
+                Bytecodes::name((Bytecodes::Code)opcode));
           goto finish;
 
       } /* switch(opc) */
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -35,7 +35,7 @@
 #ifdef ASSERT
 #define VERIFY_OOP(o_) \
       if (VerifyOops) { \
-        assert((oop(o_))->is_oop_or_null(), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(oop(o_)))); \
+        assert((oop(o_))->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(oop(o_))); \
         StubRoutines::_verify_oop_count++;  \
       }
 #else
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -542,8 +542,7 @@
           Code code = cast(i);
           Code java = java_code(code);
           if (can_trap(code) && !can_trap(java))
-            fatal(err_msg("%s can trap => %s can trap, too", name(code),
-                          name(java)));
+            fatal("%s can trap => %s can trap, too", name(code), name(java));
         }
       }
     }
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -353,8 +353,8 @@
 
  public:
   // Conversion
-  static void        check          (Code code)    { assert(is_defined(code),      err_msg("illegal code: %d", (int)code)); }
-  static void        wide_check     (Code code)    { assert(wide_is_defined(code), err_msg("illegal code: %d", (int)code)); }
+  static void        check          (Code code)    { assert(is_defined(code),      "illegal code: %d", (int)code); }
+  static void        wide_check     (Code code)    { assert(wide_is_defined(code), "illegal code: %d", (int)code); }
   static Code        cast           (int  code)    { return (Code)code; }
 
 
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -104,7 +104,10 @@
   (*_masm)->flush();
 
   // Commit Codelet.
-  AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->strings());
+  int committed_code_size = (*_masm)->code()->pure_insts_size();
+  if (committed_code_size) {
+    AbstractInterpreter::code()->commit(committed_code_size, (*_masm)->code()->strings());
+  }
   // Make sure nobody can use _masm outside a CodeletMark lifespan.
   *_masm = NULL;
 }
@@ -234,6 +237,13 @@
       case vmIntrinsics::_updateByteBufferCRC32  : return java_util_zip_CRC32_updateByteBuffer;
     }
   }
+  if (UseCRC32CIntrinsics) {
+    // Use optimized stub code for CRC32C methods.
+    switch (m->intrinsic_id()) {
+      case vmIntrinsics::_updateBytesCRC32C             : return java_util_zip_CRC32C_updateBytes;
+      case vmIntrinsics::_updateDirectByteBufferCRC32C  : return java_util_zip_CRC32C_updateDirectByteBuffer;
+    }
+  }
 
   switch(m->intrinsic_id()) {
   case vmIntrinsics::_intBitsToFloat:      return java_lang_Float_intBitsToFloat;
@@ -349,6 +359,8 @@
     case java_util_zip_CRC32_update           : tty->print("java_util_zip_CRC32_update"); break;
     case java_util_zip_CRC32_updateBytes      : tty->print("java_util_zip_CRC32_updateBytes"); break;
     case java_util_zip_CRC32_updateByteBuffer : tty->print("java_util_zip_CRC32_updateByteBuffer"); break;
+    case java_util_zip_CRC32C_updateBytes     : tty->print("java_util_zip_CRC32C_updateBytes"); break;
+    case java_util_zip_CRC32C_updateDirectByteBuffer: tty->print("java_util_zip_CRC32C_updateDirectByteByffer"); break;
     default:
       if (kind >= method_handle_invoke_FIRST &&
           kind <= method_handle_invoke_LAST) {
@@ -447,11 +459,11 @@
 address AbstractInterpreter::deopt_reexecute_entry(Method* method, address bcp) {
   assert(method->contains(bcp), "just checkin'");
   Bytecodes::Code code   = Bytecodes::java_code_at(method, bcp);
-#ifdef COMPILER1
+#if defined(COMPILER1) || INCLUDE_JVMCI
   if(code == Bytecodes::_athrow ) {
     return Interpreter::rethrow_exception_entry();
   }
-#endif /* COMPILER1 */
+#endif /* COMPILER1 || INCLUDE_JVMCI */
   return Interpreter::deopt_entry(vtos, 0);
 }
 
@@ -537,17 +549,18 @@
 address InterpreterGenerator::generate_method_entry(
                                         AbstractInterpreter::MethodKind kind) {
   // determine code generation flags
+  bool native = false;
   bool synchronized = false;
   address entry_point = NULL;
 
   switch (kind) {
-  case Interpreter::zerolocals             :                                                      break;
-  case Interpreter::zerolocals_synchronized: synchronized = true;                                 break;
-  case Interpreter::native                 : entry_point = generate_native_entry(false); break;
-  case Interpreter::native_synchronized    : entry_point = generate_native_entry(true);  break;
-  case Interpreter::empty                  : entry_point = generate_empty_entry(); break;
+  case Interpreter::zerolocals             :                                          break;
+  case Interpreter::zerolocals_synchronized:                synchronized = true;      break;
+  case Interpreter::native                 : native = true;                           break;
+  case Interpreter::native_synchronized    : native = true; synchronized = true;      break;
+  case Interpreter::empty                  : entry_point = generate_empty_entry();    break;
   case Interpreter::accessor               : entry_point = generate_accessor_entry(); break;
-  case Interpreter::abstract               : entry_point = generate_abstract_entry();    break;
+  case Interpreter::abstract               : entry_point = generate_abstract_entry(); break;
 
   case Interpreter::java_lang_math_sin     : // fall thru
   case Interpreter::java_lang_math_cos     : // fall thru
@@ -562,33 +575,37 @@
                                            : entry_point = generate_Reference_get_entry(); break;
 #ifndef CC_INTERP
   case Interpreter::java_util_zip_CRC32_update
-                                           : entry_point = generate_CRC32_update_entry();  break;
+                                           : native = true; entry_point = generate_CRC32_update_entry();  break;
   case Interpreter::java_util_zip_CRC32_updateBytes
                                            : // fall thru
   case Interpreter::java_util_zip_CRC32_updateByteBuffer
-                                           : entry_point = generate_CRC32_updateBytes_entry(kind); break;
+                                           : native = true; entry_point = generate_CRC32_updateBytes_entry(kind); break;
+  case Interpreter::java_util_zip_CRC32C_updateBytes
+                                           : // fall thru
+  case Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer
+                                           : entry_point = generate_CRC32C_updateBytes_entry(kind); break;
 #if defined(TARGET_ARCH_x86) && !defined(_LP64)
   // On x86_32 platforms, a special entry is generated for the following four methods.
   // On other platforms the normal entry is used to enter these methods.
   case Interpreter::java_lang_Float_intBitsToFloat
-                                           : entry_point = generate_Float_intBitsToFloat_entry(); break;
+                                           : native = true; entry_point = generate_Float_intBitsToFloat_entry(); break;
   case Interpreter::java_lang_Float_floatToRawIntBits
-                                           : entry_point = generate_Float_floatToRawIntBits_entry(); break;
+                                           : native = true; entry_point = generate_Float_floatToRawIntBits_entry(); break;
   case Interpreter::java_lang_Double_longBitsToDouble
-                                           : entry_point = generate_Double_longBitsToDouble_entry(); break;
+                                           : native = true; entry_point = generate_Double_longBitsToDouble_entry(); break;
   case Interpreter::java_lang_Double_doubleToRawLongBits
-                                           : entry_point = generate_Double_doubleToRawLongBits_entry(); break;
+                                           : native = true; entry_point = generate_Double_doubleToRawLongBits_entry(); break;
 #else
   case Interpreter::java_lang_Float_intBitsToFloat:
   case Interpreter::java_lang_Float_floatToRawIntBits:
   case Interpreter::java_lang_Double_longBitsToDouble:
   case Interpreter::java_lang_Double_doubleToRawLongBits:
-    entry_point = generate_native_entry(false);
+    native = true;
     break;
 #endif // defined(TARGET_ARCH_x86) && !defined(_LP64)
 #endif // CC_INTERP
   default:
-    fatal(err_msg("unexpected method kind: %d", kind));
+    fatal("unexpected method kind: %d", kind);
     break;
   }
 
@@ -596,5 +613,18 @@
     return entry_point;
   }
 
-  return generate_normal_entry(synchronized);
+  // We expect the normal and native entry points to be generated first so we can reuse them.
+  if (native) {
+    entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native);
+    if (entry_point == NULL) {
+      entry_point = generate_native_entry(synchronized);
+    }
+  } else {
+    entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals);
+    if (entry_point == NULL) {
+      entry_point = generate_normal_entry(synchronized);
+    }
+  }
+
+  return entry_point;
 }
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -66,8 +66,6 @@
 #include "opto/runtime.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 class UnlockFlagSaver {
   private:
     JavaThread* _thread;
@@ -444,14 +442,14 @@
       if (message != NULL) {
         tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")",
                       h_exception->print_value_string(), message->as_C_string(),
-                      (address)h_exception());
+                      p2i(h_exception()));
       } else {
         tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")",
                       h_exception->print_value_string(),
-                      (address)h_exception());
+                      p2i(h_exception()));
       }
       tty->print_cr(" thrown in interpreter method <%s>", h_method->print_value_string());
-      tty->print_cr(" at bci %d for thread " INTPTR_FORMAT, current_bci, thread);
+      tty->print_cr(" at bci %d for thread " INTPTR_FORMAT, current_bci, p2i(thread));
     }
 // Don't go paging in something which won't be used.
 //     else if (extable->length() == 0) {
@@ -481,6 +479,17 @@
     }
   } while (should_repeat == true);
 
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler && h_method->method_data() != NULL) {
+    ResourceMark rm(thread);
+    ProfileData* pdata = h_method->method_data()->allocate_bci_to_data(current_bci, NULL);
+    if (pdata != NULL && pdata->is_BitData()) {
+      BitData* bit_data = (BitData*) pdata;
+      bit_data->set_exception_seen();
+    }
+  }
+#endif
+
   // notify JVMTI of an exception throw; JVMTI will detect if this is a first
   // time throw or a stack unwinding throw and accordingly notify the debugger
   if (JvmtiExport::can_post_on_exceptions()) {
@@ -858,7 +867,7 @@
     resolve_invokedynamic(thread);
     break;
   default:
-    fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode)));
+    fatal("unexpected bytecode: %s", Bytecodes::name(bytecode));
     break;
   }
 }
@@ -885,7 +894,7 @@
 #ifndef PRODUCT
   if (TraceOnStackReplacement) {
     if (nm != NULL) {
-      tty->print("OSR entry @ pc: " INTPTR_FORMAT ": ", nm->osr_entry());
+      tty->print("OSR entry @ pc: " INTPTR_FORMAT ": ", p2i(nm->osr_entry()));
       nm->print();
     }
   }
@@ -1305,7 +1314,7 @@
       tty->cr();
       tty->print_cr("argument handler #%d at " PTR_FORMAT " for fingerprint " UINT64_FORMAT,
                     _handlers->length(),
-                    handler,
+                    p2i(handler),
                     fingerprint);
     }
     _fingerprints->append(fingerprint);
@@ -1316,8 +1325,8 @@
       tty->print_cr("duplicate argument handler #%d for fingerprint " UINT64_FORMAT "(old: " PTR_FORMAT ", new : " PTR_FORMAT ")",
                     _handlers->length(),
                     fingerprint,
-                    _handlers->at(handler_index),
-                    handler);
+                    p2i(_handlers->at(handler_index)),
+                    p2i(handler));
     }
   }
 }
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -124,7 +124,7 @@
     // Note: with several active threads, the must_be_compiled may be true
     //       while can_be_compiled is false; remove assert
     // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile");
-    if (THREAD->is_Compiler_thread()) {
+    if (!THREAD->can_call_java()) {
       // don't force compilation, resolve was on behalf of compiler
       return;
     }
@@ -179,11 +179,11 @@
     KlassHandle object_klass = SystemDictionary::Object_klass();
     Method * object_resolved_method = object_klass()->vtable()->method_at(index);
     assert(object_resolved_method->name() == resolved_method->name(),
-      err_msg("Object and interface method names should match at vtable index %d, %s != %s",
-      index, object_resolved_method->name()->as_C_string(), resolved_method->name()->as_C_string()));
+      "Object and interface method names should match at vtable index %d, %s != %s",
+      index, object_resolved_method->name()->as_C_string(), resolved_method->name()->as_C_string());
     assert(object_resolved_method->signature() == resolved_method->signature(),
-      err_msg("Object and interface method signatures should match at vtable index %d, %s != %s",
-      index, object_resolved_method->signature()->as_C_string(), resolved_method->signature()->as_C_string()));
+      "Object and interface method signatures should match at vtable index %d, %s != %s",
+      index, object_resolved_method->signature()->as_C_string(), resolved_method->signature()->as_C_string());
 #endif // ASSERT
 
     kind = CallInfo::vtable_call;
@@ -192,7 +192,7 @@
     kind = CallInfo::itable_call;
     index = resolved_method->itable_index();
   }
-  assert(index == Method::nonvirtual_vtable_index || index >= 0, err_msg("bad index %d", index));
+  assert(index == Method::nonvirtual_vtable_index || index >= 0, "bad index %d", index);
   _call_kind  = kind;
   _call_index = index;
   _resolved_appendix = Handle();
@@ -215,7 +215,7 @@
     assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set");
     break;
   default:
-    fatal(err_msg_res("Unexpected call kind %d", call_kind()));
+    fatal("Unexpected call kind %d", call_kind());
   }
 }
 #endif //ASSERT
@@ -450,7 +450,7 @@
       }
       return result;
     } else if (iid == vmIntrinsics::_invokeGeneric
-               && !THREAD->is_Compiler_thread()
+               && THREAD->can_call_java()
                && appendix_result_or_null != NULL) {
       // This is a method with type-checking semantics.
       // We will ask Java code to spin an adapter method for it.
@@ -499,7 +499,7 @@
           result->print();
         }
         assert(actual_size_of_params == expected_size_of_params,
-               err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
+               "%d != %d", actual_size_of_params, expected_size_of_params);
 #endif //ASSERT
 
         assert(appendix_result_or_null != NULL, "");
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -174,9 +174,11 @@
   static methodHandle lookup_polymorphic_method(const LinkInfo& link_info,
                                                 Handle *appendix_result_or_null,
                                                 Handle *method_type_result, TRAPS);
+ JVMCI_ONLY(public:) // Needed for CompilerToVM.resolveMethod()
   // Not Linktime so doesn't take LinkInfo
   static methodHandle lookup_instance_method_in_klasses (
                                        KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
+ JVMCI_ONLY(private:)
 
   // Similar loader constraint checking functions that throw
   // LinkageError with descriptive message.
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,8 +31,6 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/signature.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 class OopMapCacheEntry: private InterpreterOopMap {
   friend class InterpreterOopMap;
   friend class OopMapForCacheEntry;
@@ -213,31 +211,6 @@
   }
 }
 
-
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-
-void InterpreterOopMap::iterate_all(OffsetClosure* oop_closure, OffsetClosure* value_closure, OffsetClosure* dead_closure) {
-  int n = number_of_entries();
-  int word_index = 0;
-  uintptr_t value = 0;
-  uintptr_t mask = 0;
-  // iterate over entries
-  for (int i = 0; i < n; i++, mask <<= bits_per_entry) {
-    // get current word
-    if (mask == 0) {
-      value = bit_mask()[word_index++];
-      mask = 1;
-    }
-    // test for dead values  & oops, and for live values
-         if ((value & (mask << dead_bit_number)) != 0)  dead_closure->offset_do(i); // call this for all dead values or oops
-    else if ((value & (mask <<  oop_bit_number)) != 0)   oop_closure->offset_do(i); // call this for all live oops
-    else                                               value_closure->offset_do(i); // call this for all live values
-  }
-}
-
-#endif
-
-
 void InterpreterOopMap::print() const {
   int n = number_of_entries();
   tty->print("oop map for ");
@@ -297,12 +270,6 @@
     bool v2 = vars[i].is_reference()  ? true : false;
     assert(v1 == v2, "locals oop mask generation error");
     if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0);
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-    bool v3 = is_dead(i)              ? true : false;
-    bool v4 = !vars[i].is_live()      ? true : false;
-    assert(v3 == v4, "locals live mask generation error");
-    assert(!(v1 && v3), "dead value marked as oop");
-#endif
   }
 
   if (TraceOopMapGeneration && Verbose) { tty->cr(); tty->print("Stack (%d): ", stack_top); }
@@ -311,12 +278,6 @@
     bool v2 = stack[j].is_reference() ? true : false;
     assert(v1 == v2, "stack oop mask generation error");
     if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0);
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-    bool v3 = is_dead(max_locals + j) ? true : false;
-    bool v4 = !stack[j].is_live()     ? true : false;
-    assert(v3 == v4, "stack live mask generation error");
-    assert(!(v1 && v3), "dead value marked as oop");
-#endif
   }
   if (TraceOopMapGeneration && Verbose) tty->cr();
   return true;
--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -141,9 +141,6 @@
 
   int expression_stack_size() const              { return _expression_stack_size; }
 
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-  void iterate_all(OffsetClosure* oop_closure, OffsetClosure* value_closure, OffsetClosure* dead_closure);
-#endif
 };
 
 class OopMapCache : public CHeapObj<mtClass> {
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -412,17 +412,6 @@
       method_entry(java_lang_math_pow  )
       method_entry(java_lang_ref_reference_get)
 
-      if (UseCRC32Intrinsics) {
-        method_entry(java_util_zip_CRC32_update)
-        method_entry(java_util_zip_CRC32_updateBytes)
-        method_entry(java_util_zip_CRC32_updateByteBuffer)
-      }
-
-      method_entry(java_lang_Float_intBitsToFloat);
-      method_entry(java_lang_Float_floatToRawIntBits);
-      method_entry(java_lang_Double_longBitsToDouble);
-      method_entry(java_lang_Double_doubleToRawLongBits);
-
       initialize_method_handle_entries();
 
       // all native method kinds (must be one contiguous block)
@@ -431,6 +420,22 @@
       method_entry(native_synchronized)
       Interpreter::_native_entry_end = Interpreter::code()->code_end();
 
+      if (UseCRC32Intrinsics) {
+        method_entry(java_util_zip_CRC32_update)
+        method_entry(java_util_zip_CRC32_updateBytes)
+        method_entry(java_util_zip_CRC32_updateByteBuffer)
+      }
+
+      if (UseCRC32CIntrinsics) {
+        method_entry(java_util_zip_CRC32C_updateBytes)
+        method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
+      }
+
+      method_entry(java_lang_Float_intBitsToFloat);
+      method_entry(java_lang_Float_floatToRawIntBits);
+      method_entry(java_lang_Double_longBitsToDouble);
+      method_entry(java_lang_Double_doubleToRawLongBits);
+
 #undef method_entry
 
       // Bytecodes
@@ -602,7 +607,7 @@
   case Bytecodes::_invokedynamic:
     return Interpreter::invokedynamic_return_entry_table();
   default:
-    fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code)));
+    fatal("invalid bytecode: %s", Bytecodes::name(code));
     return NULL;
   }
 }
@@ -624,7 +629,7 @@
   case Bytecodes::_invokedynamic:
     return _invokedynamic_return_entry[index];
   default:
-    assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code)));
+    assert(!Bytecodes::is_invoke(code), "invoke instructions should be handled separately: %s", Bytecodes::name(code));
     return _return_entry[length].entry(state);
   }
 }
--- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -59,6 +59,8 @@
   address generate_safept_entry_for(TosState state, address runtime_entry);
   void    generate_throw_exception();
 
+  void lock_method();
+
   // Instruction generation
   void generate_and_dispatch (Template* t, TosState tos_out = ilgl);
   void set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/commandLineFlagConstraintsJVMCI.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, 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 "jvmci/commandLineFlagConstraintsJVMCI.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/defaultStream.hpp"
+
+Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(bool value, bool verbose) {
+  if (!EnableJVMCI) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(), "EnableJVMCI must be enabled\n");
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(intx value, bool verbose) {
+  if (!EnableJVMCI) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(), "EnableJVMCI must be enabled\n");
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/commandLineFlagConstraintsJVMCI.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 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_JVMCI_COMMANDLINEFLAGCONSTRAINTSJVMCI_HPP
+#define SHARE_VM_JVMCI_COMMANDLINEFLAGCONSTRAINTSJVMCI_HPP
+
+#include "runtime/globals.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+/*
+ * Here we have JVMCI arguments constraints functions, which are called automatically
+ * whenever flag's value changes. If the constraint fails the function should return
+ * an appropriate error value.
+ */
+
+Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(bool value, bool verbose);
+Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(intx value, bool verbose);
+
+#endif /* SHARE_VM_JVMCI_COMMANDLINEFLAGCONSTRAINTSJVMCI_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1029 @@
+/*
+ * Copyright (c) 2011, 2015, 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 "code/compiledIC.hpp"
+#include "compiler/compileBroker.hpp"
+#include "compiler/disassembler.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
+#include "runtime/javaCalls.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciCodeInstaller.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "asm/register.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "code/vmreg.hpp"
+
+#ifdef TARGET_ARCH_x86
+# include "vmreg_x86.inline.hpp"
+#endif
+#ifdef TARGET_ARCH_sparc
+# include "vmreg_sparc.inline.hpp"
+#endif
+#ifdef TARGET_ARCH_zero
+# include "vmreg_zero.inline.hpp"
+#endif
+#ifdef TARGET_ARCH_arm
+# include "vmreg_arm.inline.hpp"
+#endif
+#ifdef TARGET_ARCH_ppc
+# include "vmreg_ppc.inline.hpp"
+#endif
+
+
+// frequently used constants
+// Allocate them with new so they are never destroyed (otherwise, a
+// forced exit could destroy these objects while they are still in
+// use).
+ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL);
+ConstantIntValue*      CodeInstaller::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1);
+ConstantIntValue*      CodeInstaller::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0);
+ConstantIntValue*      CodeInstaller::_int_1_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1);
+ConstantIntValue*      CodeInstaller::_int_2_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2);
+LocationValue*         CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location());
+
+Method* getMethodFromHotSpotMethod(oop hotspot_method) {
+  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass()), "sanity");
+  return CompilerToVM::asMethod(hotspot_method);
+}
+
+VMReg getVMRegFromLocation(oop location, int total_frame_size) {
+  oop reg = code_Location::reg(location);
+  jint offset = code_Location::offset(location);
+
+  if (reg != NULL) {
+    // register
+    jint number = code_Register::number(reg);
+    VMReg vmReg = CodeInstaller::get_hotspot_reg(number);
+    assert(offset % 4 == 0, "must be aligned");
+    return vmReg->next(offset / 4);
+  } else {
+    // stack slot
+    assert(offset % 4 == 0, "must be aligned");
+    return VMRegImpl::stack2reg(offset / 4);
+  }
+}
+
+// creates a HotSpot oop map out of the byte arrays provided by DebugInfo
+OopMap* CodeInstaller::create_oop_map(oop debug_info) {
+  oop reference_map = DebugInfo::referenceMap(debug_info);
+  if (HotSpotReferenceMap::maxRegisterSize(reference_map) > 16) {
+    _has_wide_vector = true;
+  }
+  OopMap* map = new OopMap(_total_frame_size, _parameter_count);
+  objArrayOop objects = HotSpotReferenceMap::objects(reference_map);
+  objArrayOop derivedBase = HotSpotReferenceMap::derivedBase(reference_map);
+  typeArrayOop sizeInBytes = HotSpotReferenceMap::sizeInBytes(reference_map);
+  for (int i = 0; i < objects->length(); i++) {
+    oop location = objects->obj_at(i);
+    oop baseLocation = derivedBase->obj_at(i);
+    int bytes = sizeInBytes->int_at(i);
+
+    VMReg vmReg = getVMRegFromLocation(location, _total_frame_size);
+    if (baseLocation != NULL) {
+      // derived oop
+      assert(bytes == 8, "derived oop can't be compressed");
+      VMReg baseReg = getVMRegFromLocation(baseLocation, _total_frame_size);
+      map->set_derived_oop(vmReg, baseReg);
+    } else if (bytes == 8) {
+      // wide oop
+      map->set_oop(vmReg);
+    } else {
+      // narrow oop
+      assert(bytes == 4, "wrong size");
+      map->set_narrowoop(vmReg);
+    }
+  }
+
+  oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info);
+  if (callee_save_info != NULL) {
+    objArrayOop registers = RegisterSaveLayout::registers(callee_save_info);
+    typeArrayOop slots = RegisterSaveLayout::slots(callee_save_info);
+    for (jint i = 0; i < slots->length(); i++) {
+      oop jvmci_reg = registers->obj_at(i);
+      jint jvmci_reg_number = code_Register::number(jvmci_reg);
+      VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number);
+      // HotSpot stack slots are 4 bytes
+      jint jvmci_slot = slots->int_at(i);
+      jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word;
+      VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot);
+      map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg);
+#ifdef _LP64
+      // (copied from generate_oop_map() in c1_Runtime1_x86.cpp)
+      VMReg hotspot_slot_hi_as_reg = VMRegImpl::stack2reg(hotspot_slot + 1);
+      map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next());
+#endif
+    }
+  }
+  return map;
+}
+
+static void record_metadata_reference(oop obj, jlong prim, jboolean compressed, OopRecorder* oop_recorder) {
+  if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
+    Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
+    if (compressed) {
+      assert(Klass::decode_klass((narrowKlass) prim) == klass, "%s @ " INTPTR_FORMAT " != " PTR64_FORMAT, klass->name()->as_C_string(), p2i(klass), prim);
+    } else {
+      assert((Klass*) prim == klass, "%s @ " INTPTR_FORMAT " != " PTR64_FORMAT, klass->name()->as_C_string(), p2i(klass), prim);
+    }
+    int index = oop_recorder->find_index(klass);
+    TRACE_jvmci_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
+  } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
+    Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj);
+    assert(!compressed, "unexpected compressed method pointer %s @ " INTPTR_FORMAT " = " PTR64_FORMAT, method->name()->as_C_string(), p2i(method), prim);
+    int index = oop_recorder->find_index(method);
+    TRACE_jvmci_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string());
+  } else {
+    assert(java_lang_String::is_instance(obj),
+        "unexpected metadata reference (%s) for constant " JLONG_FORMAT " (" PTR64_FORMAT ")", obj->klass()->name()->as_C_string(), prim, prim);
+  }
+}
+
+// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectTypeImpl.klass()).
+static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
+  if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
+    oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
+    jlong prim = HotSpotMetaspaceConstantImpl::primitive(constant);
+    assert(obj != NULL, "must have an object");
+    assert(prim != 0, "must have a primitive value");
+
+    record_metadata_reference(obj, prim, false, oop_recorder);
+  }
+}
+
+static void record_metadata_in_patch(Handle& constant, OopRecorder* oop_recorder) {
+  record_metadata_reference(HotSpotMetaspaceConstantImpl::metaspaceObject(constant), HotSpotMetaspaceConstantImpl::primitive(constant), HotSpotMetaspaceConstantImpl::compressed(constant), oop_recorder);
+}
+
+Location::Type CodeInstaller::get_oop_type(oop value) {
+  oop lirKind = Value::lirKind(value);
+  oop platformKind = LIRKind::platformKind(lirKind);
+  assert(LIRKind::referenceMask(lirKind) == 1, "unexpected referenceMask");
+
+  if (platformKind == word_kind()) {
+    return Location::oop;
+  } else {
+    return Location::narrowoop;
+  }
+}
+
+ScopeValue* CodeInstaller::get_scope_value(oop value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) {
+  second = NULL;
+  if (value == Value::ILLEGAL()) {
+    assert(type == T_ILLEGAL, "expected legal value");
+    return _illegal_value;
+  } else if (value->is_a(RegisterValue::klass())) {
+    oop reg = RegisterValue::reg(value);
+    jint number = code_Register::number(reg);
+    VMReg hotspotRegister = get_hotspot_reg(number);
+    if (is_general_purpose_reg(hotspotRegister)) {
+      Location::Type locationType;
+      if (type == T_OBJECT) {
+        locationType = get_oop_type(value);
+      } else if (type == T_LONG) {
+        locationType = Location::lng;
+      } else {
+        assert(type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN, "unexpected type in cpu register");
+        locationType = Location::int_in_long;
+      }
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister));
+      if (type == T_LONG) {
+        second = value;
+      }
+      return value;
+    } else {
+      assert(type == T_FLOAT || type == T_DOUBLE, "only float and double expected in xmm register");
+      Location::Type locationType;
+      if (type == T_FLOAT) {
+        // this seems weird, but the same value is used in c1_LinearScan
+        locationType = Location::normal;
+      } else {
+        locationType = Location::dbl;
+      }
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister));
+      if (type == T_DOUBLE) {
+        second = value;
+      }
+      return value;
+    }
+  } else if (value->is_a(StackSlot::klass())) {
+    jint offset = StackSlot::offset(value);
+    if (StackSlot::addFrameSize(value)) {
+      offset += _total_frame_size;
+    }
+
+    Location::Type locationType;
+    if (type == T_OBJECT) {
+      locationType = get_oop_type(value);
+    } else if (type == T_LONG) {
+      locationType = Location::lng;
+    } else if (type == T_DOUBLE) {
+      locationType = Location::dbl;
+    } else {
+      assert(type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN, "unexpected type in stack slot");
+      locationType = Location::normal;
+    }
+    ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset));
+    if (type == T_DOUBLE || type == T_LONG) {
+      second = value;
+    }
+    return value;
+  } else if (value->is_a(JavaConstant::klass())) {
+    record_metadata_in_constant(value, _oop_recorder);
+    if (value->is_a(PrimitiveConstant::klass())) {
+      if (value->is_a(RawConstant::klass())) {
+        jlong prim = PrimitiveConstant::primitive(value);
+        return new ConstantLongValue(prim);
+      } else {
+        assert(type == JVMCIRuntime::kindToBasicType(JavaKind::typeChar(PrimitiveConstant::kind(value))), "primitive constant type doesn't match");
+        if (type == T_INT || type == T_FLOAT) {
+          jint prim = (jint)PrimitiveConstant::primitive(value);
+          switch (prim) {
+            case -1: return _int_m1_scope_value;
+            case  0: return _int_0_scope_value;
+            case  1: return _int_1_scope_value;
+            case  2: return _int_2_scope_value;
+            default: return new ConstantIntValue(prim);
+          }
+        } else {
+          assert(type == T_LONG || type == T_DOUBLE, "unexpected primitive constant type");
+          jlong prim = PrimitiveConstant::primitive(value);
+          second = _int_1_scope_value;
+          return new ConstantLongValue(prim);
+        }
+      }
+    } else {
+      assert(type == T_OBJECT, "unexpected object constant");
+      if (value->is_a(NullConstant::klass()) || value->is_a(HotSpotCompressedNullConstant::klass())) {
+        return _oop_null_scope_value;
+      } else {
+        assert(value->is_a(HotSpotObjectConstantImpl::klass()), "unexpected constant type");
+        oop obj = HotSpotObjectConstantImpl::object(value);
+        assert(obj != NULL, "null value must be in NullConstant");
+        return new ConstantOopWriteValue(JNIHandles::make_local(obj));
+      }
+    }
+  } else if (value->is_a(VirtualObject::klass())) {
+    assert(type == T_OBJECT, "unexpected virtual object");
+    int id = VirtualObject::id(value);
+    ScopeValue* object = objects->at(id);
+    assert(object != NULL, "missing value");
+    return object;
+  } else {
+    value->klass()->print();
+    value->print();
+  }
+  ShouldNotReachHere();
+  return NULL;
+}
+
+void CodeInstaller::record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects) {
+  oop type = VirtualObject::type(value);
+  int id = VirtualObject::id(value);
+  oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type);
+  Klass* klass = java_lang_Class::as_Klass(javaMirror);
+  bool isLongArray = klass == Universe::longArrayKlassObj();
+
+  objArrayOop values = VirtualObject::values(value);
+  objArrayOop slotKinds = VirtualObject::slotKinds(value);
+  for (jint i = 0; i < values->length(); i++) {
+    ScopeValue* cur_second = NULL;
+    oop object = values->obj_at(i);
+    oop kind = slotKinds->obj_at(i);
+    BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind));
+    ScopeValue* value = get_scope_value(object, type, objects, cur_second);
+
+    if (isLongArray && cur_second == NULL) {
+      // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
+      // add an int 0 constant
+      cur_second = _int_0_scope_value;
+    }
+
+    if (cur_second != NULL) {
+      sv->field_values()->append(cur_second);
+    }
+    assert(value != NULL, "missing value");
+    sv->field_values()->append(value);
+  }
+}
+
+MonitorValue* CodeInstaller::get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects) {
+  guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type StackLockValue");
+
+  ScopeValue* second = NULL;
+  ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), T_OBJECT, objects, second);
+  assert(second == NULL, "monitor cannot occupy two stack slots");
+
+  ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), T_LONG, objects, second);
+  assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
+  assert(lock_data_value->is_location(), "invalid monitor location");
+  Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
+
+  bool eliminated = false;
+  if (StackLockValue::eliminated(value)) {
+    eliminated = true;
+  }
+
+  return new MonitorValue(owner_value, lock_data_loc, eliminated);
+}
+
+void CodeInstaller::initialize_dependencies(oop compiled_code, OopRecorder* recorder) {
+  JavaThread* thread = JavaThread::current();
+  CompilerThread* compilerThread = thread->is_Compiler_thread() ? thread->as_CompilerThread() : NULL;
+  _oop_recorder = recorder;
+  _dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != NULL ? compilerThread->log() : NULL);
+  objArrayHandle assumptions = HotSpotCompiledCode::assumptions(compiled_code);
+  if (!assumptions.is_null()) {
+    int length = assumptions->length();
+    for (int i = 0; i < length; ++i) {
+      Handle assumption = assumptions->obj_at(i);
+      if (!assumption.is_null()) {
+        if (assumption->klass() == Assumptions_NoFinalizableSubclass::klass()) {
+          assumption_NoFinalizableSubclass(assumption);
+        } else if (assumption->klass() == Assumptions_ConcreteSubtype::klass()) {
+          assumption_ConcreteSubtype(assumption);
+        } else if (assumption->klass() == Assumptions_LeafType::klass()) {
+          assumption_LeafType(assumption);
+        } else if (assumption->klass() == Assumptions_ConcreteMethod::klass()) {
+          assumption_ConcreteMethod(assumption);
+        } else if (assumption->klass() == Assumptions_CallSiteTargetValue::klass()) {
+          assumption_CallSiteTargetValue(assumption);
+        } else {
+          assumption->print();
+          fatal("unexpected Assumption subclass");
+        }
+      }
+    }
+  }
+  objArrayHandle methods = HotSpotCompiledCode::methods(compiled_code);
+  if (!methods.is_null()) {
+    int length = methods->length();
+    for (int i = 0; i < length; ++i) {
+      Handle method_handle = methods->obj_at(i);
+      methodHandle method = getMethodFromHotSpotMethod(method_handle());
+
+      _dependencies->assert_evol_method(method());
+    }
+  }
+}
+
+RelocBuffer::~RelocBuffer() {
+  if (_buffer != NULL) {
+    FREE_C_HEAP_ARRAY(char, _buffer);
+  }
+}
+
+address RelocBuffer::begin() const {
+  if (_buffer != NULL) {
+    return (address) _buffer;
+  }
+  return (address) _static_buffer;
+}
+
+void RelocBuffer::set_size(size_t bytes) {
+  assert(bytes <= _size, "can't grow in size!");
+  _size = bytes;
+}
+
+void RelocBuffer::ensure_size(size_t bytes) {
+  assert(_buffer == NULL, "can only be used once");
+  assert(_size == 0, "can only be used once");
+  if (bytes >= RelocBuffer::stack_size) {
+    _buffer = NEW_C_HEAP_ARRAY(char, bytes, mtInternal);
+  }
+  _size = bytes;
+}
+
+JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle& compiled_code, CodeMetadata& metadata) {
+  CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata");
+  jobject compiled_code_obj = JNIHandles::make_local(compiled_code());
+  initialize_dependencies(JNIHandles::resolve(compiled_code_obj), NULL);
+
+  // Get instructions and constants CodeSections early because we need it.
+  _instructions = buffer.insts();
+  _constants = buffer.consts();
+
+  initialize_fields(target(), JNIHandles::resolve(compiled_code_obj));
+  if (!initialize_buffer(buffer)) {
+    return JVMCIEnv::code_too_large;
+  }
+  process_exception_handlers();
+
+  _debug_recorder->pcs_size(); // ehm, create the sentinel record
+
+  assert(_debug_recorder->pcs_length() >= 2, "must be at least 2");
+
+  metadata.set_pc_desc(_debug_recorder->pcs(), _debug_recorder->pcs_length());
+  metadata.set_scopes(_debug_recorder->stream()->buffer(), _debug_recorder->data_size());
+  metadata.set_exception_table(&_exception_handler_table);
+
+  RelocBuffer* reloc_buffer = metadata.get_reloc_buffer();
+
+  reloc_buffer->ensure_size(buffer.total_relocation_size());
+  size_t size = (size_t) buffer.copy_relocations_to(reloc_buffer->begin(), (CodeBuffer::csize_t) reloc_buffer->size(), true);
+  reloc_buffer->set_size(size);
+  return JVMCIEnv::ok;
+}
+
+// constructor used to create a method
+JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Handle target, Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log) {
+  CodeBuffer buffer("JVMCI Compiler CodeBuffer");
+  jobject compiled_code_obj = JNIHandles::make_local(compiled_code());
+  OopRecorder* recorder = new OopRecorder(&_arena, true);
+  initialize_dependencies(JNIHandles::resolve(compiled_code_obj), recorder);
+
+  // Get instructions and constants CodeSections early because we need it.
+  _instructions = buffer.insts();
+  _constants = buffer.consts();
+
+  initialize_fields(target(), JNIHandles::resolve(compiled_code_obj));
+  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer);
+  if (result != JVMCIEnv::ok) {
+    return result;
+  }
+  process_exception_handlers();
+
+  int stack_slots = _total_frame_size / HeapWordSize; // conversion to words
+
+  if (!compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
+    oop stubName = HotSpotCompiledCode::name(compiled_code_obj);
+    char* name = strdup(java_lang_String::as_utf8_string(stubName));
+    cb = RuntimeStub::new_runtime_stub(name,
+                                       &buffer,
+                                       CodeOffsets::frame_never_safe,
+                                       stack_slots,
+                                       _debug_recorder->_oopmaps,
+                                       false);
+    result = JVMCIEnv::ok;
+  } else {
+    nmethod* nm = NULL;
+    methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code));
+    jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code);
+    jint id = HotSpotCompiledNmethod::id(compiled_code);
+    bool has_unsafe_access = HotSpotCompiledNmethod::hasUnsafeAccess(compiled_code) == JNI_TRUE;
+    JVMCIEnv* env = (JVMCIEnv*) (address) HotSpotCompiledNmethod::jvmciEnv(compiled_code);
+    if (id == -1) {
+      // Make sure a valid compile_id is associated with every compile
+      id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
+    }
+    result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer,
+                                       stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
+                                       compiler, _debug_recorder, _dependencies, env, id,
+                                       has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log);
+    cb = nm;
+  }
+
+  if (cb != NULL) {
+    // Make sure the pre-calculated constants section size was correct.
+    guarantee((cb->code_begin() - cb->content_begin()) >= _constants_size, "%d < %d", (int)(cb->code_begin() - cb->content_begin()), _constants_size);
+  }
+  return result;
+}
+
+void CodeInstaller::initialize_fields(oop target, oop compiled_code) {
+  if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
+    Handle hotspotJavaMethod = HotSpotCompiledNmethod::method(compiled_code);
+    methodHandle method = getMethodFromHotSpotMethod(hotspotJavaMethod());
+    _parameter_count = method->size_of_parameters();
+    TRACE_jvmci_2("installing code for %s", method->name_and_sig_as_C_string());
+  } else {
+    // Must be a HotSpotCompiledRuntimeStub.
+    // Only used in OopMap constructor for non-product builds
+    _parameter_count = 0;
+  }
+  _sites_handle = JNIHandles::make_local(HotSpotCompiledCode::sites(compiled_code));
+  _exception_handlers_handle = JNIHandles::make_local(HotSpotCompiledCode::exceptionHandlers(compiled_code));
+
+  _code_handle = JNIHandles::make_local(HotSpotCompiledCode::targetCode(compiled_code));
+  _code_size = HotSpotCompiledCode::targetCodeSize(compiled_code);
+  _total_frame_size = HotSpotCompiledCode::totalFrameSize(compiled_code);
+  _custom_stack_area_offset = HotSpotCompiledCode::customStackAreaOffset(compiled_code);
+
+  // Pre-calculate the constants section size.  This is required for PC-relative addressing.
+  _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code));
+  guarantee(HotSpotCompiledCode::dataSectionAlignment(compiled_code) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+  _constants_size = data_section()->length();
+
+  _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code));
+
+#ifndef PRODUCT
+  _comments_handle = JNIHandles::make_local(HotSpotCompiledCode::comments(compiled_code));
+#endif
+
+  _next_call_type = INVOKE_INVALID;
+
+  _has_wide_vector = false;
+
+  oop arch = TargetDescription::arch(target);
+  _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch));
+}
+
+int CodeInstaller::estimate_stubs_size() {
+  // Return size for all stubs.
+  int static_call_stubs = 0;
+  objArrayOop sites = this->sites();
+  for (int i = 0; i < sites->length(); i++) {
+    oop site = sites->obj_at(i);
+    if (site->is_a(CompilationResult_Mark::klass())) {
+      oop id_obj = CompilationResult_Mark::id(site);
+      if (id_obj != NULL) {
+        assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected");
+        jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
+        if (id == INVOKESTATIC || id == INVOKESPECIAL) {
+          static_call_stubs++;
+        }
+      }
+    }
+  }
+  return static_call_stubs * CompiledStaticCall::to_interp_stub_size();
+}
+
+// perform data and call relocation on the CodeBuffer
+JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer) {
+  objArrayHandle sites = this->sites();
+  int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
+
+  // Allocate enough space in the stub section for the static call
+  // stubs.  Stubs have extra relocs but they are managed by the stub
+  // section itself so they don't need to be accounted for in the
+  // locs_buffer above.
+  int stubs_size = estimate_stubs_size();
+  int total_size = round_to(_code_size, buffer.insts()->alignment()) + round_to(_constants_size, buffer.consts()->alignment()) + round_to(stubs_size, buffer.stubs()->alignment());
+
+  if (total_size > JVMCINMethodSizeLimit) {
+    return JVMCIEnv::code_too_large;
+  }
+
+  buffer.initialize(total_size, locs_buffer_size);
+  if (buffer.blob() == NULL) {
+    return JVMCIEnv::cache_full;
+  }
+  buffer.initialize_stubs_size(stubs_size);
+  buffer.initialize_consts_size(_constants_size);
+
+  _debug_recorder = new DebugInformationRecorder(_oop_recorder);
+  _debug_recorder->set_oopmaps(new OopMapSet());
+
+  buffer.initialize_oop_recorder(_oop_recorder);
+
+  // copy the constant data into the newly created CodeBuffer
+  address end_data = _constants->start() + _constants_size;
+  memcpy(_constants->start(), data_section()->base(T_BYTE), _constants_size);
+  _constants->set_end(end_data);
+
+  // copy the code into the newly created CodeBuffer
+  address end_pc = _instructions->start() + _code_size;
+  guarantee(_instructions->allocates2(end_pc), "initialize should have reserved enough space for all the code");
+  memcpy(_instructions->start(), code()->base(T_BYTE), _code_size);
+  _instructions->set_end(end_pc);
+
+  for (int i = 0; i < data_section_patches()->length(); i++) {
+    Handle patch = data_section_patches()->obj_at(i);
+    Handle reference = CompilationResult_DataPatch::reference(patch);
+    assert(reference->is_a(CompilationResult_ConstantReference::klass()), "patch in data section must be a ConstantReference");
+    Handle constant = CompilationResult_ConstantReference::constant(reference);
+    if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
+      record_metadata_in_patch(constant, _oop_recorder);
+    } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
+      Handle obj = HotSpotObjectConstantImpl::object(constant);
+      jobject value = JNIHandles::make_local(obj());
+      int oop_index = _oop_recorder->find_index(value);
+
+      address dest = _constants->start() + CompilationResult_Site::pcOffset(patch);
+      if (HotSpotObjectConstantImpl::compressed(constant)) {
+#ifdef _LP64
+        _constants->relocate(dest, oop_Relocation::spec(oop_index), relocInfo::narrow_oop_in_const);
+#else
+        fatal("unexpected compressed oop in 32-bit mode");
+#endif
+      } else {
+        _constants->relocate(dest, oop_Relocation::spec(oop_index));
+      }
+    } else {
+      ShouldNotReachHere();
+    }
+  }
+  jint last_pc_offset = -1;
+  for (int i = 0; i < sites->length(); i++) {
+    {
+        No_Safepoint_Verifier no_safepoint;
+        oop site = sites->obj_at(i);
+        jint pc_offset = CompilationResult_Site::pcOffset(site);
+
+        if (site->is_a(CompilationResult_Call::klass())) {
+          TRACE_jvmci_4("call at %i", pc_offset);
+          site_Call(buffer, pc_offset, site);
+        } else if (site->is_a(CompilationResult_Infopoint::klass())) {
+          // three reasons for infopoints denote actual safepoints
+          oop reason = CompilationResult_Infopoint::reason(site);
+          if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) {
+            TRACE_jvmci_4("safepoint at %i", pc_offset);
+            site_Safepoint(buffer, pc_offset, site);
+          } else {
+            // if the infopoint is not an actual safepoint, it must have one of the other reasons
+            // (safeguard against new safepoint types that require handling above)
+            assert(InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason, "");
+            site_Infopoint(buffer, pc_offset, site);
+          }
+        } else if (site->is_a(CompilationResult_DataPatch::klass())) {
+          TRACE_jvmci_4("datapatch at %i", pc_offset);
+          site_DataPatch(buffer, pc_offset, site);
+        } else if (site->is_a(CompilationResult_Mark::klass())) {
+          TRACE_jvmci_4("mark at %i", pc_offset);
+          site_Mark(buffer, pc_offset, site);
+        } else {
+          fatal("unexpected Site subclass");
+        }
+        last_pc_offset = pc_offset;
+    }
+    if (CodeInstallSafepointChecks && SafepointSynchronize::do_call_back()) {
+      // this is a hacky way to force a safepoint check but nothing else was jumping out at me.
+      ThreadToNativeFromVM ttnfv(JavaThread::current());
+    }
+  }
+
+#ifndef PRODUCT
+  if (comments() != NULL) {
+    No_Safepoint_Verifier no_safepoint;
+    for (int i = 0; i < comments()->length(); i++) {
+      oop comment = comments()->obj_at(i);
+      assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce");
+      jint offset = HotSpotCompiledCode_Comment::pcOffset(comment);
+      char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment));
+      buffer.block_comment(offset, text);
+    }
+  }
+#endif
+  return JVMCIEnv::ok;
+}
+
+void CodeInstaller::assumption_NoFinalizableSubclass(Handle assumption) {
+  Handle receiverType_handle = Assumptions_NoFinalizableSubclass::receiverType(assumption());
+  Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(receiverType_handle));
+  _dependencies->assert_has_no_finalizable_subclasses(receiverType);
+}
+
+void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) {
+  Handle context_handle = Assumptions_ConcreteSubtype::context(assumption());
+  Handle subtype_handle = Assumptions_ConcreteSubtype::subtype(assumption());
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
+  Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(subtype_handle));
+
+  assert(context->is_abstract(), "");
+  _dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype);
+}
+
+void CodeInstaller::assumption_LeafType(Handle assumption) {
+  Handle context_handle = Assumptions_LeafType::context(assumption());
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
+
+  _dependencies->assert_leaf_type(context);
+}
+
+void CodeInstaller::assumption_ConcreteMethod(Handle assumption) {
+  Handle impl_handle = Assumptions_ConcreteMethod::impl(assumption());
+  Handle context_handle = Assumptions_ConcreteMethod::context(assumption());
+
+  methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
+
+  _dependencies->assert_unique_concrete_method(context, impl());
+}
+
+void CodeInstaller::assumption_CallSiteTargetValue(Handle assumption) {
+  Handle callSite = Assumptions_CallSiteTargetValue::callSite(assumption());
+  Handle methodHandle = Assumptions_CallSiteTargetValue::methodHandle(assumption());
+
+  _dependencies->assert_call_site_target_value(callSite(), methodHandle());
+}
+
+void CodeInstaller::process_exception_handlers() {
+  if (exception_handlers() != NULL) {
+    objArrayOop handlers = exception_handlers();
+    for (int i = 0; i < handlers->length(); i++) {
+      oop exc = handlers->obj_at(i);
+      jint pc_offset = CompilationResult_Site::pcOffset(exc);
+      jint handler_offset = CompilationResult_ExceptionHandler::handlerPos(exc);
+
+      // Subtable header
+      _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0));
+
+      // Subtable entry
+      _exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0));
+    }
+  }
+}
+
+// If deoptimization happens, the interpreter should reexecute these bytecodes.
+// This function mainly helps the compilers to set up the reexecute bit.
+static bool bytecode_should_reexecute(Bytecodes::Code code) {
+  switch (code) {
+    case Bytecodes::_invokedynamic:
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_invokeinterface:
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokestatic:
+      return false;
+    default:
+      return true;
+    }
+  return true;
+}
+
+GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(oop debug_info) {
+  objArrayOop virtualObjects = DebugInfo::virtualObjectMapping(debug_info);
+  if (virtualObjects == NULL) {
+    return NULL;
+  }
+  GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(virtualObjects->length(), virtualObjects->length(), NULL);
+  // Create the unique ObjectValues
+  for (int i = 0; i < virtualObjects->length(); i++) {
+    oop value = virtualObjects->obj_at(i);
+    int id = VirtualObject::id(value);
+    oop type = VirtualObject::type(value);
+    oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type);
+    ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror)));
+    assert(objects->at(id) == NULL, "once");
+    objects->at_put(id, sv);
+  }
+  // All the values which could be referenced by the VirtualObjects
+  // exist, so now describe all the VirtualObjects themselves.
+  for (int i = 0; i < virtualObjects->length(); i++) {
+    oop value = virtualObjects->obj_at(i);
+    int id = VirtualObject::id(value);
+    record_object_value(objects->at(id)->as_ObjectValue(), value, objects);
+  }
+  _debug_recorder->dump_object_pool(objects);
+  return objects;
+}
+
+void CodeInstaller::record_scope(jint pc_offset, oop debug_info) {
+  oop position = DebugInfo::bytecodePosition(debug_info);
+  if (position == NULL) {
+    // Stubs do not record scope info, just oop maps
+    return;
+  }
+
+  GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info);
+  record_scope(pc_offset, position, objectMapping);
+}
+
+void CodeInstaller::record_scope(jint pc_offset, oop position, GrowableArray<ScopeValue*>* objects) {
+  oop frame = NULL;
+  if (position->is_a(BytecodeFrame::klass())) {
+    frame = position;
+  }
+  oop caller_frame = BytecodePosition::caller(position);
+  if (caller_frame != NULL) {
+    record_scope(pc_offset, caller_frame, objects);
+  }
+
+  oop hotspot_method = BytecodePosition::method(position);
+  Method* method = getMethodFromHotSpotMethod(hotspot_method);
+  jint bci = BytecodePosition::bci(position);
+  if (bci == BytecodeFrame::BEFORE_BCI()) {
+    bci = SynchronizationEntryBCI;
+  }
+
+  TRACE_jvmci_2("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string());
+
+  bool reexecute = false;
+  if (frame != NULL) {
+    if (bci == SynchronizationEntryBCI){
+       reexecute = false;
+    } else {
+      Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));
+      reexecute = bytecode_should_reexecute(code);
+      if (frame != NULL) {
+        reexecute = (BytecodeFrame::duringCall(frame) == JNI_FALSE);
+      }
+    }
+  }
+
+  DebugToken* locals_token = NULL;
+  DebugToken* expressions_token = NULL;
+  DebugToken* monitors_token = NULL;
+  bool throw_exception = false;
+
+  if (frame != NULL) {
+    jint local_count = BytecodeFrame::numLocals(frame);
+    jint expression_count = BytecodeFrame::numStack(frame);
+    jint monitor_count = BytecodeFrame::numLocks(frame);
+    objArrayOop values = BytecodeFrame::values(frame);
+    objArrayOop slotKinds = BytecodeFrame::slotKinds(frame);
+
+    assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length");
+    assert(local_count + expression_count == slotKinds->length(), "unexpected slotKinds length");
+
+    GrowableArray<ScopeValue*>* locals = local_count > 0 ? new GrowableArray<ScopeValue*> (local_count) : NULL;
+    GrowableArray<ScopeValue*>* expressions = expression_count > 0 ? new GrowableArray<ScopeValue*> (expression_count) : NULL;
+    GrowableArray<MonitorValue*>* monitors = monitor_count > 0 ? new GrowableArray<MonitorValue*> (monitor_count) : NULL;
+
+    TRACE_jvmci_2("Scope at bci %d with %d values", bci, values->length());
+    TRACE_jvmci_2("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);
+
+    for (jint i = 0; i < values->length(); i++) {
+      ScopeValue* second = NULL;
+      oop value = values->obj_at(i);
+      if (i < local_count) {
+        oop kind = slotKinds->obj_at(i);
+        BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind));
+        ScopeValue* first = get_scope_value(value, type, objects, second);
+        if (second != NULL) {
+          locals->append(second);
+        }
+        locals->append(first);
+      } else if (i < local_count + expression_count) {
+        oop kind = slotKinds->obj_at(i);
+        BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind));
+        ScopeValue* first = get_scope_value(value, type, objects, second);
+        if (second != NULL) {
+          expressions->append(second);
+        }
+        expressions->append(first);
+      } else {
+        monitors->append(get_monitor_value(value, objects));
+      }
+      if (second != NULL) {
+        i++;
+        assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL");
+        assert(values->obj_at(i) == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL");
+      }
+    }
+
+    locals_token = _debug_recorder->create_scope_values(locals);
+    expressions_token = _debug_recorder->create_scope_values(expressions);
+    monitors_token = _debug_recorder->create_monitor_values(monitors);
+
+    throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
+  }
+
+  _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false,
+                                  locals_token, expressions_token, monitors_token);
+}
+
+void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop debug_info = CompilationResult_Infopoint::debugInfo(site);
+  assert(debug_info != NULL, "debug info expected");
+
+  // address instruction = _instructions->start() + pc_offset;
+  // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
+  _debug_recorder->add_safepoint(pc_offset, create_oop_map(debug_info));
+  record_scope(pc_offset, debug_info);
+  _debug_recorder->end_safepoint(pc_offset);
+}
+
+void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop debug_info = CompilationResult_Infopoint::debugInfo(site);
+  assert(debug_info != NULL, "debug info expected");
+
+  _debug_recorder->add_non_safepoint(pc_offset);
+  record_scope(pc_offset, debug_info);
+  _debug_recorder->end_non_safepoint(pc_offset);
+}
+
+void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop target = CompilationResult_Call::target(site);
+  InstanceKlass* target_klass = InstanceKlass::cast(target->klass());
+
+  oop hotspot_method = NULL; // JavaMethod
+  oop foreign_call = NULL;
+
+  if (target_klass->is_subclass_of(SystemDictionary::HotSpotForeignCallTarget_klass())) {
+    foreign_call = target;
+  } else {
+    hotspot_method = target;
+  }
+
+  oop debug_info = CompilationResult_Call::debugInfo(site);
+
+  assert(!!hotspot_method ^ !!foreign_call, "Call site needs exactly one type");
+
+  NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
+  jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method);
+
+  if (debug_info != NULL) {
+    _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(debug_info));
+    record_scope(next_pc_offset, debug_info);
+  }
+
+  if (foreign_call != NULL) {
+    jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call);
+    CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination);
+  } else { // method != NULL
+    assert(hotspot_method != NULL, "unexpected JavaMethod");
+    assert(debug_info != NULL, "debug info expected");
+
+    TRACE_jvmci_3("method call");
+    CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset);
+    if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) {
+      // Need a static call stub for transitions from compiled to interpreted.
+      CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset);
+    }
+  }
+
+  _next_call_type = INVOKE_INVALID;
+
+  if (debug_info != NULL) {
+    _debug_recorder->end_safepoint(next_pc_offset);
+  }
+}
+
+void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop reference = CompilationResult_DataPatch::reference(site);
+  if (reference->is_a(CompilationResult_ConstantReference::klass())) {
+    Handle constant = CompilationResult_ConstantReference::constant(reference);
+    if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
+      pd_patch_OopConstant(pc_offset, constant);
+    } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
+      record_metadata_in_patch(constant, _oop_recorder);
+    } else if (constant->is_a(HotSpotSentinelConstant::klass())) {
+      fatal("sentinel constant unsupported");
+    } else {
+      fatal("unknown constant type in data patch");
+    }
+  } else if (reference->is_a(CompilationResult_DataSectionReference::klass())) {
+    int data_offset = CompilationResult_DataSectionReference::offset(reference);
+    assert(0 <= data_offset && data_offset < _constants_size, "data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size);
+    pd_patch_DataSectionReference(pc_offset, data_offset);
+  } else {
+    fatal("unknown data patch type");
+  }
+}
+
+void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop id_obj = CompilationResult_Mark::id(site);
+
+  if (id_obj != NULL) {
+    assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected");
+    jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
+
+    address pc = _instructions->start() + pc_offset;
+
+    switch (id) {
+      case UNVERIFIED_ENTRY:
+        _offsets.set_value(CodeOffsets::Entry, pc_offset);
+        break;
+      case VERIFIED_ENTRY:
+        _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset);
+        break;
+      case OSR_ENTRY:
+        _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset);
+        break;
+      case EXCEPTION_HANDLER_ENTRY:
+        _offsets.set_value(CodeOffsets::Exceptions, pc_offset);
+        break;
+      case DEOPT_HANDLER_ENTRY:
+        _offsets.set_value(CodeOffsets::Deopt, pc_offset);
+        break;
+      case INVOKEVIRTUAL:
+      case INVOKEINTERFACE:
+      case INLINE_INVOKE:
+      case INVOKESTATIC:
+      case INVOKESPECIAL:
+        _next_call_type = (MarkId) id;
+        _invoke_mark_pc = pc;
+        break;
+      case POLL_NEAR:
+      case POLL_FAR:
+      case POLL_RETURN_NEAR:
+      case POLL_RETURN_FAR:
+        pd_relocate_poll(pc, id);
+        break;
+      case CARD_TABLE_ADDRESS:
+      case HEAP_TOP_ADDRESS:
+      case HEAP_END_ADDRESS:
+      case NARROW_KLASS_BASE_ADDRESS:
+      case CRC_TABLE_ADDRESS:
+        break;
+      default:
+        ShouldNotReachHere();
+        break;
+    }
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2011, 2015, 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_JVMCI_JVMCI_CODE_INSTALLER_HPP
+#define SHARE_VM_JVMCI_JVMCI_CODE_INSTALLER_HPP
+
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "code/nativeInst.hpp"
+
+class RelocBuffer : public StackObj {
+  enum { stack_size = 1024 };
+public:
+  RelocBuffer() : _size(0), _buffer(0) {}
+  ~RelocBuffer();
+  void ensure_size(size_t bytes);
+  void set_size(size_t bytes);
+  address begin() const;
+  size_t size() const { return _size; }
+private:
+  size_t _size;
+  char _static_buffer[stack_size];
+  char *_buffer;
+};
+
+class CodeMetadata {
+public:
+  CodeMetadata() {}
+
+  CodeBlob* get_code_blob() const { return _cb; }
+
+  PcDesc* get_pc_desc() const { return _pc_desc; }
+  int get_nr_pc_desc() const { return _nr_pc_desc; }
+
+  u_char* get_scopes_desc() const { return _scopes_desc; }
+  int get_scopes_size() const { return _nr_scopes_desc; }
+
+  RelocBuffer* get_reloc_buffer() { return &_reloc_buffer; }
+
+  ExceptionHandlerTable* get_exception_table() { return _exception_table; }
+
+  void set_pc_desc(PcDesc* desc, int count) {
+    _pc_desc = desc;
+    _nr_pc_desc = count;
+  }
+
+  void set_scopes(u_char* scopes, int size) {
+    _scopes_desc = scopes;
+    _nr_scopes_desc = size;
+  }
+
+  void set_exception_table(ExceptionHandlerTable* table) {
+    _exception_table = table;
+  }
+
+private:
+  CodeBlob* _cb;
+  PcDesc* _pc_desc;
+  int _nr_pc_desc;
+
+  u_char* _scopes_desc;
+  int _nr_scopes_desc;
+
+  RelocBuffer _reloc_buffer;
+  ExceptionHandlerTable* _exception_table;
+};
+
+/*
+ * This class handles the conversion from a InstalledCode to a CodeBlob or an nmethod.
+ */
+class CodeInstaller : public StackObj {
+  friend class VMStructs;
+private:
+  enum MarkId {
+    VERIFIED_ENTRY             = 1,
+    UNVERIFIED_ENTRY           = 2,
+    OSR_ENTRY                  = 3,
+    EXCEPTION_HANDLER_ENTRY    = 4,
+    DEOPT_HANDLER_ENTRY        = 5,
+    INVOKEINTERFACE            = 6,
+    INVOKEVIRTUAL              = 7,
+    INVOKESTATIC               = 8,
+    INVOKESPECIAL              = 9,
+    INLINE_INVOKE              = 10,
+    POLL_NEAR                  = 11,
+    POLL_RETURN_NEAR           = 12,
+    POLL_FAR                   = 13,
+    POLL_RETURN_FAR            = 14,
+    CARD_TABLE_ADDRESS         = 15,
+    HEAP_TOP_ADDRESS           = 16,
+    HEAP_END_ADDRESS           = 17,
+    NARROW_KLASS_BASE_ADDRESS  = 18,
+    CRC_TABLE_ADDRESS          = 19,
+    INVOKE_INVALID             = -1
+  };
+
+  Arena         _arena;
+
+  jobject       _data_section_handle;
+  jobject       _data_section_patches_handle;
+  jobject       _sites_handle;
+  jobject       _exception_handlers_handle;
+  CodeOffsets   _offsets;
+
+  jobject       _code_handle;
+  jint          _code_size;
+  jint          _total_frame_size;
+  jint          _custom_stack_area_offset;
+  jint          _parameter_count;
+  jint          _constants_size;
+#ifndef PRODUCT
+  jobject       _comments_handle;
+#endif
+
+  bool          _has_wide_vector;
+  jobject       _word_kind_handle;
+
+  MarkId        _next_call_type;
+  address       _invoke_mark_pc;
+
+  CodeSection*  _instructions;
+  CodeSection*  _constants;
+
+  OopRecorder*              _oop_recorder;
+  DebugInformationRecorder* _debug_recorder;
+  Dependencies*             _dependencies;
+  ExceptionHandlerTable     _exception_handler_table;
+
+  static ConstantOopWriteValue* _oop_null_scope_value;
+  static ConstantIntValue*    _int_m1_scope_value;
+  static ConstantIntValue*    _int_0_scope_value;
+  static ConstantIntValue*    _int_1_scope_value;
+  static ConstantIntValue*    _int_2_scope_value;
+  static LocationValue*       _illegal_value;
+
+  jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method);
+  void pd_patch_OopConstant(int pc_offset, Handle& constant);
+  void pd_patch_DataSectionReference(int pc_offset, int data_offset);
+  void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst);
+  void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination);
+  void pd_relocate_JavaMethod(oop method, jint pc_offset);
+  void pd_relocate_poll(address pc, jint mark);
+
+  objArrayOop sites() { return (objArrayOop) JNIHandles::resolve(_sites_handle); }
+  arrayOop code() { return (arrayOop) JNIHandles::resolve(_code_handle); }
+  arrayOop data_section() { return (arrayOop) JNIHandles::resolve(_data_section_handle); }
+  objArrayOop data_section_patches() { return (objArrayOop) JNIHandles::resolve(_data_section_patches_handle); }
+  objArrayOop exception_handlers() { return (objArrayOop) JNIHandles::resolve(_exception_handlers_handle); }
+#ifndef PRODUCT
+  objArrayOop comments() { return (objArrayOop) JNIHandles::resolve(_comments_handle); }
+#endif
+
+  void record_resolved(oop obj);
+
+  oop word_kind() { return (oop) JNIHandles::resolve(_word_kind_handle); }
+
+public:
+  CodeInstaller() : _arena(mtCompiler) {}
+
+  JVMCIEnv::CodeInstallResult gather_metadata(Handle target, Handle& compiled_code, CodeMetadata& metadata);
+  JVMCIEnv::CodeInstallResult install(JVMCICompiler* compiler, Handle target, Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log);
+
+  static address runtime_call_target_address(oop runtime_call);
+  static VMReg get_hotspot_reg(jint jvmciRegisterNumber);
+  static bool is_general_purpose_reg(VMReg hotspotRegister);
+
+  const OopMapSet* oopMapSet() const { return _debug_recorder->_oopmaps; }
+
+protected:
+  Location::Type get_oop_type(oop value);
+  ScopeValue* get_scope_value(oop value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second);
+  MonitorValue* get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects);
+
+  // extract the fields of the CompilationResult
+  void initialize_fields(oop target, oop target_method);
+  void initialize_dependencies(oop target_method, OopRecorder* oop_recorder);
+
+  int estimate_stubs_size();
+
+  // perform data and call relocation on the CodeBuffer
+  JVMCIEnv::CodeInstallResult initialize_buffer(CodeBuffer& buffer);
+
+  void assumption_NoFinalizableSubclass(Handle assumption);
+  void assumption_ConcreteSubtype(Handle assumption);
+  void assumption_LeafType(Handle assumption);
+  void assumption_ConcreteMethod(Handle assumption);
+  void assumption_CallSiteTargetValue(Handle assumption);
+
+  void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_Call(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site);
+
+  OopMap* create_oop_map(oop debug_info);
+
+  void record_scope(jint pc_offset, oop debug_info);
+  void record_scope(jint pc_offset, oop code_pos, GrowableArray<ScopeValue*>* objects);
+  void record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects);
+
+  GrowableArray<ScopeValue*>* record_virtual_objects(oop debug_info);
+
+  void process_exception_handlers();
+  int estimateStubSpace(int static_call_stubs);
+};
+
+/**
+ * Gets the Method metaspace object from a HotSpotResolvedJavaMethodImpl Java object.
+ */
+Method* getMethodFromHotSpotMethod(oop hotspot_method);
+
+
+
+#endif // SHARE_VM_JVMCI_JVMCI_CODE_INSTALLER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/handles.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "runtime/compilationPolicy.hpp"
+#include "runtime/globals_extension.hpp"
+
+JVMCICompiler* JVMCICompiler::_instance = NULL;
+elapsedTimer JVMCICompiler::_codeInstallTimer;
+
+JVMCICompiler::JVMCICompiler() : AbstractCompiler(jvmci) {
+  _bootstrapping = false;
+  _methodsCompiled = 0;
+  assert(_instance == NULL, "only one instance allowed");
+  _instance = this;
+}
+
+// Initialization
+void JVMCICompiler::initialize() {
+  if (!UseCompiler || !EnableJVMCI || !UseJVMCICompiler || !should_perform_init()) {
+    return;
+  }
+
+  set_state(initialized);
+
+  // JVMCI is considered as application code so we need to
+  // stop the VM deferring compilation now.
+  CompilationPolicy::completed_vm_startup();
+}
+
+void JVMCICompiler::bootstrap() {
+#ifndef PRODUCT
+  // We turn off CompileTheWorld so that compilation requests are not
+  // ignored during bootstrap or that JVMCI can be compiled by C1/C2.
+  FlagSetting ctwOff(CompileTheWorld, false);
+#endif
+
+  JavaThread* THREAD = JavaThread::current();
+  _bootstrapping = true;
+  ResourceMark rm;
+  HandleMark hm;
+  if (PrintBootstrap) {
+    tty->print("Bootstrapping JVMCI");
+  }
+  jlong start = os::javaTimeMillis();
+
+  Array<Method*>* objectMethods = InstanceKlass::cast(SystemDictionary::Object_klass())->methods();
+  // Initialize compile queue with a selected set of methods.
+  int len = objectMethods->length();
+  for (int i = 0; i < len; i++) {
+    methodHandle mh = objectMethods->at(i);
+    if (!mh->is_native() && !mh->is_static() && !mh->is_initializer()) {
+      ResourceMark rm;
+      int hot_count = 10; // TODO: what's the appropriate value?
+      CompileBroker::compile_method(mh, InvocationEntryBci, CompLevel_full_optimization, mh, hot_count, "bootstrap", THREAD);
+    }
+  }
+
+  int qsize;
+  bool first_round = true;
+  int z = 0;
+  do {
+    // Loop until there is something in the queue.
+    do {
+      os::sleep(THREAD, 100, true);
+      qsize = CompileBroker::queue_size(CompLevel_full_optimization);
+    } while (first_round && qsize == 0);
+    first_round = false;
+    if (PrintBootstrap) {
+      while (z < (_methodsCompiled / 100)) {
+        ++z;
+        tty->print_raw(".");
+      }
+    }
+  } while (qsize != 0);
+
+  if (PrintBootstrap) {
+    tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methodsCompiled);
+  }
+  _bootstrapping = false;
+}
+
+void JVMCICompiler::compile_method(methodHandle method, int entry_bci, JVMCIEnv* env) {
+  JVMCI_EXCEPTION_CONTEXT
+
+  bool is_osr = entry_bci != InvocationEntryBci;
+  if (_bootstrapping && is_osr) {
+      // no OSR compilations during bootstrap - the compiler is just too slow at this point,
+      // and we know that there are no endless loops
+      return;
+  }
+
+  JVMCIRuntime::initialize_well_known_classes(CHECK_ABORT);
+
+  HandleMark hm;
+  ResourceMark rm;
+  Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_ABORT);
+
+  JavaValue method_result(T_OBJECT);
+  {
+    JavaCallArguments args;
+    args.push_long((jlong) (address) method());
+    JavaCalls::call_static(&method_result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_ABORT);
+  }
+
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(receiver);
+  args.push_oop((oop)method_result.get_jobject());
+  args.push_int(entry_bci);
+  args.push_long((jlong) (address) env);
+  args.push_int(env->task()->compile_id());
+  JavaCalls::call_special(&result, receiver->klass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, CHECK_ABORT);
+
+  _methodsCompiled++;
+}
+
+
+// Compilation entry point for methods
+void JVMCICompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
+  ShouldNotReachHere();
+}
+
+// Print compilation timers and statistics
+void JVMCICompiler::print_timers() {
+  print_compilation_timers();
+}
+
+// Print compilation timers and statistics
+void JVMCICompiler::print_compilation_timers() {
+  TRACE_jvmci_1("JVMCICompiler::print_timers");
+  tty->print_cr("       JVMCI code install time:        %6.3f s",    _codeInstallTimer.seconds());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, 2015, 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_JVMCI_JVMCI_COMPILER_HPP
+#define SHARE_VM_JVMCI_JVMCI_COMPILER_HPP
+
+#include "compiler/abstractCompiler.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "utilities/exceptions.hpp"
+
+class JVMCICompiler : public AbstractCompiler {
+private:
+  bool _bootstrapping;
+
+  /**
+   * Number of methods compiled by JVMCI. This is not synchronized
+   * so may not be 100% accurate.
+   */
+  volatile int _methodsCompiled;
+
+  static JVMCICompiler* _instance;
+
+  static elapsedTimer _codeInstallTimer;
+
+public:
+  JVMCICompiler();
+
+  static JVMCICompiler* instance(TRAPS) {
+    if (!EnableJVMCI) {
+      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
+    }
+    return _instance;
+  }
+
+  virtual const char* name() { return "JVMCI"; }
+
+  virtual bool supports_native()                 { return true; }
+  virtual bool supports_osr   ()                 { return true; }
+
+  bool is_jvmci()                                { return true; }
+  bool is_c1   ()                                { return false; }
+  bool is_c2   ()                                { return false; }
+
+  bool needs_stubs            () { return false; }
+
+  // Initialization
+  virtual void initialize();
+
+  void bootstrap();
+
+  // Compilation entry point for methods
+  virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
+
+  void compile_method(methodHandle target, int entry_bci, JVMCIEnv* env);
+
+  // Print compilation timers and statistics
+  virtual void print_timers();
+
+  // Print compilation statistics
+  void reset_compilation_stats();
+
+  // Print compilation timers and statistics
+  static void print_compilation_timers();
+
+  static elapsedTimer* codeInstallTimer() { return &_codeInstallTimer; }
+};
+
+#endif // SHARE_VM_JVMCI_JVMCI_COMPILER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1370 @@
+/*
+ * Copyright (c) 2011, 2015, 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 "code/codeCache.hpp"
+#include "code/scopeDesc.hpp"
+#include "interpreter/linkResolver.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/generateOopMap.hpp"
+#include "oops/fieldStreams.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
+#include "runtime/fieldDescriptor.hpp"
+#include "runtime/javaCalls.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "compiler/abstractCompiler.hpp"
+#include "compiler/compileBroker.hpp"
+#include "compiler/compilerOracle.hpp"
+#include "compiler/disassembler.hpp"
+#include "compiler/oopMap.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciCodeInstaller.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/deoptimization.hpp"
+#include "runtime/vframe.hpp"
+#include "runtime/vframe_hp.hpp"
+#include "runtime/vmStructs.hpp"
+
+
+// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
+#define C2V_VMENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+  TRACE_jvmci_1("CompilerToVM::" #name); \
+  TRACE_CALL(result_type, jvmci_ ## name signature) \
+  JVMCI_VM_ENTRY_MARK; \
+
+#define C2V_END }
+
+oop CompilerToVM::get_jvmci_method(methodHandle method, TRAPS) {
+  if (method() != NULL) {
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args;
+    args.push_long((jlong) (address) method());
+    JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_NULL);
+
+    return (oop)result.get_jobject();
+  }
+  return NULL;
+}
+
+oop CompilerToVM::get_jvmci_type(KlassHandle klass, TRAPS) {
+  if (klass() != NULL) {
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args;
+    args.push_oop(klass->java_mirror());
+    JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedObjectTypeImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::klass_fromMetaspace_signature(), &args, CHECK_NULL);
+
+    return (oop)result.get_jobject();
+  }
+  return NULL;
+}
+
+extern "C" {
+extern VMStructEntry* gHotSpotVMStructs;
+extern uint64_t gHotSpotVMStructEntryTypeNameOffset;
+extern uint64_t gHotSpotVMStructEntryFieldNameOffset;
+extern uint64_t gHotSpotVMStructEntryTypeStringOffset;
+extern uint64_t gHotSpotVMStructEntryIsStaticOffset;
+extern uint64_t gHotSpotVMStructEntryOffsetOffset;
+extern uint64_t gHotSpotVMStructEntryAddressOffset;
+extern uint64_t gHotSpotVMStructEntryArrayStride;
+
+extern VMTypeEntry* gHotSpotVMTypes;
+extern uint64_t gHotSpotVMTypeEntryTypeNameOffset;
+extern uint64_t gHotSpotVMTypeEntrySuperclassNameOffset;
+extern uint64_t gHotSpotVMTypeEntryIsOopTypeOffset;
+extern uint64_t gHotSpotVMTypeEntryIsIntegerTypeOffset;
+extern uint64_t gHotSpotVMTypeEntryIsUnsignedOffset;
+extern uint64_t gHotSpotVMTypeEntrySizeOffset;
+extern uint64_t gHotSpotVMTypeEntryArrayStride;
+
+extern VMIntConstantEntry* gHotSpotVMIntConstants;
+extern uint64_t gHotSpotVMIntConstantEntryNameOffset;
+extern uint64_t gHotSpotVMIntConstantEntryValueOffset;
+extern uint64_t gHotSpotVMIntConstantEntryArrayStride;
+
+extern VMLongConstantEntry* gHotSpotVMLongConstants;
+extern uint64_t gHotSpotVMLongConstantEntryNameOffset;
+extern uint64_t gHotSpotVMLongConstantEntryValueOffset;
+extern uint64_t gHotSpotVMLongConstantEntryArrayStride;
+
+extern VMAddressEntry* gHotSpotVMAddresses;
+extern uint64_t gHotSpotVMAddressEntryNameOffset;
+extern uint64_t gHotSpotVMAddressEntryValueOffset;
+extern uint64_t gHotSpotVMAddressEntryArrayStride;
+}
+
+// FIXME This is only temporary until the GC code is changed.
+bool       CompilerToVM::_supports_inline_contig_alloc;
+HeapWord** CompilerToVM::_heap_end_addr;
+HeapWord** CompilerToVM::_heap_top_addr;
+
+/**
+ * We put all gHotSpotVM values in an array so we can read them easily from Java.
+ */
+static uintptr_t ciHotSpotVMData[28];
+
+C2V_VMENTRY(jlong, initializeConfiguration, (JNIEnv *env, jobject))
+  ciHotSpotVMData[0] = (uintptr_t) gHotSpotVMStructs;
+  ciHotSpotVMData[1] = gHotSpotVMStructEntryTypeNameOffset;
+  ciHotSpotVMData[2] = gHotSpotVMStructEntryFieldNameOffset;
+  ciHotSpotVMData[3] = gHotSpotVMStructEntryTypeStringOffset;
+  ciHotSpotVMData[4] = gHotSpotVMStructEntryIsStaticOffset;
+  ciHotSpotVMData[5] = gHotSpotVMStructEntryOffsetOffset;
+  ciHotSpotVMData[6] = gHotSpotVMStructEntryAddressOffset;
+  ciHotSpotVMData[7] = gHotSpotVMStructEntryArrayStride;
+
+  ciHotSpotVMData[8] = (uintptr_t) gHotSpotVMTypes;
+  ciHotSpotVMData[9] = gHotSpotVMTypeEntryTypeNameOffset;
+  ciHotSpotVMData[10] = gHotSpotVMTypeEntrySuperclassNameOffset;
+  ciHotSpotVMData[11] = gHotSpotVMTypeEntryIsOopTypeOffset;
+  ciHotSpotVMData[12] = gHotSpotVMTypeEntryIsIntegerTypeOffset;
+  ciHotSpotVMData[13] = gHotSpotVMTypeEntryIsUnsignedOffset;
+  ciHotSpotVMData[14] = gHotSpotVMTypeEntrySizeOffset;
+  ciHotSpotVMData[15] = gHotSpotVMTypeEntryArrayStride;
+
+  ciHotSpotVMData[16] = (uintptr_t) gHotSpotVMIntConstants;
+  ciHotSpotVMData[17] = gHotSpotVMIntConstantEntryNameOffset;
+  ciHotSpotVMData[18] = gHotSpotVMIntConstantEntryValueOffset;
+  ciHotSpotVMData[19] = gHotSpotVMIntConstantEntryArrayStride;
+
+  ciHotSpotVMData[20] = (uintptr_t) gHotSpotVMLongConstants;
+  ciHotSpotVMData[21] = gHotSpotVMLongConstantEntryNameOffset;
+  ciHotSpotVMData[22] = gHotSpotVMLongConstantEntryValueOffset;
+  ciHotSpotVMData[23] = gHotSpotVMLongConstantEntryArrayStride;
+
+  ciHotSpotVMData[24] = (uintptr_t) gHotSpotVMAddresses;
+  ciHotSpotVMData[25] = gHotSpotVMAddressEntryNameOffset;
+  ciHotSpotVMData[26] = gHotSpotVMAddressEntryValueOffset;
+  ciHotSpotVMData[27] = gHotSpotVMAddressEntryArrayStride;
+
+  // FIXME This is only temporary until the GC code is changed.
+  CompilerToVM::_supports_inline_contig_alloc = Universe::heap()->supports_inline_contig_alloc();
+  CompilerToVM::_heap_end_addr = CompilerToVM::_supports_inline_contig_alloc ? Universe::heap()->end_addr() : (HeapWord**) -1;
+  CompilerToVM::_heap_top_addr = CompilerToVM::_supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord**) -1;
+
+  return (jlong) (address) &ciHotSpotVMData;
+C2V_END
+
+C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  ResourceMark rm;
+
+  int code_size = method->code_size();
+  typeArrayOop reconstituted_code = oopFactory::new_byteArray(code_size, CHECK_NULL);
+
+  guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
+  // iterate over all bytecodes and replace non-Java bytecodes
+
+  for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
+    Bytecodes::Code code = s.code();
+    Bytecodes::Code raw_code = s.raw_code();
+    int bci = s.bci();
+    int len = s.instruction_size();
+
+    // Restore original byte code.
+    reconstituted_code->byte_at_put(bci, (jbyte) (s.is_wide()? Bytecodes::_wide : code));
+    if (len > 1) {
+      memcpy(reconstituted_code->byte_at_addr(bci + 1), s.bcp()+1, len-1);
+    }
+
+    if (len > 1) {
+      // Restore the big-endian constant pool indexes.
+      // Cf. Rewriter::scan_method
+      switch (code) {
+        case Bytecodes::_getstatic:
+        case Bytecodes::_putstatic:
+        case Bytecodes::_getfield:
+        case Bytecodes::_putfield:
+        case Bytecodes::_invokevirtual:
+        case Bytecodes::_invokespecial:
+        case Bytecodes::_invokestatic:
+        case Bytecodes::_invokeinterface:
+        case Bytecodes::_invokehandle: {
+          int cp_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1));
+          Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index);
+          break;
+        }
+
+        case Bytecodes::_invokedynamic:
+          int cp_index = Bytes::get_native_u4((address) reconstituted_code->byte_at_addr(bci + 1));
+          Bytes::put_Java_u4((address) reconstituted_code->byte_at_addr(bci + 1), (u4) cp_index);
+          break;
+      }
+
+      // Not all ldc byte code are rewritten.
+      switch (raw_code) {
+        case Bytecodes::_fast_aldc: {
+          int cpc_index = reconstituted_code->byte_at(bci + 1) & 0xff;
+          int cp_index = method->constants()->object_to_cp_index(cpc_index);
+          assert(cp_index < method->constants()->length(), "sanity check");
+          reconstituted_code->byte_at_put(bci + 1, (jbyte) cp_index);
+          break;
+        }
+
+        case Bytecodes::_fast_aldc_w: {
+          int cpc_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1));
+          int cp_index = method->constants()->object_to_cp_index(cpc_index);
+          assert(cp_index < method->constants()->length(), "sanity check");
+          Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index);
+          break;
+        }
+      }
+    }
+  }
+
+  return (jbyteArray) JNIHandles::make_local(THREAD, reconstituted_code);
+C2V_END
+
+C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv *, jobject, jobject jvmci_method))
+  ResourceMark rm;
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  return method->exception_table_length();
+C2V_END
+
+C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv *, jobject, jobject jvmci_method))
+  ResourceMark rm;
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  if (method->exception_table_length() == 0) {
+    return 0L;
+  }
+  return (jlong) (address) method->exception_table_start();
+C2V_END
+
+C2V_VMENTRY(jobject, getResolvedJavaMethodAtSlot, (JNIEnv *, jobject, jclass holder_handle, jint slot))
+  oop java_class = JNIHandles::resolve(holder_handle);
+  Klass* holder = java_lang_Class::as_Klass(java_class);
+  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
+  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+}
+
+C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv *, jobject, jobject base, jlong offset))
+  methodHandle method;
+  oop base_object = JNIHandles::resolve(base);
+  if (base_object == NULL) {
+    method = *((Method**)(offset));
+  } else if (base_object->is_a(SystemDictionary::MemberName_klass())) {
+    method = (Method*) (intptr_t) base_object->long_field(offset);
+  } else if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
+    method = *((Method**)(HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object) + offset));
+  } else {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+                err_msg("Unexpected type: %s", base_object->klass()->external_name()));
+  }
+  assert (method.is_null() || method->is_method(), "invalid read");
+  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+}
+
+C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject base, jlong offset))
+  constantPoolHandle cp;
+  oop base_object = JNIHandles::resolve(base);
+  jlong base_address = 0;
+  if (base_object != NULL) {
+    if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
+      base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object);
+    } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
+      base_address = HotSpotConstantPool::metaspaceConstantPool(base_object);
+    } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
+      base_address = (jlong) CompilerToVM::asKlass(base_object);
+    } else {
+      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+                  err_msg("Unexpected type: %s", base_object->klass()->external_name()));
+    }
+  }
+  cp = *((ConstantPool**) (intptr_t) (base_address + offset));
+  if (!cp.is_null()) {
+    JavaValue method_result(T_OBJECT);
+    JavaCallArguments args;
+    args.push_long((jlong) (address) cp());
+    JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject());
+  }
+  return NULL;
+}
+
+C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed))
+  KlassHandle klass;
+  oop base_object = JNIHandles::resolve(base);
+  jlong base_address = 0;
+  if (base_object != NULL && offset == oopDesc::klass_offset_in_bytes()) {
+    klass = base_object->klass();
+  } else if (!compressed) {
+    if (base_object != NULL) {
+      if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
+        base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object);
+      } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
+        base_address = HotSpotConstantPool::metaspaceConstantPool(base_object);
+      } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
+        base_address = (jlong) CompilerToVM::asKlass(base_object);
+      } else if (base_object->is_a(SystemDictionary::Class_klass())) {
+        base_address = (jlong) (address) base_object;
+      } else {
+        THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+                    err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", base_object->klass()->external_name(), offset, compressed ? "true" : "false"));
+      }
+    }
+    klass = *((Klass**) (intptr_t) (base_address + offset));
+  } else {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+                err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", base_object->klass()->external_name(), offset, compressed ? "true" : "false"));
+  }
+  assert (klass.is_null() || klass->is_klass(), "invalid read");
+  oop result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+}
+
+C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
+  ResourceMark rm;
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  KlassHandle holder = CompilerToVM::asKlass(jvmci_type);
+  if (holder->is_interface()) {
+    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", holder->external_name()));
+  }
+
+  methodHandle ucm;
+  {
+    MutexLocker locker(Compile_lock);
+    ucm = Dependencies::find_unique_concrete_method(holder(), method());
+  }
+  oop result = CompilerToVM::get_jvmci_method(ucm, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type))
+  InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
+  oop implementor = CompilerToVM::get_jvmci_type(klass->implementor(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, implementor);
+C2V_END
+
+C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  return method->is_ignored_by_security_stack_walk();
+C2V_END
+
+C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
+C2V_END
+
+C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  return CompilerOracle::should_inline(method) || method->force_inline();
+C2V_END
+
+C2V_VMENTRY(jobject, lookupType, (JNIEnv*, jobject, jstring jname, jclass accessing_class, jboolean resolve))
+  ResourceMark rm;
+  Handle name = JNIHandles::resolve(jname);
+  Symbol* class_name = java_lang_String::as_symbol(name, CHECK_0);
+  if (java_lang_String::length(name()) <= 1) {
+    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));
+  }
+
+  Klass* resolved_klass = NULL;
+  Handle class_loader;
+  Handle protection_domain;
+  if (JNIHandles::resolve(accessing_class) == NULL) {
+    THROW_0(vmSymbols::java_lang_NullPointerException());
+  }
+  Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class));
+  class_loader = accessing_klass->class_loader();
+  protection_domain = accessing_klass->protection_domain();
+
+  if (resolve) {
+    resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
+  } else {
+    if (class_name->byte_at(0) == 'L' &&
+      class_name->byte_at(class_name->utf8_length()-1) == ';') {
+      // This is a name from a signature.  Strip off the trimmings.
+      // Call recursive to keep scope of strippedsym.
+      TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1,
+                                                          class_name->utf8_length()-2,
+                                                          CHECK_0);
+      resolved_klass = SystemDictionary::find(strippedsym, class_loader, protection_domain, CHECK_0);
+    } else if (FieldType::is_array(class_name)) {
+      FieldArrayInfo fd;
+      // dimension and object_key in FieldArrayInfo are assigned as a side-effect
+      // of this call
+      BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0);
+      if (t == T_OBJECT) {
+        TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
+                                                            class_name->utf8_length()-2-fd.dimension(),
+                                                            CHECK_0);
+        // naked oop "k" is OK here -- we assign back into it
+        resolved_klass = SystemDictionary::find(strippedsym,
+                                                             class_loader,
+                                                             protection_domain,
+                                                             CHECK_0);
+        if (resolved_klass != NULL) {
+          resolved_klass = resolved_klass->array_klass(fd.dimension(), CHECK_0);
+        }
+      } else {
+        resolved_klass = Universe::typeArrayKlassObj(t);
+        resolved_klass = TypeArrayKlass::cast(resolved_klass)->array_klass(fd.dimension(), CHECK_0);
+      }
+    }
+  }
+  Handle result = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+C2V_END
+
+C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  oop result = cp->resolve_constant_at(index, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  return cp->name_and_type_ref_index_at(index);
+C2V_END
+
+C2V_VMENTRY(jobject, lookupNameInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  Handle sym = java_lang_String::create_from_symbol(cp->name_ref_at(which), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, sym());
+C2V_END
+
+C2V_VMENTRY(jobject, lookupSignatureInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  Handle sym = java_lang_String::create_from_symbol(cp->signature_ref_at(which), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, sym());
+C2V_END
+
+C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  return cp->klass_ref_index_at(index);
+C2V_END
+
+C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  Klass* resolved_klass = cp->klass_at(index, CHECK_NULL);
+  Handle klass = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, klass());
+C2V_END
+
+C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  KlassHandle loading_klass(cp->pool_holder());
+  bool is_accessible = false;
+  KlassHandle klass = JVMCIEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
+  Symbol* symbol = NULL;
+  if (klass.is_null()) {
+    symbol = cp->klass_name_at(index);
+  }
+  Handle result;
+  if (!klass.is_null()) {
+    result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
+  } else {
+    result = java_lang_String::create_from_symbol(symbol, CHECK_NULL);
+  }
+  return JNIHandles::make_local(THREAD, result());
+C2V_END
+
+C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
+  return JNIHandles::make_local(THREAD, appendix_oop);
+C2V_END
+
+C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  instanceKlassHandle pool_holder(cp->pool_holder());
+  Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
+  methodHandle method = JVMCIEnv::get_method_by_index(cp, index, bc, pool_holder);
+  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  return cp->remap_instruction_operand_from_cache(index);
+C2V_END
+
+C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
+  ResourceMark rm;
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
+  fieldDescriptor fd;
+  LinkInfo link_info(cp, index, CHECK_0);
+  LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
+  typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
+  assert(info != NULL && info->length() == 2, "must be");
+  info->long_at_put(0, (jlong) fd.access_flags().as_int());
+  info->long_at_put(1, (jlong) fd.offset());
+  oop field_holder = CompilerToVM::get_jvmci_type(fd.field_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, field_holder);
+C2V_END
+
+C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
+  ResourceMark rm;
+  Klass* klass = CompilerToVM::asKlass(jvmci_type);
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+  if (klass->is_interface()) {
+    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name()));
+  }
+  if (!method->method_holder()->is_interface()) {
+    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string()));
+  }
+  if (!InstanceKlass::cast(klass)->is_initialized()) {
+    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be initialized", klass->external_name()));
+  }
+  return LinkResolver::vtable_index_of_interface_method(klass, method);
+C2V_END
+
+C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
+  Klass* recv_klass = CompilerToVM::asKlass(receiver_jvmci_type);
+  Klass* caller_klass = CompilerToVM::asKlass(caller_jvmci_type);
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+
+  if (recv_klass->oop_is_array() || (InstanceKlass::cast(recv_klass)->is_linked())) {
+    Klass* holder_klass = method->method_holder();
+    Symbol* method_name = method->name();
+    Symbol* method_signature = method->signature();
+
+    if (holder_klass->is_interface()) {
+      // do link-time resolution to check all access rules.
+      LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true);
+      methodHandle resolved_method = LinkResolver::linktime_resolve_interface_method_or_null(link_info);
+      if (resolved_method.is_null() || resolved_method->is_private()) {
+        return NULL;
+      }
+      assert(recv_klass->is_subtype_of(holder_klass), "");
+      // do actual lookup
+      methodHandle sel_method = LinkResolver::lookup_instance_method_in_klasses(recv_klass, resolved_method->name(), resolved_method->signature(), CHECK_AND_CLEAR_0);
+      oop result = CompilerToVM::get_jvmci_method(sel_method, CHECK_NULL);
+      return JNIHandles::make_local(THREAD, result);
+    } else {
+      // do link-time resolution to check all access rules.
+      LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true);
+      methodHandle resolved_method = LinkResolver::linktime_resolve_virtual_method_or_null(link_info);
+      if (resolved_method.is_null()) {
+        return NULL;
+      }
+      // do actual lookup (see LinkResolver::runtime_resolve_virtual_method)
+      int vtable_index = Method::invalid_vtable_index;
+      Method* selected_method;
+
+      if (resolved_method->method_holder()->is_interface()) { // miranda method
+        vtable_index = LinkResolver::vtable_index_of_interface_method(holder_klass, resolved_method);
+        assert(vtable_index >= 0 , "we should have valid vtable index at this point");
+
+        InstanceKlass* inst = InstanceKlass::cast(recv_klass);
+        selected_method = inst->method_at_vtable(vtable_index);
+      } else {
+        // at this point we are sure that resolved_method is virtual and not
+        // a miranda method; therefore, it must have a valid vtable index.
+        assert(!resolved_method->has_itable_index(), "");
+        vtable_index = resolved_method->vtable_index();
+        // We could get a negative vtable_index for final methods,
+        // because as an optimization they are they are never put in the vtable,
+        // unless they override an existing method.
+        // If we do get a negative, it means the resolved method is the the selected
+        // method, and it can never be changed by an override.
+        if (vtable_index == Method::nonvirtual_vtable_index) {
+          assert(resolved_method->can_be_statically_bound(), "cannot override this method");
+          selected_method = resolved_method();
+        } else {
+          // recv_klass might be an arrayKlassOop but all vtables start at
+          // the same place. The cast is to avoid virtual call and assertion.
+          InstanceKlass* inst = (InstanceKlass*)recv_klass;
+          selected_method = inst->method_at_vtable(vtable_index);
+        }
+      }
+      oop result = CompilerToVM::get_jvmci_method(selected_method, CHECK_NULL);
+      return JNIHandles::make_local(THREAD, result);
+    }
+  }
+  return NULL;
+C2V_END
+
+C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type))
+  Klass* klass = CompilerToVM::asKlass(jvmci_type);
+  assert(klass != NULL, "method must not be called for primitive types");
+  return Dependencies::find_finalizable_subclass(klass) != NULL;
+C2V_END
+
+C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type))
+  InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
+  oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr))
+  address target_addr = (address) addr;
+  if (target_addr != 0x0) {
+    int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
+    int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
+    return MAX2(ABS(off_low), ABS(off_high));
+  }
+  return -1;
+C2V_END
+
+C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject,  jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  method->set_not_c1_compilable();
+  method->set_not_c2_compilable();
+  method->set_dont_inline(true);
+C2V_END
+
+C2V_VMENTRY(jint, installCode, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject installed_code, jobject speculation_log))
+  ResourceMark rm;
+  HandleMark hm;
+  Handle target_handle = JNIHandles::resolve(target);
+  Handle compiled_code_handle = JNIHandles::resolve(compiled_code);
+  CodeBlob* cb = NULL;
+  Handle installed_code_handle = JNIHandles::resolve(installed_code);
+  Handle speculation_log_handle = JNIHandles::resolve(speculation_log);
+
+  JVMCICompiler* compiler = JVMCICompiler::instance(CHECK_JNI_ERR);
+
+  TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
+  CodeInstaller installer;
+  JVMCIEnv::CodeInstallResult result = installer.install(compiler, target_handle, compiled_code_handle, cb, installed_code_handle, speculation_log_handle);
+
+  if (PrintCodeCacheOnCompilation) {
+    stringStream s;
+    // Dump code cache  into a buffer before locking the tty,
+    {
+      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+      CodeCache::print_summary(&s, false);
+    }
+    ttyLocker ttyl;
+    tty->print_raw_cr(s.as_string());
+  }
+
+  if (result != JVMCIEnv::ok) {
+    assert(cb == NULL, "should be");
+  } else {
+    if (!installed_code_handle.is_null()) {
+      assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type");
+      InstalledCode::set_address(installed_code_handle, (jlong) cb);
+      InstalledCode::set_version(installed_code_handle, InstalledCode::version(installed_code_handle) + 1);
+      if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) {
+        HotSpotInstalledCode::set_size(installed_code_handle, cb->size());
+        HotSpotInstalledCode::set_codeStart(installed_code_handle, (jlong) cb->code_begin());
+        HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size());
+      }
+      nmethod* nm = cb->as_nmethod_or_null();
+      if (nm != NULL && installed_code_handle->is_scavengable()) {
+        assert(nm->detect_scavenge_root_oops(), "nm should be scavengable if installed_code is scavengable");
+        if (!UseG1GC) {
+          assert(nm->on_scavenge_root_list(), "nm should be on scavengable list");
+        }
+      }
+    }
+  }
+  return result;
+C2V_END
+
+C2V_VMENTRY(jint, getMetadata, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject metadata))
+  ResourceMark rm;
+  HandleMark hm;
+
+  Handle target_handle = JNIHandles::resolve(target);
+  Handle compiled_code_handle = JNIHandles::resolve(compiled_code);
+  Handle metadata_handle = JNIHandles::resolve(metadata);
+
+  HotSpotOopMap::klass()->initialize(thread);
+
+  CodeMetadata code_metadata;
+  CodeBlob *cb = NULL;
+  CodeInstaller installer;
+
+  JVMCIEnv::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata); //cb, pc_descs, nr_pc_descs, scopes_descs, scopes_size, reloc_buffer);
+  if (result != JVMCIEnv::ok) {
+    return result;
+  }
+
+  if (code_metadata.get_nr_pc_desc() > 0) {
+    typeArrayHandle pcArrayOop = oopFactory::new_byteArray(sizeof(PcDesc) * code_metadata.get_nr_pc_desc(), CHECK_(JVMCIEnv::cache_full));
+    memcpy(pcArrayOop->byte_at_addr(0), code_metadata.get_pc_desc(), sizeof(PcDesc) * code_metadata.get_nr_pc_desc());
+    HotSpotMetaData::set_pcDescBytes(metadata_handle, pcArrayOop());
+  }
+
+  if (code_metadata.get_scopes_size() > 0) {
+    typeArrayHandle scopesArrayOop = oopFactory::new_byteArray(code_metadata.get_scopes_size(), CHECK_(JVMCIEnv::cache_full));
+    memcpy(scopesArrayOop->byte_at_addr(0), code_metadata.get_scopes_desc(), code_metadata.get_scopes_size());
+    HotSpotMetaData::set_scopesDescBytes(metadata_handle, scopesArrayOop());
+  }
+
+  RelocBuffer* reloc_buffer = code_metadata.get_reloc_buffer();
+  typeArrayHandle relocArrayOop = oopFactory::new_byteArray((int) reloc_buffer->size(), CHECK_(JVMCIEnv::cache_full));
+  if (reloc_buffer->size() > 0) {
+    memcpy(relocArrayOop->byte_at_addr(0), reloc_buffer->begin(), reloc_buffer->size());
+  }
+  HotSpotMetaData::set_relocBytes(metadata_handle, relocArrayOop());
+
+  const OopMapSet* oopMapSet = installer.oopMapSet();
+  {
+    ResourceMark mark;
+    ImmutableOopMapBuilder builder(oopMapSet);
+    int oopmap_size = builder.heap_size();
+    typeArrayHandle oopMapArrayHandle = oopFactory::new_byteArray(oopmap_size, CHECK_(JVMCIEnv::cache_full));
+    builder.generate_into((address) oopMapArrayHandle->byte_at_addr(0));
+    HotSpotMetaData::set_oopMaps(metadata_handle, oopMapArrayHandle());
+  }
+
+  HotSpotMetaData::set_metadata(metadata_handle, NULL);
+
+  ExceptionHandlerTable* handler = code_metadata.get_exception_table();
+  int table_size = handler->size_in_bytes();
+  typeArrayHandle exceptionArrayOop = oopFactory::new_byteArray(table_size, CHECK_(JVMCIEnv::cache_full));
+
+  if (table_size > 0) {
+    handler->copy_bytes_to((address) exceptionArrayOop->byte_at_addr(0));
+  }
+  HotSpotMetaData::set_exceptionBytes(metadata_handle, exceptionArrayOop());
+
+  return result;
+C2V_END
+
+C2V_VMENTRY(void, notifyCompilationStatistics, (JNIEnv *jniEnv, jobject, jint id, jobject hotspot_method, jboolean osr, jint processedBytecodes, jlong time, jlong timeUnitsPerSecond, jobject installed_code))
+  JVMCICompiler* compiler = JVMCICompiler::instance(CHECK);
+  CompilerStatistics* stats = compiler->stats();
+
+  elapsedTimer timer = elapsedTimer(time, timeUnitsPerSecond);
+  if (osr) {
+    stats->_osr.update(timer, processedBytecodes);
+  } else {
+    stats->_standard.update(timer, processedBytecodes);
+  }
+  Handle installed_code_handle = JNIHandles::resolve(installed_code);
+  if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) {
+    stats->_nmethods_size += HotSpotInstalledCode::size(installed_code_handle);
+    stats->_nmethods_code_size += HotSpotInstalledCode::codeSize(installed_code_handle);
+  }
+
+  if (CITimeEach) {
+    methodHandle method = CompilerToVM::asMethod(hotspot_method);
+    float bytes_per_sec = 1.0 * processedBytecodes / timer.seconds();
+    tty->print_cr("%3d   seconds: %f bytes/sec: %f (bytes %d)",
+                  id, timer.seconds(), bytes_per_sec, processedBytecodes);
+  }
+C2V_END
+
+C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject))
+  JVMCICompiler* compiler = JVMCICompiler::instance(CHECK);
+  CompilerStatistics* stats = compiler->stats();
+  stats->_standard.reset();
+  stats->_osr.reset();
+C2V_END
+
+C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv *jniEnv, jobject, jlong codeBlob))
+  ResourceMark rm;
+  HandleMark hm;
+
+  CodeBlob* cb = (CodeBlob*) (address) codeBlob;
+  if (cb == NULL) {
+    return NULL;
+  }
+
+  // We don't want the stringStream buffer to resize during disassembly as it
+  // uses scoped resource memory. If a nested function called during disassembly uses
+  // a ResourceMark and the buffer expands within the scope of the mark,
+  // the buffer becomes garbage when that scope is exited. Experience shows that
+  // the disassembled code is typically about 10x the code size so a fixed buffer
+  // sized to 20x code size plus a fixed amount for header info should be sufficient.
+  int bufferSize = cb->code_size() * 20 + 1024;
+  char* buffer = NEW_RESOURCE_ARRAY(char, bufferSize);
+  stringStream st(buffer, bufferSize);
+  if (cb->is_nmethod()) {
+    nmethod* nm = (nmethod*) cb;
+    if (!nm->is_alive()) {
+      return NULL;
+    }
+    Disassembler::decode(nm, &st);
+  } else {
+    Disassembler::decode(cb, &st);
+  }
+  if (st.size() <= 0) {
+    return NULL;
+  }
+
+  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+C2V_END
+
+C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv*, jobject, jobject jvmci_method, int bci))
+  ResourceMark rm;
+  HandleMark hm;
+
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, element);
+C2V_END
+
+C2V_VMENTRY(jobject, executeInstalledCode, (JNIEnv*, jobject, jobject args, jobject hotspotInstalledCode))
+  ResourceMark rm;
+  HandleMark hm;
+
+  jlong nmethodValue = InstalledCode::address(hotspotInstalledCode);
+  if (nmethodValue == 0L) {
+    THROW_NULL(vmSymbols::jdk_vm_ci_code_InvalidInstalledCodeException());
+  }
+  nmethod* nm = (nmethod*) (address) nmethodValue;
+  methodHandle mh = nm->method();
+  Symbol* signature = mh->signature();
+  JavaCallArguments jca(mh->size_of_parameters());
+
+  JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
+  JavaValue result(jap.get_ret_type());
+  jca.set_alternative_target(nm);
+  JavaCalls::call(&result, mh, &jca, CHECK_NULL);
+
+  if (jap.get_ret_type() == T_VOID) {
+    return NULL;
+  } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
+    return JNIHandles::make_local(THREAD, (oop) result.get_jobject());
+  } else {
+    jvalue *value = (jvalue *) result.get_value_addr();
+    // Narrow the value down if required (Important on big endian machines)
+    switch (jap.get_ret_type()) {
+      case T_BOOLEAN:
+       value->z = (jboolean) value->i;
+       break;
+      case T_BYTE:
+       value->b = (jbyte) value->i;
+       break;
+      case T_CHAR:
+       value->c = (jchar) value->i;
+       break;
+      case T_SHORT:
+       value->s = (jshort) value->i;
+       break;
+     }
+    oop o = java_lang_boxing_object::create(jap.get_ret_type(), value, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, o);
+  }
+C2V_END
+
+C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv *, jobject, jobject jvmci_method))
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+  if (!method->has_linenumber_table()) {
+    return NULL;
+  }
+  u2 num_entries = 0;
+  CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table());
+  while (streamForSize.read_pair()) {
+    num_entries++;
+  }
+
+  CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
+  typeArrayOop result = oopFactory::new_longArray(2 * num_entries, CHECK_NULL);
+
+  int i = 0;
+  jlong value;
+  while (stream.read_pair()) {
+    value = ((long) stream.bci());
+    result->long_at_put(i, value);
+    value = ((long) stream.line());
+    result->long_at_put(i + 1, value);
+    i += 2;
+  }
+
+  return (jlongArray) JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv *, jobject, jobject jvmci_method))
+  ResourceMark rm;
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+  if (!method->has_localvariable_table()) {
+    return 0;
+  }
+  return (jlong) (address) method->localvariable_table_start();
+C2V_END
+
+C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv *, jobject, jobject jvmci_method))
+  ResourceMark rm;
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+  return method->localvariable_table_length();
+C2V_END
+
+C2V_VMENTRY(void, reprofile, (JNIEnv*, jobject, jobject jvmci_method))
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+  MethodCounters* mcs = method->method_counters();
+  if (mcs != NULL) {
+    mcs->clear_counters();
+  }
+  NOT_PRODUCT(method->set_compiled_invocation_count(0));
+
+  nmethod* code = method->code();
+  if (code != NULL) {
+    code->make_not_entrant();
+  }
+
+  MethodData* method_data = method->method_data();
+  if (method_data == NULL) {
+    ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
+    method_data = MethodData::allocate(loader_data, method, CHECK);
+    method->set_method_data(method_data);
+  } else {
+    method_data->initialize();
+  }
+C2V_END
+
+
+C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv*, jobject, jobject hotspotInstalledCode))
+  jlong nativeMethod = InstalledCode::address(hotspotInstalledCode);
+  nmethod* m = (nmethod*)nativeMethod;
+  if (m != NULL && !m->is_not_entrant()) {
+    m->mark_for_deoptimization();
+    VM_Deoptimize op;
+    VMThread::execute(&op);
+  }
+  InstalledCode::set_address(hotspotInstalledCode, 0);
+C2V_END
+
+C2V_VMENTRY(jobject, readUncompressedOop, (JNIEnv*, jobject, jlong addr))
+  oop ret = oopDesc::load_decode_heap_oop((oop*)(address)addr);
+  return JNIHandles::make_local(THREAD, ret);
+C2V_END
+
+C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv*, jobject))
+  typeArrayOop arrayOop = oopFactory::new_longArray(JVMCICounterSize, CHECK_NULL);
+  JavaThread::collect_counters(arrayOop);
+  return (jlongArray) JNIHandles::make_local(THREAD, arrayOop);
+C2V_END
+
+C2V_VMENTRY(int, allocateCompileId, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci))
+  HandleMark hm;
+  ResourceMark rm;
+  if (JNIHandles::resolve(jvmci_method) == NULL) {
+    THROW_0(vmSymbols::java_lang_NullPointerException());
+  }
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+  if (entry_bci >= method->code_size() || entry_bci < -1) {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Unexpected bci %d", entry_bci));
+  }
+  return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
+C2V_END
+
+
+C2V_VMENTRY(jboolean, isMature, (JNIEnv*, jobject, jlong metaspace_method_data))
+  MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data);
+  return mdo != NULL && mdo->is_mature();
+C2V_END
+
+C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci, int comp_level))
+  Method* method = CompilerToVM::asMethod(jvmci_method);
+  return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
+C2V_END
+
+C2V_VMENTRY(jobject, getSymbol, (JNIEnv*, jobject, jlong symbol))
+  Handle sym = java_lang_String::create_from_symbol((Symbol*)(address)symbol, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, sym());
+C2V_END
+
+bool matches(jobjectArray methods, Method* method) {
+  objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
+
+  for (int i = 0; i < methods_oop->length(); i++) {
+    if (CompilerToVM::asMethod(methods_oop->obj_at(i)) == method) {
+      return true;
+    }
+  }
+  return false;
+}
+
+C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject hs_frame, jobjectArray methods, jint initialSkip))
+  ResourceMark rm;
+
+  if (!thread->has_last_Java_frame()) return NULL;
+  Handle result = HotSpotStackFrameReference::klass()->allocate_instance(thread);
+  HotSpotStackFrameReference::klass()->initialize(thread);
+
+  StackFrameStream fst(thread);
+  if (hs_frame != NULL) {
+    // look for the correct stack frame if one is given
+    intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame);
+    while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
+      fst.next();
+    }
+    if (fst.current()->sp() != stack_pointer) {
+      THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "stack frame not found")
+    }
+  }
+
+  int frame_number = 0;
+  vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
+  if (hs_frame != NULL) {
+    // look for the correct vframe within the stack frame if one is given
+    int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame);
+    while (frame_number < last_frame_number) {
+      if (vf->is_top()) {
+        THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "invalid frame number")
+      }
+      vf = vf->sender();
+      frame_number ++;
+    }
+    // move one frame forward
+    if (vf->is_top()) {
+      if (fst.is_done()) {
+        return NULL;
+      }
+      fst.next();
+      vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
+      frame_number = 0;
+    } else {
+      vf = vf->sender();
+      frame_number++;
+    }
+  }
+
+  while (true) {
+    // look for the given method
+    while (true) {
+      StackValueCollection* locals = NULL;
+      if (vf->is_compiled_frame()) {
+        // compiled method frame
+        compiledVFrame* cvf = compiledVFrame::cast(vf);
+        if (methods == NULL || matches(methods, cvf->method())) {
+          if (initialSkip > 0) {
+            initialSkip --;
+          } else {
+            ScopeDesc* scope = cvf->scope();
+            // native wrapper do not have a scope
+            if (scope != NULL && scope->objects() != NULL) {
+              bool realloc_failures = Deoptimization::realloc_objects(thread, fst.current(), scope->objects(), THREAD);
+              Deoptimization::reassign_fields(fst.current(), fst.register_map(), scope->objects(), realloc_failures, false);
+
+              GrowableArray<ScopeValue*>* local_values = scope->locals();
+              typeArrayHandle array = oopFactory::new_boolArray(local_values->length(), thread);
+              for (int i = 0; i < local_values->length(); i++) {
+                ScopeValue* value = local_values->at(i);
+                if (value->is_object()) {
+                  array->bool_at_put(i, true);
+                }
+              }
+              HotSpotStackFrameReference::set_localIsVirtual(result, array());
+            } else {
+              HotSpotStackFrameReference::set_localIsVirtual(result, NULL);
+            }
+
+            locals = cvf->locals();
+            HotSpotStackFrameReference::set_bci(result, cvf->bci());
+            oop method = CompilerToVM::get_jvmci_method(cvf->method(), CHECK_NULL);
+            HotSpotStackFrameReference::set_method(result, method);
+          }
+        }
+      } else if (vf->is_interpreted_frame()) {
+        // interpreted method frame
+        interpretedVFrame* ivf = interpretedVFrame::cast(vf);
+        if (methods == NULL || matches(methods, ivf->method())) {
+          if (initialSkip > 0) {
+            initialSkip --;
+          } else {
+            locals = ivf->locals();
+            HotSpotStackFrameReference::set_bci(result, ivf->bci());
+            oop method = CompilerToVM::get_jvmci_method(ivf->method(), CHECK_NULL);
+            HotSpotStackFrameReference::set_method(result, method);
+            HotSpotStackFrameReference::set_localIsVirtual(result, NULL);
+          }
+        }
+      }
+
+      // locals != NULL means that we found a matching frame and result is already partially initialized
+      if (locals != NULL) {
+        HotSpotStackFrameReference::set_compilerToVM(result, JNIHandles::resolve(compilerToVM));
+        HotSpotStackFrameReference::set_stackPointer(result, (jlong) fst.current()->sp());
+        HotSpotStackFrameReference::set_frameNumber(result, frame_number);
+
+        // initialize the locals array
+        objArrayHandle array = oopFactory::new_objectArray(locals->size(), thread);
+        for (int i = 0; i < locals->size(); i++) {
+          StackValue* var = locals->at(i);
+          if (var->type() == T_OBJECT) {
+            array->obj_at_put(i, locals->at(i)->get_obj()());
+          }
+        }
+        HotSpotStackFrameReference::set_locals(result, array());
+
+        return JNIHandles::make_local(thread, result());
+      }
+
+      if (vf->is_top()) {
+        break;
+      }
+      frame_number++;
+      vf = vf->sender();
+    } // end of vframe loop
+
+    if (fst.is_done()) {
+      break;
+    }
+    fst.next();
+    vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
+    frame_number = 0;
+  } // end of frame loop
+
+  // the end was reached without finding a matching method
+  return NULL;
+C2V_END
+
+C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  CallInfo callInfo;
+  LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK);
+  ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index);
+  cp_cache_entry->set_dynamic_call(cp, callInfo);
+C2V_END
+
+C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  CallInfo callInfo;
+  LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
+  ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
+  cp_cache_entry->set_method_handle(cp, callInfo);
+C2V_END
+
+C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv*, jobject))
+  //see compute_recording_non_safepoints in debugInfroRec.cpp
+  if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
+    return true;
+  }
+  return DebugNonSafepoints;
+C2V_END
+
+// public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
+C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv*, jobject, jobject hs_frame, bool invalidate))
+  ResourceMark rm;
+
+  if (hs_frame == NULL) {
+    THROW_MSG(vmSymbols::java_lang_NullPointerException(), "stack frame is null")
+  }
+
+  HotSpotStackFrameReference::klass()->initialize(thread);
+
+  // look for the given stack frame
+  StackFrameStream fst(thread);
+  intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame);
+  while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
+    fst.next();
+  }
+  if (fst.current()->sp() != stack_pointer) {
+    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found")
+  }
+
+  if (invalidate) {
+    if (!fst.current()->is_compiled_frame()) {
+      THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected")
+    }
+    assert(fst.current()->cb()->is_nmethod(), "nmethod expected");
+    ((nmethod*) fst.current()->cb())->make_not_entrant();
+  }
+  Deoptimization::deoptimize(thread, *fst.current(), fst.register_map(), Deoptimization::Reason_none);
+  // look for the frame again as it has been updated by deopt (pc, deopt state...)
+  StackFrameStream fstAfterDeopt(thread);
+  while (fstAfterDeopt.current()->sp() != stack_pointer && !fstAfterDeopt.is_done()) {
+    fstAfterDeopt.next();
+  }
+  if (fstAfterDeopt.current()->sp() != stack_pointer) {
+    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found after deopt")
+  }
+
+  vframe* vf = vframe::new_vframe(fstAfterDeopt.current(), fstAfterDeopt.register_map(), thread);
+  if (!vf->is_compiled_frame()) {
+    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected")
+  }
+
+  GrowableArray<compiledVFrame*>* virtualFrames = new GrowableArray<compiledVFrame*>(10);
+  while (true) {
+    assert(vf->is_compiled_frame(), "Wrong frame type");
+    virtualFrames->push(compiledVFrame::cast(vf));
+    if (vf->is_top()) {
+      break;
+    }
+    vf = vf->sender();
+  }
+
+  int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame);
+  if (last_frame_number >= virtualFrames->length()) {
+    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "invalid frame number")
+  }
+
+  // Reallocate the non-escaping objects and restore their fields.
+  assert (virtualFrames->at(last_frame_number)->scope() != NULL,"invalid scope");
+  GrowableArray<ScopeValue*>* objects = virtualFrames->at(last_frame_number)->scope()->objects();
+
+  if (objects == NULL) {
+    // no objects to materialize
+    return;
+  }
+
+  bool realloc_failures = Deoptimization::realloc_objects(thread, fstAfterDeopt.current(), objects, THREAD);
+  Deoptimization::reassign_fields(fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, realloc_failures, false);
+
+  for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) {
+    compiledVFrame* cvf = virtualFrames->at(frame_index);
+
+    GrowableArray<ScopeValue*>* scopeLocals = cvf->scope()->locals();
+    StackValueCollection* locals = cvf->locals();
+
+    if (locals != NULL) {
+      for (int i2 = 0; i2 < locals->size(); i2++) {
+        StackValue* var = locals->at(i2);
+        if (var->type() == T_OBJECT && scopeLocals->at(i2)->is_object()) {
+          jvalue val;
+          val.l = (jobject) locals->at(i2)->get_obj()();
+          cvf->update_local(T_OBJECT, i2, val);
+        }
+      }
+    }
+  }
+
+  // all locals are materialized by now
+  HotSpotStackFrameReference::set_localIsVirtual(hs_frame, NULL);
+
+  // update the locals array
+  objArrayHandle array = HotSpotStackFrameReference::locals(hs_frame);
+  StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals();
+  for (int i = 0; i < locals->size(); i++) {
+    StackValue* var = locals->at(i);
+    if (var->type() == T_OBJECT) {
+      array->obj_at_put(i, locals->at(i)->get_obj()());
+    }
+  }
+C2V_END
+
+C2V_VMENTRY(void, writeDebugOutput, (JNIEnv*, jobject, jbyteArray bytes, jint offset, jint length))
+  if (bytes == NULL) {
+    THROW(vmSymbols::java_lang_NullPointerException());
+  }
+  typeArrayOop array = (typeArrayOop) JNIHandles::resolve(bytes);
+
+  // Check if offset and length are non negative.
+  if (offset < 0 || length < 0) {
+    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+  }
+  // Check if the range is valid.
+  if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array->length())) {
+    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+  }
+  while (length > 0) {
+    jbyte* start = array->byte_at_addr(offset);
+    tty->write((char*) start, MIN2(length, O_BUFLEN));
+    length -= O_BUFLEN;
+    offset += O_BUFLEN;
+  }
+C2V_END
+
+C2V_VMENTRY(void, flushDebugOutput, (JNIEnv*, jobject))
+  tty->flush();
+C2V_END
+
+
+#define CC (char*)  /*cast a literal from (const char*)*/
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
+
+#define SPECULATION_LOG       "Ljdk/vm/ci/meta/SpeculationLog;"
+#define STRING                "Ljava/lang/String;"
+#define OBJECT                "Ljava/lang/Object;"
+#define CLASS                 "Ljava/lang/Class;"
+#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
+#define INSTALLED_CODE        "Ljdk/vm/ci/code/InstalledCode;"
+#define TARGET_DESCRIPTION    "Ljdk/vm/ci/code/TargetDescription;"
+#define RESOLVED_METHOD       "Ljdk/vm/ci/meta/ResolvedJavaMethod;"
+#define HS_RESOLVED_METHOD    "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;"
+#define HS_RESOLVED_KLASS     "Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;"
+#define HS_CONSTANT_POOL      "Ljdk/vm/ci/hotspot/HotSpotConstantPool;"
+#define HS_COMPILED_CODE      "Ljdk/vm/ci/hotspot/HotSpotCompiledCode;"
+#define HS_METADATA           "Ljdk/vm/ci/hotspot/HotSpotMetaData;"
+#define HS_STACK_FRAME_REF    "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;"
+#define METASPACE_METHOD_DATA "J"
+
+JNINativeMethod CompilerToVM::methods[] = {
+  {CC"getBytecode",                                  CC"("HS_RESOLVED_METHOD")[B",                                                     FN_PTR(getBytecode)},
+  {CC"getExceptionTableStart",                       CC"("HS_RESOLVED_METHOD")J",                                                      FN_PTR(getExceptionTableStart)},
+  {CC"getExceptionTableLength",                      CC"("HS_RESOLVED_METHOD")I",                                                      FN_PTR(getExceptionTableLength)},
+  {CC"findUniqueConcreteMethod",                     CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD")"HS_RESOLVED_METHOD,                   FN_PTR(findUniqueConcreteMethod)},
+  {CC"getImplementor",                               CC"("HS_RESOLVED_KLASS")"HS_RESOLVED_KLASS,                                       FN_PTR(getImplementor)},
+  {CC"getStackTraceElement",                         CC"("HS_RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT,                                   FN_PTR(getStackTraceElement)},
+  {CC"methodIsIgnoredBySecurityStackWalk",           CC"("HS_RESOLVED_METHOD")Z",                                                      FN_PTR(methodIsIgnoredBySecurityStackWalk)},
+  {CC"doNotInlineOrCompile",                         CC"("HS_RESOLVED_METHOD")V",                                                      FN_PTR(doNotInlineOrCompile)},
+  {CC"canInlineMethod",                              CC"("HS_RESOLVED_METHOD")Z",                                                      FN_PTR(canInlineMethod)},
+  {CC"shouldInlineMethod",                           CC"("HS_RESOLVED_METHOD")Z",                                                      FN_PTR(shouldInlineMethod)},
+  {CC"lookupType",                                   CC"("STRING CLASS"Z)"HS_RESOLVED_KLASS,                                           FN_PTR(lookupType)},
+  {CC"lookupNameInPool",                             CC"("HS_CONSTANT_POOL"I)"STRING,                                                  FN_PTR(lookupNameInPool)},
+  {CC"lookupNameAndTypeRefIndexInPool",              CC"("HS_CONSTANT_POOL"I)I",                                                       FN_PTR(lookupNameAndTypeRefIndexInPool)},
+  {CC"lookupSignatureInPool",                        CC"("HS_CONSTANT_POOL"I)"STRING,                                                  FN_PTR(lookupSignatureInPool)},
+  {CC"lookupKlassRefIndexInPool",                    CC"("HS_CONSTANT_POOL"I)I",                                                       FN_PTR(lookupKlassRefIndexInPool)},
+  {CC"lookupKlassInPool",                            CC"("HS_CONSTANT_POOL"I)Ljava/lang/Object;",                                      FN_PTR(lookupKlassInPool)},
+  {CC"lookupAppendixInPool",                         CC"("HS_CONSTANT_POOL"I)"OBJECT,                                                  FN_PTR(lookupAppendixInPool)},
+  {CC"lookupMethodInPool",                           CC"("HS_CONSTANT_POOL"IB)"HS_RESOLVED_METHOD,                                     FN_PTR(lookupMethodInPool)},
+  {CC"constantPoolRemapInstructionOperandFromCache", CC"("HS_CONSTANT_POOL"I)I",                                                       FN_PTR(constantPoolRemapInstructionOperandFromCache)},
+  {CC"resolveConstantInPool",                        CC"("HS_CONSTANT_POOL"I)"OBJECT,                                                  FN_PTR(resolveConstantInPool)},
+  {CC"resolvePossiblyCachedConstantInPool",          CC"("HS_CONSTANT_POOL"I)"OBJECT,                                                  FN_PTR(resolvePossiblyCachedConstantInPool)},
+  {CC"resolveTypeInPool",                            CC"("HS_CONSTANT_POOL"I)"HS_RESOLVED_KLASS,                                       FN_PTR(resolveTypeInPool)},
+  {CC"resolveFieldInPool",                           CC"("HS_CONSTANT_POOL"IB[J)"HS_RESOLVED_KLASS,                                    FN_PTR(resolveFieldInPool)},
+  {CC"resolveInvokeDynamicInPool",                   CC"("HS_CONSTANT_POOL"I)V",                                                       FN_PTR(resolveInvokeDynamicInPool)},
+  {CC"resolveInvokeHandleInPool",                    CC"("HS_CONSTANT_POOL"I)V",                                                       FN_PTR(resolveInvokeHandleInPool)},
+  {CC"resolveMethod",                                CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS")"HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
+  {CC"getVtableIndexForInterfaceMethod",             CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD")I",                                    FN_PTR(getVtableIndexForInterfaceMethod)},
+  {CC"getClassInitializer",                          CC"("HS_RESOLVED_KLASS")"HS_RESOLVED_METHOD,                                      FN_PTR(getClassInitializer)},
+  {CC"hasFinalizableSubclass",                       CC"("HS_RESOLVED_KLASS")Z",                                                       FN_PTR(hasFinalizableSubclass)},
+  {CC"getMaxCallTargetOffset",                       CC"(J)J",                                                                         FN_PTR(getMaxCallTargetOffset)},
+  {CC"getResolvedJavaMethodAtSlot",                  CC"("CLASS"I)"HS_RESOLVED_METHOD,                                                 FN_PTR(getResolvedJavaMethodAtSlot)},
+  {CC"getResolvedJavaMethod",                        CC"(Ljava/lang/Object;J)"HS_RESOLVED_METHOD,                                      FN_PTR(getResolvedJavaMethod)},
+  {CC"getConstantPool",                              CC"(Ljava/lang/Object;J)"HS_CONSTANT_POOL,                                        FN_PTR(getConstantPool)},
+  {CC"getResolvedJavaType",                          CC"(Ljava/lang/Object;JZ)"HS_RESOLVED_KLASS,                                      FN_PTR(getResolvedJavaType)},
+  {CC"initializeConfiguration",                      CC"()J",                                                                          FN_PTR(initializeConfiguration)},
+  {CC"installCode",                                  CC"("TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE SPECULATION_LOG")I",      FN_PTR(installCode)},
+  {CC"getMetadata",                                  CC"("TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA")I",                         FN_PTR(getMetadata)},
+  {CC"notifyCompilationStatistics",                  CC"(I"HS_RESOLVED_METHOD"ZIJJ"INSTALLED_CODE")V",                                 FN_PTR(notifyCompilationStatistics)},
+  {CC"resetCompilationStatistics",                   CC"()V",                                                                          FN_PTR(resetCompilationStatistics)},
+  {CC"disassembleCodeBlob",                          CC"(J)"STRING,                                                                    FN_PTR(disassembleCodeBlob)},
+  {CC"executeInstalledCode",                         CC"(["OBJECT INSTALLED_CODE")"OBJECT,                                             FN_PTR(executeInstalledCode)},
+  {CC"getLineNumberTable",                           CC"("HS_RESOLVED_METHOD")[J",                                                     FN_PTR(getLineNumberTable)},
+  {CC"getLocalVariableTableStart",                   CC"("HS_RESOLVED_METHOD")J",                                                      FN_PTR(getLocalVariableTableStart)},
+  {CC"getLocalVariableTableLength",                  CC"("HS_RESOLVED_METHOD")I",                                                      FN_PTR(getLocalVariableTableLength)},
+  {CC"reprofile",                                    CC"("HS_RESOLVED_METHOD")V",                                                      FN_PTR(reprofile)},
+  {CC"invalidateInstalledCode",                      CC"("INSTALLED_CODE")V",                                                          FN_PTR(invalidateInstalledCode)},
+  {CC"readUncompressedOop",                          CC"(J)"OBJECT,                                                                    FN_PTR(readUncompressedOop)},
+  {CC"collectCounters",                              CC"()[J",                                                                         FN_PTR(collectCounters)},
+  {CC"allocateCompileId",                            CC"("HS_RESOLVED_METHOD"I)I",                                                     FN_PTR(allocateCompileId)},
+  {CC"isMature",                                     CC"("METASPACE_METHOD_DATA")Z",                                                   FN_PTR(isMature)},
+  {CC"hasCompiledCodeForOSR",                        CC"("HS_RESOLVED_METHOD"II)Z",                                                    FN_PTR(hasCompiledCodeForOSR)},
+  {CC"getSymbol",                                    CC"(J)"STRING,                                                                    FN_PTR(getSymbol)},
+  {CC"getNextStackFrame",                            CC"("HS_STACK_FRAME_REF "["HS_RESOLVED_METHOD"I)"HS_STACK_FRAME_REF,              FN_PTR(getNextStackFrame)},
+  {CC"materializeVirtualObjects",                    CC"("HS_STACK_FRAME_REF"Z)V",                                                     FN_PTR(materializeVirtualObjects)},
+  {CC"shouldDebugNonSafepoints",                     CC"()Z",                                                                          FN_PTR(shouldDebugNonSafepoints)},
+  {CC"writeDebugOutput",                             CC"([BII)V",                                                                      FN_PTR(writeDebugOutput)},
+  {CC"flushDebugOutput",                             CC"()V",                                                                          FN_PTR(flushDebugOutput)},
+};
+
+int CompilerToVM::methods_count() {
+  return sizeof(methods) / sizeof(JNINativeMethod);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,144 @@
+/*
+ * 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
+ * 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_JVMCI_JVMCI_COMPILER_TO_VM_HPP
+#define SHARE_VM_JVMCI_JVMCI_COMPILER_TO_VM_HPP
+
+#include "prims/jni.h"
+#include "runtime/javaCalls.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+
+class CompilerToVM {
+public:
+  /**
+   * Tag bits used by lookupKlassInPool to distinguish the types in Java.
+   */
+  enum Tags {
+    KLASS_TAG = 0x0,
+    SYMBOL_TAG = 0x1
+  };
+
+  // FIXME This is only temporary until the GC code is changed.
+  static bool _supports_inline_contig_alloc;
+  static HeapWord** _heap_end_addr;
+  static HeapWord** _heap_top_addr;
+
+  static intptr_t tag_pointer(Klass* klass) {
+    return ((intptr_t) klass) | KLASS_TAG;
+  }
+
+  static intptr_t tag_pointer(Symbol* symbol) {
+    return ((intptr_t) symbol) | SYMBOL_TAG;
+  }
+
+  static JNINativeMethod methods[];
+  static int methods_count();
+
+  static inline Method* asMethod(jobject jvmci_method) {
+    return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
+  }
+
+  static inline Method* asMethod(Handle jvmci_method) {
+    return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
+  }
+
+  static inline Method* asMethod(oop jvmci_method) {
+    return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
+  }
+
+  static inline ConstantPool* asConstantPool(jobject jvmci_constant_pool) {
+    return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
+  }
+
+  static inline ConstantPool* asConstantPool(Handle jvmci_constant_pool) {
+    return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
+  }
+
+  static inline ConstantPool* asConstantPool(oop jvmci_constant_pool) {
+    return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
+  }
+
+  static inline Klass* asKlass(jobject jvmci_type) {
+    return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
+  }
+
+  static inline Klass* asKlass(Handle jvmci_type) {
+    return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
+  }
+
+  static inline Klass* asKlass(oop jvmci_type) {
+    return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
+  }
+
+  static inline MethodData* asMethodData(jlong metaspaceMethodData) {
+    return (MethodData*) (address) metaspaceMethodData;
+  }
+
+  static oop get_jvmci_method(methodHandle method, TRAPS);
+
+  static oop get_jvmci_type(KlassHandle klass, TRAPS);
+};
+
+class JavaArgumentUnboxer : public SignatureIterator {
+ protected:
+  JavaCallArguments*  _jca;
+  arrayOop _args;
+  int _index;
+
+  oop next_arg(BasicType expectedType) {
+    assert(_index < _args->length(), "out of bounds");
+    oop arg=((objArrayOop) (_args))->obj_at(_index++);
+    assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
+    return arg;
+  }
+
+ public:
+  JavaArgumentUnboxer(Symbol* signature, JavaCallArguments*  jca, arrayOop args, bool is_static) : SignatureIterator(signature) {
+    this->_return_type = T_ILLEGAL;
+    _jca = jca;
+    _index = 0;
+    _args = args;
+    if (!is_static) {
+      _jca->push_oop(next_arg(T_OBJECT));
+    }
+    iterate();
+    assert(_index == args->length(), "arg count mismatch with signature");
+  }
+
+  inline void do_bool()   { if (!is_return_type()) _jca->push_int(next_arg(T_BOOLEAN)->bool_field(java_lang_boxing_object::value_offset_in_bytes(T_BOOLEAN))); }
+  inline void do_char()   { if (!is_return_type()) _jca->push_int(next_arg(T_CHAR)->char_field(java_lang_boxing_object::value_offset_in_bytes(T_CHAR))); }
+  inline void do_short()  { if (!is_return_type()) _jca->push_int(next_arg(T_SHORT)->short_field(java_lang_boxing_object::value_offset_in_bytes(T_SHORT))); }
+  inline void do_byte()   { if (!is_return_type()) _jca->push_int(next_arg(T_BYTE)->byte_field(java_lang_boxing_object::value_offset_in_bytes(T_BYTE))); }
+  inline void do_int()    { if (!is_return_type()) _jca->push_int(next_arg(T_INT)->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT))); }
+
+  inline void do_long()   { if (!is_return_type()) _jca->push_long(next_arg(T_LONG)->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG))); }
+  inline void do_float()  { if (!is_return_type()) _jca->push_float(next_arg(T_FLOAT)->float_field(java_lang_boxing_object::value_offset_in_bytes(T_FLOAT))); }
+  inline void do_double() { if (!is_return_type()) _jca->push_double(next_arg(T_DOUBLE)->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); }
+
+  inline void do_object() { _jca->push_oop(next_arg(T_OBJECT)); }
+  inline void do_object(int begin, int end) { if (!is_return_type()) _jca->push_oop(next_arg(T_OBJECT)); }
+  inline void do_array(int begin, int end)  { if (!is_return_type()) _jca->push_oop(next_arg(T_OBJECT)); }
+  inline void do_void()                     { }
+};
+
+#endif // SHARE_VM_JVMCI_JVMCI_COMPILER_TO_VM_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciEnv.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "classfile/javaAssertions.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "code/codeCache.hpp"
+#include "code/scopeDesc.hpp"
+#include "runtime/sweeper.hpp"
+#include "compiler/compileBroker.hpp"
+#include "compiler/compileLog.hpp"
+#include "compiler/compilerOracle.hpp"
+#include "interpreter/linkResolver.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/oopFactory.hpp"
+#include "memory/universe.inline.hpp"
+#include "oops/methodData.hpp"
+#include "oops/objArrayKlass.hpp"
+#include "oops/oop.inline.hpp"
+#include "prims/jvmtiExport.hpp"
+#include "runtime/init.hpp"
+#include "runtime/reflection.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "utilities/dtrace.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+
+JVMCIEnv::JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter) {
+  _task = task;
+  _system_dictionary_modification_counter = system_dictionary_modification_counter;
+  {
+    // Get Jvmti capabilities under lock to get consistent values.
+    MutexLocker mu(JvmtiThreadState_lock);
+    _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
+    _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables();
+    _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions();
+  }
+}
+
+// ------------------------------------------------------------------
+// Note: the logic of this method should mirror the logic of
+// constantPoolOopDesc::verify_constant_pool_resolve.
+bool JVMCIEnv::check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klass) {
+  if (accessing_klass->oop_is_objArray()) {
+    accessing_klass = ObjArrayKlass::cast(accessing_klass())->bottom_klass();
+  }
+  if (!accessing_klass->oop_is_instance()) {
+    return true;
+  }
+
+  if (resolved_klass->oop_is_objArray()) {
+    // Find the element klass, if this is an array.
+    resolved_klass = ObjArrayKlass::cast(resolved_klass())->bottom_klass();
+  }
+  if (resolved_klass->oop_is_instance()) {
+    return Reflection::verify_class_access(accessing_klass(), resolved_klass(), true);
+  }
+  return true;
+}
+
+// ------------------------------------------------------------------
+KlassHandle JVMCIEnv::get_klass_by_name_impl(KlassHandle& accessing_klass,
+                                          constantPoolHandle& cpool,
+                                          Symbol* sym,
+                                          bool require_local) {
+  JVMCI_EXCEPTION_CONTEXT;
+
+  // Now we need to check the SystemDictionary
+  if (sym->byte_at(0) == 'L' &&
+    sym->byte_at(sym->utf8_length()-1) == ';') {
+    // This is a name from a signature.  Strip off the trimmings.
+    // Call recursive to keep scope of strippedsym.
+    TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
+                    sym->utf8_length()-2,
+                    CHECK_(KlassHandle()));
+    return get_klass_by_name_impl(accessing_klass, cpool, strippedsym, require_local);
+  }
+
+  Handle loader(THREAD, (oop)NULL);
+  Handle domain(THREAD, (oop)NULL);
+  if (!accessing_klass.is_null()) {
+    loader = Handle(THREAD, accessing_klass->class_loader());
+    domain = Handle(THREAD, accessing_klass->protection_domain());
+  }
+
+  KlassHandle found_klass;
+  {
+    ttyUnlocker ttyul;  // release tty lock to avoid ordering problems
+    MutexLocker ml(Compile_lock);
+    Klass*  kls;
+    if (!require_local) {
+      kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, CHECK_(KlassHandle()));
+    } else {
+      kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, CHECK_(KlassHandle()));
+    }
+    found_klass = KlassHandle(THREAD, kls);
+  }
+
+  // If we fail to find an array klass, look again for its element type.
+  // The element type may be available either locally or via constraints.
+  // In either case, if we can find the element type in the system dictionary,
+  // we must build an array type around it.  The CI requires array klasses
+  // to be loaded if their element klasses are loaded, except when memory
+  // is exhausted.
+  if (sym->byte_at(0) == '[' &&
+      (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) {
+    // We have an unloaded array.
+    // Build it on the fly if the element class exists.
+    TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
+                                                 sym->utf8_length()-1,
+                                                 CHECK_(KlassHandle()));
+
+    // Get element Klass recursively.
+    KlassHandle elem_klass =
+      get_klass_by_name_impl(accessing_klass,
+                             cpool,
+                             elem_sym,
+                             require_local);
+    if (!elem_klass.is_null()) {
+      // Now make an array for it
+      return elem_klass->array_klass(CHECK_(KlassHandle()));
+    }
+  }
+
+  if (found_klass.is_null() && !cpool.is_null() && cpool->has_preresolution()) {
+    // Look inside the constant pool for pre-resolved class entries.
+    for (int i = cpool->length() - 1; i >= 1; i--) {
+      if (cpool->tag_at(i).is_klass()) {
+        Klass*  kls = cpool->resolved_klass_at(i);
+        if (kls->name() == sym) {
+          return kls;
+        }
+      }
+    }
+  }
+
+  return found_klass();
+}
+
+// ------------------------------------------------------------------
+KlassHandle JVMCIEnv::get_klass_by_name(KlassHandle& accessing_klass,
+                                  Symbol* klass_name,
+                                  bool require_local) {
+  ResourceMark rm;
+  constantPoolHandle cpool;
+  return get_klass_by_name_impl(accessing_klass,
+                                                 cpool,
+                                                 klass_name,
+                                                 require_local);
+}
+
+// ------------------------------------------------------------------
+// Implementation of get_klass_by_index.
+KlassHandle JVMCIEnv::get_klass_by_index_impl(constantPoolHandle& cpool,
+                                        int index,
+                                        bool& is_accessible,
+                                        KlassHandle& accessor) {
+  JVMCI_EXCEPTION_CONTEXT;
+  KlassHandle klass (THREAD, ConstantPool::klass_at_if_loaded(cpool, index));
+  Symbol* klass_name = NULL;
+  if (klass.is_null()) {
+    klass_name = cpool->klass_name_at(index);
+  }
+
+  if (klass.is_null()) {
+    // Not found in constant pool.  Use the name to do the lookup.
+    KlassHandle k = get_klass_by_name_impl(accessor,
+                                        cpool,
+                                        klass_name,
+                                        false);
+    // Calculate accessibility the hard way.
+    if (k.is_null()) {
+      is_accessible = false;
+    } else if (k->class_loader() != accessor->class_loader() &&
+               get_klass_by_name_impl(accessor, cpool, k->name(), true).is_null()) {
+      // Loaded only remotely.  Not linked yet.
+      is_accessible = false;
+    } else {
+      // Linked locally, and we must also check public/private, etc.
+      is_accessible = check_klass_accessibility(accessor, k);
+    }
+    if (!is_accessible) {
+      return KlassHandle();
+    }
+    return k;
+  }
+
+  // It is known to be accessible, since it was found in the constant pool.
+  is_accessible = true;
+  return klass;
+}
+
+// ------------------------------------------------------------------
+// Get a klass from the constant pool.
+KlassHandle JVMCIEnv::get_klass_by_index(constantPoolHandle& cpool,
+                                   int index,
+                                   bool& is_accessible,
+                                   KlassHandle& accessor) {
+  ResourceMark rm;
+  KlassHandle result = get_klass_by_index_impl(cpool, index, is_accessible, accessor);
+  return result;
+}
+
+// ------------------------------------------------------------------
+// Implementation of get_field_by_index.
+//
+// Implementation note: the results of field lookups are cached
+// in the accessor klass.
+void JVMCIEnv::get_field_by_index_impl(instanceKlassHandle& klass, fieldDescriptor& field_desc,
+                                        int index) {
+  JVMCI_EXCEPTION_CONTEXT;
+
+  assert(klass->is_linked(), "must be linked before using its constant-pool");
+
+  constantPoolHandle cpool(thread, klass->constants());
+
+  // Get the field's name, signature, and type.
+  Symbol* name  = cpool->name_ref_at(index);
+
+  int nt_index = cpool->name_and_type_ref_index_at(index);
+  int sig_index = cpool->signature_ref_index_at(nt_index);
+  Symbol* signature = cpool->symbol_at(sig_index);
+
+  // Get the field's declared holder.
+  int holder_index = cpool->klass_ref_index_at(index);
+  bool holder_is_accessible;
+  KlassHandle declared_holder = get_klass_by_index(cpool, holder_index,
+                                               holder_is_accessible,
+                                               klass);
+
+  // The declared holder of this field may not have been loaded.
+  // Bail out with partial field information.
+  if (!holder_is_accessible) {
+    return;
+  }
+
+
+  // Perform the field lookup.
+  Klass*  canonical_holder =
+    InstanceKlass::cast(declared_holder())->find_field(name, signature, &field_desc);
+  if (canonical_holder == NULL) {
+    return;
+  }
+
+  assert(canonical_holder == field_desc.field_holder(), "just checking");
+}
+
+// ------------------------------------------------------------------
+// Get a field by index from a klass's constant pool.
+void JVMCIEnv::get_field_by_index(instanceKlassHandle& accessor, fieldDescriptor& fd, int index) {
+  ResourceMark rm;
+  return get_field_by_index_impl(accessor, fd, index);
+}
+
+// ------------------------------------------------------------------
+// Perform an appropriate method lookup based on accessor, holder,
+// name, signature, and bytecode.
+methodHandle JVMCIEnv::lookup_method(instanceKlassHandle& h_accessor,
+                               instanceKlassHandle& h_holder,
+                               Symbol*       name,
+                               Symbol*       sig,
+                               Bytecodes::Code bc) {
+  JVMCI_EXCEPTION_CONTEXT;
+  LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
+  methodHandle dest_method;
+  LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true);
+  switch (bc) {
+  case Bytecodes::_invokestatic:
+    dest_method =
+      LinkResolver::resolve_static_call_or_null(link_info);
+    break;
+  case Bytecodes::_invokespecial:
+    dest_method =
+      LinkResolver::resolve_special_call_or_null(link_info);
+    break;
+  case Bytecodes::_invokeinterface:
+    dest_method =
+      LinkResolver::linktime_resolve_interface_method_or_null(link_info);
+    break;
+  case Bytecodes::_invokevirtual:
+    dest_method =
+      LinkResolver::linktime_resolve_virtual_method_or_null(link_info);
+    break;
+  default: ShouldNotReachHere();
+  }
+
+  return dest_method;
+}
+
+
+// ------------------------------------------------------------------
+methodHandle JVMCIEnv::get_method_by_index_impl(constantPoolHandle& cpool,
+                                          int index, Bytecodes::Code bc,
+                                          instanceKlassHandle& accessor) {
+  if (bc == Bytecodes::_invokedynamic) {
+    ConstantPoolCacheEntry* cpce = cpool->invokedynamic_cp_cache_entry_at(index);
+    bool is_resolved = !cpce->is_f1_null();
+    if (is_resolved) {
+      // Get the invoker Method* from the constant pool.
+      // (The appendix argument, if any, will be noted in the method's signature.)
+      Method* adapter = cpce->f1_as_method();
+      return methodHandle(adapter);
+    }
+
+    return NULL;
+  }
+
+  int holder_index = cpool->klass_ref_index_at(index);
+  bool holder_is_accessible;
+  KlassHandle holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
+
+  // Get the method's name and signature.
+  Symbol* name_sym = cpool->name_ref_at(index);
+  Symbol* sig_sym  = cpool->signature_ref_at(index);
+
+  if (cpool->has_preresolution()
+      || (holder() == SystemDictionary::MethodHandle_klass() &&
+          MethodHandles::is_signature_polymorphic_name(holder(), name_sym))) {
+    // Short-circuit lookups for JSR 292-related call sites.
+    // That is, do not rely only on name-based lookups, because they may fail
+    // if the names are not resolvable in the boot class loader (7056328).
+    switch (bc) {
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_invokeinterface:
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokestatic:
+      {
+        Method* m = ConstantPool::method_at_if_loaded(cpool, index);
+        if (m != NULL) {
+          return m;
+        }
+      }
+      break;
+    }
+  }
+
+  if (holder_is_accessible) { // Our declared holder is loaded.
+    instanceKlassHandle lookup = get_instance_klass_for_declared_method_holder(holder);
+    methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc);
+    if (!m.is_null() &&
+        (bc == Bytecodes::_invokestatic
+         ?  InstanceKlass::cast(m->method_holder())->is_not_initialized()
+         : !InstanceKlass::cast(m->method_holder())->is_loaded())) {
+      m = NULL;
+    }
+    if (!m.is_null()) {
+      // We found the method.
+      return m;
+    }
+  }
+
+  // Either the declared holder was not loaded, or the method could
+  // not be found.
+
+  return NULL;
+}
+
+// ------------------------------------------------------------------
+instanceKlassHandle JVMCIEnv::get_instance_klass_for_declared_method_holder(KlassHandle& method_holder) {
+  // For the case of <array>.clone(), the method holder can be an ArrayKlass*
+  // instead of an InstanceKlass*.  For that case simply pretend that the
+  // declared holder is Object.clone since that's where the call will bottom out.
+  if (method_holder->oop_is_instance()) {
+    return instanceKlassHandle(method_holder());
+  } else if (method_holder->oop_is_array()) {
+    return instanceKlassHandle(SystemDictionary::Object_klass());
+  } else {
+    ShouldNotReachHere();
+  }
+  return NULL;
+}
+
+
+// ------------------------------------------------------------------
+methodHandle JVMCIEnv::get_method_by_index(constantPoolHandle& cpool,
+                                     int index, Bytecodes::Code bc,
+                                     instanceKlassHandle& accessor) {
+  ResourceMark rm;
+  return get_method_by_index_impl(cpool, index, bc, accessor);
+}
+
+// ------------------------------------------------------------------
+// Check for changes to the system dictionary during compilation
+// class loads, evolution, breakpoints
+JVMCIEnv::CodeInstallResult JVMCIEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code,
+                                                                               JVMCIEnv* env, char** failure_detail) {
+  // If JVMTI capabilities were enabled during compile, the compilation is invalidated.
+  if (env != NULL) {
+    if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) {
+      *failure_detail = (char*) "Hotswapping or breakpointing was enabled during compilation";
+      return JVMCIEnv::dependencies_failed;
+    }
+  }
+
+  // Dependencies must be checked when the system dictionary changes
+  // or if we don't know whether it has changed (i.e., env == NULL).
+  // In debug mode, always check dependencies.
+  bool counter_changed = env != NULL && env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications();
+  bool verify_deps = env == NULL || trueInDebug || JavaAssertions::enabled(SystemDictionary::HotSpotInstalledCode_klass()->name()->as_C_string(), true);
+  if (!counter_changed && !verify_deps) {
+    return JVMCIEnv::ok;
+  }
+
+  for (Dependencies::DepStream deps(dependencies); deps.next(); ) {
+    Klass* witness = deps.check_dependency();
+    if (witness != NULL) {
+      // Use a fixed size buffer to prevent the string stream from
+      // resizing in the context of an inner resource mark.
+      char* buffer = NEW_RESOURCE_ARRAY(char, O_BUFLEN);
+      stringStream st(buffer, O_BUFLEN);
+      deps.print_dependency(witness, true, &st);
+      *failure_detail = st.as_string();
+      if (env == NULL || counter_changed) {
+        return JVMCIEnv::dependencies_failed;
+      } else {
+        // The dependencies were invalid at the time of installation
+        // without any intervening modification of the system
+        // dictionary.  That means they were invalidly constructed.
+        return JVMCIEnv::dependencies_invalid;
+      }
+    }
+    if (LogCompilation) {
+      deps.log_dependency();
+    }
+  }
+
+  return JVMCIEnv::ok;
+}
+
+// ------------------------------------------------------------------
+JVMCIEnv::CodeInstallResult JVMCIEnv::register_method(
+                                methodHandle& method,
+                                nmethod*& nm,
+                                int entry_bci,
+                                CodeOffsets* offsets,
+                                int orig_pc_offset,
+                                CodeBuffer* code_buffer,
+                                int frame_words,
+                                OopMapSet* oop_map_set,
+                                ExceptionHandlerTable* handler_table,
+                                AbstractCompiler* compiler,
+                                DebugInformationRecorder* debug_info,
+                                Dependencies* dependencies,
+                                JVMCIEnv* env,
+                                int compile_id,
+                                bool has_unsafe_access,
+                                bool has_wide_vector,
+                                Handle installed_code,
+                                Handle compiled_code,
+                                Handle speculation_log) {
+  JVMCI_EXCEPTION_CONTEXT;
+  nm = NULL;
+  int comp_level = CompLevel_full_optimization;
+  char* failure_detail = NULL;
+  JVMCIEnv::CodeInstallResult result;
+  {
+    // To prevent compile queue updates.
+    MutexLocker locker(MethodCompileQueue_lock, THREAD);
+
+    // Prevent SystemDictionary::add_to_hierarchy from running
+    // and invalidating our dependencies until we install this method.
+    MutexLocker ml(Compile_lock);
+
+    // Encode the dependencies now, so we can check them right away.
+    dependencies->encode_content_bytes();
+
+    // Check for {class loads, evolution, breakpoints} during compilation
+    result = check_for_system_dictionary_modification(dependencies, compiled_code, env, &failure_detail);
+    if (result != JVMCIEnv::ok) {
+      // While not a true deoptimization, it is a preemptive decompile.
+      MethodData* mdp = method()->method_data();
+      if (mdp != NULL) {
+        mdp->inc_decompile_count();
+        if (mdp->decompile_count() > (uint)PerMethodRecompilationCutoff) {
+          // TODO (chaeubl) enable this in the fastdebug build only once we are more stable
+          ResourceMark m;
+          tty->print_cr("WARN: endless recompilation of %s. Method was set to not compilable.", method()->name_and_sig_as_C_string());
+          //ShouldNotReachHere();
+        }
+      }
+
+      // All buffers in the CodeBuffer are allocated in the CodeCache.
+      // If the code buffer is created on each compile attempt
+      // as in C2, then it must be freed.
+      //code_buffer->free_blob();
+    } else {
+      ImplicitExceptionTable implicit_tbl;
+      nm =  nmethod::new_nmethod(method,
+                                 compile_id,
+                                 entry_bci,
+                                 offsets,
+                                 orig_pc_offset,
+                                 debug_info, dependencies, code_buffer,
+                                 frame_words, oop_map_set,
+                                 handler_table, &implicit_tbl,
+                                 compiler, comp_level, installed_code, speculation_log);
+
+      // Free codeBlobs
+      //code_buffer->free_blob();
+      if (nm == NULL) {
+        // The CodeCache is full.  Print out warning and disable compilation.
+        {
+          MutexUnlocker ml(Compile_lock);
+          MutexUnlocker locker(MethodCompileQueue_lock);
+          CompileBroker::handle_full_code_cache(CodeCache::get_code_blob_type(comp_level));
+        }
+      } else {
+        nm->set_has_unsafe_access(has_unsafe_access);
+        nm->set_has_wide_vectors(has_wide_vector);
+
+        // Record successful registration.
+        // (Put nm into the task handle *before* publishing to the Java heap.)
+        CompileTask* task = env == NULL ? NULL : env->task();
+        if (task != NULL)  task->set_code(nm);
+
+        if (installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(installed_code())) {
+          if (entry_bci == InvocationEntryBci) {
+            if (TieredCompilation) {
+              // If there is an old version we're done with it
+              nmethod* old = method->code();
+              if (TraceMethodReplacement && old != NULL) {
+                ResourceMark rm;
+                char *method_name = method->name_and_sig_as_C_string();
+                tty->print_cr("Replacing method %s", method_name);
+              }
+              if (old != NULL ) {
+                old->make_not_entrant();
+              }
+            }
+            if (TraceNMethodInstalls) {
+              ResourceMark rm;
+              char *method_name = method->name_and_sig_as_C_string();
+              ttyLocker ttyl;
+              tty->print_cr("Installing method (%d) %s [entry point: %p]",
+                            comp_level,
+                            method_name, nm->entry_point());
+            }
+            // Allow the code to be executed
+            method->set_code(method, nm);
+          } else {
+            if (TraceNMethodInstalls ) {
+              ResourceMark rm;
+              char *method_name = method->name_and_sig_as_C_string();
+              ttyLocker ttyl;
+              tty->print_cr("Installing osr method (%d) %s @ %d",
+                            comp_level,
+                            method_name,
+                            entry_bci);
+            }
+            InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
+          }
+        }
+      }
+      result = nm != NULL ? JVMCIEnv::ok :JVMCIEnv::cache_full;
+    }
+  }
+
+  // String creation must be done outside lock
+  if (failure_detail != NULL) {
+    // A failure to allocate the string is silently ignored.
+    Handle message = java_lang_String::create_from_str(failure_detail, THREAD);
+    HotSpotCompiledNmethod::set_installationFailureMessage(compiled_code, message());
+  }
+
+  // JVMTI -- compiled method notification (must be done outside lock)
+  if (nm != NULL) {
+    nm->post_compiled_method_load_event();
+  }
+
+  return result;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciEnv.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_JVMCI_JVMCIENV_HPP
+#define SHARE_VM_JVMCI_JVMCIENV_HPP
+
+#include "classfile/systemDictionary.hpp"
+#include "code/debugInfoRec.hpp"
+#include "code/dependencies.hpp"
+#include "code/exceptionHandlerTable.hpp"
+#include "compiler/oopMap.hpp"
+#include "runtime/thread.hpp"
+
+class CompileTask;
+
+// Bring the JVMCI compiler thread into the VM state.
+#define JVMCI_VM_ENTRY_MARK                       \
+  JavaThread* thread = JavaThread::current(); \
+  ThreadInVMfromNative __tiv(thread);       \
+  ResetNoHandleMark rnhm;                   \
+  HandleMarkCleaner __hm(thread);           \
+  Thread* THREAD = thread;                  \
+  debug_only(VMNativeEntryWrapper __vew;)
+
+#define JVMCI_EXCEPTION_CONTEXT \
+  JavaThread* thread=JavaThread::current(); \
+  Thread* THREAD = thread;
+
+//
+// This class is the top level broker for requests from the compiler
+// to the VM.
+class JVMCIEnv : StackObj {
+  CI_PACKAGE_ACCESS_TO
+
+  friend class CompileBroker;
+  friend class Dependencies;  // for get_object, during logging
+
+public:
+
+  enum CodeInstallResult {
+     ok,
+     dependencies_failed,
+     dependencies_invalid,
+     cache_full,
+     code_too_large
+  };
+
+  // Look up a klass by name from a particular class loader (the accessor's).
+  // If require_local, result must be defined in that class loader, or NULL.
+  // If !require_local, a result from remote class loader may be reported,
+  // if sufficient class loader constraints exist such that initiating
+  // a class loading request from the given loader is bound to return
+  // the class defined in the remote loader (or throw an error).
+  //
+  // Return an unloaded klass if !require_local and no class at all is found.
+  //
+  // The CI treats a klass as loaded if it is consistently defined in
+  // another loader, even if it hasn't yet been loaded in all loaders
+  // that could potentially see it via delegation.
+  static KlassHandle get_klass_by_name(KlassHandle& accessing_klass,
+                             Symbol* klass_name,
+                             bool require_local);
+
+  // Constant pool access.
+  static KlassHandle   get_klass_by_index(constantPoolHandle& cpool,
+                                int klass_index,
+                                bool& is_accessible,
+                                KlassHandle& loading_klass);
+  static void   get_field_by_index(instanceKlassHandle& loading_klass, fieldDescriptor& fd,
+                                int field_index);
+  static methodHandle  get_method_by_index(constantPoolHandle& cpool,
+                                 int method_index, Bytecodes::Code bc,
+                                 instanceKlassHandle& loading_klass);
+
+  JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter);
+
+private:
+  CompileTask*     _task;
+  int              _system_dictionary_modification_counter;
+
+  // Cache JVMTI state
+  bool  _jvmti_can_hotswap_or_post_breakpoint;
+  bool  _jvmti_can_access_local_variables;
+  bool  _jvmti_can_post_on_exceptions;
+
+  // Implementation methods for loading and constant pool access.
+  static KlassHandle get_klass_by_name_impl(KlassHandle& accessing_klass,
+                                  constantPoolHandle& cpool,
+                                  Symbol* klass_name,
+                                  bool require_local);
+  static KlassHandle   get_klass_by_index_impl(constantPoolHandle& cpool,
+                                     int klass_index,
+                                     bool& is_accessible,
+                                     KlassHandle& loading_klass);
+  static void   get_field_by_index_impl(instanceKlassHandle& loading_klass, fieldDescriptor& fd,
+                                     int field_index);
+  static methodHandle  get_method_by_index_impl(constantPoolHandle& cpool,
+                                      int method_index, Bytecodes::Code bc,
+                                      instanceKlassHandle& loading_klass);
+
+  // Helper methods
+  static bool       check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klass);
+  static methodHandle  lookup_method(instanceKlassHandle&  accessor,
+                           instanceKlassHandle&  holder,
+                           Symbol*         name,
+                           Symbol*         sig,
+                           Bytecodes::Code bc);
+
+  private:
+
+  // Is this thread currently in the VM state?
+  static bool is_in_vm();
+
+  // Helper routine for determining the validity of a compilation
+  // with respect to concurrent class loading.
+  static JVMCIEnv::CodeInstallResult check_for_system_dictionary_modification(Dependencies* target, Handle compiled_code,
+                                                                              JVMCIEnv* env, char** failure_detail);
+
+public:
+  CompileTask* task() { return _task; }
+
+  // Register the result of a compilation.
+  static JVMCIEnv::CodeInstallResult register_method(
+                       methodHandle&             target,
+                       nmethod*&                 nm,
+                       int                       entry_bci,
+                       CodeOffsets*              offsets,
+                       int                       orig_pc_offset,
+                       CodeBuffer*               code_buffer,
+                       int                       frame_words,
+                       OopMapSet*                oop_map_set,
+                       ExceptionHandlerTable*    handler_table,
+                       AbstractCompiler*         compiler,
+                       DebugInformationRecorder* debug_info,
+                       Dependencies*             dependencies,
+                       JVMCIEnv*                 env,
+                       int                       compile_id,
+                       bool                      has_unsafe_access,
+                       bool                      has_wide_vector,
+                       Handle                    installed_code,
+                       Handle                    compiled_code,
+                       Handle                    speculation_log);
+
+  // converts the Klass* representing the holder of a method into a
+  // InstanceKlass*.  This is needed since the holder of a method in
+  // the bytecodes could be an array type.  Basically this converts
+  // array types into java/lang/Object and other types stay as they are.
+  static instanceKlassHandle get_instance_klass_for_declared_method_holder(KlassHandle& klass);
+};
+
+#endif // SHARE_VM_JVMCI_JVMCIENV_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, 2015, 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 "jvmci/jvmciJavaClasses.hpp"
+#include "runtime/jniHandles.hpp"
+#include "classfile/symbolTable.hpp"
+#include "memory/resourceArea.hpp"
+
+// This function is similar to javaClasses.cpp, it computes the field offset of a (static or instance) field.
+// It looks up the name and signature symbols without creating new ones, all the symbols of these classes need to be already loaded.
+
+void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field) {
+  InstanceKlass* ik = InstanceKlass::cast(klass);
+  Symbol* name_symbol = SymbolTable::probe(name, (int)strlen(name));
+  Symbol* signature_symbol = SymbolTable::probe(signature, (int)strlen(signature));
+  if (name_symbol == NULL || signature_symbol == NULL) {
+#ifndef PRODUCT
+    ik->print_on(tty);
+#endif
+    fatal("symbol with name %s and signature %s was not found in symbol table (klass=%s)", name, signature, klass->name()->as_C_string());
+  }
+
+  fieldDescriptor fd;
+  if (!ik->find_field(name_symbol, signature_symbol, &fd)) {
+    ResourceMark rm;
+    fatal("Invalid layout of %s at %s", name_symbol->as_C_string(), ik->external_name());
+  }
+  guarantee(fd.is_static() == static_field, "static/instance mismatch");
+  dest_offset = fd.offset();
+  assert(dest_offset != 0, "must be valid offset");
+}
+
+// This piece of macro magic creates the contents of the jvmci_compute_offsets method that initializes the field indices of all the access classes.
+
+#define START_CLASS(name) { Klass* k = SystemDictionary::name##_klass(); assert(k != NULL, "Could not find class " #name "");
+
+#define END_CLASS }
+
+#define FIELD(klass, name, signature, static_field) compute_offset(klass::_##name##_offset, k, #name, signature, static_field);
+#define CHAR_FIELD(klass, name) FIELD(klass, name, "C", false)
+#define INT_FIELD(klass, name) FIELD(klass, name, "I", false)
+#define BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", false)
+#define LONG_FIELD(klass, name) FIELD(klass, name, "J", false)
+#define FLOAT_FIELD(klass, name) FIELD(klass, name, "F", false)
+#define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false)
+#define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true)
+#define STATIC_INT_FIELD(klass, name) FIELD(klass, name, "I", true)
+#define STATIC_BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", true)
+
+
+void JVMCIJavaClasses::compute_offsets() {
+  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
+  guarantee(InstalledCode::_address_offset == sizeof(oopDesc), "codeBlob must be first field!");
+}
+
+#define EMPTY0
+#define EMPTY1(x)
+#define EMPTY2(x,y)
+#define FIELD2(klass, name) int klass::_##name##_offset = 0;
+#define FIELD3(klass, name, sig) FIELD2(klass, name)
+
+COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2)
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2011, 2015, 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_JVMCI_JVMCIJAVACLASSES_HPP
+#define SHARE_VM_JVMCI_JVMCIJAVACLASSES_HPP
+
+#include "classfile/systemDictionary.hpp"
+#include "oops/instanceMirrorKlass.hpp"
+
+class JVMCIJavaClasses : AllStatic {
+ public:
+  static void compute_offsets();
+};
+
+/* This macro defines the structure of the CompilationResult - classes.
+ * It will generate classes with accessors similar to javaClasses.hpp, but with specializations for oops, Handles and jni handles.
+ *
+ * The public interface of these classes will look like this:
+
+ * class StackSlot : AllStatic {
+ * public:
+ *   static Klass* klass();
+ *   static jint  index(oop obj);
+ *   static jint  index(Handle obj);
+ *   static jint  index(jobject obj);
+ *   static void set_index(oop obj, jint x);
+ *   static void set_index(Handle obj, jint x);
+ *   static void set_index(jobject obj, jint x);
+ * };
+ *
+ */
+
+#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_objArrayOop_field, static_int_field, static_boolean_field) \
+  start_class(Architecture)                                                                                                                                    \
+    oop_field(Architecture, wordKind, "Ljdk/vm/ci/meta/PlatformKind;")                                                                                         \
+  end_class                                                                                                                                                    \
+  start_class(TargetDescription)                                                                                                                               \
+    oop_field(TargetDescription, arch, "Ljdk/vm/ci/code/Architecture;")                                                                                        \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotResolvedObjectTypeImpl)                                                                                                                   \
+    oop_field(HotSpotResolvedObjectTypeImpl, javaClass, "Ljava/lang/Class;")                                                                                   \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotResolvedJavaMethodImpl)                                                                                                                   \
+    long_field(HotSpotResolvedJavaMethodImpl, metaspaceMethod)                                                                                                 \
+  end_class                                                                                                                                                    \
+  start_class(InstalledCode)                                                                                                                                   \
+    long_field(InstalledCode, address)                                                                                                                         \
+    long_field(InstalledCode, version)                                                                                                                         \
+    oop_field(InstalledCode, name, "Ljava/lang/String;")                                                                                                       \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotInstalledCode)                                                                                                                            \
+    int_field(HotSpotInstalledCode, size)                                                                                                                      \
+    long_field(HotSpotInstalledCode, codeStart)                                                                                                                \
+    int_field(HotSpotInstalledCode, codeSize)                                                                                                                  \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotNmethod)                                                                                                                                  \
+    boolean_field(HotSpotNmethod, isDefault)                                                                                                                   \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotCompiledCode)                                                                                                                             \
+    oop_field(HotSpotCompiledCode, name, "Ljava/lang/String;")                                                                                                 \
+    objArrayOop_field(HotSpotCompiledCode, sites, "[Ljdk/vm/ci/code/CompilationResult$Site;")                                                                  \
+    objArrayOop_field(HotSpotCompiledCode, exceptionHandlers, "[Ljdk/vm/ci/code/CompilationResult$ExceptionHandler;")                                          \
+    objArrayOop_field(HotSpotCompiledCode, comments, "[Ljdk/vm/ci/hotspot/HotSpotCompiledCode$Comment;")                                                       \
+    objArrayOop_field(HotSpotCompiledCode, assumptions, "[Ljdk/vm/ci/meta/Assumptions$Assumption;")                                                            \
+    typeArrayOop_field(HotSpotCompiledCode, targetCode, "[B")                                                                                                  \
+    int_field(HotSpotCompiledCode, targetCodeSize)                                                                                                             \
+    typeArrayOop_field(HotSpotCompiledCode, dataSection, "[B")                                                                                                 \
+    int_field(HotSpotCompiledCode, dataSectionAlignment)                                                                                                       \
+    objArrayOop_field(HotSpotCompiledCode, dataSectionPatches, "[Ljdk/vm/ci/code/CompilationResult$DataPatch;")                                                \
+    boolean_field(HotSpotCompiledCode, isImmutablePIC)                                                                                                         \
+    int_field(HotSpotCompiledCode, totalFrameSize)                                                                                                             \
+    int_field(HotSpotCompiledCode, customStackAreaOffset)                                                                                                      \
+    objArrayOop_field(HotSpotCompiledCode, methods, "[Ljdk/vm/ci/meta/ResolvedJavaMethod;")                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotCompiledCode_Comment)                                                                                                                     \
+    oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;")                                                                                         \
+    int_field(HotSpotCompiledCode_Comment, pcOffset)                                                                                                           \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotCompiledNmethod)                                                                                                                          \
+    oop_field(HotSpotCompiledNmethod, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;")                                                                 \
+    oop_field(HotSpotCompiledNmethod, installationFailureMessage, "Ljava/lang/String;")                                                                        \
+    int_field(HotSpotCompiledNmethod, entryBCI)                                                                                                                \
+    int_field(HotSpotCompiledNmethod, id)                                                                                                                      \
+    long_field(HotSpotCompiledNmethod, jvmciEnv)                                                                                                               \
+    boolean_field(HotSpotCompiledNmethod, hasUnsafeAccess)                                                                                                     \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotJVMCIMetaAccessContext)                                                                                                                   \
+    static_objArrayOop_field(HotSpotJVMCIMetaAccessContext, allContexts, "[Ljava/lang/ref/WeakReference;")                                                     \
+    objArrayOop_field(HotSpotJVMCIMetaAccessContext, metadataRoots, "[Ljava/lang/Object;")                                                                     \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotForeignCallTarget)                                                                                                                        \
+    long_field(HotSpotForeignCallTarget, address)                                                                                                              \
+  end_class                                                                                                                                                    \
+  start_class(Assumptions_NoFinalizableSubclass)                                                                                                               \
+    oop_field(Assumptions_NoFinalizableSubclass, receiverType, "Ljdk/vm/ci/meta/ResolvedJavaType;")                                                            \
+  end_class                                                                                                                                                    \
+  start_class(Assumptions_ConcreteSubtype)                                                                                                                     \
+    oop_field(Assumptions_ConcreteSubtype, context, "Ljdk/vm/ci/meta/ResolvedJavaType;")                                                                       \
+    oop_field(Assumptions_ConcreteSubtype, subtype, "Ljdk/vm/ci/meta/ResolvedJavaType;")                                                                       \
+  end_class                                                                                                                                                    \
+  start_class(Assumptions_LeafType)                                                                                                                            \
+    oop_field(Assumptions_LeafType, context, "Ljdk/vm/ci/meta/ResolvedJavaType;")                                                                              \
+  end_class                                                                                                                                                    \
+  start_class(Assumptions_ConcreteMethod)                                                                                                                      \
+    oop_field(Assumptions_ConcreteMethod, method, "Ljdk/vm/ci/meta/ResolvedJavaMethod;")                                                                       \
+    oop_field(Assumptions_ConcreteMethod, context, "Ljdk/vm/ci/meta/ResolvedJavaType;")                                                                        \
+    oop_field(Assumptions_ConcreteMethod, impl, "Ljdk/vm/ci/meta/ResolvedJavaMethod;")                                                                         \
+  end_class                                                                                                                                                    \
+  start_class(Assumptions_CallSiteTargetValue)                                                                                                                 \
+    oop_field(Assumptions_CallSiteTargetValue, callSite, "Ljava/lang/invoke/CallSite;")                                                                        \
+    oop_field(Assumptions_CallSiteTargetValue, methodHandle, "Ljava/lang/invoke/MethodHandle;")                                                                \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_Site)                                                                                                                          \
+    int_field(CompilationResult_Site, pcOffset)                                                                                                                \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_Call)                                                                                                                          \
+    oop_field(CompilationResult_Call, target, "Ljdk/vm/ci/meta/InvokeTarget;")                                                                                 \
+    oop_field(CompilationResult_Call, debugInfo, "Ljdk/vm/ci/code/DebugInfo;")                                                                                 \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_DataPatch)                                                                                                                     \
+    oop_field(CompilationResult_DataPatch, reference, "Ljdk/vm/ci/code/CompilationResult$Reference;")                                                          \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_ConstantReference)                                                                                                             \
+    oop_field(CompilationResult_ConstantReference, constant, "Ljdk/vm/ci/meta/VMConstant;")                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_DataSectionReference)                                                                                                          \
+    int_field(CompilationResult_DataSectionReference, offset)                                                                                                  \
+  end_class                                                                                                                                                    \
+  start_class(InfopointReason)                                                                                                                                 \
+    static_oop_field(InfopointReason, UNKNOWN, "Ljdk/vm/ci/code/InfopointReason;")                                                                             \
+    static_oop_field(InfopointReason, SAFEPOINT, "Ljdk/vm/ci/code/InfopointReason;")                                                                           \
+    static_oop_field(InfopointReason, CALL, "Ljdk/vm/ci/code/InfopointReason;")                                                                                \
+    static_oop_field(InfopointReason, IMPLICIT_EXCEPTION, "Ljdk/vm/ci/code/InfopointReason;")                                                                  \
+    static_oop_field(InfopointReason, METHOD_START, "Ljdk/vm/ci/code/InfopointReason;")                                                                        \
+    static_oop_field(InfopointReason, METHOD_END, "Ljdk/vm/ci/code/InfopointReason;")                                                                          \
+    static_oop_field(InfopointReason, LINE_NUMBER, "Ljdk/vm/ci/code/InfopointReason;")                                                                         \
+    static_oop_field(InfopointReason, METASPACE_ACCESS, "Ljdk/vm/ci/code/InfopointReason;")                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_Infopoint)                                                                                                                     \
+    oop_field(CompilationResult_Infopoint, debugInfo, "Ljdk/vm/ci/code/DebugInfo;")                                                                            \
+    oop_field(CompilationResult_Infopoint, reason, "Ljdk/vm/ci/code/InfopointReason;")                                                                         \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_ExceptionHandler)                                                                                                              \
+    int_field(CompilationResult_ExceptionHandler, handlerPos)                                                                                                  \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_Mark)                                                                                                                          \
+    oop_field(CompilationResult_Mark, id, "Ljava/lang/Object;")                                                                                                \
+  end_class                                                                                                                                                    \
+  start_class(DebugInfo)                                                                                                                                       \
+    oop_field(DebugInfo, bytecodePosition, "Ljdk/vm/ci/code/BytecodePosition;")                                                                                \
+    oop_field(DebugInfo, referenceMap, "Ljdk/vm/ci/code/ReferenceMap;")                                                                                        \
+    oop_field(DebugInfo, calleeSaveInfo, "Ljdk/vm/ci/code/RegisterSaveLayout;")                                                                                \
+    objArrayOop_field(DebugInfo, virtualObjectMapping, "[Ljdk/vm/ci/code/VirtualObject;")                                                                      \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotReferenceMap)                                                                                                                             \
+    objArrayOop_field(HotSpotReferenceMap, objects, "[Ljdk/vm/ci/code/Location;")                                                                              \
+    objArrayOop_field(HotSpotReferenceMap, derivedBase, "[Ljdk/vm/ci/code/Location;")                                                                          \
+    typeArrayOop_field(HotSpotReferenceMap, sizeInBytes, "[I")                                                                                                 \
+    int_field(HotSpotReferenceMap, maxRegisterSize)                                                                                                            \
+  end_class                                                                                                                                                    \
+  start_class(RegisterSaveLayout)                                                                                                                              \
+    objArrayOop_field(RegisterSaveLayout, registers, "[Ljdk/vm/ci/code/Register;")                                                                             \
+    typeArrayOop_field(RegisterSaveLayout, slots, "[I")                                                                                                        \
+  end_class                                                                                                                                                    \
+  start_class(BytecodeFrame)                                                                                                                                   \
+    objArrayOop_field(BytecodeFrame, values, "[Ljdk/vm/ci/meta/JavaValue;")                                                                                    \
+    objArrayOop_field(BytecodeFrame, slotKinds, "[Ljdk/vm/ci/meta/JavaKind;")                                                                                  \
+    int_field(BytecodeFrame, numLocals)                                                                                                                        \
+    int_field(BytecodeFrame, numStack)                                                                                                                         \
+    int_field(BytecodeFrame, numLocks)                                                                                                                         \
+    boolean_field(BytecodeFrame, rethrowException)                                                                                                             \
+    boolean_field(BytecodeFrame, duringCall)                                                                                                                   \
+    static_int_field(BytecodeFrame, BEFORE_BCI)                                                                                                                \
+  end_class                                                                                                                                                    \
+  start_class(BytecodePosition)                                                                                                                                \
+    oop_field(BytecodePosition, caller, "Ljdk/vm/ci/code/BytecodePosition;")                                                                                   \
+    oop_field(BytecodePosition, method, "Ljdk/vm/ci/meta/ResolvedJavaMethod;")                                                                                 \
+    int_field(BytecodePosition, bci)                                                                                                                           \
+  end_class                                                                                                                                                    \
+  start_class(JavaConstant)                                                                                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(PrimitiveConstant)                                                                                                                               \
+    oop_field(PrimitiveConstant, kind, "Ljdk/vm/ci/meta/JavaKind;")                                                                                            \
+    long_field(PrimitiveConstant, primitive)                                                                                                                   \
+  end_class                                                                                                                                                    \
+  start_class(RawConstant)                                                                                                                                     \
+    long_field(RawConstant, primitive)                                                                                                                         \
+  end_class                                                                                                                                                    \
+  start_class(NullConstant)                                                                                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotCompressedNullConstant)                                                                                                                   \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotObjectConstantImpl)                                                                                                                       \
+    oop_field(HotSpotObjectConstantImpl, object, "Ljava/lang/Object;")                                                                                         \
+    boolean_field(HotSpotObjectConstantImpl, compressed)                                                                                                       \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotMetaspaceConstantImpl)                                                                                                                    \
+    long_field(HotSpotMetaspaceConstantImpl, primitive)                                                                                                        \
+    oop_field(HotSpotMetaspaceConstantImpl, metaspaceObject, "Ljava/lang/Object;")                                                                             \
+    boolean_field(HotSpotMetaspaceConstantImpl, compressed)                                                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotSentinelConstant)                                                                                                                         \
+  end_class                                                                                                                                                    \
+  start_class(JavaKind)                                                                                                                                        \
+    char_field(JavaKind, typeChar)                                                                                                                             \
+    static_oop_field(JavaKind, Boolean, "Ljdk/vm/ci/meta/JavaKind;");                                                                                          \
+    static_oop_field(JavaKind, Byte, "Ljdk/vm/ci/meta/JavaKind;");                                                                                             \
+    static_oop_field(JavaKind, Char, "Ljdk/vm/ci/meta/JavaKind;");                                                                                             \
+    static_oop_field(JavaKind, Short, "Ljdk/vm/ci/meta/JavaKind;");                                                                                            \
+    static_oop_field(JavaKind, Int, "Ljdk/vm/ci/meta/JavaKind;");                                                                                              \
+    static_oop_field(JavaKind, Long, "Ljdk/vm/ci/meta/JavaKind;");                                                                                             \
+  end_class                                                                                                                                                    \
+  start_class(LIRKind)                                                                                                                                         \
+    oop_field(LIRKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;")                                                                                          \
+    int_field(LIRKind, referenceMask)                                                                                                                          \
+  end_class                                                                                                                                                    \
+  start_class(Value)                                                                                                                                           \
+    oop_field(Value, lirKind, "Ljdk/vm/ci/meta/LIRKind;")                                                                                                      \
+    static_oop_field(Value, ILLEGAL, "Ljdk/vm/ci/meta/AllocatableValue;");                                                                                     \
+  end_class                                                                                                                                                    \
+  start_class(RegisterValue)                                                                                                                                   \
+    oop_field(RegisterValue, reg, "Ljdk/vm/ci/code/Register;")                                                                                                 \
+  end_class                                                                                                                                                    \
+  start_class(code_Location)                                                                                                                                   \
+    oop_field(code_Location, reg, "Ljdk/vm/ci/code/Register;")                                                                                                 \
+    int_field(code_Location, offset)                                                                                                                           \
+  end_class                                                                                                                                                    \
+  start_class(code_Register)                                                                                                                                   \
+    int_field(code_Register, number)                                                                                                                           \
+    int_field(code_Register, encoding)                                                                                                                         \
+  end_class                                                                                                                                                    \
+  start_class(StackSlot)                                                                                                                                       \
+    int_field(StackSlot, offset)                                                                                                                               \
+    boolean_field(StackSlot, addFrameSize)                                                                                                                     \
+  end_class                                                                                                                                                    \
+  start_class(VirtualObject)                                                                                                                                   \
+    int_field(VirtualObject, id)                                                                                                                               \
+    oop_field(VirtualObject, type, "Ljdk/vm/ci/meta/ResolvedJavaType;")                                                                                        \
+    objArrayOop_field(VirtualObject, values, "[Ljdk/vm/ci/meta/JavaValue;")                                                                                    \
+    objArrayOop_field(VirtualObject, slotKinds, "[Ljdk/vm/ci/meta/JavaKind;")                                                                                  \
+  end_class                                                                                                                                                    \
+  start_class(StackLockValue)                                                                                                                                  \
+    oop_field(StackLockValue, owner, "Ljdk/vm/ci/meta/JavaValue;")                                                                                             \
+    oop_field(StackLockValue, slot, "Ljdk/vm/ci/code/StackSlotValue;")                                                                                         \
+    boolean_field(StackLockValue, eliminated)                                                                                                                  \
+  end_class                                                                                                                                                    \
+  start_class(SpeculationLog)                                                                                                                                  \
+    oop_field(SpeculationLog, lastFailed, "Ljava/lang/Object;")                                                                                                \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotStackFrameReference)                                                                                                                      \
+    oop_field(HotSpotStackFrameReference, compilerToVM, "Ljdk/vm/ci/hotspot/CompilerToVM;")                                                                    \
+    long_field(HotSpotStackFrameReference, stackPointer)                                                                                                       \
+    int_field(HotSpotStackFrameReference, frameNumber)                                                                                                         \
+    int_field(HotSpotStackFrameReference, bci)                                                                                                                 \
+    oop_field(HotSpotStackFrameReference, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;")                                                             \
+    objArrayOop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;")                                                                               \
+    typeArrayOop_field(HotSpotStackFrameReference, localIsVirtual, "[Z")                                                                                       \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotMetaData) \
+    typeArrayOop_field(HotSpotMetaData, pcDescBytes, "[B") \
+    typeArrayOop_field(HotSpotMetaData, scopesDescBytes, "[B") \
+    typeArrayOop_field(HotSpotMetaData, relocBytes, "[B") \
+    typeArrayOop_field(HotSpotMetaData, exceptionBytes, "[B") \
+    typeArrayOop_field(HotSpotMetaData, oopMaps, "[B") \
+    objArrayOop_field(HotSpotMetaData, metadata, "[Ljava/lang/String;") \
+  end_class \
+  start_class(HotSpotOopMap) \
+    int_field(HotSpotOopMap, offset) \
+    int_field(HotSpotOopMap, count) \
+    typeArrayOop_field(HotSpotOopMap, data, "[B") \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotConstantPool)                                                                                                                             \
+    long_field(HotSpotConstantPool, metaspaceConstantPool)                                                                                                     \
+  end_class                                                                                                                                                    \
+  /* end*/
+
+
+#define START_CLASS(name)                                                                                                                                      \
+class name : AllStatic {                                                                                                                                       \
+  private:                                                                                                                                                     \
+    friend class JVMCICompiler;                                                                                                                                \
+    static void check(oop obj, const char* field_name, int offset) {                                                                                           \
+        assert(obj != NULL, "NULL field access of %s.%s", #name, field_name);                                                                                  \
+        assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected, found %s", obj->klass()->external_name());                       \
+        assert(offset != 0, "must be valid offset");                                                                                                           \
+    }                                                                                                                                                          \
+    static void compute_offsets();                                                                                                                             \
+  public:                                                                                                                                                      \
+    static InstanceKlass* klass() { return SystemDictionary::name##_klass() == NULL ? NULL : InstanceKlass::cast(SystemDictionary::name##_klass()); }
+
+#define END_CLASS };
+
+#define FIELD(name, type, accessor, cast)                                                                                                                         \
+    static int _##name##_offset;                                                                                                                                  \
+    static type name(oop obj)                   { check(obj, #name, _##name##_offset); return cast obj->accessor(_##name##_offset); }                                               \
+    static type name(Handle& obj)                { check(obj(), #name, _##name##_offset); return cast obj->accessor(_##name##_offset); }                                            \
+    static type name(jobject obj)               { check(JNIHandles::resolve(obj), #name, _##name##_offset); return cast JNIHandles::resolve(obj)->accessor(_##name##_offset); }     \
+    static void set_##name(oop obj, type x)     { check(obj, #name, _##name##_offset); obj->accessor##_put(_##name##_offset, x); }                                                  \
+    static void set_##name(Handle& obj, type x)  { check(obj(), #name, _##name##_offset); obj->accessor##_put(_##name##_offset, x); }                                               \
+    static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj), #name, _##name##_offset); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); }
+
+#define EMPTY_CAST
+#define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field, EMPTY_CAST)
+#define INT_FIELD(klass, name) FIELD(name, jint, int_field, EMPTY_CAST)
+#define BOOLEAN_FIELD(klass, name) FIELD(name, jboolean, bool_field, EMPTY_CAST)
+#define LONG_FIELD(klass, name) FIELD(name, jlong, long_field, EMPTY_CAST)
+#define FLOAT_FIELD(klass, name) FIELD(name, jfloat, float_field, EMPTY_CAST)
+#define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field, EMPTY_CAST)
+#define OBJARRAYOOP_FIELD(klass, name, signature) FIELD(name, objArrayOop, obj_field, (objArrayOop))
+#define TYPEARRAYOOP_FIELD(klass, name, signature) FIELD(name, typeArrayOop, obj_field, (typeArrayOop))
+#define STATIC_OOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, oop, signature)
+#define STATIC_OBJARRAYOOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, objArrayOop, signature)
+#define STATIC_OOPISH_FIELD(klassName, name, type, signature)                                                  \
+    static int _##name##_offset;                                                                               \
+    static type name() {                                                                                       \
+      assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
+      InstanceKlass* ik = klassName::klass();                                                                  \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      if (UseCompressedOops) {                                                                                 \
+        return (type) oopDesc::load_decode_heap_oop((narrowOop *)addr);                                        \
+      } else {                                                                                                 \
+        return (type) oopDesc::load_decode_heap_oop((oop*)addr);                                               \
+      }                                                                                                        \
+    }                                                                                                          \
+    static void set_##name(type x) {                                                                           \
+      assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
+      assert(klassName::klass() != NULL, "Class not yet loaded: " #klassName);                                 \
+      InstanceKlass* ik = klassName::klass();                                                                  \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      if (UseCompressedOops) {                                                                                 \
+        oop_store((narrowOop *)addr, x);                                                                       \
+      } else {                                                                                                 \
+        oop_store((oop*)addr, x);                                                                              \
+      }                                                                                                        \
+    }
+#define STATIC_PRIMITIVE_FIELD(klassName, name, jtypename)                                                     \
+    static int _##name##_offset;                                                                               \
+    static jtypename name() {                                                                                  \
+      assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
+      InstanceKlass* ik = klassName::klass();                                                                  \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      return *((jtypename *)addr);                                                                             \
+    }                                                                                                          \
+    static void set_##name(jtypename x) {                                                                      \
+      assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
+      InstanceKlass* ik = klassName::klass();                                                                  \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      *((jtypename *)addr) = x;                                                                                \
+    }
+
+#define STATIC_INT_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jint)
+#define STATIC_BOOLEAN_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jboolean)
+
+COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_OBJARRAYOOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
+#undef START_CLASS
+#undef END_CLASS
+#undef FIELD
+#undef CHAR_FIELD
+#undef INT_FIELD
+#undef BOOLEAN_FIELD
+#undef LONG_FIELD
+#undef FLOAT_FIELD
+#undef OOP_FIELD
+#undef TYPEARRAYOOP_FIELD
+#undef OBJARRAYOOP_FIELD
+#undef STATIC_OOPISH_FIELD
+#undef STATIC_OOP_FIELD
+#undef STATIC_OBJARRAYOOP_FIELD
+#undef STATIC_INT_FIELD
+#undef STATIC_BOOLEAN_FIELD
+#undef EMPTY_CAST
+
+void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field);
+
+#endif // SHARE_VM_JVMCI_JVMCIJAVACLASSES_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1014 @@
+/*
+ * Copyright (c) 2012, 2015, 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 "asm/codeBuffer.hpp"
+#include "code/codeCache.hpp"
+#include "compiler/compileBroker.hpp"
+#include "compiler/disassembler.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
+#include "prims/jvm.h"
+#include "runtime/biasedLocking.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "runtime/reflection.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/defaultStream.hpp"
+
+#if defined(_MSC_VER)
+#define strtoll _strtoi64
+#endif
+
+jobject JVMCIRuntime::_HotSpotJVMCIRuntime_instance = NULL;
+bool JVMCIRuntime::_HotSpotJVMCIRuntime_initialized = false;
+bool JVMCIRuntime::_well_known_classes_initialized = false;
+const char* JVMCIRuntime::_compiler = NULL;
+int JVMCIRuntime::_options_count = 0;
+SystemProperty** JVMCIRuntime::_options = NULL;
+bool JVMCIRuntime::_shutdown_called = false;
+
+static const char* OPTION_PREFIX = "jvmci.option.";
+static const size_t OPTION_PREFIX_LEN = strlen(OPTION_PREFIX);
+
+BasicType JVMCIRuntime::kindToBasicType(jchar ch) {
+  switch(ch) {
+    case 'z': return T_BOOLEAN;
+    case 'b': return T_BYTE;
+    case 's': return T_SHORT;
+    case 'c': return T_CHAR;
+    case 'i': return T_INT;
+    case 'f': return T_FLOAT;
+    case 'j': return T_LONG;
+    case 'd': return T_DOUBLE;
+    case 'a': return T_OBJECT;
+    case '-': return T_ILLEGAL;
+    default:
+      fatal("unexpected Kind: %c", ch);
+      break;
+  }
+  return T_ILLEGAL;
+}
+
+// Simple helper to see if the caller of a runtime stub which
+// entered the VM has been deoptimized
+
+static bool caller_is_deopted() {
+  JavaThread* thread = JavaThread::current();
+  RegisterMap reg_map(thread, false);
+  frame runtime_frame = thread->last_frame();
+  frame caller_frame = runtime_frame.sender(&reg_map);
+  assert(caller_frame.is_compiled_frame(), "must be compiled");
+  return caller_frame.is_deoptimized_frame();
+}
+
+// Stress deoptimization
+static void deopt_caller() {
+  if ( !caller_is_deopted()) {
+    JavaThread* thread = JavaThread::current();
+    RegisterMap reg_map(thread, false);
+    frame runtime_frame = thread->last_frame();
+    frame caller_frame = runtime_frame.sender(&reg_map);
+    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
+    assert(caller_is_deopted(), "Must be deoptimized");
+  }
+}
+
+JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_instance(JavaThread* thread, Klass* klass))
+  JRT_BLOCK;
+  assert(klass->is_klass(), "not a class");
+  instanceKlassHandle h(thread, klass);
+  h->check_valid_for_instantiation(true, CHECK);
+  // make sure klass is initialized
+  h->initialize(CHECK);
+  // allocate instance and return via TLS
+  oop obj = h->allocate_instance(CHECK);
+  thread->set_vm_result(obj);
+  JRT_BLOCK_END;
+
+  if (ReduceInitialCardMarks) {
+    new_store_pre_barrier(thread);
+  }
+JRT_END
+
+JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length))
+  JRT_BLOCK;
+  // Note: no handle for klass needed since they are not used
+  //       anymore after new_objArray() and no GC can happen before.
+  //       (This may have to change if this code changes!)
+  assert(array_klass->is_klass(), "not a class");
+  oop obj;
+  if (array_klass->oop_is_typeArray()) {
+    BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type();
+    obj = oopFactory::new_typeArray(elt_type, length, CHECK);
+  } else {
+    Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
+    obj = oopFactory::new_objArray(elem_klass, length, CHECK);
+  }
+  thread->set_vm_result(obj);
+  // This is pretty rare but this runtime patch is stressful to deoptimization
+  // if we deoptimize here so force a deopt to stress the path.
+  if (DeoptimizeALot) {
+    static int deopts = 0;
+    // Alternate between deoptimizing and raising an error (which will also cause a deopt)
+    if (deopts++ % 2 == 0) {
+      ResourceMark rm(THREAD);
+      THROW(vmSymbols::java_lang_OutOfMemoryError());
+    } else {
+      deopt_caller();
+    }
+  }
+  JRT_BLOCK_END;
+
+  if (ReduceInitialCardMarks) {
+    new_store_pre_barrier(thread);
+  }
+JRT_END
+
+void JVMCIRuntime::new_store_pre_barrier(JavaThread* thread) {
+  // After any safepoint, just before going back to compiled code,
+  // we inform the GC that we will be doing initializing writes to
+  // this object in the future without emitting card-marks, so
+  // GC may take any compensating steps.
+  // NOTE: Keep this code consistent with GraphKit::store_barrier.
+
+  oop new_obj = thread->vm_result();
+  if (new_obj == NULL)  return;
+
+  assert(Universe::heap()->can_elide_tlab_store_barriers(),
+         "compiler must check this first");
+  // GC may decide to give back a safer copy of new_obj.
+  new_obj = Universe::heap()->new_store_pre_barrier(thread, new_obj);
+  thread->set_vm_result(new_obj);
+}
+
+JRT_ENTRY(void, JVMCIRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
+  assert(klass->is_klass(), "not a class");
+  assert(rank >= 1, "rank must be nonzero");
+  oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, JVMCIRuntime::dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length))
+  oop obj = Reflection::reflect_new_array(element_mirror, length, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, JVMCIRuntime::dynamic_new_instance(JavaThread* thread, oopDesc* type_mirror))
+  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(type_mirror));
+
+  if (klass == NULL) {
+    ResourceMark rm(THREAD);
+    THROW(vmSymbols::java_lang_InstantiationException());
+  }
+
+  // Create new instance (the receiver)
+  klass->check_valid_for_instantiation(false, CHECK);
+
+  // Make sure klass gets initialized
+  klass->initialize(CHECK);
+
+  oop obj = klass->allocate_instance(CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+extern void vm_exit(int code);
+
+// Enter this method from compiled code handler below. This is where we transition
+// to VM mode. This is done as a helper routine so that the method called directly
+// from compiled code does not have to transition to VM. This allows the entry
+// method to see if the nmethod that we have just looked up a handler for has
+// been deoptimized while we were in the vm. This simplifies the assembly code
+// cpu directories.
+//
+// We are entering here from exception stub (via the entry method below)
+// If there is a compiled exception handler in this method, we will continue there;
+// otherwise we will unwind the stack and continue at the caller of top frame method
+// Note: we enter in Java using a special JRT wrapper. This wrapper allows us to
+// control the area where we can allow a safepoint. After we exit the safepoint area we can
+// check to see if the handler we are going to return is now in a nmethod that has
+// been deoptimized. If that is the case we return the deopt blob
+// unpack_with_exception entry instead. This makes life for the exception blob easier
+// because making that same check and diverting is painful from assembly language.
+JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
+  // Reset method handle flag.
+  thread->set_is_method_handle_return(false);
+
+  Handle exception(thread, ex);
+  nm = CodeCache::find_nmethod(pc);
+  assert(nm != NULL, "this is not a compiled method");
+  // Adjust the pc as needed/
+  if (nm->is_deopt_pc(pc)) {
+    RegisterMap map(thread, false);
+    frame exception_frame = thread->last_frame().sender(&map);
+    // if the frame isn't deopted then pc must not correspond to the caller of last_frame
+    assert(exception_frame.is_deoptimized_frame(), "must be deopted");
+    pc = exception_frame.pc();
+  }
+#ifdef ASSERT
+  assert(exception.not_null(), "NULL exceptions should be handled by throw_exception");
+  assert(exception->is_oop(), "just checking");
+  // Check that exception is a subclass of Throwable, otherwise we have a VerifyError
+  if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
+    if (ExitVMOnVerifyError) vm_exit(-1);
+    ShouldNotReachHere();
+  }
+#endif
+
+  // Check the stack guard pages and reenable them if necessary and there is
+  // enough space on the stack to do so.  Use fast exceptions only if the guard
+  // pages are enabled.
+  bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
+  if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
+
+  if (JvmtiExport::can_post_on_exceptions()) {
+    // To ensure correct notification of exception catches and throws
+    // we have to deoptimize here.  If we attempted to notify the
+    // catches and throws during this exception lookup it's possible
+    // we could deoptimize on the way out of the VM and end back in
+    // the interpreter at the throw site.  This would result in double
+    // notifications since the interpreter would also notify about
+    // these same catches and throws as it unwound the frame.
+
+    RegisterMap reg_map(thread);
+    frame stub_frame = thread->last_frame();
+    frame caller_frame = stub_frame.sender(&reg_map);
+
+    // We don't really want to deoptimize the nmethod itself since we
+    // can actually continue in the exception handler ourselves but I
+    // don't see an easy way to have the desired effect.
+    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
+    assert(caller_is_deopted(), "Must be deoptimized");
+
+    return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+  }
+
+  // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
+  if (guard_pages_enabled) {
+    address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
+    if (fast_continuation != NULL) {
+      // Set flag if return address is a method handle call site.
+      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+      return fast_continuation;
+    }
+  }
+
+  // If the stack guard pages are enabled, check whether there is a handler in
+  // the current method.  Otherwise (guard pages disabled), force an unwind and
+  // skip the exception cache update (i.e., just leave continuation==NULL).
+  address continuation = NULL;
+  if (guard_pages_enabled) {
+
+    // New exception handling mechanism can support inlined methods
+    // with exception handlers since the mappings are from PC to PC
+
+    // debugging support
+    // tracing
+    if (TraceExceptions) {
+      ttyLocker ttyl;
+      ResourceMark rm;
+      tty->print_cr("Exception <%s> (" INTPTR_FORMAT ") thrown in compiled method <%s> at PC " INTPTR_FORMAT " for thread " INTPTR_FORMAT "",
+                    exception->print_value_string(), p2i((address)exception()), nm->method()->print_value_string(), p2i(pc), p2i(thread));
+    }
+    // for AbortVMOnException flag
+    NOT_PRODUCT(Exceptions::debug_check_abort(exception));
+
+    // Clear out the exception oop and pc since looking up an
+    // exception handler can cause class loading, which might throw an
+    // exception and those fields are expected to be clear during
+    // normal bytecode execution.
+    thread->clear_exception_oop_and_pc();
+
+    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
+    // If an exception was thrown during exception dispatch, the exception oop may have changed
+    thread->set_exception_oop(exception());
+    thread->set_exception_pc(pc);
+
+    // the exception cache is used only by non-implicit exceptions
+    if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
+      nm->add_handler_for_exception_and_pc(exception, pc, continuation);
+    }
+  }
+
+  // Set flag if return address is a method handle call site.
+  thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+
+  if (TraceExceptions) {
+    ttyLocker ttyl;
+    ResourceMark rm;
+    tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT,
+                  p2i(thread), p2i(continuation), p2i(pc));
+  }
+
+  return continuation;
+JRT_END
+
+// Enter this method from compiled code only if there is a Java exception handler
+// in the method handling the exception.
+// We are entering here from exception stub. We don't do a normal VM transition here.
+// We do it in a helper. This is so we can check to see if the nmethod we have just
+// searched for an exception handler has been deoptimized in the meantime.
+address JVMCIRuntime::exception_handler_for_pc(JavaThread* thread) {
+  oop exception = thread->exception_oop();
+  address pc = thread->exception_pc();
+  // Still in Java mode
+  DEBUG_ONLY(ResetNoHandleMark rnhm);
+  nmethod* nm = NULL;
+  address continuation = NULL;
+  {
+    // Enter VM mode by calling the helper
+    ResetNoHandleMark rnhm;
+    continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
+  }
+  // Back in JAVA, use no oops DON'T safepoint
+
+  // Now check to see if the compiled method we were called from is now deoptimized.
+  // If so we must return to the deopt blob and deoptimize the nmethod
+  if (nm != NULL && caller_is_deopted()) {
+    continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+  }
+
+  assert(continuation != NULL, "no handler found");
+  return continuation;
+}
+
+JRT_ENTRY(void, JVMCIRuntime::create_null_exception(JavaThread* thread))
+  SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException());
+  thread->set_vm_result(PENDING_EXCEPTION);
+  CLEAR_PENDING_EXCEPTION;
+JRT_END
+
+JRT_ENTRY(void, JVMCIRuntime::create_out_of_bounds_exception(JavaThread* thread, jint index))
+  char message[jintAsStringSize];
+  sprintf(message, "%d", index);
+  SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message);
+  thread->set_vm_result(PENDING_EXCEPTION);
+  CLEAR_PENDING_EXCEPTION;
+JRT_END
+
+JRT_ENTRY_NO_ASYNC(void, JVMCIRuntime::monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  IF_TRACE_jvmci_3 {
+    char type[O_BUFLEN];
+    obj->klass()->name()->as_C_string(type, O_BUFLEN);
+    markOop mark = obj->mark();
+    TRACE_jvmci_3("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, p2i(mark), p2i(lock));
+    tty->flush();
+  }
+#ifdef ASSERT
+  if (PrintBiasedLockingStatistics) {
+    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
+  }
+#endif
+  Handle h_obj(thread, obj);
+  assert(h_obj()->is_oop(), "must be NULL or an object");
+  if (UseBiasedLocking) {
+    // Retry fast entry if bias is revoked to avoid unnecessary inflation
+    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
+  } else {
+    if (JVMCIUseFastLocking) {
+      // When using fast locking, the compiled code has already tried the fast case
+      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
+    } else {
+      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
+    }
+  }
+  TRACE_jvmci_3("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), p2i(obj));
+JRT_END
+
+JRT_LEAF(void, JVMCIRuntime::monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  assert(thread == JavaThread::current(), "threads must correspond");
+  assert(thread->last_Java_sp(), "last_Java_sp must be set");
+  // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown
+  EXCEPTION_MARK;
+
+#ifdef DEBUG
+  if (!obj->is_oop()) {
+    ResetNoHandleMark rhm;
+    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
+    if (method != NULL) {
+      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), p2i(obj));
+    }
+    thread->print_stack_on(tty);
+    assert(false, "invalid lock object pointer dected");
+  }
+#endif
+
+  if (JVMCIUseFastLocking) {
+    // When using fast locking, the compiled code has already tried the fast case
+    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
+  } else {
+    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
+  }
+  IF_TRACE_jvmci_3 {
+    char type[O_BUFLEN];
+    obj->klass()->name()->as_C_string(type, O_BUFLEN);
+    TRACE_jvmci_3("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, p2i(obj->mark()), p2i(lock));
+    tty->flush();
+  }
+JRT_END
+
+JRT_LEAF(void, JVMCIRuntime::log_object(JavaThread* thread, oopDesc* obj, jint flags))
+  bool string =  mask_bits_are_true(flags, LOG_OBJECT_STRING);
+  bool addr = mask_bits_are_true(flags, LOG_OBJECT_ADDRESS);
+  bool newline = mask_bits_are_true(flags, LOG_OBJECT_NEWLINE);
+  if (!string) {
+    if (!addr && obj->is_oop_or_null(true)) {
+      char buf[O_BUFLEN];
+      tty->print("%s@" INTPTR_FORMAT, obj->klass()->name()->as_C_string(buf, O_BUFLEN), p2i(obj));
+    } else {
+      tty->print(INTPTR_FORMAT, p2i(obj));
+    }
+  } else {
+    ResourceMark rm;
+    assert(obj != NULL && java_lang_String::is_instance(obj), "must be");
+    char *buf = java_lang_String::as_utf8_string(obj);
+    tty->print_raw(buf);
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+JRT_LEAF(void, JVMCIRuntime::write_barrier_pre(JavaThread* thread, oopDesc* obj))
+  thread->satb_mark_queue().enqueue(obj);
+JRT_END
+
+JRT_LEAF(void, JVMCIRuntime::write_barrier_post(JavaThread* thread, void* card_addr))
+  thread->dirty_card_queue().enqueue(card_addr);
+JRT_END
+
+JRT_LEAF(jboolean, JVMCIRuntime::validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child))
+  bool ret = true;
+  if(!Universe::heap()->is_in_closed_subset(parent)) {
+    tty->print_cr("Parent Object " INTPTR_FORMAT " not in heap", p2i(parent));
+    parent->print();
+    ret=false;
+  }
+  if(!Universe::heap()->is_in_closed_subset(child)) {
+    tty->print_cr("Child Object " INTPTR_FORMAT " not in heap", p2i(child));
+    child->print();
+    ret=false;
+  }
+  return (jint)ret;
+JRT_END
+
+JRT_ENTRY(void, JVMCIRuntime::vm_error(JavaThread* thread, jlong where, jlong format, jlong value))
+  ResourceMark rm;
+  const char *error_msg = where == 0L ? "<internal JVMCI error>" : (char*) (address) where;
+  char *detail_msg = NULL;
+  if (format != 0L) {
+    const char* buf = (char*) (address) format;
+    size_t detail_msg_length = strlen(buf) * 2;
+    detail_msg = (char *) NEW_RESOURCE_ARRAY(u_char, detail_msg_length);
+    jio_snprintf(detail_msg, detail_msg_length, buf, value);
+    report_vm_error(__FILE__, __LINE__, error_msg, "%s", detail_msg);
+  } else {
+    report_vm_error(__FILE__, __LINE__, error_msg);
+  }
+JRT_END
+
+JRT_LEAF(oopDesc*, JVMCIRuntime::load_and_clear_exception(JavaThread* thread))
+  oop exception = thread->exception_oop();
+  assert(exception != NULL, "npe");
+  thread->set_exception_oop(NULL);
+  thread->set_exception_pc(0);
+  return exception;
+JRT_END
+
+PRAGMA_DIAG_PUSH
+PRAGMA_FORMAT_NONLITERAL_IGNORED
+JRT_LEAF(void, JVMCIRuntime::log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3))
+  ResourceMark rm;
+  assert(format != NULL && java_lang_String::is_instance(format), "must be");
+  char *buf = java_lang_String::as_utf8_string(format);
+  tty->print((const char*)buf, v1, v2, v3);
+JRT_END
+PRAGMA_DIAG_POP
+
+static void decipher(jlong v, bool ignoreZero) {
+  if (v != 0 || !ignoreZero) {
+    void* p = (void *)(address) v;
+    CodeBlob* cb = CodeCache::find_blob(p);
+    if (cb) {
+      if (cb->is_nmethod()) {
+        char buf[O_BUFLEN];
+        tty->print("%s [" INTPTR_FORMAT "+" JLONG_FORMAT "]", cb->as_nmethod_or_null()->method()->name_and_sig_as_C_string(buf, O_BUFLEN), p2i(cb->code_begin()), (jlong)((address)v - cb->code_begin()));
+        return;
+      }
+      cb->print_value_on(tty);
+      return;
+    }
+    if (Universe::heap()->is_in(p)) {
+      oop obj = oop(p);
+      obj->print_value_on(tty);
+      return;
+    }
+    tty->print(INTPTR_FORMAT " [long: " JLONG_FORMAT ", double %lf, char %c]",p2i((void *)v), (jlong)v, (jdouble)v, (char)v);
+  }
+}
+
+PRAGMA_DIAG_PUSH
+PRAGMA_FORMAT_NONLITERAL_IGNORED
+JRT_LEAF(void, JVMCIRuntime::vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3))
+  ResourceMark rm;
+  const char *buf = (const char*) (address) format;
+  if (vmError) {
+    if (buf != NULL) {
+      fatal(buf, v1, v2, v3);
+    } else {
+      fatal("<anonymous error>");
+    }
+  } else if (buf != NULL) {
+    tty->print(buf, v1, v2, v3);
+  } else {
+    assert(v2 == 0, "v2 != 0");
+    assert(v3 == 0, "v3 != 0");
+    decipher(v1, false);
+  }
+JRT_END
+PRAGMA_DIAG_POP
+
+JRT_LEAF(void, JVMCIRuntime::log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline))
+  union {
+      jlong l;
+      jdouble d;
+      jfloat f;
+  } uu;
+  uu.l = value;
+  switch (typeChar) {
+    case 'z': tty->print(value == 0 ? "false" : "true"); break;
+    case 'b': tty->print("%d", (jbyte) value); break;
+    case 'c': tty->print("%c", (jchar) value); break;
+    case 's': tty->print("%d", (jshort) value); break;
+    case 'i': tty->print("%d", (jint) value); break;
+    case 'f': tty->print("%f", uu.f); break;
+    case 'j': tty->print(JLONG_FORMAT, value); break;
+    case 'd': tty->print("%lf", uu.d); break;
+    default: assert(false, "unknown typeChar"); break;
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+JRT_ENTRY(jint, JVMCIRuntime::identity_hash_code(JavaThread* thread, oopDesc* obj))
+  return (jint) obj->identity_hash();
+JRT_END
+
+JRT_ENTRY(jboolean, JVMCIRuntime::thread_is_interrupted(JavaThread* thread, oopDesc* receiver, jboolean clear_interrupted))
+  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate.
+  // This locking requires thread_in_vm which is why this method cannot be JRT_LEAF.
+  Handle receiverHandle(thread, receiver);
+  MutexLockerEx ml(thread->threadObj() == (void*)receiver ? NULL : Threads_lock);
+  JavaThread* receiverThread = java_lang_Thread::thread(receiverHandle());
+  if (receiverThread == NULL) {
+    // The other thread may exit during this process, which is ok so return false.
+    return JNI_FALSE;
+  } else {
+    return (jint) Thread::is_interrupted(receiverThread, clear_interrupted != 0);
+  }
+JRT_END
+
+JRT_ENTRY(jint, JVMCIRuntime::test_deoptimize_call_int(JavaThread* thread, int value))
+  deopt_caller();
+  return value;
+JRT_END
+
+// private static JVMCIRuntime JVMCI.initializeRuntime()
+JVM_ENTRY(jobject, JVM_GetJVMCIRuntime(JNIEnv *env, jclass c))
+  if (!EnableJVMCI) {
+    THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
+  }
+  JVMCIRuntime::initialize_HotSpotJVMCIRuntime(CHECK_NULL);
+  jobject ret = JVMCIRuntime::get_HotSpotJVMCIRuntime_jobject(CHECK_NULL);
+  return ret;
+JVM_END
+
+Handle JVMCIRuntime::callStatic(const char* className, const char* methodName, const char* signature, JavaCallArguments* args, TRAPS) {
+  guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime");
+
+  TempNewSymbol name = SymbolTable::new_symbol(className, CHECK_(Handle()));
+  KlassHandle klass = SystemDictionary::resolve_or_fail(name, true, CHECK_(Handle()));
+  TempNewSymbol runtime = SymbolTable::new_symbol(methodName, CHECK_(Handle()));
+  TempNewSymbol sig = SymbolTable::new_symbol(signature, CHECK_(Handle()));
+  JavaValue result(T_OBJECT);
+  if (args == NULL) {
+    JavaCalls::call_static(&result, klass, runtime, sig, CHECK_(Handle()));
+  } else {
+    JavaCalls::call_static(&result, klass, runtime, sig, args, CHECK_(Handle()));
+  }
+  return Handle((oop)result.get_jobject());
+}
+
+static bool jvmci_options_file_exists() {
+  const char* home = Arguments::get_java_home();
+  size_t path_len = strlen(home) + strlen("/lib/jvmci/options") + 1;
+  char path[JVM_MAXPATHLEN];
+  char sep = os::file_separator()[0];
+  jio_snprintf(path, JVM_MAXPATHLEN, "%s%clib%cjvmci%coptions", home, sep, sep, sep);
+  struct stat st;
+  return os::stat(path, &st) == 0;
+}
+
+void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
+  if (JNIHandles::resolve(_HotSpotJVMCIRuntime_instance) == NULL) {
+#ifdef ASSERT
+    // This should only be called in the context of the JVMCI class being initialized
+    TempNewSymbol name = SymbolTable::new_symbol("jdk/vm/ci/runtime/JVMCI", CHECK);
+    Klass* k = SystemDictionary::resolve_or_null(name, CHECK);
+    instanceKlassHandle klass = InstanceKlass::cast(k);
+    assert(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD),
+           "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization");
+#endif
+
+    bool parseOptionsFile = jvmci_options_file_exists();
+    if (_options != NULL || parseOptionsFile) {
+      JavaCallArguments args;
+      objArrayOop options;
+      if (_options != NULL) {
+        options = oopFactory::new_objArray(SystemDictionary::String_klass(), _options_count * 2, CHECK);
+        for (int i = 0; i < _options_count; i++) {
+          SystemProperty* prop = _options[i];
+          oop name = java_lang_String::create_oop_from_str(prop->key() + OPTION_PREFIX_LEN, CHECK);
+          oop value = java_lang_String::create_oop_from_str(prop->value(), CHECK);
+          options->obj_at_put(i * 2, name);
+          options->obj_at_put((i * 2) + 1, value);
+        }
+      } else {
+        options = NULL;
+      }
+      args.push_oop(options);
+      args.push_int(parseOptionsFile);
+      callStatic("jdk/vm/ci/options/OptionsParser",
+                 "parseOptionsFromVM",
+                 "([Ljava/lang/String;Z)Ljava/lang/Boolean;", &args, CHECK);
+    }
+
+    if (_compiler != NULL) {
+      JavaCallArguments args;
+      oop compiler = java_lang_String::create_oop_from_str(_compiler, CHECK);
+      args.push_oop(compiler);
+      callStatic("jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig",
+                 "selectCompiler",
+                 "(Ljava/lang/String;)Ljava/lang/Boolean;", &args, CHECK);
+    }
+
+    Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime",
+                               "runtime",
+                               "()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK);
+    _HotSpotJVMCIRuntime_initialized = true;
+    _HotSpotJVMCIRuntime_instance = JNIHandles::make_global(result());
+  }
+}
+
+void JVMCIRuntime::initialize_JVMCI(TRAPS) {
+  if (JNIHandles::resolve(_HotSpotJVMCIRuntime_instance) == NULL) {
+    callStatic("jdk/vm/ci/runtime/JVMCI",
+               "getRuntime",
+               "()Ljdk/vm/ci/runtime/JVMCIRuntime;", NULL, CHECK);
+  }
+  assert(_HotSpotJVMCIRuntime_initialized == true, "what?");
+}
+
+void JVMCIRuntime::initialize_well_known_classes(TRAPS) {
+  if (JVMCIRuntime::_well_known_classes_initialized == false) {
+    SystemDictionary::WKID scan = SystemDictionary::FIRST_JVMCI_WKID;
+    SystemDictionary::initialize_wk_klasses_through(SystemDictionary::LAST_JVMCI_WKID, scan, CHECK);
+    JVMCIJavaClasses::compute_offsets();
+    JVMCIRuntime::_well_known_classes_initialized = true;
+  }
+}
+
+void JVMCIRuntime::metadata_do(void f(Metadata*)) {
+  // For simplicity, the existence of HotSpotJVMCIMetaAccessContext in
+  // the SystemDictionary well known classes should ensure the other
+  // classes have already been loaded, so make sure their order in the
+  // table enforces that.
+  assert(SystemDictionary::WK_KLASS_ENUM_NAME(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl) <
+         SystemDictionary::WK_KLASS_ENUM_NAME(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext), "must be loaded earlier");
+  assert(SystemDictionary::WK_KLASS_ENUM_NAME(jdk_vm_ci_hotspot_HotSpotConstantPool) <
+         SystemDictionary::WK_KLASS_ENUM_NAME(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext), "must be loaded earlier");
+  assert(SystemDictionary::WK_KLASS_ENUM_NAME(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl) <
+         SystemDictionary::WK_KLASS_ENUM_NAME(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext), "must be loaded earlier");
+
+  if (HotSpotJVMCIMetaAccessContext::klass() == NULL ||
+      !HotSpotJVMCIMetaAccessContext::klass()->is_linked()) {
+    // Nothing could be registered yet
+    return;
+  }
+
+  // WeakReference<HotSpotJVMCIMetaAccessContext>[]
+  objArrayOop allContexts = HotSpotJVMCIMetaAccessContext::allContexts();
+  if (allContexts == NULL) {
+    return;
+  }
+
+  // These must be loaded at this point but the linking state doesn't matter.
+  assert(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass() != NULL, "must be loaded");
+  assert(SystemDictionary::HotSpotConstantPool_klass() != NULL, "must be loaded");
+  assert(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass() != NULL, "must be loaded");
+
+  for (int i = 0; i < allContexts->length(); i++) {
+    oop ref = allContexts->obj_at(i);
+    if (ref != NULL) {
+      oop referent = java_lang_ref_Reference::referent(ref);
+      if (referent != NULL) {
+        // Chunked Object[] with last element pointing to next chunk
+        objArrayOop metadataRoots = HotSpotJVMCIMetaAccessContext::metadataRoots(referent);
+        while (metadataRoots != NULL) {
+          for (int typeIndex = 0; typeIndex < metadataRoots->length() - 1; typeIndex++) {
+            oop reference = metadataRoots->obj_at(typeIndex);
+            if (reference == NULL) {
+              continue;
+            }
+            oop metadataRoot = java_lang_ref_Reference::referent(reference);
+            if (metadataRoot == NULL) {
+              continue;
+            }
+            if (metadataRoot->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
+              Method* method = CompilerToVM::asMethod(metadataRoot);
+              f(method);
+            } else if (metadataRoot->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
+              ConstantPool* constantPool = CompilerToVM::asConstantPool(metadataRoot);
+              f(constantPool);
+            } else if (metadataRoot->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
+              Klass* klass = CompilerToVM::asKlass(metadataRoot);
+              f(klass);
+            } else {
+              metadataRoot->print();
+              ShouldNotReachHere();
+            }
+          }
+          metadataRoots = (objArrayOop)metadataRoots->obj_at(metadataRoots->length() - 1);
+          assert(metadataRoots == NULL || metadataRoots->is_objArray(), "wrong type");
+        }
+      }
+    }
+  }
+}
+
+// private static void CompilerToVM.registerNatives()
+JVM_ENTRY(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass))
+  if (!EnableJVMCI) {
+    THROW_MSG(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled");
+  }
+
+#ifdef _LP64
+#ifndef TARGET_ARCH_sparc
+  uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
+  uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
+  guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)");
+#endif // TARGET_ARCH_sparc
+#else
+  fatal("check TLAB allocation code for address space conflicts");
+#endif
+
+  JVMCIRuntime::initialize_well_known_classes(CHECK);
+
+  {
+    ThreadToNativeFromVM trans(thread);
+
+    // Ensure _non_oop_bits is initialized
+    Universe::non_oop_word();
+
+    env->RegisterNatives(c2vmClass, CompilerToVM::methods, CompilerToVM::methods_count());
+  }
+JVM_END
+
+/**
+ * Closure for parsing a line from a *.properties file in jre/lib/jvmci/properties.
+ * The line must match the regular expression "[^=]+=.*". That is one or more
+ * characters other than '=' followed by '=' followed by zero or more characters.
+ * Everything before the '=' is the property name and everything after '=' is the value.
+ * Lines that start with '#' are treated as comments and ignored.
+ * No special processing of whitespace or any escape characters is performed.
+ * The last definition of a property "wins" (i.e., it overrides all earlier
+ * definitions of the property).
+ */
+class JVMCIPropertiesFileClosure : public ParseClosure {
+  SystemProperty** _plist;
+public:
+  JVMCIPropertiesFileClosure(SystemProperty** plist) : _plist(plist) {}
+  void do_line(char* line) {
+    if (line[0] == '#') {
+      // skip comment
+      return;
+    }
+    size_t len = strlen(line);
+    char* sep = strchr(line, '=');
+    if (sep == NULL) {
+      warn_and_abort("invalid format: could not find '=' character");
+      return;
+    }
+    if (sep == line) {
+      warn_and_abort("invalid format: name cannot be empty");
+      return;
+    }
+    *sep = '\0';
+    const char* name = line;
+    char* value = sep + 1;
+    Arguments::PropertyList_unique_add(_plist, name, value);
+  }
+};
+
+void JVMCIRuntime::init_system_properties(SystemProperty** plist) {
+  char jvmciDir[JVM_MAXPATHLEN];
+  const char* fileSep = os::file_separator();
+  jio_snprintf(jvmciDir, sizeof(jvmciDir), "%s%slib%sjvmci",
+               Arguments::get_java_home(), fileSep, fileSep, fileSep);
+  DIR* dir = os::opendir(jvmciDir);
+  if (dir != NULL) {
+    struct dirent *entry;
+    char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(jvmciDir), mtInternal);
+    JVMCIPropertiesFileClosure closure(plist);
+    const unsigned suffix_len = (unsigned)strlen(".properties");
+    while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL && !closure.is_aborted()) {
+      const char* name = entry->d_name;
+      if (strlen(name) > suffix_len && strcmp(name + strlen(name) - suffix_len, ".properties") == 0) {
+        char propertiesFilePath[JVM_MAXPATHLEN];
+        jio_snprintf(propertiesFilePath, sizeof(propertiesFilePath), "%s%s%s",jvmciDir, fileSep, name);
+        JVMCIRuntime::parse_lines(propertiesFilePath, &closure, false);
+      }
+    }
+    FREE_C_HEAP_ARRAY(char, dbuf);
+    os::closedir(dir);
+  }
+}
+
+#define CHECK_WARN_ABORT_(message) THREAD); \
+  if (HAS_PENDING_EXCEPTION) { \
+    warning(message); \
+    char buf[512]; \
+    jio_snprintf(buf, 512, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
+    JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
+    return; \
+  } \
+  (void)(0
+
+void JVMCIRuntime::save_compiler(const char* compiler) {
+  assert(compiler != NULL, "npe");
+  assert(_compiler == NULL, "cannot reassign JVMCI compiler");
+  _compiler = compiler;
+}
+
+jint JVMCIRuntime::save_options(SystemProperty* props) {
+  int count = 0;
+  SystemProperty* first = NULL;
+  for (SystemProperty* p = props; p != NULL; p = p->next()) {
+    if (strncmp(p->key(), OPTION_PREFIX, OPTION_PREFIX_LEN) == 0) {
+      if (p->value() == NULL || strlen(p->value()) == 0) {
+        jio_fprintf(defaultStream::output_stream(), "JVMCI option %s must have non-zero length value\n", p->key());
+        return JNI_ERR;
+      }
+      if (first == NULL) {
+        first = p;
+      }
+      count++;
+    }
+  }
+  if (count != 0) {
+    _options_count = count;
+    _options = NEW_C_HEAP_ARRAY(SystemProperty*, count, mtCompiler);
+    _options[0] = first;
+    SystemProperty** insert_pos = _options + 1;
+    for (SystemProperty* p = first->next(); p != NULL; p = p->next()) {
+      if (strncmp(p->key(), OPTION_PREFIX, OPTION_PREFIX_LEN) == 0) {
+        *insert_pos = p;
+        insert_pos++;
+      }
+    }
+    assert (insert_pos - _options == count, "must be");
+  }
+  return JNI_OK;
+}
+
+void JVMCIRuntime::shutdown() {
+  if (_HotSpotJVMCIRuntime_instance != NULL) {
+    _shutdown_called = true;
+    JavaThread* THREAD = JavaThread::current();
+    HandleMark hm(THREAD);
+    Handle receiver = get_HotSpotJVMCIRuntime(CHECK_ABORT);
+    JavaValue result(T_VOID);
+    JavaCallArguments args;
+    args.push_oop(receiver);
+    JavaCalls::call_special(&result, receiver->klass(), vmSymbols::shutdown_method_name(), vmSymbols::void_method_signature(), &args, CHECK_ABORT);
+  }
+}
+
+void JVMCIRuntime::call_printStackTrace(Handle exception, Thread* thread) {
+  assert(exception->is_a(SystemDictionary::Throwable_klass()), "Throwable instance expected");
+  JavaValue result(T_VOID);
+  JavaCalls::call_virtual(&result,
+                          exception,
+                          KlassHandle(thread,
+                          SystemDictionary::Throwable_klass()),
+                          vmSymbols::printStackTrace_name(),
+                          vmSymbols::void_method_signature(),
+                          thread);
+}
+
+void JVMCIRuntime::abort_on_pending_exception(Handle exception, const char* message, bool dump_core) {
+  Thread* THREAD = Thread::current();
+  CLEAR_PENDING_EXCEPTION;
+  tty->print_raw_cr(message);
+  call_printStackTrace(exception, THREAD);
+
+  // Give other aborting threads to also print their stack traces.
+  // This can be very useful when debugging class initialization
+  // failures.
+  os::sleep(THREAD, 200, false);
+
+  vm_abort(dump_core);
+}
+
+void JVMCIRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure) {
+  struct stat st;
+  if (os::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file
+    int file_handle = os::open(path, 0, 0);
+    if (file_handle != -1) {
+      char* buffer = NEW_C_HEAP_ARRAY(char, st.st_size + 1, mtInternal);
+      int num_read;
+      num_read = (int) os::read(file_handle, (char*) buffer, st.st_size);
+      if (num_read == -1) {
+        warning("Error reading file %s due to %s", path, strerror(errno));
+      } else if (num_read != st.st_size) {
+        warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path);
+      }
+      os::close(file_handle);
+      closure->set_filename(path);
+      if (num_read == st.st_size) {
+        buffer[num_read] = '\0';
+
+        char* line = buffer;
+        while (line - buffer < num_read && !closure->is_aborted()) {
+          // find line end (\r, \n or \r\n)
+          char* nextline = NULL;
+          char* cr = strchr(line, '\r');
+          char* lf = strchr(line, '\n');
+          if (cr != NULL && lf != NULL) {
+            char* min = MIN2(cr, lf);
+            *min = '\0';
+            if (lf == cr + 1) {
+              nextline = lf + 1;
+            } else {
+              nextline = min + 1;
+            }
+          } else if (cr != NULL) {
+            *cr = '\0';
+            nextline = cr + 1;
+          } else if (lf != NULL) {
+            *lf = '\0';
+            nextline = lf + 1;
+          }
+          // trim left
+          while (*line == ' ' || *line == '\t') line++;
+          char* end = line + strlen(line);
+          // trim right
+          while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--;
+          *end = '\0';
+          // skip comments and empty lines
+          if (*line != '#' && strlen(line) > 0) {
+            closure->parse_line(line);
+          }
+          if (nextline != NULL) {
+            line = nextline;
+          } else {
+            // File without newline at the end
+            break;
+          }
+        }
+      }
+      FREE_C_HEAP_ARRAY(char, buffer);
+    } else {
+      warning("Error opening file %s due to %s", path, strerror(errno));
+    }
+  } else if (warnStatFailure) {
+    warning("Could not stat file %s due to %s", path, strerror(errno));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2012, 2015, 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_JVMCI_JVMCI_RUNTIME_HPP
+#define SHARE_VM_JVMCI_JVMCI_RUNTIME_HPP
+
+#include "interpreter/interpreter.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/deoptimization.hpp"
+
+class ParseClosure : public StackObj {
+  int _lineNo;
+  char* _filename;
+  bool _abort;
+protected:
+  void abort() { _abort = true; }
+  void warn_and_abort(const char* message) {
+    warn(message);
+    abort();
+  }
+  void warn(const char* message) {
+    warning("Error at line %d while parsing %s: %s", _lineNo, _filename == NULL ? "?" : _filename, message);
+  }
+ public:
+  ParseClosure() : _lineNo(0), _filename(NULL), _abort(false) {}
+  void parse_line(char* line) {
+    _lineNo++;
+    do_line(line);
+  }
+  virtual void do_line(char* line) = 0;
+  int lineNo() { return _lineNo; }
+  bool is_aborted() { return _abort; }
+  void set_filename(char* path) {_filename = path; _lineNo = 0;}
+};
+
+#define CHECK_ABORT THREAD); \
+  if (HAS_PENDING_EXCEPTION) { \
+    char buf[256]; \
+    jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
+    JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
+    return; \
+  } \
+  (void)(0
+
+#define CHECK_ABORT_(result) THREAD); \
+  if (HAS_PENDING_EXCEPTION) { \
+    char buf[256]; \
+    jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
+    JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
+    return result; \
+  } \
+  (void)(0
+
+class JVMCIRuntime: public AllStatic {
+ private:
+  static jobject _HotSpotJVMCIRuntime_instance;
+  static bool _HotSpotJVMCIRuntime_initialized;
+  static bool _well_known_classes_initialized;
+  static const char* _compiler;
+  static int _options_count;
+  static SystemProperty** _options;
+
+  static bool _shutdown_called;
+
+  /**
+   * Instantiates a service object, calls its default constructor and returns it.
+   *
+   * @param name the name of a class implementing jdk.vm.ci.service.Service
+   */
+  static Handle create_Service(const char* name, TRAPS);
+
+ public:
+
+  /**
+   * Parses *.properties files in jre/lib/jvmci/ and adds the properties to plist.
+   */
+  static void init_system_properties(SystemProperty** plist);
+
+  /**
+   * Saves the value of the "jvmci.compiler" system property for processing
+   * when JVMCI is initialized.
+   */
+  static void save_compiler(const char* compiler);
+
+  /**
+   * Saves the value of the system properties starting with "jvmci.option." for processing
+   * when JVMCI is initialized.
+   *
+   * @param props the head of the system property list
+   * @return JNI_ERR if a JVMCI option has a zero length value, JNI_OK otherwise
+   */
+  static jint save_options(SystemProperty* props);
+
+  static bool is_HotSpotJVMCIRuntime_initialized() { return _HotSpotJVMCIRuntime_initialized; }
+
+  /**
+   * Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary
+   */
+  static Handle get_HotSpotJVMCIRuntime(TRAPS) {
+    initialize_JVMCI(CHECK_(Handle()));
+    return Handle(JNIHandles::resolve_non_null(_HotSpotJVMCIRuntime_instance));
+  }
+
+  static jobject get_HotSpotJVMCIRuntime_jobject(TRAPS) {
+    initialize_JVMCI(CHECK_NULL);
+    assert(_HotSpotJVMCIRuntime_initialized, "must be");
+    return _HotSpotJVMCIRuntime_instance;
+  }
+
+  static Handle callStatic(const char* className, const char* methodName, const char* returnType, JavaCallArguments* args, TRAPS);
+
+  /**
+   * Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime()
+   */
+  static void initialize_JVMCI(TRAPS);
+
+  /**
+   * Explicitly initialize HotSpotJVMCIRuntime itself
+   */
+  static void initialize_HotSpotJVMCIRuntime(TRAPS);
+
+  static void initialize_well_known_classes(TRAPS);
+
+  static void metadata_do(void f(Metadata*));
+
+  static void shutdown();
+
+  static bool shutdown_called() {
+    return _shutdown_called;
+  }
+
+  static void parse_lines(char* path, ParseClosure* closure, bool warnStatFailure);
+
+  /**
+   * Aborts the VM due to an unexpected exception.
+   */
+  static void abort_on_pending_exception(Handle exception, const char* message, bool dump_core = false);
+
+  /**
+   * Calls Throwable.printStackTrace() on a given exception.
+   */
+  static void call_printStackTrace(Handle exception, Thread* thread);
+
+  static BasicType kindToBasicType(jchar ch);
+
+  // The following routines are all called from compiled JVMCI code
+
+  static void new_instance(JavaThread* thread, Klass* klass);
+  static void new_array(JavaThread* thread, Klass* klass, jint length);
+  static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
+  static void dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length);
+  static void dynamic_new_instance(JavaThread* thread, oopDesc* type_mirror);
+  static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupted);
+  static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3);
+  static jint identity_hash_code(JavaThread* thread, oopDesc* obj);
+  static address exception_handler_for_pc(JavaThread* thread);
+  static void monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);
+  static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock);
+  static void create_null_exception(JavaThread* thread);
+  static void create_out_of_bounds_exception(JavaThread* thread, jint index);
+  static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value);
+  static oopDesc* load_and_clear_exception(JavaThread* thread);
+  static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3);
+  static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
+  // Note: Must be kept in sync with constants in com.oracle.graal.replacements.Log
+  enum {
+    LOG_OBJECT_NEWLINE = 0x01,
+    LOG_OBJECT_STRING  = 0x02,
+    LOG_OBJECT_ADDRESS = 0x04
+  };
+  static void log_object(JavaThread* thread, oopDesc* msg, jint flags);
+  static void write_barrier_pre(JavaThread* thread, oopDesc* obj);
+  static void write_barrier_post(JavaThread* thread, void* card);
+  static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child);
+  static void new_store_pre_barrier(JavaThread* thread);
+
+  // Test only function
+  static int test_deoptimize_call_int(JavaThread* thread, int value);
+};
+
+// Tracing macros.
+
+#define IF_TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1)) ; else
+#define IF_TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2)) ; else
+#define IF_TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3)) ; else
+#define IF_TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4)) ; else
+#define IF_TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5)) ; else
+
+#define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print("JVMCITrace-1: "), true))) ; else tty->print_cr
+#define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print("   JVMCITrace-2: "), true))) ; else tty->print_cr
+#define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print("      JVMCITrace-3: "), true))) ; else tty->print_cr
+#define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print("         JVMCITrace-4: "), true))) ; else tty->print_cr
+#define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print("            JVMCITrace-5: "), true))) ; else tty->print_cr
+
+#endif // SHARE_VM_JVMCI_JVMCI_RUNTIME_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2000, 2015, 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 "jvmci/jvmci_globals.hpp"
+
+JVMCI_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
+            MATERIALIZE_PD_DEVELOPER_FLAG, \
+            MATERIALIZE_PRODUCT_FLAG, \
+            MATERIALIZE_PD_PRODUCT_FLAG, \
+            MATERIALIZE_DIAGNOSTIC_FLAG, \
+            MATERIALIZE_EXPERIMENTAL_FLAG, \
+            MATERIALIZE_NOTPRODUCT_FLAG,
+            IGNORE_RANGE, \
+            IGNORE_CONSTRAINT)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2000, 2015, 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_JVMCI_JVMCIGLOBALS_HPP
+#define SHARE_VM_JVMCI_JVMCIGLOBALS_HPP
+
+#include "runtime/globals.hpp"
+
+//
+// Defines all global flags used by the JVMCI compiler. Only flags that need
+// to be accessible to the JVMCI C++ code should be defined here. All other
+// JVMCI flags should be defined in JVMCIOptions.java.
+//
+#define JVMCI_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, range, constraint) \
+                                                                            \
+  experimental(bool, EnableJVMCI, false,                                    \
+          "Enable JVMCI")                                                   \
+                                                                            \
+  experimental(bool, UseJVMCICompiler, false,                               \
+          "Use JVMCI as the default compiler")                              \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(bool, BootstrapJVMCI, false,                                 \
+          "Bootstrap JVMCI before running Java main method")                \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(bool, PrintBootstrap, true,                                  \
+          "Print JVMCI bootstrap progress and summary")                     \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(intx, JVMCIThreads, 1,                                       \
+          "Force number of JVMCI compiler threads to use")                  \
+          range(1, max_jint)                                                \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(intx, JVMCIHostThreads, 1,                                   \
+          "Force number of compiler threads for JVMCI host compiler")       \
+          range(1, max_jint)                                                \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(bool, CodeInstallSafepointChecks, true,                      \
+          "Perform explicit safepoint checks while installing code")        \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  NOT_COMPILER2(product(intx, MaxVectorSize, 64,                            \
+          "Max vector size in bytes, "                                      \
+          "actual size could be less depending on elements type"))          \
+                                                                            \
+  NOT_COMPILER2(product(bool, ReduceInitialCardMarks, true,                 \
+          "Defer write barriers of young objects"))                         \
+                                                                            \
+  experimental(intx, JVMCITraceLevel, 0,                                    \
+          "Trace level for JVMCI: "                                         \
+          "1 means emit a message for each CompilerToVM call,"              \
+          "levels greater than 1 provide progressively greater detail")     \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(intx, JVMCICounterSize, 0,                                   \
+          "Reserved size for benchmark counters")                           \
+          range(0, max_jint)                                                \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(bool, JVMCICountersExcludeCompiler, true,                    \
+          "Exclude JVMCI compiler threads from benchmark counters")         \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  develop(bool, JVMCIUseFastLocking, true,                                  \
+          "Use fast inlined locking code")                                  \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  experimental(intx, JVMCINMethodSizeLimit, (80*K)*wordSize,                \
+          "Maximum size of a compiled method.")                             \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+                                                                            \
+  develop(bool, TraceUncollectedSpeculations, false,                        \
+          "Print message when a failed speculation was not collected")      \
+          constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse)        \
+
+
+// Read default values for JVMCI globals
+
+JVMCI_FLAGS(DECLARE_DEVELOPER_FLAG, \
+            DECLARE_PD_DEVELOPER_FLAG, \
+            DECLARE_PRODUCT_FLAG, \
+            DECLARE_PD_PRODUCT_FLAG, \
+            DECLARE_DIAGNOSTIC_FLAG, \
+            DECLARE_EXPERIMENTAL_FLAG, \
+            DECLARE_NOTPRODUCT_FLAG, \
+            IGNORE_RANGE, \
+            IGNORE_CONSTRAINT)
+
+#endif // SHARE_VM_JVMCI_JVMCIGLOBALS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 2015, 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_JVMCI_SYSTEMDICTIONARY_JVMCI_HPP
+#define SHARE_VM_JVMCI_SYSTEMDICTIONARY_JVMCI_HPP
+
+#if !INCLUDE_JVMCI
+#define JVMCI_WK_KLASSES_DO(do_klass)
+#else
+#define JVMCI_WK_KLASSES_DO(do_klass)                                                                                           \
+  /* JVMCI classes. These are loaded on-demand. */                                                                              \
+  do_klass(HotSpotCompiledCode_klass,                    jdk_vm_ci_hotspot_HotSpotCompiledCode,                 Jvmci) \
+  do_klass(HotSpotCompiledCode_Comment_klass,            jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment,         Jvmci) \
+  do_klass(HotSpotCompiledNmethod_klass,                 jdk_vm_ci_hotspot_HotSpotCompiledNmethod,              Jvmci) \
+  do_klass(HotSpotForeignCallTarget_klass,               jdk_vm_ci_hotspot_HotSpotForeignCallTarget,            Jvmci) \
+  do_klass(HotSpotReferenceMap_klass,                    jdk_vm_ci_hotspot_HotSpotReferenceMap,                 Jvmci) \
+  do_klass(HotSpotInstalledCode_klass,                   jdk_vm_ci_hotspot_HotSpotInstalledCode,                Jvmci) \
+  do_klass(HotSpotNmethod_klass,                         jdk_vm_ci_hotspot_HotSpotNmethod,                      Jvmci) \
+  do_klass(HotSpotResolvedJavaMethodImpl_klass,          jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl,       Jvmci) \
+  do_klass(HotSpotResolvedObjectTypeImpl_klass,          jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl,       Jvmci) \
+  do_klass(HotSpotCompressedNullConstant_klass,          jdk_vm_ci_hotspot_HotSpotCompressedNullConstant,       Jvmci) \
+  do_klass(HotSpotObjectConstantImpl_klass,              jdk_vm_ci_hotspot_HotSpotObjectConstantImpl,           Jvmci) \
+  do_klass(HotSpotMetaspaceConstantImpl_klass,           jdk_vm_ci_hotspot_HotSpotMetaspaceConstantImpl,        Jvmci) \
+  do_klass(HotSpotSentinelConstant_klass,                jdk_vm_ci_hotspot_HotSpotSentinelConstant,             Jvmci) \
+  do_klass(HotSpotStackFrameReference_klass,             jdk_vm_ci_hotspot_HotSpotStackFrameReference,          Jvmci) \
+  do_klass(HotSpotMetaData_klass,                        jdk_vm_ci_hotspot_HotSpotMetaData,                     Jvmci) \
+  do_klass(HotSpotOopMap_klass,                          jdk_vm_ci_hotspot_HotSpotOopMap,                       Jvmci) \
+  do_klass(HotSpotConstantPool_klass,                    jdk_vm_ci_hotspot_HotSpotConstantPool,                 Jvmci) \
+  do_klass(HotSpotJVMCIMetaAccessContext_klass,          jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext,       Jvmci) \
+  do_klass(Assumptions_ConcreteMethod_klass,             jdk_vm_ci_meta_Assumptions_ConcreteMethod,             Jvmci) \
+  do_klass(Assumptions_NoFinalizableSubclass_klass,      jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass,      Jvmci) \
+  do_klass(Assumptions_ConcreteSubtype_klass,            jdk_vm_ci_meta_Assumptions_ConcreteSubtype,            Jvmci) \
+  do_klass(Assumptions_LeafType_klass,                   jdk_vm_ci_meta_Assumptions_LeafType,                   Jvmci) \
+  do_klass(Assumptions_CallSiteTargetValue_klass,        jdk_vm_ci_meta_Assumptions_CallSiteTargetValue,        Jvmci) \
+  do_klass(Architecture_klass,                           jdk_vm_ci_code_Architecture,                           Jvmci) \
+  do_klass(TargetDescription_klass,                      jdk_vm_ci_code_TargetDescription,                      Jvmci) \
+  do_klass(BytecodePosition_klass,                       jdk_vm_ci_code_BytecodePosition,                       Jvmci) \
+  do_klass(DebugInfo_klass,                              jdk_vm_ci_code_DebugInfo,                              Jvmci) \
+  do_klass(RegisterSaveLayout_klass,                     jdk_vm_ci_code_RegisterSaveLayout,                     Jvmci) \
+  do_klass(BytecodeFrame_klass,                          jdk_vm_ci_code_BytecodeFrame,                          Jvmci) \
+  do_klass(CompilationResult_Call_klass,                 jdk_vm_ci_code_CompilationResult_Call,                 Jvmci) \
+  do_klass(CompilationResult_ConstantReference_klass,    jdk_vm_ci_code_CompilationResult_ConstantReference,    Jvmci) \
+  do_klass(CompilationResult_DataPatch_klass,            jdk_vm_ci_code_CompilationResult_DataPatch,            Jvmci) \
+  do_klass(CompilationResult_DataSectionReference_klass, jdk_vm_ci_code_CompilationResult_DataSectionReference, Jvmci) \
+  do_klass(CompilationResult_ExceptionHandler_klass,     jdk_vm_ci_code_CompilationResult_ExceptionHandler,     Jvmci) \
+  do_klass(CompilationResult_Mark_klass,                 jdk_vm_ci_code_CompilationResult_Mark,                 Jvmci) \
+  do_klass(CompilationResult_Infopoint_klass,            jdk_vm_ci_code_CompilationResult_Infopoint,            Jvmci) \
+  do_klass(CompilationResult_Site_klass,                 jdk_vm_ci_code_CompilationResult_Site,                 Jvmci) \
+  do_klass(InfopointReason_klass,                        jdk_vm_ci_code_InfopointReason,                        Jvmci) \
+  do_klass(InstalledCode_klass,                          jdk_vm_ci_code_InstalledCode,                          Jvmci) \
+  do_klass(code_Location_klass,                          jdk_vm_ci_code_Location,                               Jvmci) \
+  do_klass(code_Register_klass,                          jdk_vm_ci_code_Register,                               Jvmci) \
+  do_klass(RegisterValue_klass,                          jdk_vm_ci_code_RegisterValue,                          Jvmci) \
+  do_klass(StackSlot_klass,                              jdk_vm_ci_code_StackSlot,                              Jvmci) \
+  do_klass(StackLockValue_klass,                         jdk_vm_ci_code_StackLockValue,                         Jvmci) \
+  do_klass(VirtualObject_klass,                          jdk_vm_ci_code_VirtualObject,                          Jvmci) \
+  do_klass(SpeculationLog_klass,                         jdk_vm_ci_meta_SpeculationLog,                         Jvmci) \
+  do_klass(JavaConstant_klass,                           jdk_vm_ci_meta_JavaConstant,                           Jvmci) \
+  do_klass(PrimitiveConstant_klass,                      jdk_vm_ci_meta_PrimitiveConstant,                      Jvmci) \
+  do_klass(RawConstant_klass,                            jdk_vm_ci_meta_RawConstant,                            Jvmci) \
+  do_klass(NullConstant_klass,                           jdk_vm_ci_meta_NullConstant,                           Jvmci) \
+  do_klass(ExceptionHandler_klass,                       jdk_vm_ci_meta_ExceptionHandler,                       Jvmci) \
+  do_klass(JavaKind_klass,                               jdk_vm_ci_meta_JavaKind,                               Jvmci) \
+  do_klass(LIRKind_klass,                                jdk_vm_ci_meta_LIRKind,                                Jvmci) \
+  do_klass(Value_klass,                                  jdk_vm_ci_meta_Value,                                  Jvmci)
+#endif
+
+#endif // SHARE_VM_JVMCI_SYSTEMDICTIONARY_JVMCI_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, 2014, 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_JVMCI_VMSTRUCTS_JVMCI_HPP
+#define SHARE_VM_JVMCI_VMSTRUCTS_JVMCI_HPP
+
+#include "compiler/abstractCompiler.hpp"
+#include "jvmci/jvmciCodeInstaller.hpp"
+#include "jvmci/jvmciCompilerToVM.hpp"
+#include "jvmci/jvmciEnv.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+
+#define VM_STRUCTS_JVMCI(nonstatic_field, static_field)                               \
+  nonstatic_field(JavaThread,    _pending_deoptimization,               int)          \
+  nonstatic_field(JavaThread,    _pending_failed_speculation,           oop)          \
+  nonstatic_field(JavaThread,    _pending_transfer_to_interpreter,      bool)         \
+  nonstatic_field(JavaThread,    _jvmci_counters,                       jlong*)       \
+  nonstatic_field(MethodData,    _jvmci_ir_size,                        int)          \
+  nonstatic_field(JVMCIEnv,      _task,                                 CompileTask*) \
+  nonstatic_field(JVMCIEnv,      _jvmti_can_hotswap_or_post_breakpoint, bool)         \
+  nonstatic_field(DeoptimizationBlob, _uncommon_trap_offset,            int)          \
+  \
+  static_field(CompilerToVM, _supports_inline_contig_alloc, bool) \
+  static_field(CompilerToVM, _heap_end_addr, HeapWord**) \
+  static_field(CompilerToVM, _heap_top_addr, HeapWord**)
+
+#define VM_TYPES_JVMCI(declare_type, declare_toplevel_type)                   \
+  declare_toplevel_type(CompilerToVM)                                         \
+  declare_toplevel_type(JVMCIEnv)                                             \
+
+#define VM_INT_CONSTANTS_JVMCI(declare_constant, declare_preprocessor_constant)                   \
+  declare_constant(Deoptimization::Reason_unreached0)                                             \
+  declare_constant(Deoptimization::Reason_type_checked_inlining)                                  \
+  declare_constant(Deoptimization::Reason_optimized_type_check)                                   \
+  declare_constant(Deoptimization::Reason_aliasing)                                               \
+  declare_constant(Deoptimization::Reason_transfer_to_interpreter)                                \
+  declare_constant(Deoptimization::Reason_not_compiled_exception_handler)                         \
+  declare_constant(Deoptimization::Reason_unresolved)                                             \
+  declare_constant(Deoptimization::Reason_jsr_mismatch)                                           \
+  declare_constant(JVMCIEnv::ok)                                                                  \
+  declare_constant(JVMCIEnv::dependencies_failed)                                                 \
+  declare_constant(JVMCIEnv::dependencies_invalid)                                                \
+  declare_constant(JVMCIEnv::cache_full)                                                          \
+  declare_constant(JVMCIEnv::code_too_large)                                                      \
+                                                                                                  \
+  declare_preprocessor_constant("JVM_ACC_SYNTHETIC", JVM_ACC_SYNTHETIC)                           \
+  declare_preprocessor_constant("JVM_RECOGNIZED_FIELD_MODIFIERS", JVM_RECOGNIZED_FIELD_MODIFIERS) \
+                                                                                                  \
+  declare_constant(CompilerToVM::KLASS_TAG)                                                       \
+  declare_constant(CompilerToVM::SYMBOL_TAG)                                                      \
+                                                                                                  \
+  declare_constant(CodeInstaller::VERIFIED_ENTRY)                                                 \
+  declare_constant(CodeInstaller::UNVERIFIED_ENTRY)                                               \
+  declare_constant(CodeInstaller::OSR_ENTRY)                                                      \
+  declare_constant(CodeInstaller::EXCEPTION_HANDLER_ENTRY)                                        \
+  declare_constant(CodeInstaller::DEOPT_HANDLER_ENTRY)                                            \
+  declare_constant(CodeInstaller::INVOKEINTERFACE)                                                \
+  declare_constant(CodeInstaller::INVOKEVIRTUAL)                                                  \
+  declare_constant(CodeInstaller::INVOKESTATIC)                                                   \
+  declare_constant(CodeInstaller::INVOKESPECIAL)                                                  \
+  declare_constant(CodeInstaller::INLINE_INVOKE)                                                  \
+  declare_constant(CodeInstaller::POLL_NEAR)                                                      \
+  declare_constant(CodeInstaller::POLL_RETURN_NEAR)                                               \
+  declare_constant(CodeInstaller::POLL_FAR)                                                       \
+  declare_constant(CodeInstaller::POLL_RETURN_FAR)                                                \
+  declare_constant(CodeInstaller::CARD_TABLE_ADDRESS)                                             \
+  declare_constant(CodeInstaller::HEAP_TOP_ADDRESS)                                               \
+  declare_constant(CodeInstaller::HEAP_END_ADDRESS)                                               \
+  declare_constant(CodeInstaller::NARROW_KLASS_BASE_ADDRESS)                                      \
+  declare_constant(CodeInstaller::CRC_TABLE_ADDRESS)                                              \
+  declare_constant(CodeInstaller::INVOKE_INVALID)                                                 \
+                                                                                                  \
+  declare_constant(Method::invalid_vtable_index)                                                  \
+
+#define VM_ADDRESSES_JVMCI(declare_address, declare_preprocessor_address, declare_function)      \
+  declare_function(JVMCIRuntime::new_instance) \
+  declare_function(JVMCIRuntime::new_array) \
+  declare_function(JVMCIRuntime::new_multi_array) \
+  declare_function(JVMCIRuntime::dynamic_new_array) \
+  declare_function(JVMCIRuntime::dynamic_new_instance) \
+  \
+  declare_function(JVMCIRuntime::thread_is_interrupted) \
+  declare_function(JVMCIRuntime::vm_message) \
+  declare_function(JVMCIRuntime::identity_hash_code) \
+  declare_function(JVMCIRuntime::exception_handler_for_pc) \
+  declare_function(JVMCIRuntime::monitorenter) \
+  declare_function(JVMCIRuntime::monitorexit) \
+  declare_function(JVMCIRuntime::create_null_exception) \
+  declare_function(JVMCIRuntime::create_out_of_bounds_exception) \
+  declare_function(JVMCIRuntime::log_primitive) \
+  declare_function(JVMCIRuntime::log_object) \
+  declare_function(JVMCIRuntime::log_printf) \
+  declare_function(JVMCIRuntime::vm_error) \
+  declare_function(JVMCIRuntime::load_and_clear_exception) \
+  declare_function(JVMCIRuntime::write_barrier_pre) \
+  declare_function(JVMCIRuntime::write_barrier_post) \
+  declare_function(JVMCIRuntime::validate_object) \
+  \
+  declare_function(JVMCIRuntime::test_deoptimize_call_int)
+
+#endif // SHARE_VM_JVMCI_VMSTRUCTS_JVMCI_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 2015, 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_JVMCI_VMSYMBOLS_JVMCI_HPP
+#define SHARE_VM_JVMCI_VMSYMBOLS_JVMCI_HPP
+
+
+#if !INCLUDE_JVMCI
+#define JVMCI_VM_SYMBOLS_DO(template, do_alias)
+#else
+#define JVMCI_VM_SYMBOLS_DO(template, do_alias)                                                                            \
+  template(jdk_vm_ci_hotspot_HotSpotCompiledCode,                 "jdk/vm/ci/hotspot/HotSpotCompiledCode")                 \
+  template(jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment,         "jdk/vm/ci/hotspot/HotSpotCompiledCode$Comment")         \
+  template(jdk_vm_ci_hotspot_HotSpotCompiledNmethod,              "jdk/vm/ci/hotspot/HotSpotCompiledNmethod")              \
+  template(jdk_vm_ci_hotspot_HotSpotForeignCallTarget,            "jdk/vm/ci/hotspot/HotSpotForeignCallTarget")            \
+  template(jdk_vm_ci_hotspot_HotSpotReferenceMap,                 "jdk/vm/ci/hotspot/HotSpotReferenceMap")                 \
+  template(jdk_vm_ci_hotspot_CompilerToVM,                        "jdk/vm/ci/hotspot/CompilerToVM")                        \
+  template(jdk_vm_ci_hotspot_HotSpotInstalledCode,                "jdk/vm/ci/hotspot/HotSpotInstalledCode")                \
+  template(jdk_vm_ci_hotspot_HotSpotNmethod,                      "jdk/vm/ci/hotspot/HotSpotNmethod")                      \
+  template(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl,       "jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl")       \
+  template(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl,       "jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl")       \
+  template(jdk_vm_ci_hotspot_HotSpotCompressedNullConstant,       "jdk/vm/ci/hotspot/HotSpotCompressedNullConstant")       \
+  template(jdk_vm_ci_hotspot_HotSpotObjectConstantImpl,           "jdk/vm/ci/hotspot/HotSpotObjectConstantImpl")           \
+  template(jdk_vm_ci_hotspot_HotSpotMetaspaceConstantImpl,        "jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl")        \
+  template(jdk_vm_ci_hotspot_HotSpotSentinelConstant,             "jdk/vm/ci/hotspot/HotSpotSentinelConstant")             \
+  template(jdk_vm_ci_hotspot_HotSpotStackFrameReference,          "jdk/vm/ci/hotspot/HotSpotStackFrameReference")          \
+  template(jdk_vm_ci_hotspot_HotSpotMetaData,                     "jdk/vm/ci/hotspot/HotSpotMetaData")                     \
+  template(jdk_vm_ci_hotspot_HotSpotOopMap,                       "jdk/vm/ci/hotspot/HotSpotOopMap")                       \
+  template(jdk_vm_ci_hotspot_HotSpotConstantPool,                 "jdk/vm/ci/hotspot/HotSpotConstantPool")                 \
+  template(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext,       "jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext")       \
+  template(jdk_vm_ci_meta_JavaConstant,                           "jdk/vm/ci/meta/JavaConstant")                           \
+  template(jdk_vm_ci_meta_PrimitiveConstant,                      "jdk/vm/ci/meta/PrimitiveConstant")                      \
+  template(jdk_vm_ci_meta_RawConstant,                            "jdk/vm/ci/meta/RawConstant")                            \
+  template(jdk_vm_ci_meta_NullConstant,                           "jdk/vm/ci/meta/NullConstant")                           \
+  template(jdk_vm_ci_meta_ExceptionHandler,                       "jdk/vm/ci/meta/ExceptionHandler")                       \
+  template(jdk_vm_ci_meta_JavaKind,                               "jdk/vm/ci/meta/JavaKind")                               \
+  template(jdk_vm_ci_meta_LIRKind,                                "jdk/vm/ci/meta/LIRKind")                                \
+  template(jdk_vm_ci_meta_Value,                                  "jdk/vm/ci/meta/Value")                                  \
+  template(jdk_vm_ci_meta_Assumptions_ConcreteSubtype,            "jdk/vm/ci/meta/Assumptions$ConcreteSubtype")            \
+  template(jdk_vm_ci_meta_Assumptions_LeafType,                   "jdk/vm/ci/meta/Assumptions$LeafType")                   \
+  template(jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass,      "jdk/vm/ci/meta/Assumptions$NoFinalizableSubclass")      \
+  template(jdk_vm_ci_meta_Assumptions_ConcreteMethod,             "jdk/vm/ci/meta/Assumptions$ConcreteMethod")             \
+  template(jdk_vm_ci_meta_Assumptions_CallSiteTargetValue,        "jdk/vm/ci/meta/Assumptions$CallSiteTargetValue")        \
+  template(jdk_vm_ci_meta_SpeculationLog,                         "jdk/vm/ci/meta/SpeculationLog")                         \
+  template(jdk_vm_ci_code_Architecture,                           "jdk/vm/ci/code/Architecture")                           \
+  template(jdk_vm_ci_code_TargetDescription,                      "jdk/vm/ci/code/TargetDescription")                      \
+  template(jdk_vm_ci_code_CompilationResult_Call,                 "jdk/vm/ci/code/CompilationResult$Call")                 \
+  template(jdk_vm_ci_code_CompilationResult_ConstantReference,    "jdk/vm/ci/code/CompilationResult$ConstantReference")    \
+  template(jdk_vm_ci_code_CompilationResult_DataPatch,            "jdk/vm/ci/code/CompilationResult$DataPatch")            \
+  template(jdk_vm_ci_code_CompilationResult_DataSectionReference, "jdk/vm/ci/code/CompilationResult$DataSectionReference") \
+  template(jdk_vm_ci_code_CompilationResult_ExceptionHandler,     "jdk/vm/ci/code/CompilationResult$ExceptionHandler")     \
+  template(jdk_vm_ci_code_CompilationResult_Mark,                 "jdk/vm/ci/code/CompilationResult$Mark")                 \
+  template(jdk_vm_ci_code_CompilationResult_Infopoint,            "jdk/vm/ci/code/CompilationResult$Infopoint")            \
+  template(jdk_vm_ci_code_CompilationResult_Site,                 "jdk/vm/ci/code/CompilationResult$Site")                 \
+  template(jdk_vm_ci_code_InfopointReason,                        "jdk/vm/ci/code/InfopointReason")                        \
+  template(jdk_vm_ci_code_InstalledCode,                          "jdk/vm/ci/code/InstalledCode")                          \
+  template(jdk_vm_ci_code_BytecodeFrame,                          "jdk/vm/ci/code/BytecodeFrame")                          \
+  template(jdk_vm_ci_code_BytecodePosition,                       "jdk/vm/ci/code/BytecodePosition")                       \
+  template(jdk_vm_ci_code_DebugInfo,                              "jdk/vm/ci/code/DebugInfo")                              \
+  template(jdk_vm_ci_code_Location,                               "jdk/vm/ci/code/Location")                               \
+  template(jdk_vm_ci_code_Register,                               "jdk/vm/ci/code/Register")                               \
+  template(jdk_vm_ci_code_RegisterValue,                          "jdk/vm/ci/code/RegisterValue")                          \
+  template(jdk_vm_ci_code_StackSlot,                              "jdk/vm/ci/code/StackSlot")                              \
+  template(jdk_vm_ci_code_StackLockValue,                         "jdk/vm/ci/code/StackLockValue")                         \
+  template(jdk_vm_ci_code_VirtualObject,                          "jdk/vm/ci/code/VirtualObject")                          \
+  template(jdk_vm_ci_code_RegisterSaveLayout,                     "jdk/vm/ci/code/RegisterSaveLayout")                     \
+  template(jdk_vm_ci_code_InvalidInstalledCodeException,          "jdk/vm/ci/code/InvalidInstalledCodeException")          \
+  template(compileMethod_name,                                    "compileMethod")                                         \
+  template(compileMethod_signature,                               "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)V")   \
+  template(fromMetaspace_name,                                    "fromMetaspace")                                         \
+  template(method_fromMetaspace_signature,                        "(J)Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;")      \
+  template(constantPool_fromMetaspace_signature,                  "(J)Ljdk/vm/ci/hotspot/HotSpotConstantPool;")            \
+  template(klass_fromMetaspace_signature,                         "(Ljava/lang/Class;)Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;") \
+  template(jdk_vm_ci_hotspot_Stable_signature,                    "Ljdk/vm/ci/hotspot/Stable;")
+#endif
+
+#endif // SHARE_VM_JVMCI_VMSYMBOLS_JVMCI_HPP
--- a/hotspot/src/share/vm/libadt/dict.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/libadt/dict.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,8 +31,6 @@
 
 #include <assert.h>
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 //------------------------------data-----------------------------------------
 // String hash tables
 #define MAXID 20
@@ -288,9 +286,9 @@
 // Handier print routine
 void Dict::print() {
   DictI i(this); // Moved definition in iterator here because of g++.
-  tty->print("Dict@0x%lx[%d] = {", this, _cnt);
+  tty->print("Dict@" INTPTR_FORMAT "[%d] = {", p2i(this), _cnt);
   for( ; i.test(); ++i ) {
-    tty->print("(0x%lx,0x%lx),", i._key, i._value);
+    tty->print("(" INTPTR_FORMAT "," INTPTR_FORMAT "),", p2i(i._key), p2i(i._value));
   }
   tty->print_cr("}");
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/log.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOG_HPP
+#define SHARE_VM_LOGGING_LOG_HPP
+
+#include "logging/logLevel.hpp"
+#include "logging/logPrefix.hpp"
+#include "logging/logTagSet.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/ostream.hpp"
+
+//
+// Logging macros
+//
+// Usage:
+//   log_<level>(<comma separated log tags>)(<printf-style log arguments>);
+// e.g.
+//   log_debug(logging)("message %d", i);
+//
+// Note that these macros will not evaluate the arguments unless the logging is enabled.
+//
+#define log_error(...)   (!log_is_enabled(Error, __VA_ARGS__))   ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Error>
+#define log_warning(...) (!log_is_enabled(Warning, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Warning>
+#define log_info(...)    (!log_is_enabled(Info, __VA_ARGS__))    ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Info>
+#define log_debug(...)   (!log_is_enabled(Debug, __VA_ARGS__))   ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Debug>
+#define log_trace(...)   (!log_is_enabled(Trace, __VA_ARGS__))   ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Trace>
+#ifndef PRODUCT
+#define log_develop(...) (!log_is_enabled(Develop, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Develop>
+#else
+#define DUMMY_ARGUMENT_CONSUMER(...)
+#define log_develop(...) DUMMY_ARGUMENT_CONSUMER
+#endif
+
+// Convenience macro to test if the logging is enabled on the specified level for given tags.
+#define log_is_enabled(level, ...) (Log<LOG_TAGS(__VA_ARGS__)>::is_level(LogLevel::level))
+
+//
+// Log class for more advanced logging scenarios.
+// Has printf-style member functions for each log level (trace(), debug(), etc).
+//
+// Also has outputStream compatible API for the different log-levels.
+// The streams are resource allocated when requested and are accessed through
+// calls to <level>_stream() functions (trace_stream(), debug_stream(), etc).
+//
+// Example usage:
+//   LogHandle(logging) log;
+//   if (log.is_debug()) {
+//     ...
+//     log.debug("result = %d", result).trace(" tracing info");
+//     obj->print_on(log.debug_stream());
+//   }
+//
+#define LogHandle(...)  Log<LOG_TAGS(__VA_ARGS__)>
+
+template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG,
+          LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
+class Log VALUE_OBJ_CLASS_SPEC {
+ private:
+  static const size_t LogBufferSize = 512;
+ public:
+  // Make sure no more than the maximum number of tags have been given.
+  // The GuardTag allows this to be detected if/when it happens. If the GuardTag
+  // is not __NO_TAG, the number of tags given exceeds the maximum allowed.
+  STATIC_ASSERT(GuardTag == LogTag::__NO_TAG); // Number of logging tags exceeds maximum supported!
+
+  static bool is_level(LogLevelType level) {
+    return LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().is_level(level);
+  }
+
+  template <LogLevelType Level>
+  ATTRIBUTE_PRINTF(1, 2)
+  static void write(const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    vwrite<Level>(fmt, args);
+    va_end(args);
+  };
+
+  template <LogLevelType Level>
+  ATTRIBUTE_PRINTF(1, 0)
+  static void vwrite(const char* fmt, va_list args) {
+    char buf[LogBufferSize];
+    size_t prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(buf, sizeof(buf));
+    int ret = vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
+    assert(ret >= 0 && (size_t)ret < sizeof(buf), "Log message too long");
+    puts<Level>(buf);
+  }
+
+  template <LogLevelType Level>
+  static void puts(const char* string) {
+    LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().log(Level, string);
+  }
+
+#define LOG_LEVEL(level, name) ATTRIBUTE_PRINTF(2, 0) \
+  Log& v##name(const char* fmt, va_list args) { \
+    vwrite<LogLevel::level>(fmt, args); \
+    return *this; \
+  } \
+  Log& name(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) { \
+    va_list args; \
+    va_start(args, fmt); \
+    vwrite<LogLevel::level>(fmt, args); \
+    va_end(args); \
+    return *this; \
+  } \
+  static bool is_##name() { \
+    return is_level(LogLevel::level); \
+  } \
+  static outputStream* name##_stream() { \
+    return new logStream(write<LogLevel::level>); \
+  }
+  LOG_LEVEL_LIST
+#undef LOG_LEVEL
+};
+
+#endif // SHARE_VM_LOGGING_LOG_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logConfiguration.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2015, 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 "logging/log.hpp"
+#include "logging/logConfiguration.hpp"
+#include "logging/logDecorations.hpp"
+#include "logging/logDecorators.hpp"
+#include "logging/logDiagnosticCommand.hpp"
+#include "logging/logFileOutput.hpp"
+#include "logging/logOutput.hpp"
+#include "logging/logTagLevelExpression.hpp"
+#include "logging/logTagSet.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/os.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+LogOutput** LogConfiguration::_outputs = NULL;
+size_t      LogConfiguration::_n_outputs = 0;
+
+void LogConfiguration::post_initialize() {
+  assert(LogConfiguration_lock != NULL, "Lock must be initialized before post-initialization");
+  LogDiagnosticCommand::registerCommand();
+  LogHandle(logging) log;
+  log.info("Log configuration fully initialized.");
+  if (log.is_trace()) {
+    ResourceMark rm;
+    MutexLocker ml(LogConfiguration_lock);
+    describe(log.trace_stream());
+  }
+}
+
+void LogConfiguration::initialize(jlong vm_start_time) {
+  LogFileOutput::set_file_name_parameters(vm_start_time);
+  LogDecorations::set_vm_start_time_millis(vm_start_time);
+
+  assert(_outputs == NULL, "Should not initialize _outputs before this function, initialize called twice?");
+  _outputs = NEW_C_HEAP_ARRAY(LogOutput*, 2, mtLogging);
+  _outputs[0] = LogOutput::Stdout;
+  _outputs[1] = LogOutput::Stderr;
+  _n_outputs = 2;
+}
+
+void LogConfiguration::finalize() {
+  for (size_t i = 2; i < _n_outputs; i++) {
+    delete _outputs[i];
+  }
+  FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
+}
+
+size_t LogConfiguration::find_output(const char* name) {
+  for (size_t i = 0; i < _n_outputs; i++) {
+    if (strcmp(_outputs[i]->name(), name) == 0) {
+      return i;
+    }
+  }
+  return SIZE_MAX;
+}
+
+LogOutput* LogConfiguration::new_output(char* name, const char* options) {
+  const char* type;
+  char* equals_pos = strchr(name, '=');
+  if (equals_pos == NULL) {
+    type = "file";
+  } else {
+    *equals_pos = '\0';
+    type = name;
+    name = equals_pos + 1;
+  }
+
+  LogOutput* output;
+  if (strcmp(type, "file") == 0) {
+    output = new LogFileOutput(name);
+  } else {
+    // unsupported log output type
+    return NULL;
+  }
+
+  bool success = output->initialize(options);
+  if (!success) {
+    delete output;
+    return NULL;
+  }
+  return output;
+}
+
+size_t LogConfiguration::add_output(LogOutput* output) {
+  size_t idx = _n_outputs++;
+  _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtLogging);
+  _outputs[idx] = output;
+  return idx;
+}
+
+void LogConfiguration::delete_output(size_t idx) {
+  assert(idx > 1 && idx < _n_outputs,
+         "idx must be in range 1 < idx < _n_outputs, but idx = " SIZE_FORMAT
+         " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs);
+  LogOutput* output = _outputs[idx];
+  // Swap places with the last output and shrink the array
+  _outputs[idx] = _outputs[--_n_outputs];
+  _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtLogging);
+  delete output;
+}
+
+void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators) {
+  assert(idx < _n_outputs, "Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs);
+  LogOutput* output = _outputs[idx];
+  output->set_decorators(decorators);
+  output->set_config_string(tag_level_expression.to_string());
+  bool enabled = false;
+  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+    LogLevelType level = tag_level_expression.level_for(*ts);
+    if (level != LogLevel::Off) {
+      enabled = true;
+    }
+    ts->update_decorators(decorators);
+    ts->set_output_level(output, level);
+  }
+
+  // If the output is not used by any tagset it should be removed, unless it is stdout/stderr.
+  if (!enabled && idx > 1) {
+    delete_output(idx);
+  }
+}
+
+void LogConfiguration::disable_output(size_t idx) {
+  LogOutput* out = _outputs[idx];
+  LogDecorators empty_decorators;
+  empty_decorators.clear();
+
+  // Remove the output from all tagsets.
+  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+    ts->set_output_level(out, LogLevel::Off);
+    ts->update_decorators(empty_decorators);
+  }
+
+  // Delete the output unless stdout/stderr
+  if (out != LogOutput::Stderr && out != LogOutput::Stdout) {
+    delete_output(find_output(out->name()));
+  } else {
+    out->set_config_string("all=off");
+  }
+}
+
+void LogConfiguration::disable_logging() {
+  assert(LogConfiguration_lock == NULL || LogConfiguration_lock->owned_by_self(),
+         "LogConfiguration lock must be held when calling this function");
+  for (size_t i = 0; i < _n_outputs; i++) {
+    disable_output(i);
+  }
+}
+
+bool LogConfiguration::parse_command_line_arguments(const char* opts) {
+  char* copy = os::strdup_check_oom(opts, mtLogging);
+
+  // Split the option string to its colon separated components.
+  char* what = NULL;
+  char* output_str = NULL;
+  char* decorators_str = NULL;
+  char* output_options = NULL;
+
+  what = copy;
+  char* colon = strchr(what, ':');
+  if (colon != NULL) {
+    *colon = '\0';
+    output_str = colon + 1;
+    colon = strchr(output_str, ':');
+    if (colon != NULL) {
+      *colon = '\0';
+      decorators_str = colon + 1;
+      colon = strchr(decorators_str, ':');
+      if (colon != NULL) {
+        *colon = '\0';
+        output_options = colon + 1;
+      }
+    }
+  }
+
+  // Parse each argument
+  char errbuf[512];
+  stringStream ss(errbuf, sizeof(errbuf));
+  bool success = parse_log_arguments(output_str, what, decorators_str, output_options, &ss);
+  if (!success) {
+    errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline.
+    log_error(logging)("%s", errbuf);
+  }
+
+  os::free(copy);
+  return success;
+}
+
+bool LogConfiguration::parse_log_arguments(const char* outputstr,
+                                           const char* what,
+                                           const char* decoratorstr,
+                                           const char* output_options,
+                                           outputStream* errstream) {
+  assert(LogConfiguration_lock == NULL || LogConfiguration_lock->owned_by_self(),
+         "LogConfiguration lock must be held when calling this function");
+  if (outputstr == NULL || strlen(outputstr) == 0) {
+    outputstr = "stdout";
+  }
+
+  size_t idx;
+  if (outputstr[0] == '#') {
+    int ret = sscanf(outputstr+1, SIZE_FORMAT, &idx);
+    if (ret != 1 || idx >= _n_outputs) {
+      errstream->print_cr("Invalid output index '%s'", outputstr);
+      return false;
+    }
+  } else {
+    idx = find_output(outputstr);
+    if (idx == SIZE_MAX) {
+      char* tmp = os::strdup_check_oom(outputstr, mtLogging);
+      LogOutput* output = new_output(tmp, output_options);
+      os::free(tmp);
+      if (output == NULL) {
+        errstream->print("Unable to add output '%s'", outputstr);
+        if (output_options != NULL && strlen(output_options) > 0) {
+          errstream->print(" with options '%s'", output_options);
+        }
+        errstream->cr();
+        return false;
+      }
+      idx = add_output(output);
+    } else if (output_options != NULL && strlen(output_options) > 0) {
+      errstream->print_cr("Output options for existing outputs are ignored.");
+    }
+  }
+
+  LogTagLevelExpression expr;
+  if (!expr.parse(what, errstream)) {
+    return false;
+  }
+
+  LogDecorators decorators;
+  if (!decorators.parse(decoratorstr, errstream)) {
+    return false;
+  }
+
+  configure_output(idx, expr, decorators);
+  return true;
+}
+
+void LogConfiguration::describe(outputStream* out) {
+  assert(LogConfiguration_lock == NULL || LogConfiguration_lock->owned_by_self(),
+         "LogConfiguration lock must be held when calling this function");
+
+  out->print("Available log levels:");
+  for (size_t i = 0; i < LogLevel::Count; i++) {
+    out->print("%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast<LogLevelType>(i)));
+  }
+  out->cr();
+
+  out->print("Available log decorators:");
+  for (size_t i = 0; i < LogDecorators::Count; i++) {
+    LogDecorators::Decorator d = static_cast<LogDecorators::Decorator>(i);
+    out->print("%s %s (%s)", (i == 0 ? "" : ","), LogDecorators::name(d), LogDecorators::abbreviation(d));
+  }
+  out->cr();
+
+  out->print("Available log tags:");
+  for (size_t i = 1; i < LogTag::Count; i++) {
+    out->print("%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
+  }
+  out->cr();
+
+  out->print_cr("Log output configuration:");
+  for (size_t i = 0; i < _n_outputs; i++) {
+    out->print("#" SIZE_FORMAT ": %s %s ", i, _outputs[i]->name(), _outputs[i]->config_string());
+    for (size_t d = 0; d < LogDecorators::Count; d++) {
+      LogDecorators::Decorator decorator = static_cast<LogDecorators::Decorator>(d);
+      if (_outputs[i]->decorators().is_decorator(decorator)) {
+        out->print("%s,", LogDecorators::name(decorator));
+      }
+    }
+    out->cr();
+  }
+}
+
+void LogConfiguration::print_command_line_help(FILE* out) {
+  jio_fprintf(out, "-Xlog Usage: -Xlog[:[what][:[output][:[decorators][:output-options]]]]\n"
+              "\t where 'what' is a combination of tags and levels on the form tag1[+tag2...][*][=level][,...]\n"
+              "\t Unless wildcard (*) is specified, only log messages tagged with exactly the tags specified will be matched.\n\n");
+
+  jio_fprintf(out, "Available log levels:\n");
+  for (size_t i = 0; i < LogLevel::Count; i++) {
+    jio_fprintf(out, "%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast<LogLevelType>(i)));
+  }
+
+  jio_fprintf(out, "\n\nAvailable log decorators: \n");
+  for (size_t i = 0; i < LogDecorators::Count; i++) {
+    LogDecorators::Decorator d = static_cast<LogDecorators::Decorator>(i);
+    jio_fprintf(out, "%s %s (%s)", (i == 0 ? "" : ","), LogDecorators::name(d), LogDecorators::abbreviation(d));
+  }
+  jio_fprintf(out, "\n Decorators can also be specified as 'none' for no decoration.\n\n");
+
+  jio_fprintf(out, "Available log tags:\n");
+  for (size_t i = 1; i < LogTag::Count; i++) {
+    jio_fprintf(out, "%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
+  }
+  jio_fprintf(out, "\n Specifying 'all' instead of a tag combination matches all tag combinations.\n\n");
+
+  jio_fprintf(out, "Available log outputs:\n"
+              " stdout, stderr, file=<filename>\n"
+              " Specifying %%p and/or %%t in the filename will expand to the JVM's PID and startup timestamp, respectively.\n\n"
+
+              "Some examples:\n"
+              " -Xlog\n"
+              "\t Log all messages using 'info' level to stdout with 'uptime', 'levels' and 'tags' decorations.\n"
+              "\t (Equivalent to -Xlog:all=info:stdout:uptime,levels,tags).\n\n"
+
+              " -Xlog:gc\n"
+              "\t Log messages tagged with 'gc' tag using 'info' level to stdout, with default decorations.\n\n"
+
+              " -Xlog:gc=debug:file=gc.txt:none\n"
+              "\t Log messages tagged with 'gc' tag using 'debug' level to file 'gc.txt' with no decorations.\n\n"
+
+              " -Xlog:gc=trace:file=gctrace.txt:uptimemillis,pids:filecount=5,filesize=1024\n"
+              "\t Log messages tagged with 'gc' tag using 'trace' level to a rotating fileset of 5 files of size 1MB,\n"
+              "\t using the base name 'gctrace.txt', with 'uptimemillis' and 'pid' decorations.\n\n"
+
+              " -Xlog:gc::uptime,tid\n"
+              "\t Log messages tagged with 'gc' tag using 'info' level to output 'stdout', using 'uptime' and 'tid' decorations.\n\n"
+
+              " -Xlog:gc*=info,rt*=off\n"
+              "\t Log messages tagged with at least 'gc' using 'info' level, but turn off logging of messages tagged with 'rt'.\n"
+              "\t (Messages tagged with both 'gc' and 'rt' will not be logged.)\n\n"
+
+              " -Xlog:disable -Xlog:rt=trace:rttrace.txt\n"
+              "\t Turn off all logging, including warnings and errors,\n"
+              "\t and then enable messages tagged with 'rt' using 'trace' level to file 'rttrace.txt'.\n");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logConfiguration.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGCONFIGURATION_HPP
+#define SHARE_VM_LOGGING_LOGCONFIGURATION_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogOutput;
+class LogDecorators;
+class LogTagLevelExpression;
+
+// Global configuration of logging. Handles parsing and configuration of the logging framework,
+// and manages the list of configured log outputs. The actual tag and level configuration is
+// kept implicitly in the LogTagSets and their LogOutputLists. During configuration the tagsets
+// are iterated over and updated accordingly.
+class LogConfiguration : public AllStatic {
+ private:
+  static LogOutput**  _outputs;
+  static size_t       _n_outputs;
+
+  // Create a new output. Returns NULL if failed.
+  static LogOutput* new_output(char* name, const char* options = NULL);
+
+  // Add an output to the list of configured outputs. Returns the assigned index.
+  static size_t add_output(LogOutput* out);
+
+  // Delete a configured output. The stderr/stdout outputs can not be removed.
+  // Output should be completely disabled before it is deleted.
+  static void delete_output(size_t idx);
+
+  // Disable all logging to the specified output and then delete it (unless it is stdout/stderr).
+  static void disable_output(size_t idx);
+
+  // Get output index by name. Returns SIZE_MAX if output not found.
+  static size_t find_output(const char* name);
+
+  // Configure output (add or update existing configuration) to log on tag-level combination using specified decorators.
+  static void configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators);
+
+ public:
+  // Initialization and finalization of log configuration, to be run at vm startup and shutdown respectively.
+  static void initialize(jlong vm_start_time);
+  static void finalize();
+
+  // Perform necessary post-initialization after VM startup. Enables reconfiguration of logging.
+  static void post_initialize();
+
+  // Disable all logging, equivalent to -Xlog:disable.
+  static void disable_logging();
+
+  // Parse command line configuration. Parameter 'opts' is the string immediately following the -Xlog: argument ("gc" for -Xlog:gc).
+  static bool parse_command_line_arguments(const char* opts = "all");
+
+  // Parse separated configuration arguments (from JCmd/MBean and command line).
+  static bool parse_log_arguments(const char* outputstr,
+                                  const char* what,
+                                  const char* decoratorstr,
+                                  const char* output_options,
+                                  outputStream* errstream);
+
+  // Prints log configuration to outputStream, used by JCmd/MBean.
+  static void describe(outputStream* out);
+
+  // Prints usage help for command line log configuration.
+  static void print_command_line_help(FILE* out);
+};
+
+#endif // SHARE_VM_LOGGING_LOGCONFIGURATION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logDecorations.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logConfiguration.hpp"
+#include "logging/logDecorations.hpp"
+#include "runtime/os.inline.hpp"
+#include "runtime/thread.inline.hpp"
+#include "services/management.hpp"
+
+jlong LogDecorations::_vm_start_time_millis = 0;
+
+LogDecorations::LogDecorations(LogLevelType level, const LogTagSet &tagset, const LogDecorators &decorators)
+  : _level(level), _tagset(tagset), _millis(-1) {
+  create_decorations(decorators);
+}
+
+void LogDecorations::create_decorations(const LogDecorators &decorators) {
+  char* position = _decorations_buffer;
+  #define DECORATOR(full_name, abbr) \
+  if (decorators.is_decorator(LogDecorators::full_name##_decorator)) { \
+    _decoration_offset[LogDecorators::full_name##_decorator] = position; \
+    position = create_##full_name##_decoration(position) + 1; \
+  }
+  DECORATOR_LIST
+#undef DECORATOR
+}
+
+jlong LogDecorations::java_millis() {
+  if (_millis < 0) {
+    _millis = os::javaTimeMillis();
+  }
+  return _millis;
+}
+
+#define ASSERT_AND_RETURN(written, pos) \
+    assert(written >= 0, "Decorations buffer overflow"); \
+    return pos + written;
+
+char* LogDecorations::create_time_decoration(char* pos) {
+  char* buf = os::iso8601_time(pos, 29);
+  int written = buf == NULL ? -1 : 29;
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char * LogDecorations::create_uptime_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), "%.3fs", os::elapsedTime());
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char * LogDecorations::create_timemillis_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), INT64_FORMAT "ms", java_millis());
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char * LogDecorations::create_uptimemillis_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer),
+                             INT64_FORMAT "ms", java_millis() - _vm_start_time_millis);
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char * LogDecorations::create_timenanos_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), INT64_FORMAT "ns", os::javaTimeNanos());
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char * LogDecorations::create_uptimenanos_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), INT64_FORMAT "ns", os::elapsed_counter());
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char * LogDecorations::create_pid_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), "%d", os::current_process_id());
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char * LogDecorations::create_tid_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer),
+                             INTX_FORMAT, Thread::current()->osthread()->thread_id());
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char* LogDecorations::create_level_decoration(char* pos) {
+  int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), "%s", LogLevel::name(_level));
+  ASSERT_AND_RETURN(written, pos)
+}
+
+char* LogDecorations::create_tags_decoration(char* pos) {
+  int written = _tagset.label(pos, DecorationsBufferSize - (pos - _decorations_buffer));
+  ASSERT_AND_RETURN(written, pos)
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logDecorations.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGDECORATIONS_HPP
+#define SHARE_VM_LOGGING_LOGDECORATIONS_HPP
+
+#include "logging/logDecorators.hpp"
+#include "logging/logTagSet.hpp"
+#include "memory/allocation.hpp"
+
+// Temporary object containing the necessary data for a log call's decorations (timestamps, etc).
+class LogDecorations VALUE_OBJ_CLASS_SPEC {
+ public:
+  static const int DecorationsBufferSize = 256;
+ private:
+  char _decorations_buffer[DecorationsBufferSize];
+  char* _decoration_offset[LogDecorators::Count];
+  LogLevelType _level;
+  LogTagSet _tagset;
+  jlong _millis;
+  static jlong _vm_start_time_millis;
+
+  jlong java_millis();
+  void create_decorations(const LogDecorators& decorators);
+
+#define DECORATOR(name, abbr) char* create_##name##_decoration(char* pos);
+  DECORATOR_LIST
+#undef DECORATOR
+
+ public:
+  LogDecorations(LogLevelType level, const LogTagSet& tagset, const LogDecorators& decorators);
+
+  const char* decoration(LogDecorators::Decorator decorator) const {
+    return _decoration_offset[decorator];
+  }
+
+  static void set_vm_start_time_millis(jlong start_time) {
+    _vm_start_time_millis = start_time;
+  }
+};
+
+#endif // SHARE_VM_LOGGING_LOGDECORATIONS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logDecorators.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logDecorators.hpp"
+#include "runtime/os.inline.hpp"
+
+const char* LogDecorators::_name[][2] = {
+#define DECORATOR(n, a) {#n, #a},
+  DECORATOR_LIST
+#undef DECORATOR
+};
+
+LogDecorators::Decorator LogDecorators::from_string(const char* str) {
+  for (size_t i = 0; i < Count; i++) {
+    Decorator d = static_cast<Decorator>(i);
+    if (strcasecmp(str, name(d)) == 0 || strcasecmp(str, abbreviation(d)) == 0) {
+      return d;
+    }
+  }
+  return Invalid;
+}
+
+bool LogDecorators::parse(const char* decorator_args, outputStream* errstream) {
+  if (decorator_args == NULL || strlen(decorator_args) == 0) {
+    _decorators = DefaultDecoratorsMask;
+    return true;
+  }
+
+  if (strcasecmp(decorator_args, "none") == 0 ) {
+    _decorators = 0;
+    return true;
+  }
+
+  bool result = true;
+  uint tmp_decorators = 0;
+  char* args_copy = os::strdup_check_oom(decorator_args, mtLogging);
+  char* token = args_copy;
+  char* comma_pos;
+  do {
+    comma_pos = strchr(token, ',');
+    if (comma_pos != NULL) {
+      *comma_pos = '\0';
+    }
+    Decorator d = from_string(token);
+    if (d == Invalid) {
+      if (errstream != NULL) {
+        errstream->print_cr("Invalid decorator '%s'.", token);
+      }
+      result = false;
+      break;
+    }
+    tmp_decorators |= mask(d);
+    token = comma_pos + 1;
+  } while (comma_pos != NULL);
+  os::free(args_copy);
+  if (result) {
+    _decorators = tmp_decorators;
+  }
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logDecorators.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGDECORATORS_HPP
+#define SHARE_VM_LOGGING_LOGDECORATORS_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// The list of available decorators:
+// time         - Current time and date in ISO-8601 format
+// uptime       - Time since the start of the JVM in seconds and milliseconds (e.g., 6.567s)
+// timemillis   - The same value as generated by System.currentTimeMillis()
+// uptimemillis - Milliseconds since the JVM started
+// timenanos    - The same value as generated by System.nanoTime()
+// uptimenanos  - Nanoseconds since the JVM started
+// pid          - The process identifier
+// tid          - The thread identifier
+// level        - The level associated with the log message
+// tags         - The tag-set associated with the log message
+#define DECORATOR_LIST          \
+  DECORATOR(time,         t)    \
+  DECORATOR(uptime,       u)    \
+  DECORATOR(timemillis,   tm)   \
+  DECORATOR(uptimemillis, um)   \
+  DECORATOR(timenanos,    tn)   \
+  DECORATOR(uptimenanos,  un)   \
+  DECORATOR(pid,          p)    \
+  DECORATOR(tid,          ti)   \
+  DECORATOR(level,        l)    \
+  DECORATOR(tags,         tg)
+
+// LogDecorators represents a selection of decorators that should be prepended to
+// each log message for a given output. Decorators are always prepended in the order
+// declared above. For example, logging with 'uptime, level, tags' decorators results in:
+// [0,943s][info   ][logging] message.
+class LogDecorators VALUE_OBJ_CLASS_SPEC {
+ public:
+  enum Decorator {
+#define DECORATOR(name, abbr) name##_decorator,
+    DECORATOR_LIST
+#undef DECORATOR
+    Count,
+    Invalid
+  };
+
+ private:
+  uint _decorators;
+  static const char* _name[][2];
+  static const uint DefaultDecoratorsMask = (1 << uptime_decorator) | (1 << level_decorator) | (1 << tags_decorator);
+
+  static uint mask(LogDecorators::Decorator decorator) {
+    return 1 << decorator;
+  }
+
+ public:
+  LogDecorators() : _decorators(DefaultDecoratorsMask) {
+  };
+
+  void clear() {
+    _decorators = 0;
+  }
+
+  static const char* name(LogDecorators::Decorator decorator) {
+    return _name[decorator][0];
+  }
+
+  static const char* abbreviation(LogDecorators::Decorator decorator) {
+    return _name[decorator][1];
+  }
+
+  static LogDecorators::Decorator from_string(const char* str);
+
+  void combine_with(const LogDecorators &source) {
+    _decorators |= source._decorators;
+  }
+
+  bool is_decorator(LogDecorators::Decorator decorator) const {
+    return (_decorators & mask(decorator)) != 0;
+  }
+
+  bool parse(const char* decorator_args, outputStream* errstream = NULL);
+};
+
+#endif // SHARE_VM_LOGGING_LOGDECORATORS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logDiagnosticCommand.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logConfiguration.hpp"
+#include "logging/logDiagnosticCommand.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+LogDiagnosticCommand::LogDiagnosticCommand(outputStream* output, bool heap_allocated)
+  : DCmdWithParser(output, heap_allocated),
+    _output("output", "The name or index (#<index>) of output to configure.", "STRING", false),
+    _output_options("output_options", "Options for the output.", "STRING", false),
+    _what("what", "Configures what tags to log.", "STRING", false),
+    _decorators("decorators", "Configures which decorators to use. Use 'none' or an empty value to remove all.", "STRING", false),
+    _disable("disable", "Turns off all logging and clears the log configuration.", "BOOLEAN", false),
+    _list("list", "Lists current log configuration.", "BOOLEAN", false) {
+  _dcmdparser.add_dcmd_option(&_output);
+  _dcmdparser.add_dcmd_option(&_output_options);
+  _dcmdparser.add_dcmd_option(&_what);
+  _dcmdparser.add_dcmd_option(&_decorators);
+  _dcmdparser.add_dcmd_option(&_disable);
+  _dcmdparser.add_dcmd_option(&_list);
+}
+
+int LogDiagnosticCommand::num_arguments() {
+  ResourceMark rm;
+  LogDiagnosticCommand* dcmd = new LogDiagnosticCommand(NULL, false);
+  if (dcmd != NULL) {
+    DCmdMark mark(dcmd);
+    return dcmd->_dcmdparser.num_arguments();
+  } else {
+    return 0;
+  }
+}
+
+void LogDiagnosticCommand::registerCommand() {
+  uint32_t full_visibility = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<LogDiagnosticCommand>(full_visibility, true, false));
+}
+
+void LogDiagnosticCommand::execute(DCmdSource source, TRAPS) {
+  bool any_command = false;
+  if (_disable.has_value()) {
+    MutexLocker ml(LogConfiguration_lock);
+    LogConfiguration::disable_logging();
+    any_command = true;
+  }
+
+  if (_output.has_value() || _what.has_value() || _decorators.has_value()) {
+    MutexLocker ml(LogConfiguration_lock);
+    if (!LogConfiguration::parse_log_arguments(_output.value(),
+                                               _what.value(),
+                                               _decorators.value(),
+                                               _output_options.value(),
+                                               output())) {
+      return;
+    }
+    any_command = true;
+  }
+
+  if (_list.has_value()) {
+    MutexLocker ml(LogConfiguration_lock);
+    LogConfiguration::describe(output());
+    any_command = true;
+  }
+
+  if (!any_command) {
+    // If no argument was provided, print usage
+    print_help(LogDiagnosticCommand::name());
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logDiagnosticCommand.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGDIAGNOSTICCOMMAND_HPP
+#define SHARE_VM_LOGGING_LOGDIAGNOSTICCOMMAND_HPP
+
+#include "services/diagnosticCommand.hpp"
+
+// The LogDiagnosticCommand represents the 'VM.log' DCMD
+// that allows configuration of the logging at runtime.
+// It can be used to view or modify the current log configuration.
+// VM.log without additional arguments prints the usage description.
+// The 'list' argument will list all available log tags,
+// levels, decorators and currently configured log outputs.
+// Specifying 'disable' will disable logging completely.
+// The remaining arguments are used to set a log output to log everything
+// with the specified tags and levels using the given decorators.
+class LogDiagnosticCommand : public DCmdWithParser {
+ protected:
+  DCmdArgument<char *> _output;
+  DCmdArgument<char *> _output_options;
+  DCmdArgument<char *> _what;
+  DCmdArgument<char *> _decorators;
+  DCmdArgument<bool> _disable;
+  DCmdArgument<bool> _list;
+
+ public:
+  LogDiagnosticCommand(outputStream* output, bool heap_allocated);
+  void execute(DCmdSource source, TRAPS);
+  static void registerCommand();
+  static int num_arguments();
+
+  static const char* name() {
+    return "VM.log";
+  }
+
+  static const char* description() {
+    return "Lists, enables, disables or changes a log output configuration.";
+  }
+
+  // Used by SecurityManager. This DCMD requires ManagementPermission = control.
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission", "control", NULL};
+    return p;
+  }
+};
+
+#endif // SHARE_VM_LOGGING_LOGDIAGNOSTICCOMMAND_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logFileOutput.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2015, 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 "logging/log.hpp"
+#include "logging/logConfiguration.hpp"
+#include "logging/logFileOutput.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/os.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/defaultStream.hpp"
+
+const char* LogFileOutput::FileOpenMode = "a";
+const char* LogFileOutput::PidFilenamePlaceholder = "%p";
+const char* LogFileOutput::TimestampFilenamePlaceholder = "%t";
+const char* LogFileOutput::TimestampFormat = "%Y-%m-%d_%H-%M-%S";
+const char* LogFileOutput::FileSizeOptionKey = "filesize";
+const char* LogFileOutput::FileCountOptionKey = "filecount";
+char        LogFileOutput::_pid_str[PidBufferSize];
+char        LogFileOutput::_vm_start_time_str[StartTimeBufferSize];
+
+LogFileOutput::LogFileOutput(const char* name)
+    : LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)),
+      _file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0),
+      _rotate_size(0), _current_file(1), _file_count(0),
+      _rotation_lock(Mutex::leaf, "LogFileOutput rotation lock", true, Mutex::_safepoint_check_sometimes) {
+  _file_name = make_file_name(name, _pid_str, _vm_start_time_str);
+}
+
+void LogFileOutput::set_file_name_parameters(jlong vm_start_time) {
+  int res = jio_snprintf(_pid_str, sizeof(_pid_str), "%d", os::current_process_id());
+  assert(res > 0, "PID buffer too small");
+
+  struct tm local_time;
+  time_t utc_time = vm_start_time / 1000;
+  os::localtime_pd(&utc_time, &local_time);
+  res = (int)strftime(_vm_start_time_str, sizeof(_vm_start_time_str), TimestampFormat, &local_time);
+  assert(res > 0, "VM start time buffer too small.");
+}
+
+LogFileOutput::~LogFileOutput() {
+  if (_stream != NULL) {
+    if (_archive_name != NULL) {
+      archive();
+    }
+    if (fclose(_stream) != 0) {
+      jio_fprintf(defaultStream::error_stream(), "Could not close log file '%s' (%s).\n",
+                  _file_name, strerror(errno));
+    }
+  }
+  os::free(_archive_name);
+  os::free(_file_name);
+  os::free(const_cast<char*>(_name));
+}
+
+size_t LogFileOutput::parse_value(const char* value_str) {
+  char* end;
+  unsigned long long value = strtoull(value_str, &end, 10);
+  if (!isdigit(*value_str) || end != value_str + strlen(value_str) || value >= SIZE_MAX) {
+    return SIZE_MAX;
+  }
+  return value;
+}
+
+bool LogFileOutput::configure_rotation(const char* options) {
+  if (options == NULL || strlen(options) == 0) {
+    return true;
+  }
+  bool success = true;
+  char* opts = os::strdup_check_oom(options, mtLogging);
+
+  char* comma_pos;
+  char* pos = opts;
+  do {
+    comma_pos = strchr(pos, ',');
+    if (comma_pos != NULL) {
+      *comma_pos = '\0';
+    }
+
+    char* equals_pos = strchr(pos, '=');
+    if (equals_pos == NULL) {
+      success = false;
+      break;
+    }
+    char* key = pos;
+    char* value_str = equals_pos + 1;
+    *equals_pos = '\0';
+
+    if (strcmp(FileCountOptionKey, key) == 0) {
+      size_t value = parse_value(value_str);
+      if (value == SIZE_MAX || value >= UINT_MAX) {
+        success = false;
+        break;
+      }
+      _file_count = static_cast<uint>(value);
+      _file_count_max_digits = static_cast<uint>(log10(static_cast<double>(_file_count)) + 1);
+      _archive_name_len = 2 + strlen(_file_name) + _file_count_max_digits;
+      _archive_name = NEW_C_HEAP_ARRAY(char, _archive_name_len, mtLogging);
+    } else if (strcmp(FileSizeOptionKey, key) == 0) {
+      size_t value = parse_value(value_str);
+      if (value == SIZE_MAX || value > SIZE_MAX / K) {
+        success = false;
+        break;
+      }
+      _rotate_size = value * K;
+    } else {
+      success = false;
+      break;
+    }
+    pos = comma_pos + 1;
+  } while (comma_pos != NULL);
+
+  os::free(opts);
+  return success;
+}
+
+bool LogFileOutput::initialize(const char* options) {
+  if (!configure_rotation(options)) {
+    return false;
+  }
+  _stream = fopen(_file_name, FileOpenMode);
+  if (_stream == NULL) {
+    log_error(logging)("Could not open log file '%s' (%s).\n", _file_name, strerror(errno));
+    return false;
+  }
+  return true;
+}
+
+int LogFileOutput::write(const LogDecorations& decorations, const char* msg) {
+  if (_stream == NULL) {
+    // An error has occurred with this output, avoid writing to it.
+    return 0;
+  }
+  int written = LogFileStreamOutput::write(decorations, msg);
+  _current_size += written;
+
+  if (should_rotate()) {
+    MutexLockerEx ml(&_rotation_lock, true /* no safepoint check */);
+    if (should_rotate()) {
+      rotate();
+    }
+  }
+
+  return written;
+}
+
+void LogFileOutput::archive() {
+  assert(_archive_name != NULL && _archive_name_len > 0, "Rotation must be configured before using this function.");
+  int ret = jio_snprintf(_archive_name, _archive_name_len, "%s.%0*u",
+                         _file_name, _file_count_max_digits, _current_file);
+  assert(ret >= 0, "Buffer should always be large enough");
+
+  // Attempt to remove possibly existing archived log file before we rename.
+  // Don't care if it fails, we really only care about the rename that follows.
+  remove(_archive_name);
+
+  // Rename the file from ex hotspot.log to hotspot.log.2
+  if (rename(_file_name, _archive_name) == -1) {
+    jio_fprintf(defaultStream::error_stream(), "Could not rename log file '%s' to '%s' (%s).\n",
+                _file_name, _archive_name, strerror(errno));
+  }
+}
+
+void LogFileOutput::rotate() {
+  // Archive the current log file
+  archive();
+
+  // Open the active log file using the same stream as before
+  _stream = freopen(_file_name, FileOpenMode, _stream);
+  if (_stream == NULL) {
+    jio_fprintf(defaultStream::error_stream(), "Could not reopen file '%s' during log rotation (%s).\n",
+                _file_name, strerror(errno));
+    return;
+  }
+
+  // Reset accumulated size, increase current file counter, and check for file count wrap-around.
+  _current_size = 0;
+  _current_file = (_current_file >= _file_count ? 1 : _current_file + 1);
+}
+
+char* LogFileOutput::make_file_name(const char* file_name,
+                                    const char* pid_string,
+                                    const char* timestamp_string) {
+  char* result = NULL;
+
+  // Lets start finding out if we have any %d and/or %t in the name.
+  // We will only replace the first occurrence of any placeholder
+  const char* pid = strstr(file_name, PidFilenamePlaceholder);
+  const char* timestamp = strstr(file_name, TimestampFilenamePlaceholder);
+
+  if (pid == NULL && timestamp == NULL) {
+    // We found no place-holders, return the simple filename
+    return os::strdup_check_oom(file_name, mtLogging);
+  }
+
+  // At least one of the place-holders were found in the file_name
+  const char* first = "";
+  size_t first_pos = SIZE_MAX;
+  size_t first_replace_len = 0;
+
+  const char* second = "";
+  size_t second_pos = SIZE_MAX;
+  size_t second_replace_len = 0;
+
+  // If we found a %p, then setup our variables accordingly
+  if (pid != NULL) {
+    if (timestamp == NULL || pid < timestamp) {
+      first = pid_string;
+      first_pos = pid - file_name;
+      first_replace_len = strlen(PidFilenamePlaceholder);
+    } else {
+      second = pid_string;
+      second_pos = pid - file_name;
+      second_replace_len = strlen(PidFilenamePlaceholder);
+    }
+  }
+
+  if (timestamp != NULL) {
+    if (pid == NULL || timestamp < pid) {
+      first = timestamp_string;
+      first_pos = timestamp - file_name;
+      first_replace_len = strlen(TimestampFilenamePlaceholder);
+    } else {
+      second = timestamp_string;
+      second_pos = timestamp - file_name;
+      second_replace_len = strlen(TimestampFilenamePlaceholder);
+    }
+  }
+
+  size_t first_len = strlen(first);
+  size_t second_len = strlen(second);
+
+  // Allocate the new buffer, size it to hold all we want to put in there +1.
+  size_t result_len =  strlen(file_name) + first_len - first_replace_len + second_len - second_replace_len;
+  result = NEW_C_HEAP_ARRAY(char, result_len + 1, mtLogging);
+
+  // Assemble the strings
+  size_t file_name_pos = 0;
+  size_t i = 0;
+  while (i < result_len) {
+    if (file_name_pos == first_pos) {
+      // We are in the range of the first placeholder
+      strcpy(result + i, first);
+      // Bump output buffer position with length of replacing string
+      i += first_len;
+      // Bump source buffer position to skip placeholder
+      file_name_pos += first_replace_len;
+    } else if (file_name_pos == second_pos) {
+      // We are in the range of the second placeholder
+      strcpy(result + i, second);
+      i += second_len;
+      file_name_pos += second_replace_len;
+    } else {
+      // Else, copy char by char of the original file
+      result[i] = file_name[file_name_pos++];
+      i++;
+    }
+  }
+  // Add terminating char
+  result[result_len] = '\0';
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logFileOutput.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGFILEOUTPUT_HPP
+#define SHARE_VM_LOGGING_LOGFILEOUTPUT_HPP
+
+#include "logging/logFileStreamOutput.hpp"
+#include "runtime/mutex.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogDecorations;
+
+// The log file output, with support for file rotation based on a target size.
+class LogFileOutput : public LogFileStreamOutput {
+ private:
+  static const char*  FileOpenMode;
+  static const char*  FileCountOptionKey;
+  static const char*  FileSizeOptionKey;
+  static const char*  PidFilenamePlaceholder;
+  static const char*  TimestampFilenamePlaceholder;
+  static const char*  TimestampFormat;
+  static const size_t StartTimeBufferSize = 20;
+  static const size_t PidBufferSize       = 21;
+  static char         _pid_str[PidBufferSize];
+  static char         _vm_start_time_str[StartTimeBufferSize];
+
+  Mutex _rotation_lock;
+  const char* _name;
+  char* _file_name;
+  char* _archive_name;
+
+  uint  _current_file;
+  uint  _file_count;
+  uint  _file_count_max_digits;
+
+  size_t  _archive_name_len;
+  size_t  _rotate_size;
+  size_t  _current_size;
+
+  void archive();
+  void rotate();
+  bool configure_rotation(const char* options);
+  char *make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string);
+  static size_t parse_value(const char* value_str);
+
+  bool should_rotate() const {
+    return _file_count > 0 && _rotate_size > 0 && _current_size >= _rotate_size;
+  }
+
+ public:
+  LogFileOutput(const char *name);
+  virtual ~LogFileOutput();
+  virtual bool initialize(const char* options);
+  virtual int write(const LogDecorations& decorations, const char* msg);
+
+  virtual const char* name() const {
+    return _name;
+  }
+
+  static void set_file_name_parameters(jlong start_time);
+};
+
+#endif // SHARE_VM_LOGGING_LOGFILEOUTPUT_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logFileStreamOutput.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logDecorators.hpp"
+#include "logging/logDecorations.hpp"
+#include "logging/logFileStreamOutput.hpp"
+#include "memory/allocation.inline.hpp"
+
+LogStdoutOutput LogStdoutOutput::_instance;
+LogStderrOutput LogStderrOutput::_instance;
+
+int LogFileStreamOutput::write(const LogDecorations& decorations, const char* msg) {
+  char decoration_buf[LogDecorations::DecorationsBufferSize];
+  char* position = decoration_buf;
+  int total_written = 0;
+
+  for (uint i = 0; i < LogDecorators::Count; i++) {
+    LogDecorators::Decorator decorator = static_cast<LogDecorators::Decorator>(i);
+    if (!_decorators.is_decorator(decorator)) {
+      continue;
+    }
+    int written = jio_snprintf(position, sizeof(decoration_buf) - total_written, "[%-*s]",
+                               _decorator_padding[decorator],
+                               decorations.decoration(decorator));
+    if (written <= 0) {
+      return -1;
+    } else if (static_cast<size_t>(written - 2) > _decorator_padding[decorator]) {
+      _decorator_padding[decorator] = written - 2;
+    }
+    position += written;
+    total_written += written;
+  }
+
+  if (total_written == 0) {
+    total_written = jio_fprintf(_stream, "%s\n", msg);
+  } else {
+    total_written = jio_fprintf(_stream, "%s %s\n", decoration_buf, msg);
+  }
+  fflush(_stream);
+  return total_written;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logFileStreamOutput.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGFILESTREAMOUTPUT_HPP
+#define SHARE_VM_LOGGING_LOGFILESTREAMOUTPUT_HPP
+
+#include "logging/logDecorators.hpp"
+#include "logging/logOutput.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogDecorations;
+
+// Base class for all FileStream-based log outputs.
+class LogFileStreamOutput : public LogOutput {
+ protected:
+  FILE*               _stream;
+  size_t              _decorator_padding[LogDecorators::Count];
+
+  LogFileStreamOutput(FILE *stream) : _stream(stream) {
+    for (size_t i = 0; i < LogDecorators::Count; i++) {
+      _decorator_padding[i] = 0;
+    }
+    _decorator_padding[LogDecorators::level_decorator] = 7;
+  }
+
+ public:
+  virtual int write(const LogDecorations &decorations, const char* msg);
+};
+
+class LogStdoutOutput : public LogFileStreamOutput {
+  friend class LogOutput;
+ private:
+  static LogStdoutOutput _instance;
+  LogStdoutOutput() : LogFileStreamOutput(stdout) {
+    set_config_string("all=off");
+  }
+  virtual bool initialize(const char* options) {
+    return false;
+  }
+ public:
+  virtual const char* name() const {
+    return "stdout";
+  }
+};
+
+class LogStderrOutput : public LogFileStreamOutput {
+  friend class LogOutput;
+ private:
+  static LogStderrOutput _instance;
+  LogStderrOutput() : LogFileStreamOutput(stderr) {
+    set_config_string("all=warning");
+  }
+  virtual bool initialize(const char* options) {
+    return false;
+  }
+ public:
+  virtual const char* name() const {
+    return "stderr";
+  }
+};
+
+#endif // SHARE_VM_LOGGING_LOGFILESTREAMOUTPUT_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logLevel.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logLevel.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+const char* LogLevel::_name[] = {
+  "off",
+#define LOG_LEVEL(name, printname) #printname,
+  LOG_LEVEL_LIST
+#undef LOG_LEVEL
+};
+
+LogLevelType LogLevel::from_string(const char* str) {
+  for (uint i = 0; i < Count; i++) {
+    if (strcasecmp(str, _name[i]) == 0) {
+      return static_cast<LogLevelType>(i);
+    }
+  }
+  return Invalid;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logLevel.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGLEVEL_HPP
+#define SHARE_VM_LOGGING_LOGLEVEL_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/macros.hpp"
+
+// The list of log levels:
+//
+//  develop - A non-product level that is finer than trace.
+//            Should be used for really expensive and/or
+//            extensive logging, or logging that shouldn't
+//            or can't be included in a product build.
+//
+//  trace   - Finest level of logging in product builds.
+//            Use for extensive/noisy logging that can
+//            give slow-down when enabled.
+//
+//  debug   - A finer level of logging. Use for semi-noisy
+//            logging that is does not fit the info level.
+//
+//  info    - General level of logging. Use for significant
+//            events and/or informative summaries.
+//
+//  warning - Important messages that are not strictly errors.
+//
+//  error   - Critical messages caused by errors.
+//
+#define LOG_LEVEL_LIST \
+  NOT_PRODUCT(LOG_LEVEL(Develop, develop)) \
+  LOG_LEVEL(Trace, trace) \
+  LOG_LEVEL(Debug, debug) \
+  LOG_LEVEL(Info, info) \
+  LOG_LEVEL(Warning, warning) \
+  LOG_LEVEL(Error, error)
+
+class LogLevel : public AllStatic {
+ public:
+  enum type {
+    Off,
+#define LOG_LEVEL(name, printname) name,
+    LOG_LEVEL_LIST
+#undef LOG_LEVEL
+    Count,
+    Invalid,
+    First = Off + 1,
+    Last = Error,
+    Default = Warning,
+    Unspecified = Info
+  };
+
+  static const char *name(LogLevel::type level) {
+    return _name[level];
+  }
+
+  static LogLevel::type from_string(const char* str);
+
+ private:
+  static const char* _name[];
+};
+
+typedef LogLevel::type LogLevelType;
+
+#endif // SHARE_VM_LOGGING_LOGLEVEL_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logOutput.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logFileStreamOutput.hpp"
+#include "logging/logOutput.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/os.inline.hpp"
+
+LogOutput* const LogOutput::Stdout = &LogStdoutOutput::_instance;
+LogOutput* const LogOutput::Stderr = &LogStderrOutput::_instance;
+
+LogOutput::~LogOutput() {
+  os::free(_config_string);
+}
+
+void LogOutput::set_config_string(const char* string) {
+  os::free(_config_string);
+  _config_string = os::strdup_check_oom(string, mtLogging);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logOutput.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGOUTPUT_HPP
+#define SHARE_VM_LOGGING_LOGOUTPUT_HPP
+
+#include "logging/logDecorators.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogDecorations;
+
+// The base class/interface for log outputs.
+// Keeps track of the latest configuration string,
+// and its selected decorators.
+class LogOutput : public CHeapObj<mtLogging> {
+ protected:
+  LogDecorators _decorators;
+  char* _config_string;
+
+ public:
+  static LogOutput* const Stdout;
+  static LogOutput* const Stderr;
+
+  void set_decorators(const LogDecorators &decorators) {
+    _decorators = decorators;
+  }
+
+  const LogDecorators& decorators() const {
+    return _decorators;
+  }
+
+  const char* config_string() const {
+    return _config_string;
+  }
+
+  LogOutput() : _config_string(NULL) {
+  }
+
+  virtual ~LogOutput();
+  void set_config_string(const char* string);
+
+  virtual const char* name() const = 0;
+  virtual bool initialize(const char* options) = 0;
+  virtual int write(const LogDecorations &decorations, const char* msg) = 0;
+};
+
+#endif // SHARE_VM_LOGGING_LOGOUTPUT_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logOutputList.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logLevel.hpp"
+#include "logging/logOutputList.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/atomic.inline.hpp"
+#include "runtime/orderAccess.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+jint LogOutputList::increase_readers() {
+  jint result = Atomic::add(1, &_active_readers);
+  assert(_active_readers > 0, "Ensure we have consistent state");
+  return result;
+}
+
+jint LogOutputList::decrease_readers() {
+  jint result = Atomic::add(-1, &_active_readers);
+  assert(result >= 0, "Ensure we have consistent state");
+  return result;
+}
+
+void LogOutputList::wait_until_no_readers() const {
+  OrderAccess::storeload();
+  while (_active_readers != 0) {
+    // Busy wait
+  }
+}
+
+void LogOutputList::set_output_level(LogOutput* output, LogLevelType level) {
+  LogOutputNode* node = find(output);
+  if (level == LogLevel::Off && node != NULL) {
+    remove_output(node);
+  } else if (level != LogLevel::Off && node == NULL) {
+    add_output(output, level);
+  } else if (node != NULL) {
+    update_output_level(node, level);
+  }
+}
+
+LogOutputList::LogOutputNode* LogOutputList::find(LogOutput* output) {
+  for (LogOutputNode* node = _level_start[LogLevel::Last]; node != NULL; node = node->_next) {
+    if (output == node->_value) {
+      return node;
+    }
+  }
+  return NULL;
+}
+
+void LogOutputList::remove_output(LogOutputList::LogOutputNode* node) {
+  assert(node != NULL, "Node must be non-null");
+
+  // Remove node from _level_start first
+  bool found = false;
+  for (uint level = LogLevel::First; level < LogLevel::Count; level++) {
+    if (_level_start[level] == node) {
+      found = true;
+      _level_start[level] = node->_next;
+    }
+  }
+
+  // Now remove it from the linked list
+  for (LogOutputNode* cur = _level_start[LogLevel::Last]; cur != NULL; cur = cur->_next) {
+    if (cur->_next == node) {
+      found = true;
+      cur->_next = node->_next;
+      break;
+    }
+  }
+  assert(found, "Node to be removed should always be found");
+
+  wait_until_no_readers();
+  delete node;
+}
+
+void LogOutputList::add_output(LogOutput* output, LogLevelType level) {
+  LogOutputNode* node = new LogOutputNode();
+  node->_value = output;
+  node->_level = level;
+
+  // Set the next pointer to the first node of a lower level
+  for (node->_next = _level_start[level];
+       node->_next != NULL && node->_next->_level == level;
+       node->_next = node->_next->_next) {
+  }
+
+  // Update the _level_start index
+  for (int l = LogLevel::Last; l >= level; l--) {
+    if (_level_start[l] == NULL || _level_start[l]->_level < level) {
+      _level_start[l] = node;
+    }
+  }
+
+  // Add the node the list
+  for (LogOutputNode* cur = _level_start[LogLevel::Last]; cur != NULL; cur = cur->_next) {
+    if (cur != node && cur->_next == node->_next) {
+      cur->_next = node;
+      break;
+    }
+  }
+}
+
+void LogOutputList::update_output_level(LogOutputList::LogOutputNode* node, LogLevelType level) {
+  add_output(node->_value, level);
+  wait_until_no_readers();
+  remove_output(node);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logOutputList.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGOUTPUTLIST_HPP
+#define SHARE_VM_LOGGING_LOGOUTPUTLIST_HPP
+
+#include "logging/logLevel.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogOutput;
+
+// Data structure to keep track of log outputs for a given tagset.
+// Essentially a sorted linked list going from error level outputs
+// to outputs of finer levels. Keeps an index from each level to
+// the first node in the list for the corresponding level.
+// This allows a log message on, for example, info level to jump
+// straight into the list where the first info level output can
+// be found. The log message will then be printed on that output,
+// as well as all outputs in nodes that follow in the list (which
+// can be additional info level outputs and/or debug and trace outputs).
+//
+// Each instance keeps track of the number of current readers of the list.
+// To remove a node from the list the node must first be unlinked,
+// and the memory for that node can be freed whenever the removing
+// thread observes an active reader count of 0 (after unlinking it).
+class LogOutputList VALUE_OBJ_CLASS_SPEC {
+ private:
+  struct LogOutputNode : public CHeapObj<mtLogging> {
+    LogOutput*      _value;
+    LogOutputNode*  _next;
+    LogLevelType    _level;
+  };
+
+  LogOutputNode*  _level_start[LogLevel::Count];
+  volatile jint   _active_readers;
+
+  LogOutputNode* find(LogOutput* output);
+  void remove_output(LogOutputNode* node);
+  void add_output(LogOutput* output, LogLevelType level);
+  void update_output_level(LogOutputNode* node, LogLevelType level);
+
+ public:
+  LogOutputList() : _active_readers(0) {
+    for (size_t i = 0; i < LogLevel::Count; i++) {
+      _level_start[i] = NULL;
+    }
+  }
+
+  // Test if the outputlist has an output for the given level.
+  bool is_level(LogLevelType level) {
+    return _level_start[level] != NULL;
+  }
+
+  // Set (add/update/remove) the output to the specified level.
+  void set_output_level(LogOutput* output, LogLevelType level);
+
+  // Bookkeeping functions to keep track of number of active readers/iterators for the list.
+  jint increase_readers();
+  jint decrease_readers();
+  void wait_until_no_readers() const;
+
+  class Iterator VALUE_OBJ_CLASS_SPEC {
+    friend class LogOutputList;
+   private:
+    LogOutputNode*  _current;
+    LogOutputList*  _list;
+    Iterator(LogOutputList* list, LogOutputNode* start) : _current(start), _list(list) {
+    }
+
+   public:
+    ~Iterator() {
+      _list->decrease_readers();
+    }
+
+    LogOutput* operator*() {
+      return _current->_value;
+    }
+
+    void operator++(int) {
+      _current = _current->_next;
+    }
+
+    bool operator!=(const LogOutputNode *ref) const {
+      return _current != ref;
+    }
+  };
+
+  Iterator iterator(LogLevelType level = LogLevel::Last) {
+    increase_readers();
+    return Iterator(this, _level_start[level]);
+  }
+
+  LogOutputNode* end() const {
+    return NULL;
+  }
+};
+
+#endif // SHARE_VM_LOGGING_LOGOUTPUTLIST_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logPrefix.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGPREFIX_HPP
+#define SHARE_VM_LOGGING_LOGPREFIX_HPP
+
+#include "gc/shared/gcId.hpp"
+#include "logging/logTag.hpp"
+
+// Prefixes prepend each log message for a specified tagset with the given prefix.
+// A prefix consists of a format string and a value or callback. Prefixes are added
+// after the decorations but before the log message.
+//
+// List of prefixes for specific tags and/or tagsets.
+// Syntax: LOG_PREFIX(<printf format>, <value/callback for value>, LOG_TAGS(<chosen log tags>))
+#define LOG_PREFIX_LIST // Currently unused/empty
+
+// The empty prefix, used when there's no prefix defined.
+template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag = LogTag::__NO_TAG>
+struct LogPrefix : public AllStatic {
+  STATIC_ASSERT(GuardTag == LogTag::__NO_TAG);
+  static size_t prefix(char* buf, size_t len) {
+    return 0;
+  }
+};
+
+#define LOG_PREFIX(fmt, fn, ...) \
+template <> struct LogPrefix<__VA_ARGS__> { \
+  static size_t prefix(char* buf, size_t len) { \
+    int ret = jio_snprintf(buf, len, fmt, fn); \
+    assert(ret >= 0, \
+           "Failed to prefix log message using prefix ('%s', '%s'), log buffer too small?", fmt, #fn); \
+    return ret; \
+  } \
+};
+LOG_PREFIX_LIST
+#undef LOG_PREFIX
+
+#endif // SHARE_VM_LOGGING_LOGPREFIX_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logTag.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logTag.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+const char* LogTag::_name[] = {
+  "", // __NO_TAG
+#define LOG_TAG(name) #name,
+  LOG_TAG_LIST
+#undef LOG_TAG
+};
+
+LogTagType LogTag::from_string(const char* str) {
+  for (uint i = 0; i < LogTag::Count; i++) {
+    if (strcasecmp(str, _name[i]) == 0) {
+      return static_cast<LogTagType>(i);
+    }
+  }
+  return __NO_TAG;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logTag.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGTAG_HPP
+#define SHARE_VM_LOGGING_LOGTAG_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// List of available logging tags. New tags should be added here.
+// (The tags 'all', 'disable' and 'help' are special tags that can
+// not be used in log calls, and should not be listed below.)
+#define LOG_TAG_LIST \
+  LOG_TAG(logging)
+
+#define PREFIX_LOG_TAG(T) (LogTag::T)
+
+// Expand a set of log tags to their prefixed names.
+// For error detection purposes, the macro passes one more tag than what is supported.
+// If too many tags are given, a static assert in the log class will fail.
+#define LOG_TAGS_EXPANDED(T0, T1, T2, T3, T4, T5, ...)  PREFIX_LOG_TAG(T0), PREFIX_LOG_TAG(T1), PREFIX_LOG_TAG(T2), \
+                                                        PREFIX_LOG_TAG(T3), PREFIX_LOG_TAG(T4), PREFIX_LOG_TAG(T5)
+// The EXPAND_VARARGS macro is required for MSVC, or it will resolve the LOG_TAGS_EXPANDED macro incorrectly.
+#define EXPAND_VARARGS(x) x
+#define LOG_TAGS(...) EXPAND_VARARGS(LOG_TAGS_EXPANDED(__VA_ARGS__, __NO_TAG, __NO_TAG, __NO_TAG, __NO_TAG, __NO_TAG, __NO_TAG))
+
+// Log tags are used to classify log messages.
+// Each log message can be assigned between 1 to LogTag::MaxTags number of tags.
+// Specifying multiple tags for a log message means that only outputs configured
+// for those exact tags, or a subset of the tags with a wildcard, will see the logging.
+// Multiple tags should be comma separated, e.g. log_error(tag1, tag2)("msg").
+class LogTag : public AllStatic {
+ public:
+  // The maximum number of tags that a single log message can have.
+  // E.g. there might be hundreds of different tags available,
+  // but a specific log message can only be tagged with up to MaxTags of those.
+  static const size_t MaxTags = 5;
+
+  enum type {
+    __NO_TAG,
+#define LOG_TAG(name) name,
+    LOG_TAG_LIST
+#undef LOG_TAG
+    Count
+  };
+
+  static const char* name(LogTag::type tag) {
+    return _name[tag];
+  }
+
+  static LogTag::type from_string(const char *str);
+
+ private:
+  static const char* _name[];
+};
+
+typedef LogTag::type LogTagType;
+
+#endif // SHARE_VM_LOGGING_LOGTAG_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logTagLevelExpression.hpp"
+#include "logging/logTagSet.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/os.inline.hpp"
+
+const char* LogTagLevelExpression::DefaultExpressionString = "all";
+
+LogTagLevelExpression::~LogTagLevelExpression() {
+  os::free(_string);
+}
+
+void LogTagLevelExpression::clear() {
+  _ntags = 0;
+  _ncombinations = 0;
+  for (size_t combination = 0; combination < MaxCombinations; combination++) {
+    _level[combination] = LogLevel::Invalid;
+    _allow_other_tags[combination] = false;
+    for (size_t tag = 0; tag < LogTag::MaxTags; tag++) {
+      _tags[combination][tag] = LogTag::__NO_TAG;
+    }
+  }
+  os::free(_string);
+  _string = NULL;
+}
+
+bool LogTagLevelExpression::parse(const char* str, outputStream* errstream) {
+  bool success = true;
+  clear();
+  if (str == NULL || strcmp(str, "") == 0) {
+    str = DefaultExpressionString;
+  }
+  char* copy = os::strdup_check_oom(str, mtLogging);
+  // Split string on commas
+  for (char *comma_pos = copy, *cur = copy; success && comma_pos != NULL; cur = comma_pos + 1) {
+    if (_ncombinations == MaxCombinations) {
+      if (errstream != NULL) {
+        errstream->print_cr("Can not have more than " SIZE_FORMAT " tag combinations in a what-expression.",
+                            MaxCombinations);
+      }
+      success = false;
+      break;
+    }
+
+    comma_pos = strchr(cur, ',');
+    if (comma_pos != NULL) {
+      *comma_pos = '\0';
+    }
+
+    // Parse the level, if specified
+    LogLevelType level = LogLevel::Unspecified;
+    char* equals = strchr(cur, '=');
+    if (equals != NULL) {
+      level = LogLevel::from_string(equals + 1);
+      if (level == LogLevel::Invalid) {
+        if (errstream != NULL) {
+          errstream->print_cr("Invalid level '%s' in what-expression.", equals + 1);
+        }
+        success = false;
+        break;
+      }
+      *equals = '\0'; // now ignore "=level" part of substr
+    }
+    set_level(level);
+
+    // Parse special tags such as 'all'
+    if (strcmp(cur, "all") == 0) {
+      set_allow_other_tags();
+      new_combination();
+      continue;
+    }
+
+    // Check for '*' suffix
+    char* asterisk_pos = strchr(cur, '*');
+    if (asterisk_pos != NULL && asterisk_pos[1] == '\0') {
+      set_allow_other_tags();
+      *asterisk_pos = '\0';
+    }
+
+    // Parse the tag expression (t1+t2+...+tn)
+    char* plus_pos;
+    char* cur_tag = cur;
+    do {
+      plus_pos = strchr(cur_tag, '+');
+      if (plus_pos != NULL) {
+        *plus_pos = '\0';
+      }
+      LogTagType tag = LogTag::from_string(cur_tag);
+      if (tag == LogTag::__NO_TAG) {
+        if (errstream != NULL) {
+          errstream->print_cr("Invalid tag '%s' in what-expression.", cur_tag);
+        }
+        success = false;
+        break;
+      }
+      if (_ntags == LogTag::MaxTags) {
+        if (errstream != NULL) {
+          errstream->print_cr("Tag combination exceeds the maximum of " SIZE_FORMAT " tags.",
+                              LogTag::MaxTags);
+        }
+        success = false;
+        break;
+      }
+      add_tag(tag);
+      cur_tag = plus_pos + 1;
+    } while (plus_pos != NULL);
+
+    new_combination();
+  }
+
+  // Save the (unmodified) string for printing purposes.
+  _string = copy;
+  strcpy(_string, str);
+
+  return success;
+}
+
+LogLevelType LogTagLevelExpression::level_for(const LogTagSet& ts) const {
+  LogLevelType level = LogLevel::Off;
+  for (size_t combination = 0; combination < _ncombinations; combination++) {
+    bool contains_all = true;
+    size_t tag_idx;
+    for (tag_idx = 0; tag_idx < LogTag::MaxTags && _tags[combination][tag_idx] != LogTag::__NO_TAG; tag_idx++) {
+      if (!ts.contains(_tags[combination][tag_idx])) {
+        contains_all = false;
+        break;
+      }
+    }
+    // All tags in the expression must be part of the tagset,
+    // and either the expression allows other tags (has a wildcard),
+    // or the number of tags in the expression and tagset must match.
+    if (contains_all && (_allow_other_tags[combination] || tag_idx == ts.ntags())) {
+      level = _level[combination];
+    }
+  }
+  return level;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGTAGLEVELEXPRESSION_HPP
+#define SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
+
+#include "logging/logLevel.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogTagSet;
+
+// Class used to temporary encode a 'what'-expression during log configuration.
+// Consists of a combination of tags and levels, e.g. "tag1+tag2=level1,tag3*=level2".
+class LogTagLevelExpression : public StackObj {
+ private:
+  static const size_t MaxCombinations = 32;
+  static const char* DefaultExpressionString;
+
+  size_t        _ntags, _ncombinations;
+  LogTagType    _tags[MaxCombinations][LogTag::MaxTags];
+  LogLevelType  _level[MaxCombinations];
+  bool          _allow_other_tags[MaxCombinations];
+  char*         _string;
+
+  void new_combination() {
+    _ncombinations++;
+    _ntags = 0;
+  }
+
+  void add_tag(LogTagType tag) {
+    assert(_ntags < LogTag::MaxTags, "Can't have more tags than MaxTags!");
+    _tags[_ncombinations][_ntags++] = tag;
+  }
+
+  void set_level(LogLevelType level) {
+    _level[_ncombinations] = level;
+  }
+
+  void set_allow_other_tags() {
+    _allow_other_tags[_ncombinations] = true;
+  }
+
+  void clear();
+
+ public:
+  LogTagLevelExpression() : _ntags(0), _ncombinations(0), _string(NULL) {
+  }
+
+  const char* to_string() const {
+    return _string;
+  }
+
+  ~LogTagLevelExpression();
+  bool parse(const char* str, outputStream* errstream = NULL);
+  LogLevelType level_for(const LogTagSet& ts) const;
+};
+
+#endif // SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logTagSet.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, 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 "logging/logDecorations.hpp"
+#include "logging/logLevel.hpp"
+#include "logging/logOutput.hpp"
+#include "logging/logTag.hpp"
+#include "logging/logTagSet.hpp"
+
+LogTagSet*  LogTagSet::_list      = NULL;
+size_t      LogTagSet::_ntagsets  = 0;
+
+// This constructor is called only during static initialization.
+// See the declaration in logTagSet.hpp for more information.
+LogTagSet::LogTagSet(LogTagType t0, LogTagType t1, LogTagType t2, LogTagType t3, LogTagType t4)
+    : _next(_list) {
+  _tag[0] = t0;
+  _tag[1] = t1;
+  _tag[2] = t2;
+  _tag[3] = t3;
+  _tag[4] = t4;
+  for (_ntags = 0; _ntags < LogTag::MaxTags && _tag[_ntags] != LogTag::__NO_TAG; _ntags++) {
+  }
+  _list = this;
+  _ntagsets++;
+
+  // Set the default output to warning and error level for all new tagsets.
+  _output_list.set_output_level(LogOutput::Stderr, LogLevel::Default);
+}
+
+bool LogTagSet::is_level(LogLevelType level) {
+  return _output_list.is_level(level);
+}
+
+void LogTagSet::update_decorators(const LogDecorators& decorator) {
+  LogDecorators new_decorators = decorator;
+  for (LogOutputList::Iterator it = _output_list.iterator(); it != _output_list.end(); it++) {
+    new_decorators.combine_with((*it)->decorators());
+  }
+  _decorators = new_decorators;
+}
+
+bool LogTagSet::has_output(const LogOutput* output) {
+  for (LogOutputList::Iterator it = _output_list.iterator(); it != _output_list.end(); it++) {
+    if (*it == output) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void LogTagSet::log(LogLevelType level, const char* msg) {
+  LogDecorations decorations(level, *this, _decorators);
+  for (LogOutputList::Iterator it = _output_list.iterator(level); it != _output_list.end(); it++) {
+    (*it)->write(decorations, msg);
+  }
+}
+
+int LogTagSet::label(char* buf, size_t len)  {
+  int tot_written = 0;
+  for (size_t i = 0; i < _ntags; i++) {
+    int written = jio_snprintf(buf + tot_written, len - tot_written, "%s%s",
+                               (i == 0 ? "" : ","),
+                               LogTag::name(_tag[i]));
+    if (written < 0) {
+      return -1;
+    }
+    tot_written += written;
+  }
+  return tot_written;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, 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_LOGGING_LOGTAGSET_HPP
+#define SHARE_VM_LOGGING_LOGTAGSET_HPP
+
+#include "logging/logDecorators.hpp"
+#include "logging/logLevel.hpp"
+#include "logging/logOutputList.hpp"
+#include "logging/logTag.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// The tagset represents a combination of tags that occur in a log call somewhere.
+// Tagsets are created automatically by the LogTagSetMappings and should never be
+// instantiated directly somewhere else.
+class LogTagSet VALUE_OBJ_CLASS_SPEC {
+ private:
+  static LogTagSet* _list;
+  static size_t     _ntagsets;
+
+  LogTagSet* const  _next;
+  size_t            _ntags;
+  LogTagType        _tag[LogTag::MaxTags];
+
+  LogOutputList     _output_list;
+  LogDecorators     _decorators;
+
+  // Keep constructor private to prevent incorrect instantiations of this class.
+  // Only LogTagSetMappings can create/contain instances of this class.
+  // The constructor links all tagsets together in a global list of tagsets.
+  // This list is used during configuration to be able to update all tagsets
+  // and their configurations to reflect the new global log configuration.
+  LogTagSet(LogTagType t0, LogTagType t1, LogTagType t2, LogTagType t3, LogTagType t4);
+
+  template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4>
+  friend class LogTagSetMapping;
+
+ public:
+  static LogTagSet* first() {
+    return _list;
+  }
+
+  LogTagSet* next() {
+    return _next;
+  }
+
+  size_t ntags() const {
+    return _ntags;
+  }
+
+  bool contains(LogTagType tag) const {
+    for (size_t i = 0; _tag[i] != LogTag::__NO_TAG; i++) {
+      if (tag == _tag[i]) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void set_output_level(LogOutput* output, LogLevelType level) {
+    _output_list.set_output_level(output, level);
+  }
+
+  // Refresh the decorators for this tagset to contain the decorators for all
+  // of its current outputs combined with the given decorators.
+  void update_decorators(const LogDecorators& decorator);
+
+  int label(char *buf, size_t len);
+  bool has_output(const LogOutput* output);
+  bool is_level(LogLevelType level);
+  void log(LogLevelType level, const char* msg);
+};
+
+template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG,
+          LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG>
+class LogTagSetMapping : public AllStatic {
+private:
+  static LogTagSet _tagset;
+
+public:
+  static LogTagSet& tagset() {
+    return _tagset;
+  }
+};
+
+// Instantiate the static field _tagset for all tagsets that are used for logging somewhere.
+// (This must be done here rather than the .cpp file because it's a template.)
+// Each combination of tags used as template arguments to the Log class somewhere (via macro or not)
+// will instantiate the LogTagSetMapping template, which in turn creates the static field for that
+// tagset. This _tagset contains the configuration for those tags.
+template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4>
+LogTagSet LogTagSetMapping<T0, T1, T2, T3, T4>::_tagset(T0, T1, T2, T3, T4);
+
+#endif // SHARE_VM_LOGGING_LOGTAGSET_HPP
--- a/hotspot/src/share/vm/memory/allocation.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/allocation.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -125,7 +125,7 @@
 void ResourceObj::set_allocation_type(address res, allocation_type type) {
     // Set allocation type in the resource object
     uintptr_t allocation = (uintptr_t)res;
-    assert((allocation & allocation_mask) == 0, err_msg("address should be aligned to 4 bytes at least: " INTPTR_FORMAT, p2i(res)));
+    assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least: " INTPTR_FORMAT, p2i(res));
     assert(type <= allocation_mask, "incorrect allocation type");
     ResourceObj* resobj = (ResourceObj *)res;
     resobj->_allocation_t[0] = ~(allocation + type);
@@ -161,8 +161,8 @@
     } else if (is_type_set()) {
       // Operator new() was called and type was set.
       assert(!allocated_on_stack(),
-             err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
-                     p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]));
+             "not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
+             p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
     } else {
       // Operator new() was not called.
       // Assume that it is embedded or stack object.
@@ -175,8 +175,8 @@
     // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream.
     // Note: garbage may resembles valid value.
     assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(),
-           err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
-                   p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]));
+           "embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
+           p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
     set_allocation_type((address)this, STACK_OR_EMBEDDED);
     _allocation_t[1] = 0; // Zap verification value
 }
@@ -184,8 +184,8 @@
 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment
     // Used in InlineTree::ok_to_inline() for WarmCallInfo.
     assert(allocated_on_stack(),
-           err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
-                   p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]));
+           "copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
+           p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
     // Keep current _allocation_t value;
     return *this;
 }
@@ -533,7 +533,7 @@
 }
 
 void Arena::signal_out_of_memory(size_t sz, const char* whence) const {
-  vm_exit_out_of_memory(sz, OOM_MALLOC_ERROR, whence);
+  vm_exit_out_of_memory(sz, OOM_MALLOC_ERROR, "%s", whence);
 }
 
 // Grow a new Chunk
--- a/hotspot/src/share/vm/memory/allocation.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -154,8 +154,9 @@
   mtChunk             = 0x0C,  // chunk that holds content of arenas
   mtTest              = 0x0D,  // Test type for verifying NMT
   mtTracing           = 0x0E,  // memory used for Tracing
-  mtNone              = 0x0F,  // undefined
-  mt_number_of_types  = 0x10   // number of memory types (mtDontTrack
+  mtLogging           = 0x0F,  // memory for logging
+  mtNone              = 0x10,  // undefined
+  mt_number_of_types  = 0x11   // number of memory types (mtDontTrack
                                  // is not included as validate type)
 };
 
--- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -708,8 +708,8 @@
   size_t size = fc->size();
 
   assert((size >= min_size()),
-    err_msg(SIZE_FORMAT " is too small to be a TreeChunk<Chunk_t, FreeList_t> " SIZE_FORMAT,
-      size, min_size()));
+         SIZE_FORMAT " is too small to be a TreeChunk<Chunk_t, FreeList_t> " SIZE_FORMAT,
+         size, min_size());
   if (FLSVerifyDictionary) {
     verify_tree();
   }
--- a/hotspot/src/share/vm/memory/filemap.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -50,7 +50,6 @@
 #define O_BINARY 0     // otherwise do nothing.
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 extern address JVM_FunctionAtStart();
 extern address JVM_FunctionAtEnd();
 
@@ -443,8 +442,8 @@
   if (_file_open) {
     guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
     if (PrintSharedSpaces) {
-      tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT
-                    " file offset 0x%6x", region, size, base, _file_offset);
+      tty->print_cr("Shared file region %d: " SIZE_FORMAT_HEX_W(6) " bytes, addr " INTPTR_FORMAT
+                    " file offset " SIZE_FORMAT_HEX_W(6), region, size, p2i(base), _file_offset);
     }
   } else {
     si->_file_offset = _file_offset;
@@ -602,7 +601,8 @@
   // other reserved memory (like the code cache).
   ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
   if (!rs.is_reserved()) {
-    fail_continue("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr);
+    fail_continue("Unable to reserve shared space at required address "
+                  INTPTR_FORMAT, p2i(requested_addr));
     return rs;
   }
   // the reserved virtual memory is for mapping class data sharing archive
@@ -659,7 +659,7 @@
         tty->print_cr("Shared string data from the CDS archive is being ignored. "
                      "The current CompressedOops/CompressedClassPointers encoding differs from "
                      "that archived due to heap size change. The archive was dumped using max heap "
-                     "size %dM.", max_heap_size()/M);
+                     "size " UINTX_FORMAT "M.", max_heap_size()/M);
       }
     } else {
       string_ranges = new MemRegion[MetaspaceShared::max_strings];
@@ -896,7 +896,7 @@
   }
   if (_obj_alignment != ObjectAlignmentInBytes) {
     FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
-                  " does not equal the current ObjectAlignmentInBytes of %d.",
+                  " does not equal the current ObjectAlignmentInBytes of " INTX_FORMAT ".",
                   _obj_alignment, ObjectAlignmentInBytes);
     return false;
   }
@@ -951,7 +951,7 @@
     char *base = _header->region_addr(i);
     gclog_or_tty->print("  %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
                         shared_region_name[i],
-                        base, base + si->_used);
+                        p2i(base), p2i(base + si->_used));
   }
 }
 
--- a/hotspot/src/share/vm/memory/iterator.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/iterator.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -58,7 +58,7 @@
     if (!oopDesc::is_null(heap_oop)) {
       oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
       assert(Universe::heap()->is_in_closed_subset(o),
-             err_msg("should be in closed *p " PTR_FORMAT " " PTR_FORMAT, p2i(p), p2i(o)));
+             "should be in closed *p " PTR_FORMAT " " PTR_FORMAT, p2i(p), p2i(o));
     }
   }
 }
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -189,7 +189,7 @@
   assert(index == SpecializedIndex ||                                     \
          index == SmallIndex ||                                           \
          index == MediumIndex ||                                          \
-         index == HumongousIndex, err_msg("Bad index: %d", (int) index))
+         index == HumongousIndex, "Bad index: %d", (int) index)
 
   size_t num_free_chunks(ChunkIndex index) const {
     index_bounds_check(index);
@@ -378,13 +378,13 @@
 
 #define assert_is_ptr_aligned(ptr, alignment) \
   assert(is_ptr_aligned(ptr, alignment),      \
-    err_msg(PTR_FORMAT " is not aligned to "  \
-      SIZE_FORMAT, p2i(ptr), alignment))
+         PTR_FORMAT " is not aligned to "     \
+         SIZE_FORMAT, p2i(ptr), alignment)
 
 #define assert_is_size_aligned(size, alignment) \
   assert(is_size_aligned(size, alignment),      \
-    err_msg(SIZE_FORMAT " is not aligned to "   \
-       SIZE_FORMAT, size, alignment))
+         SIZE_FORMAT " is not aligned to "      \
+         SIZE_FORMAT, size, alignment)
 
 
 // Decide if large pages should be committed when the memory is reserved.
@@ -801,8 +801,8 @@
 #ifdef ASSERT
 void VirtualSpaceNode::verify_container_count() {
   assert(_container_count == container_count_slow(),
-    err_msg("Inconsistency in container_count _container_count " UINTX_FORMAT
-            " container_count_slow() " UINTX_FORMAT, _container_count, container_count_slow()));
+         "Inconsistency in container_count _container_count " UINTX_FORMAT
+         " container_count_slow() " UINTX_FORMAT, _container_count, container_count_slow());
 }
 #endif
 
@@ -965,12 +965,12 @@
                  (HeapWord*)(_rs.base() + _rs.size())));
 
     assert(reserved()->start() == (HeapWord*) _rs.base(),
-      err_msg("Reserved start was not set properly " PTR_FORMAT
-        " != " PTR_FORMAT, p2i(reserved()->start()), p2i(_rs.base())));
+           "Reserved start was not set properly " PTR_FORMAT
+           " != " PTR_FORMAT, p2i(reserved()->start()), p2i(_rs.base()));
     assert(reserved()->word_size() == _rs.size() / BytesPerWord,
-      err_msg("Reserved size was not set properly " SIZE_FORMAT
-        " != " SIZE_FORMAT, reserved()->word_size(),
-        _rs.size() / BytesPerWord));
+           "Reserved size was not set properly " SIZE_FORMAT
+           " != " SIZE_FORMAT, reserved()->word_size(),
+           _rs.size() / BytesPerWord);
   }
 
   return result;
@@ -1016,11 +1016,11 @@
   _reserved_words = _reserved_words - v;
 }
 
-#define assert_committed_below_limit()                             \
-  assert(MetaspaceAux::committed_bytes() <= MaxMetaspaceSize,      \
-      err_msg("Too much committed memory. Committed: " SIZE_FORMAT \
-              " limit (MaxMetaspaceSize): " SIZE_FORMAT,           \
-          MetaspaceAux::committed_bytes(), MaxMetaspaceSize));
+#define assert_committed_below_limit()                        \
+  assert(MetaspaceAux::committed_bytes() <= MaxMetaspaceSize, \
+         "Too much committed memory. Committed: " SIZE_FORMAT \
+         " limit (MaxMetaspaceSize): " SIZE_FORMAT,           \
+         MetaspaceAux::committed_bytes(), MaxMetaspaceSize);
 
 void VirtualSpaceList::inc_committed_words(size_t v) {
   assert_lock_strong(SpaceManager::expand_lock());
@@ -1461,8 +1461,8 @@
   size_t capacity_until_gc = capacity_until_GC();
 
   assert(capacity_until_gc >= committed_bytes,
-        err_msg("capacity_until_gc: " SIZE_FORMAT " < committed_bytes: " SIZE_FORMAT,
-                capacity_until_gc, committed_bytes));
+         "capacity_until_gc: " SIZE_FORMAT " < committed_bytes: " SIZE_FORMAT,
+         capacity_until_gc, committed_bytes);
 
   size_t left_until_max  = MaxMetaspaceSize - committed_bytes;
   size_t left_until_GC = capacity_until_gc - committed_bytes;
@@ -1543,8 +1543,8 @@
   // No expansion, now see if we want to shrink
   // We would never want to shrink more than this
   assert(capacity_until_GC >= minimum_desired_capacity,
-         err_msg(SIZE_FORMAT " >= " SIZE_FORMAT,
-                 capacity_until_GC, minimum_desired_capacity));
+         SIZE_FORMAT " >= " SIZE_FORMAT,
+         capacity_until_GC, minimum_desired_capacity);
   size_t max_shrink_bytes = capacity_until_GC - minimum_desired_capacity;
 
   // Should shrinking be considered?
@@ -1585,8 +1585,8 @@
       shrink_bytes = align_size_down(shrink_bytes, Metaspace::commit_alignment());
 
       assert(shrink_bytes <= max_shrink_bytes,
-        err_msg("invalid shrink size " SIZE_FORMAT " not <= " SIZE_FORMAT,
-          shrink_bytes, max_shrink_bytes));
+             "invalid shrink size " SIZE_FORMAT " not <= " SIZE_FORMAT,
+             shrink_bytes, max_shrink_bytes);
       if (current_shrink_factor == 0) {
         _shrink_factor = 10;
       } else {
@@ -1676,9 +1676,9 @@
 void ChunkManager::locked_verify_free_chunks_total() {
   assert_lock_strong(SpaceManager::expand_lock());
   assert(sum_free_chunks() == _free_chunks_total,
-    err_msg("_free_chunks_total " SIZE_FORMAT " is not the"
-           " same as sum " SIZE_FORMAT, _free_chunks_total,
-           sum_free_chunks()));
+         "_free_chunks_total " SIZE_FORMAT " is not the"
+         " same as sum " SIZE_FORMAT, _free_chunks_total,
+         sum_free_chunks());
 }
 
 void ChunkManager::verify_free_chunks_total() {
@@ -1690,9 +1690,9 @@
 void ChunkManager::locked_verify_free_chunks_count() {
   assert_lock_strong(SpaceManager::expand_lock());
   assert(sum_free_chunks_count() == _free_chunks_count,
-    err_msg("_free_chunks_count " SIZE_FORMAT " is not the"
-           " same as sum " SIZE_FORMAT, _free_chunks_count,
-           sum_free_chunks_count()));
+         "_free_chunks_count " SIZE_FORMAT " is not the"
+         " same as sum " SIZE_FORMAT, _free_chunks_count,
+         sum_free_chunks_count());
 }
 
 void ChunkManager::verify_free_chunks_count() {
@@ -1891,9 +1891,9 @@
     break;
   }
   assert(*chunk_word_size != 0 && *class_chunk_word_size != 0,
-    err_msg("Initial chunks sizes bad: data  " SIZE_FORMAT
-            " class " SIZE_FORMAT,
-            *chunk_word_size, *class_chunk_word_size));
+         "Initial chunks sizes bad: data  " SIZE_FORMAT
+         " class " SIZE_FORMAT,
+         *chunk_word_size, *class_chunk_word_size);
 }
 
 size_t SpaceManager::sum_free_in_chunks_in_use() const {
@@ -2036,9 +2036,9 @@
 
   assert(!SpaceManager::is_humongous(word_size) ||
          chunk_word_size == if_humongous_sized_chunk,
-         err_msg("Size calculation is wrong, word_size " SIZE_FORMAT
-                 " chunk_word_size " SIZE_FORMAT,
-                 word_size, chunk_word_size));
+         "Size calculation is wrong, word_size " SIZE_FORMAT
+         " chunk_word_size " SIZE_FORMAT,
+         word_size, chunk_word_size);
   if (TraceMetadataHumongousAllocation &&
       SpaceManager::is_humongous(word_size)) {
     gclog_or_tty->print_cr("Metadata humongous allocation:");
@@ -2202,9 +2202,9 @@
 SpaceManager::~SpaceManager() {
   // This call this->_lock which can't be done while holding expand_lock()
   assert(sum_capacity_in_chunks_in_use() == allocated_chunks_words(),
-    err_msg("sum_capacity_in_chunks_in_use() " SIZE_FORMAT
-            " allocated_chunks_words() " SIZE_FORMAT,
-            sum_capacity_in_chunks_in_use(), allocated_chunks_words()));
+         "sum_capacity_in_chunks_in_use() " SIZE_FORMAT
+         " allocated_chunks_words() " SIZE_FORMAT,
+         sum_capacity_in_chunks_in_use(), allocated_chunks_words());
 
   MutexLockerEx fcl(SpaceManager::expand_lock(),
                     Mutex::_no_safepoint_check_flag);
@@ -2275,9 +2275,9 @@
     assert(humongous_chunks->word_size() == (size_t)
            align_size_up(humongous_chunks->word_size(),
                              smallest_chunk_size()),
-           err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT
-                   " granularity " SIZE_FORMAT,
-                   humongous_chunks->word_size(), smallest_chunk_size()));
+           "Humongous chunk size is wrong: word size " SIZE_FORMAT
+           " granularity " SIZE_FORMAT,
+           humongous_chunks->word_size(), smallest_chunk_size());
     Metachunk* next_humongous_chunks = humongous_chunks->next();
     humongous_chunks->container()->dec_container_count();
     chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks);
@@ -2331,7 +2331,7 @@
   size_t raw_word_size = get_raw_word_size(word_size);
   size_t min_size = TreeChunk<Metablock, FreeList<Metablock> >::min_size();
   assert(raw_word_size >= min_size,
-         err_msg("Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size));
+         "Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size);
   block_freelists()->return_block(p, raw_word_size);
 }
 
@@ -2541,9 +2541,9 @@
   assert(SafepointSynchronize::is_at_safepoint() || !Universe::is_fully_initialized(),
     "Verification can fail if the applications is running");
   assert(allocated_blocks_words() == sum_used_in_chunks_in_use(),
-    err_msg("allocation total is not consistent " SIZE_FORMAT
-            " vs " SIZE_FORMAT,
-            allocated_blocks_words(), sum_used_in_chunks_in_use()));
+         "allocation total is not consistent " SIZE_FORMAT
+         " vs " SIZE_FORMAT,
+         allocated_blocks_words(), sum_used_in_chunks_in_use());
 }
 
 #endif
@@ -2616,9 +2616,9 @@
 void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
   assert_lock_strong(SpaceManager::expand_lock());
   assert(words <= capacity_words(mdtype),
-    err_msg("About to decrement below 0: words " SIZE_FORMAT
-            " is greater than _capacity_words[%u] " SIZE_FORMAT,
-            words, mdtype, capacity_words(mdtype)));
+         "About to decrement below 0: words " SIZE_FORMAT
+         " is greater than _capacity_words[%u] " SIZE_FORMAT,
+         words, mdtype, capacity_words(mdtype));
   _capacity_words[mdtype] -= words;
 }
 
@@ -2630,9 +2630,9 @@
 
 void MetaspaceAux::dec_used(Metaspace::MetadataType mdtype, size_t words) {
   assert(words <= used_words(mdtype),
-    err_msg("About to decrement below 0: words " SIZE_FORMAT
-            " is greater than _used_words[%u] " SIZE_FORMAT,
-            words, mdtype, used_words(mdtype)));
+         "About to decrement below 0: words " SIZE_FORMAT
+         " is greater than _used_words[%u] " SIZE_FORMAT,
+         words, mdtype, used_words(mdtype));
   // For CMS deallocation of the Metaspaces occurs during the
   // sweep which is a concurrent phase.  Protection by the expand_lock()
   // is not enough since allocation is on a per Metaspace basis
@@ -2699,11 +2699,11 @@
   size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType);
   size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType);
   assert(capacity_bytes() == class_capacity + non_class_capacity,
-      err_msg("bad accounting: capacity_bytes() " SIZE_FORMAT
-        " class_capacity + non_class_capacity " SIZE_FORMAT
-        " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT,
-        capacity_bytes(), class_capacity + non_class_capacity,
-        class_capacity, non_class_capacity));
+         "bad accounting: capacity_bytes() " SIZE_FORMAT
+         " class_capacity + non_class_capacity " SIZE_FORMAT
+         " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT,
+         capacity_bytes(), class_capacity + non_class_capacity,
+         class_capacity, non_class_capacity);
 
   return class_capacity + non_class_capacity;
 }
@@ -2904,17 +2904,17 @@
   // For purposes of the running sum of capacity, verify against capacity
   size_t capacity_in_use_bytes = capacity_bytes_slow();
   assert(running_sum_capacity_bytes == capacity_in_use_bytes,
-    err_msg("capacity_words() * BytesPerWord " SIZE_FORMAT
-            " capacity_bytes_slow()" SIZE_FORMAT,
-            running_sum_capacity_bytes, capacity_in_use_bytes));
+         "capacity_words() * BytesPerWord " SIZE_FORMAT
+         " capacity_bytes_slow()" SIZE_FORMAT,
+         running_sum_capacity_bytes, capacity_in_use_bytes);
   for (Metaspace::MetadataType i = Metaspace::ClassType;
        i < Metaspace:: MetadataTypeCount;
        i = (Metaspace::MetadataType)(i + 1)) {
     size_t capacity_in_use_bytes = capacity_bytes_slow(i);
     assert(capacity_bytes(i) == capacity_in_use_bytes,
-      err_msg("capacity_bytes(%u) " SIZE_FORMAT
-              " capacity_bytes_slow(%u)" SIZE_FORMAT,
-              i, capacity_bytes(i), i, capacity_in_use_bytes));
+           "capacity_bytes(%u) " SIZE_FORMAT
+           " capacity_bytes_slow(%u)" SIZE_FORMAT,
+           i, capacity_bytes(i), i, capacity_in_use_bytes);
   }
 #endif
 }
@@ -2925,17 +2925,17 @@
   // For purposes of the running sum of used, verify against used
   size_t used_in_use_bytes = used_bytes_slow();
   assert(used_bytes() == used_in_use_bytes,
-    err_msg("used_bytes() " SIZE_FORMAT
-            " used_bytes_slow()" SIZE_FORMAT,
-            used_bytes(), used_in_use_bytes));
+         "used_bytes() " SIZE_FORMAT
+         " used_bytes_slow()" SIZE_FORMAT,
+         used_bytes(), used_in_use_bytes);
   for (Metaspace::MetadataType i = Metaspace::ClassType;
        i < Metaspace:: MetadataTypeCount;
        i = (Metaspace::MetadataType)(i + 1)) {
     size_t used_in_use_bytes = used_bytes_slow(i);
     assert(used_bytes(i) == used_in_use_bytes,
-      err_msg("used_bytes(%u) " SIZE_FORMAT
-              " used_bytes_slow(%u)" SIZE_FORMAT,
-              i, used_bytes(i), i, used_in_use_bytes));
+           "used_bytes(%u) " SIZE_FORMAT
+           " used_bytes_slow(%u)" SIZE_FORMAT,
+           i, used_bytes(i), i, used_in_use_bytes);
   }
 #endif
 }
@@ -3157,7 +3157,7 @@
 void Metaspace::initialize_class_space(ReservedSpace rs) {
   // The reserved space size may be bigger because of alignment, esp with UseLargePages
   assert(rs.size() >= CompressedClassSpaceSize,
-         err_msg(SIZE_FORMAT " != " SIZE_FORMAT, rs.size(), CompressedClassSpaceSize));
+         SIZE_FORMAT " != " SIZE_FORMAT, rs.size(), CompressedClassSpaceSize);
   assert(using_class_space(), "Must be using class space");
   _class_space_list = new VirtualSpaceList(rs);
   _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk);
@@ -3688,7 +3688,7 @@
     case Metaspace::ClassType: return "Class";
     case Metaspace::NonClassType: return "Metadata";
     default:
-      assert(false, err_msg("Got bad mdtype: %d", (int) mdtype));
+      assert(false, "Got bad mdtype: %d", (int) mdtype);
       return NULL;
   }
 }
@@ -3970,15 +3970,15 @@
 
 #define assert_is_available_positive(word_size) \
   assert(vsn.is_available(word_size), \
-    err_msg(#word_size ": " PTR_FORMAT " bytes were not available in " \
-            "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \
-            (uintptr_t)(word_size * BytesPerWord), p2i(vsn.bottom()), p2i(vsn.end())));
+         #word_size ": " PTR_FORMAT " bytes were not available in " \
+         "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \
+         (uintptr_t)(word_size * BytesPerWord), p2i(vsn.bottom()), p2i(vsn.end()));
 
 #define assert_is_available_negative(word_size) \
   assert(!vsn.is_available(word_size), \
-    err_msg(#word_size ": " PTR_FORMAT " bytes should not be available in " \
-            "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \
-            (uintptr_t)(word_size * BytesPerWord), p2i(vsn.bottom()), p2i(vsn.end())));
+         #word_size ": " PTR_FORMAT " bytes should not be available in " \
+         "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \
+         (uintptr_t)(word_size * BytesPerWord), p2i(vsn.bottom()), p2i(vsn.end()));
 
   static void test_is_available_positive() {
     // Reserve some memory.
--- a/hotspot/src/share/vm/memory/metaspaceGCThresholdUpdater.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceGCThresholdUpdater.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,7 +43,7 @@
       case ExpandAndAllocate:
         return "expand_and_allocate";
       default:
-        assert(false, err_msg("Got bad updater: %d", (int) updater));
+        assert(false, "Got bad updater: %d", (int) updater);
         return NULL;
     };
   }
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -44,8 +44,6 @@
 #include "runtime/vm_operations.hpp"
 #include "utilities/hashtable.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 int MetaspaceShared::_max_alignment = 0;
 
 ReservedSpace* MetaspaceShared::_shared_rs = NULL;
@@ -578,7 +576,7 @@
 
   // Print shared spaces all the time
 // To make fmt_space be a syntactic constant (for format warnings), use #define.
-#define fmt_space "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " INTPTR_FORMAT
+#define fmt_space "%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%4.1f%% used] at " INTPTR_FORMAT
   Metaspace* ro_space = _loader_data->ro_metaspace();
   Metaspace* rw_space = _loader_data->rw_metaspace();
 
@@ -611,12 +609,12 @@
   const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0;
   const double total_u_perc = total_bytes / double(total_alloced) * 100.0;
 
-  tty->print_cr(fmt_space, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom());
-  tty->print_cr(fmt_space, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom());
-  tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low);
-  tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low);
-  tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes, 100.0, ss_low);
-  tty->print_cr("total   : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]",
+  tty->print_cr(fmt_space, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, p2i(ro_space->bottom()));
+  tty->print_cr(fmt_space, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, p2i(rw_space->bottom()));
+  tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, p2i(md_low));
+  tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, p2i(mc_low));
+  tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes,   100.0,     p2i(ss_low));
+  tty->print_cr("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%4.1f%% used]",
                  total_bytes, total_alloced, total_u_perc);
 
   // Update the vtable pointers in all of the Klass objects in the
@@ -738,9 +736,9 @@
   TraceTime timer("Dump Shared Spaces", TraceStartupTime);
   ResourceMark rm;
 
-  tty->print_cr("Allocated shared space: %d bytes at " PTR_FORMAT,
+  tty->print_cr("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
                 MetaspaceShared::shared_rs()->size(),
-                MetaspaceShared::shared_rs()->base());
+                p2i(MetaspaceShared::shared_rs()->base()));
 
   // Preload classes to be shared.
   // Should use some os:: method rather than fopen() here. aB.
--- a/hotspot/src/share/vm/memory/universe.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -143,6 +143,10 @@
 // Heap
 int             Universe::_verify_count = 0;
 
+// Oop verification (see MacroAssembler::verify_oop)
+uintptr_t       Universe::_verify_oop_mask = 0;
+uintptr_t       Universe::_verify_oop_bits = (uintptr_t) -1;
+
 int             Universe::_base_vtable_size = 0;
 bool            Universe::_bootstrapping = false;
 bool            Universe::_fully_initialized = false;
@@ -812,8 +816,8 @@
 ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
 
   assert(alignment <= Arguments::conservative_max_heap_alignment(),
-      err_msg("actual alignment " SIZE_FORMAT " must be within maximum heap alignment " SIZE_FORMAT,
-          alignment, Arguments::conservative_max_heap_alignment()));
+         "actual alignment " SIZE_FORMAT " must be within maximum heap alignment " SIZE_FORMAT,
+         alignment, Arguments::conservative_max_heap_alignment());
 
   size_t total_reserved = align_size_up(heap_size, alignment);
   assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
@@ -1171,17 +1175,9 @@
   _verify_in_progress = false;
 }
 
-// Oop verification (see MacroAssembler::verify_oop)
-
-static uintptr_t _verify_oop_data[2]   = {0, (uintptr_t)-1};
-static uintptr_t _verify_klass_data[2] = {0, (uintptr_t)-1};
-
 
 #ifndef PRODUCT
-
-static void calculate_verify_data(uintptr_t verify_data[2],
-                                  HeapWord* low_boundary,
-                                  HeapWord* high_boundary) {
+void Universe::calculate_verify_data(HeapWord* low_boundary, HeapWord* high_boundary) {
   assert(low_boundary < high_boundary, "bad interval");
 
   // decide which low-order bits we require to be clear:
@@ -1206,28 +1202,25 @@
   // require address alignment, too:
   mask |= (alignSize - 1);
 
-  if (!(verify_data[0] == 0 && verify_data[1] == (uintptr_t)-1)) {
-    assert(verify_data[0] == mask && verify_data[1] == bits, "mask stability");
+  if (!(_verify_oop_mask == 0 && _verify_oop_bits == (uintptr_t)-1)) {
+    assert(_verify_oop_mask == mask && _verify_oop_bits == bits, "mask stability");
   }
-  verify_data[0] = mask;
-  verify_data[1] = bits;
+  _verify_oop_mask = mask;
+  _verify_oop_bits = bits;
 }
 
 // Oop verification (see MacroAssembler::verify_oop)
 
 uintptr_t Universe::verify_oop_mask() {
   MemRegion m = heap()->reserved_region();
-  calculate_verify_data(_verify_oop_data,
-                        m.start(),
-                        m.end());
-  return _verify_oop_data[0];
+  calculate_verify_data(m.start(), m.end());
+  return _verify_oop_mask;
 }
 
-
-
 uintptr_t Universe::verify_oop_bits() {
-  verify_oop_mask();
-  return _verify_oop_data[1];
+  MemRegion m = heap()->reserved_region();
+  calculate_verify_data(m.start(), m.end());
+  return _verify_oop_bits;
 }
 
 uintptr_t Universe::verify_mark_mask() {
--- a/hotspot/src/share/vm/memory/universe.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -248,9 +248,14 @@
 
   // Debugging
   static int _verify_count;                           // number of verifies done
+
   // True during call to verify().  Should only be set/cleared in verify().
   static bool _verify_in_progress;
 
+  static uintptr_t _verify_oop_mask;
+  static uintptr_t _verify_oop_bits;
+
+  static void calculate_verify_data(HeapWord* low_boundary, HeapWord* high_boundary) PRODUCT_RETURN;
   static void compute_verify_oop_data();
 
  public:
@@ -269,7 +274,7 @@
   }
 
   static Klass* typeArrayKlassObj(BasicType t) {
-    assert((uint)t < T_VOID+1, err_msg("range check for type: %s", type2name(t)));
+    assert((uint)t < T_VOID+1, "range check for type: %s", type2name(t));
     assert(_typeArrayKlassObjs[t] != NULL, "domain check");
     return _typeArrayKlassObjs[t];
   }
--- a/hotspot/src/share/vm/memory/virtualspace.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/memory/virtualspace.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,8 +29,6 @@
 #include "oops/oop.inline.hpp"
 #include "services/memTracker.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // ReservedSpace
 
 // Dummy constructor
@@ -82,7 +80,7 @@
     assert(UseCompressedOops, "currently requested address used only for compressed oops");
     if (PrintCompressedOopsMode) {
       tty->cr();
-      tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
+      tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
     }
     // OS ignored requested address. Try different address.
     if (special) {
@@ -137,9 +135,9 @@
       }
       // Check alignment constraints.
       assert((uintptr_t) base % alignment == 0,
-             err_msg("Large pages returned a non-aligned address, base: "
-                 PTR_FORMAT " alignment: " PTR_FORMAT,
-                 base, (void*)(uintptr_t)alignment));
+             "Large pages returned a non-aligned address, base: "
+             PTR_FORMAT " alignment: " SIZE_FORMAT_HEX,
+             p2i(base), alignment);
       _special = true;
     } else {
       // failed; try to reserve regular memory below
@@ -291,7 +289,7 @@
       if (PrintCompressedOopsMode) {
         tty->cr();
         tty->print_cr("Protected page at the reserved heap base: "
-                      PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix);
+                      PTR_FORMAT " / " INTX_FORMAT " bytes", p2i(_base), _noaccess_prefix);
       }
       assert(Universe::narrow_oop_use_implicit_null_checks() == true, "not initialized?");
     } else {
@@ -324,8 +322,8 @@
   char* base = NULL;
 
   if (PrintCompressedOopsMode && Verbose) {
-    tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " PTR_FORMAT ".\n",
-               requested_address, (address)size);
+    tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " SIZE_FORMAT_HEX ".\n",
+               p2i(requested_address), size);
   }
 
   if (special) {
@@ -334,9 +332,9 @@
     if (base != NULL) {
       // Check alignment constraints.
       assert((uintptr_t) base % alignment == 0,
-             err_msg("Large pages returned a non-aligned address, base: "
-                     PTR_FORMAT " alignment: " PTR_FORMAT,
-                     base, (void*)(uintptr_t)alignment));
+             "Large pages returned a non-aligned address, base: "
+             PTR_FORMAT " alignment: " SIZE_FORMAT_HEX,
+             p2i(base), alignment);
       _special = true;
     }
   }
@@ -561,7 +559,7 @@
     // Last, desperate try without any placement.
     if (_base == NULL) {
       if (PrintCompressedOopsMode && Verbose) {
-        tty->print("Trying to allocate at address NULL heap of size " PTR_FORMAT ".\n", (address)size + noaccess_prefix);
+        tty->print("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX ".\n", size + noaccess_prefix);
       }
       initialize(size + noaccess_prefix, alignment, large, NULL, false);
     }
@@ -853,7 +851,7 @@
     if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
                          ", lower_needs=" SIZE_FORMAT ", %d) failed",
-                         lower_high(), lower_needs, _executable);)
+                         p2i(lower_high()), lower_needs, _executable);)
       return false;
     } else {
       _lower_high += lower_needs;
@@ -867,7 +865,7 @@
                            _executable)) {
       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
                          ", middle_needs=" SIZE_FORMAT ", " SIZE_FORMAT
-                         ", %d) failed", middle_high(), middle_needs,
+                         ", %d) failed", p2i(middle_high()), middle_needs,
                          middle_alignment(), _executable);)
       return false;
     }
@@ -880,7 +878,7 @@
     if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
                          ", upper_needs=" SIZE_FORMAT ", %d) failed",
-                         upper_high(), upper_needs, _executable);)
+                         p2i(upper_high()), upper_needs, _executable);)
       return false;
     } else {
       _upper_high += upper_needs;
@@ -1017,8 +1015,8 @@
   out->cr();
   out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
   out->print_cr(" - reserved:  " SIZE_FORMAT, reserved_size());
-  out->print_cr(" - [low, high]:     [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  low(), high());
-  out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  low_boundary(), high_boundary());
+  out->print_cr(" - [low, high]:     [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  p2i(low()), p2i(high()));
+  out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  p2i(low_boundary()), p2i(high_boundary()));
 }
 
 void VirtualSpace::print() {
@@ -1205,20 +1203,20 @@
   TestReservedSpace::test_reserved_space();
 }
 
-#define assert_equals(actual, expected)     \
-  assert(actual == expected,                \
-    err_msg("Got " SIZE_FORMAT " expected " \
-      SIZE_FORMAT, actual, expected));
+#define assert_equals(actual, expected)  \
+  assert(actual == expected,             \
+         "Got " SIZE_FORMAT " expected " \
+         SIZE_FORMAT, actual, expected);
 
 #define assert_ge(value1, value2)                  \
   assert(value1 >= value2,                         \
-    err_msg("'" #value1 "': " SIZE_FORMAT " '"     \
-      #value2 "': " SIZE_FORMAT, value1, value2));
+         "'" #value1 "': " SIZE_FORMAT " '"        \
+         #value2 "': " SIZE_FORMAT, value1, value2);
 
 #define assert_lt(value1, value2)                  \
   assert(value1 < value2,                          \
-    err_msg("'" #value1 "': " SIZE_FORMAT " '"     \
-      #value2 "': " SIZE_FORMAT, value1, value2));
+         "'" #value1 "': " SIZE_FORMAT " '"        \
+         #value2 "': " SIZE_FORMAT, value1, value2);
 
 
 class TestVirtualSpace : AllStatic {
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -45,8 +45,6 @@
 #include "runtime/vframe.hpp"
 #include "utilities/copy.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
   // Tags are RW but comment below applies to tags also.
   Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL);
@@ -1826,9 +1824,9 @@
   // Ensure that all the patches have been used.
   for (int index = 0; index < cp_patches->length(); index++) {
     assert(cp_patches->at(index).is_null(),
-           err_msg("Unused constant pool patch at %d in class file %s",
-                   index,
-                   pool_holder()->external_name()));
+           "Unused constant pool patch at %d in class file %s",
+           index,
+           pool_holder()->external_name());
   }
 #endif // ASSERT
 }
@@ -1868,11 +1866,11 @@
     st->cr();
   }
   if (pool_holder() != NULL) {
-    st->print_cr(" - holder: " INTPTR_FORMAT, pool_holder());
+    st->print_cr(" - holder: " INTPTR_FORMAT, p2i(pool_holder()));
   }
-  st->print_cr(" - cache: " INTPTR_FORMAT, cache());
-  st->print_cr(" - resolved_references: " INTPTR_FORMAT, (void *)resolved_references());
-  st->print_cr(" - reference_map: " INTPTR_FORMAT, reference_map());
+  st->print_cr(" - cache: " INTPTR_FORMAT, p2i(cache()));
+  st->print_cr(" - resolved_references: " INTPTR_FORMAT, p2i(resolved_references()));
+  st->print_cr(" - reference_map: " INTPTR_FORMAT, p2i(reference_map()));
 
   for (int index = 1; index < length(); index++) {      // Index 0 is unused
     ((ConstantPool*)this)->print_entry_on(index, st);
@@ -1897,7 +1895,7 @@
       { Klass* k = klass_at(index, CATCH);
         guarantee(k != NULL, "need klass");
         k->print_value_on(st);
-        st->print(" {0x%lx}", (address)k);
+        st->print(" {" PTR_FORMAT "}", p2i(k));
       }
       break;
     case JVM_CONSTANT_Fieldref :
@@ -1910,7 +1908,7 @@
       if (is_pseudo_string_at(index)) {
         oop anObj = pseudo_string_at(index);
         anObj->print_value_on(st);
-        st->print(" {0x%lx}", (address)anObj);
+        st->print(" {" PTR_FORMAT "}", p2i(anObj));
       } else {
         unresolved_string_at(index)->print_value_on(st);
       }
@@ -1987,7 +1985,7 @@
     if (extra)  st->print(" (extra)");
   }
   if (cache() != NULL) {
-    st->print(" cache=" PTR_FORMAT, cache());
+    st->print(" cache=" PTR_FORMAT, p2i(cache()));
   }
 }
 
--- a/hotspot/src/share/vm/oops/constantPool.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -662,6 +662,8 @@
   int klass_ref_index_at(int which)               { return impl_klass_ref_index_at(which, false); }
   int name_and_type_ref_index_at(int which)       { return impl_name_and_type_ref_index_at(which, false); }
 
+  int remap_instruction_operand_from_cache(int operand);  // operand must be biased by CPCACHE_INDEX_TAG
+
   // Lookup for entries consisting of (name_index, signature_index)
   int name_ref_index_at(int which_nt);            // ==  low-order jshort of name_and_type_at(which_nt)
   int signature_ref_index_at(int which_nt);       // == high-order jshort of name_and_type_at(which_nt)
@@ -783,8 +785,6 @@
   int       impl_klass_ref_index_at(int which, bool uncached);
   int       impl_name_and_type_ref_index_at(int which, bool uncached);
 
-  int remap_instruction_operand_from_cache(int operand);  // operand must be biased by CPCACHE_INDEX_TAG
-
   // Used while constructing constant pool (only by ClassFileParser)
   jint klass_index_at(int which) {
     assert(tag_at(which).is_klass_index(), "Corrupted constant pool");
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,8 +36,6 @@
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/macros.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Implementation of ConstantPoolCacheEntry
 
 void ConstantPoolCacheEntry::initialize_entry(int index) {
@@ -126,7 +124,7 @@
   // This routine is called only in corner cases where the CPCE is not yet initialized.
   // See AbstractInterpreter::deopt_continue_after_entry.
   assert(_flags == 0 || parameter_size() == 0 || parameter_size() == value,
-         err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
+         "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
   // Setting the parameter size by itself is only safe if the
   // current value of _flags is 0, otherwise another thread may have
   // updated it and we don't want to overwrite that value.  Don't
@@ -136,7 +134,7 @@
     Atomic::cmpxchg_ptr((value & parameter_size_mask), &_flags, 0);
   }
   guarantee(parameter_size() == value,
-            err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
+            "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
 }
 
 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
@@ -310,9 +308,9 @@
   if (TraceInvokeDynamic) {
     tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method_type=" PTR_FORMAT "%s method=" PTR_FORMAT " ",
                   invoke_code,
-                  (void *)appendix(),    (has_appendix    ? "" : " (unused)"),
-                  (void *)method_type(), (has_method_type ? "" : " (unused)"),
-                  (intptr_t)adapter());
+                  p2i(appendix()),    (has_appendix    ? "" : " (unused)"),
+                  p2i(method_type()), (has_method_type ? "" : " (unused)"),
+                  p2i(adapter()));
     adapter->print();
     if (has_appendix)  appendix()->print();
   }
@@ -593,7 +591,7 @@
       // all point to the same constant pool cache entry.
       for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
         const int cpci_next = invokedynamic_references_map[ref + entry];
-        assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
+        assert(cpci == cpci_next, "%d == %d", cpci, cpci_next);
       }
 #endif
       entry_at(cpci)->initialize_resolved_reference_index(ref);
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,11 +41,10 @@
 
   // Constructor
   InstanceClassLoaderKlass(int vtable_len, int itable_len, int static_field_size, int nonstatic_oop_map_size, ReferenceType rt, AccessFlags access_flags, bool is_anonymous)
-    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous) {}
+    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size,
+                    InstanceKlass::_misc_kind_class_loader, rt, access_flags, is_anonymous) {}
 
 public:
-  virtual bool oop_is_instanceClassLoader() const { return true; }
-
   InstanceClassLoaderKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
 
   // GC specific object visitors
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -66,8 +66,6 @@
 #include "c1/c1_Compiler.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef DTRACE_ENABLED
 
 
@@ -147,8 +145,8 @@
     } else {
       // normal class
       ik = new (loader_data, size, THREAD) InstanceKlass(
-        vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
-        access_flags, is_anonymous);
+        vtable_len, itable_len, static_field_size, nonstatic_oop_map_size,
+        InstanceKlass::_misc_kind_other, rt, access_flags, is_anonymous);
     }
   } else {
     // reference klass
@@ -197,6 +195,7 @@
                              int itable_len,
                              int static_field_size,
                              int nonstatic_oop_map_size,
+                             unsigned kind,
                              ReferenceType rt,
                              AccessFlags access_flags,
                              bool is_anonymous) {
@@ -211,6 +210,7 @@
   set_nonstatic_oop_map_size(nonstatic_oop_map_size);
   set_access_flags(access_flags);
   _misc_flags = 0;  // initialize to zero
+  set_kind(kind);
   set_is_anonymous(is_anonymous);
   assert(size() == iksize, "wrong size for object");
 
@@ -1028,7 +1028,7 @@
   if (TraceFinalizerRegistration) {
     tty->print("Registered ");
     i->print_value_on(tty);
-    tty->print_cr(" (" INTPTR_FORMAT ") as finalizable", (address)i);
+    tty->print_cr(" (" INTPTR_FORMAT ") as finalizable", p2i(i));
   }
   instanceHandle h_i(THREAD, i);
   // Pass the handle as argument, JavaCalls::call expects oop as jobjects
@@ -1131,7 +1131,7 @@
   if (TraceClassInitialization) {
     tty->print("%d Initializing ", call_class_initializer_impl_counter++);
     this_k->name()->print_value();
-    tty->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", (address)this_k());
+    tty->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", p2i(this_k()));
   }
   if (h_method() != NULL) {
     JavaCallArguments args; // No arguments
@@ -1499,7 +1499,7 @@
     // not found
 #ifdef ASSERT
     int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature);
-    assert(index == -1, err_msg("binary search should have found entry %d", index));
+    assert(index == -1, "binary search should have found entry %d", index);
 #endif
   }
   return -1;
@@ -1915,7 +1915,7 @@
   for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
     if (nm == b->get_nmethod()) {
       int val = b->decrement();
-      guarantee(val >= 0, err_msg("Underflow: %d", val));
+      guarantee(val >= 0, "Underflow: %d", val);
       return (val == 0);
     }
   }
@@ -1936,7 +1936,7 @@
   nmethodBucket* b = first;
 
   while (b != NULL) {
-    assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
+    assert(b->count() >= 0, "bucket count: %d", b->count());
     nmethodBucket* next = b->next();
     if (b->count() == 0) {
       if (last == NULL) {
@@ -1976,7 +1976,7 @@
     if (nm == b->get_nmethod()) {
 #ifdef ASSERT
       int count = b->count();
-      assert(count >= 0, err_msg("count shouldn't be negative: %d", count));
+      assert(count >= 0, "count shouldn't be negative: %d", count);
 #endif
       return true;
     }
@@ -2001,7 +2001,7 @@
   else {
     // Verification
     for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) {
-      assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
+      assert(b->count() >= 0, "bucket count: %d", b->count());
       assert(b->count() != 0, "empty buckets need to be cleaned");
     }
   }
@@ -2797,7 +2797,7 @@
       st->print("   ");
     }
   }
-  if (n >= MaxSubklassPrintSize) st->print("(%d more klasses...)", n - MaxSubklassPrintSize);
+  if (n >= MaxSubklassPrintSize) st->print("(" INTX_FORMAT " more klasses...)", n - MaxSubklassPrintSize);
   st->cr();
 
   if (is_interface()) {
@@ -2873,9 +2873,9 @@
   }
   st->print(BULLET"inner classes:     "); inner_classes()->print_value_on(st);     st->cr();
   st->print(BULLET"java mirror:       "); java_mirror()->print_value_on(st);       st->cr();
-  st->print(BULLET"vtable length      %d  (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable());  st->cr();
+  st->print(BULLET"vtable length      %d  (start addr: " INTPTR_FORMAT ")", vtable_length(), p2i(start_of_vtable())); st->cr();
   if (vtable_length() > 0 && (Verbose || WizardMode))  print_vtable(start_of_vtable(), vtable_length(), st);
-  st->print(BULLET"itable length      %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr();
+  st->print(BULLET"itable length      %d (start addr: " INTPTR_FORMAT ")", itable_length(), p2i(start_of_itable())); st->cr();
   if (itable_length() > 0 && (Verbose || WizardMode))  print_vtable(start_of_itable(), itable_length(), st);
   st->print_cr(BULLET"---- static fields (%d words):", static_field_size());
   FieldPrinter print_static_field(st);
@@ -3068,7 +3068,7 @@
   template <class T> void do_oop_work(T* p) {
     oop obj = oopDesc::load_decode_heap_oop(p);
     if (!obj->is_oop_or_null()) {
-      tty->print_cr("Failed: " PTR_FORMAT " -> " PTR_FORMAT, p, (address)obj);
+      tty->print_cr("Failed: " PTR_FORMAT " -> " PTR_FORMAT, p2i(p), p2i(obj));
       Universe::print();
       guarantee(false, "boom");
     }
@@ -3110,7 +3110,7 @@
   Klass* sib = next_sibling();
   if (sib != NULL) {
     if (sib == this) {
-      fatal(err_msg("subclass points to itself " PTR_FORMAT, sib));
+      fatal("subclass points to itself " PTR_FORMAT, p2i(sib));
     }
 
     guarantee(sib->is_klass(), "should be klass");
@@ -3310,7 +3310,7 @@
         // The previous version InstanceKlass is on the ClassLoaderData deallocate list
         // so will be deallocated during the next phase of class unloading.
         RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is dead",
-                              pv_node));
+                              p2i(pv_node)));
         // For debugging purposes.
         pv_node->set_is_scratch_class();
         pv_node->class_loader_data()->add_to_deallocate_list(pv_node);
@@ -3321,7 +3321,7 @@
         continue;
       } else {
         RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is alive",
-                              pv_node));
+                              p2i(pv_node)));
         assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
         guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
         live_count++;
@@ -3472,10 +3472,10 @@
         // is never reached, but this won't be noticeable to the programmer.
         old_method->set_running_emcp(true);
         RC_TRACE(0x00000400, ("add: EMCP method %s is on_stack " INTPTR_FORMAT,
-                              old_method->name_and_sig_as_C_string(), old_method));
+                              old_method->name_and_sig_as_C_string(), p2i(old_method)));
       } else if (!old_method->is_obsolete()) {
         RC_TRACE(0x00000400, ("add: EMCP method %s is NOT on_stack " INTPTR_FORMAT,
-                              old_method->name_and_sig_as_C_string(), old_method));
+                              old_method->name_and_sig_as_C_string(), p2i(old_method)));
       }
     }
   }
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -117,6 +117,7 @@
                 int itable_len,
                 int static_field_size,
                 int nonstatic_oop_map_size,
+                unsigned kind,
                 ReferenceType rt,
                 AccessFlags access_flags,
                 bool is_anonymous);
@@ -199,16 +200,30 @@
   bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
   bool            _has_unloaded_dependent;
 
+  // The low two bits of _misc_flags contains the kind field.
+  // This can be used to quickly discriminate among the four kinds of
+  // InstanceKlass.
+
+  static const unsigned _misc_kind_field_size = 2;
+  static const unsigned _misc_kind_field_pos  = 0;
+  static const unsigned _misc_kind_field_mask = (1u << _misc_kind_field_size) - 1u;
+
+  static const unsigned _misc_kind_other        = 0; // concrete InstanceKlass
+  static const unsigned _misc_kind_reference    = 1; // InstanceRefKlass
+  static const unsigned _misc_kind_class_loader = 2; // InstanceClassLoaderKlass
+  static const unsigned _misc_kind_mirror       = 3; // InstanceMirrorKlass
+
+  // Start after _misc_kind field.
   enum {
-    _misc_rewritten                = 1 << 0, // methods rewritten.
-    _misc_has_nonstatic_fields     = 1 << 1, // for sizing with UseCompressedOops
-    _misc_should_verify_class      = 1 << 2, // allow caching of preverification
-    _misc_is_anonymous             = 1 << 3, // has embedded _host_klass field
-    _misc_is_contended             = 1 << 4, // marked with contended annotation
-    _misc_has_default_methods      = 1 << 5, // class/superclass/implemented interfaces has default methods
-    _misc_declares_default_methods = 1 << 6, // directly declares default methods (any access)
-    _misc_has_been_redefined       = 1 << 7, // class has been redefined
-    _misc_is_scratch_class         = 1 << 8  // class is the redefined scratch class
+    _misc_rewritten                = 1 << 2, // methods rewritten.
+    _misc_has_nonstatic_fields     = 1 << 3, // for sizing with UseCompressedOops
+    _misc_should_verify_class      = 1 << 4, // allow caching of preverification
+    _misc_is_anonymous             = 1 << 5, // has embedded _host_klass field
+    _misc_is_contended             = 1 << 6, // marked with contended annotation
+    _misc_has_default_methods      = 1 << 7, // class/superclass/implemented interfaces has default methods
+    _misc_declares_default_methods = 1 << 8, // directly declares default methods (any access)
+    _misc_has_been_redefined       = 1 << 9, // class has been redefined
+    _misc_is_scratch_class         = 1 << 10 // class is the redefined scratch class
   };
   u2              _misc_flags;
   u2              _minor_version;        // minor version number of class file
@@ -667,6 +682,28 @@
     _misc_flags |= _misc_is_scratch_class;
   }
 
+private:
+
+  void set_kind(unsigned kind) {
+    assert(kind <= _misc_kind_field_mask, "Invalid InstanceKlass kind");
+    unsigned fmask = _misc_kind_field_mask << _misc_kind_field_pos;
+    unsigned flags = _misc_flags & ~fmask;
+    _misc_flags = (flags | (kind << _misc_kind_field_pos));
+  }
+
+  bool is_kind(unsigned desired) const {
+    unsigned kind = (_misc_flags >> _misc_kind_field_pos) & _misc_kind_field_mask;
+    return kind == desired;
+  }
+
+public:
+
+  // Other is anything that is not one of the more specialized kinds of InstanceKlass.
+  bool is_other_instance_klass() const        { return is_kind(_misc_kind_other); }
+  bool is_reference_instance_klass() const    { return is_kind(_misc_kind_reference); }
+  bool is_mirror_instance_klass() const       { return is_kind(_misc_kind_mirror); }
+  bool is_class_loader_instance_klass() const { return is_kind(_misc_kind_class_loader); }
+
   void init_previous_versions() {
     _previous_versions = NULL;
   }
@@ -885,9 +922,8 @@
 
   // Casting from Klass*
   static InstanceKlass* cast(Klass* k) {
-    assert(k == NULL || k->is_klass(), "must be");
     assert(k == NULL || k->oop_is_instance(), "cast to InstanceKlass");
-    return (InstanceKlass*) k;
+    return static_cast<InstanceKlass*>(k);
   }
 
   InstanceKlass* java_super() const {
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -48,17 +48,17 @@
 
   // Constructor
   InstanceMirrorKlass(int vtable_len, int itable_len, int static_field_size, int nonstatic_oop_map_size, ReferenceType rt, AccessFlags access_flags,  bool is_anonymous)
-    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous) {}
+    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size,
+                    InstanceKlass::_misc_kind_mirror, rt, access_flags, is_anonymous) {}
 
  public:
   InstanceMirrorKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
-  // Type testing
-  bool oop_is_instanceMirror() const             { return true; }
 
   // Casting from Klass*
   static InstanceMirrorKlass* cast(Klass* k) {
-    assert(k->oop_is_instanceMirror(), "cast to InstanceMirrorKlass");
-    return (InstanceMirrorKlass*) k;
+    assert(InstanceKlass::cast(k)->is_mirror_instance_klass(),
+           "cast to InstanceMirrorKlass");
+    return static_cast<InstanceMirrorKlass*>(k);
   }
 
   // Returns the size of the instance including the extra static fields.
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -33,8 +33,6 @@
 #include "utilities/macros.hpp"
 #include "utilities/preserveException.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
   // Clear the nonstatic oop-map entries corresponding to referent
   // and nextPending field.  They are treated specially by the
--- a/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -51,18 +51,11 @@
 
   // Constructor
   InstanceRefKlass(int vtable_len, int itable_len, int static_field_size, int nonstatic_oop_map_size, ReferenceType rt, AccessFlags access_flags, bool is_anonymous)
-    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous) {}
+    : InstanceKlass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_size,
+                    InstanceKlass::_misc_kind_reference, rt, access_flags, is_anonymous) {}
 
  public:
   InstanceRefKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
-  // Type testing
-  bool oop_is_instanceRef() const             { return true; }
-
-  // Casting from Klass*
-  static InstanceRefKlass* cast(Klass* k) {
-    assert(k->oop_is_instanceRef(), "cast to InstanceRefKlass");
-    return (InstanceRefKlass*) k;
-  }
 
   // GC specific object visitors
   //
--- a/hotspot/src/share/vm/oops/klass.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -690,11 +690,11 @@
 bool Klass::verify_vtable_index(int i) {
   if (oop_is_instance()) {
     int limit = ((InstanceKlass*)this)->vtable_length()/vtableEntry::size();
-    assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
+    assert(i >= 0 && i < limit, "index %d out of bounds %d", i, limit);
   } else {
     assert(oop_is_array(), "Must be");
     int limit = ((ArrayKlass*)this)->vtable_length()/vtableEntry::size();
-    assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
+    assert(i >= 0 && i < limit, "index %d out of bounds %d", i, limit);
   }
   return true;
 }
@@ -715,8 +715,14 @@
 class TestKlass {
  public:
   static void test_oop_is_instanceClassLoader() {
-    assert(SystemDictionary::ClassLoader_klass()->oop_is_instanceClassLoader(), "assert");
-    assert(!SystemDictionary::String_klass()->oop_is_instanceClassLoader(), "assert");
+    Klass* klass = SystemDictionary::ClassLoader_klass();
+    guarantee(klass->oop_is_instance(), "assert");
+    guarantee(InstanceKlass::cast(klass)->is_class_loader_instance_klass(), "test failed");
+
+    klass = SystemDictionary::String_klass();
+    guarantee(!klass->oop_is_instance() ||
+              !InstanceKlass::cast(klass)->is_class_loader_instance_klass(),
+              "test failed");
   }
 };
 
--- a/hotspot/src/share/vm/oops/klass.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -341,7 +341,7 @@
     assert(lh < (jint)_lh_neutral_value, "must be array");
     int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
     assert(l2esz <= LogBitsPerLong,
-        err_msg("sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh));
+           "sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh);
     return l2esz;
   }
   static jint array_layout_helper(jint tag, int hsize, BasicType etype, int log2_esize) {
@@ -480,9 +480,6 @@
   virtual bool oop_is_objArray_slow()       const { return false; }
   virtual bool oop_is_typeArray_slow()      const { return false; }
  public:
-  virtual bool oop_is_instanceClassLoader() const { return false; }
-  virtual bool oop_is_instanceMirror()      const { return false; }
-  virtual bool oop_is_instanceRef()         const { return false; }
 
   // Fast non-virtual versions
   #ifndef ASSERT
--- a/hotspot/src/share/vm/oops/klass.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/klass.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -63,7 +63,7 @@
   assert(!is_null(v), "narrow klass value can never be zero");
   int    shift = Universe::narrow_klass_shift();
   Klass* result = (Klass*)(void*)((uintptr_t)Universe::narrow_klass_base() + ((uintptr_t)v << shift));
-  assert(check_klass_alignment(result), err_msg("address not aligned: " INTPTR_FORMAT, p2i((void*) result)));
+  assert(check_klass_alignment(result), "address not aligned: " INTPTR_FORMAT, p2i((void*) result));
   return result;
 }
 
--- a/hotspot/src/share/vm/oops/klassVtable.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,8 +38,6 @@
 #include "runtime/handles.inline.hpp"
 #include "utilities/copy.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 inline InstanceKlass* klassVtable::ik() const {
   Klass* k = _klass();
   assert(k->oop_is_instance(), "not an InstanceKlass");
@@ -1461,8 +1459,8 @@
   oop* end_of_obj = (oop*)_klass() + _klass()->size();
   oop* end_of_vtable = (oop *)&table()[_length];
   if (end_of_vtable > end_of_obj) {
-    fatal(err_msg("klass %s: klass object too short (vtable extends beyond "
-                  "end)", _klass->internal_name()));
+    fatal("klass %s: klass object too short (vtable extends beyond end)",
+          _klass->internal_name());
   }
 
   for (int i = 0; i < _length; i++) table()[i].verify(this, st);
@@ -1505,7 +1503,7 @@
 #ifndef PRODUCT
     print();
 #endif
-    fatal(err_msg("vtableEntry " PTR_FORMAT ": method is from subclass", this));
+    fatal("vtableEntry " PTR_FORMAT ": method is from subclass", p2i(this));
   }
 }
 
@@ -1515,7 +1513,7 @@
   ResourceMark rm;
   tty->print("vtableEntry %s: ", method()->name()->as_C_string());
   if (Verbose) {
-    tty->print("m %#lx ", (address)method());
+    tty->print("m " PTR_FORMAT " ", p2i(method()));
   }
 }
 
@@ -1586,7 +1584,7 @@
 void klassItable::print_statistics() {
  tty->print_cr("itable statistics:");
  tty->print_cr("%6d classes with itables", _total_classes);
- tty->print_cr("%6d K uses for itables (average by class: %d bytes)", _total_size / K, _total_size / _total_classes);
+ tty->print_cr("%6lu K uses for itables (average by class: %ld bytes)", _total_size / K, _total_size / _total_classes);
 }
 
 #endif // PRODUCT
--- a/hotspot/src/share/vm/oops/markOop.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/markOop.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -27,8 +27,6 @@
 #include "runtime/thread.inline.hpp"
 #include "runtime/objectMonitor.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 void markOopDesc::print_on(outputStream* st) const {
   if (is_marked()) {
     st->print(" marked(" INTPTR_FORMAT ")", value());
@@ -39,7 +37,7 @@
     if (mon == NULL) {
       st->print("NULL (this should never be seen!)");
     } else {
-      st->print("{count=" INTPTR_FORMAT ",waiters=" INTPTR_FORMAT
+      st->print("{count=0x%08x,waiters=0x%08x"
                 ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
                 mon->count(), mon->waiters(), mon->recursions(),
                 p2i(mon->owner()));
@@ -65,7 +63,7 @@
     assert(is_unlocked() || has_bias_pattern(), "just checking");
     st->print("mark(");
     if (has_bias_pattern()) st->print("biased,");
-    st->print("hash %#lx,", hash());
+    st->print("hash " INTPTR_FORMAT ",", hash());
     st->print("age %d)", age());
   }
 }
--- a/hotspot/src/share/vm/oops/method.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -57,8 +57,6 @@
 #include "utilities/quickSort.hpp"
 #include "utilities/xmlstream.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Implementation of Method
 
 Method* Method::allocate(ClassLoaderData* loader_data,
@@ -220,7 +218,7 @@
 
   Thread* myThread    = Thread::current();
   methodHandle h_this(myThread, this);
-#ifdef ASSERT
+#if defined(ASSERT) && !INCLUDE_JVMCI
   bool has_capability = myThread->is_VM_thread() ||
                         myThread->is_ConcurrentGC_thread() ||
                         myThread->is_GC_task_thread();
@@ -246,9 +244,11 @@
     return 0;
   }
 #ifdef ASSERT
-  { ResourceMark rm;
-  assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(),
-         err_msg("bcp doesn't belong to this method: bcp: " INTPTR_FORMAT ", method: %s", bcp, name_and_sig_as_C_string()));
+  {
+    ResourceMark rm;
+    assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(),
+           "bcp doesn't belong to this method: bcp: " INTPTR_FORMAT ", method: %s",
+           p2i(bcp), name_and_sig_as_C_string());
   }
 #endif
   return bcp - code_base();
@@ -279,7 +279,7 @@
 }
 
 address Method::bcp_from(int bci) const {
-  assert((is_native() && bci == 0)  || (!is_native() && 0 <= bci && bci < code_size()), err_msg("illegal bci: %d", bci));
+  assert((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size()), "illegal bci: %d", bci);
   address bcp = code_base() + bci;
   assert(is_native() && bcp == code_base() || contains(bcp), "bcp doesn't belong to this method");
   return bcp;
@@ -573,7 +573,7 @@
   ResourceMark rm;
   bool is_nonv = (vtable_index() == nonvirtual_vtable_index);
   if (class_access_flags.is_interface()) {
-      assert(is_nonv == is_static(), err_msg("is_nonv=%s", name_and_sig_as_C_string()));
+    assert(is_nonv == is_static(), "is_nonv=%s", name_and_sig_as_C_string());
   }
 #endif
   assert(valid_vtable_index() || valid_itable_index(), "method must be linked before we ask this question");
@@ -1373,7 +1373,7 @@
 
 // These two methods are static since a GC may move the Method
 bool Method::load_signature_classes(methodHandle m, TRAPS) {
-  if (THREAD->is_Compiler_thread()) {
+  if (!THREAD->can_call_java()) {
     // There is nothing useful this routine can do from within the Compile thread.
     // Hopefully, the signature contains only well-known classes.
     // We could scan for this and return true/false, but the caller won't care.
@@ -1491,14 +1491,20 @@
 void Method::print_name(outputStream* st) {
   Thread *thread = Thread::current();
   ResourceMark rm(thread);
-  SignatureTypePrinter sig(signature(), st);
   st->print("%s ", is_static() ? "static" : "virtual");
-  sig.print_returntype();
-  st->print(" %s.", method_holder()->internal_name());
-  name()->print_symbol_on(st);
-  st->print("(");
-  sig.print_parameters();
-  st->print(")");
+  if (WizardMode) {
+    st->print("%s.", method_holder()->internal_name());
+    name()->print_symbol_on(st);
+    signature()->print_symbol_on(st);
+  } else {
+    SignatureTypePrinter sig(signature(), st);
+    sig.print_returntype();
+    st->print(" %s.", method_holder()->internal_name());
+    name()->print_symbol_on(st);
+    st->print("(");
+    sig.print_parameters();
+    st->print(")");
+  }
 }
 #endif // !PRODUCT || INCLUDE_JVMTI
 
@@ -1572,7 +1578,7 @@
   }
   {
     ResourceMark rm;
-    fatal(err_msg("no original bytecode found in %s at bci %d", name_and_sig_as_C_string(), bci));
+    fatal("no original bytecode found in %s at bci %d", name_and_sig_as_C_string(), bci);
   }
   return Bytecodes::_shouldnotreachhere;
 }
@@ -2024,9 +2030,9 @@
   assert(is_method(), "must be method");
   st->print_cr("%s", internal_name());
   // get the effect of PrintOopAddress, always, for methods:
-  st->print_cr(" - this oop:          " INTPTR_FORMAT, (intptr_t)this);
+  st->print_cr(" - this oop:          " INTPTR_FORMAT, p2i(this));
   st->print   (" - method holder:     "); method_holder()->print_value_on(st); st->cr();
-  st->print   (" - constants:         " INTPTR_FORMAT " ", (address)constants());
+  st->print   (" - constants:         " INTPTR_FORMAT " ", p2i(constants()));
   constants()->print_value_on(st); st->cr();
   st->print   (" - access:            0x%x  ", access_flags().as_int()); access_flags().print_on(st); st->cr();
   st->print   (" - name:              ");    name()->print_value_on(st); st->cr();
@@ -2040,26 +2046,26 @@
   if (highest_comp_level() != CompLevel_none)
     st->print_cr(" - highest level:     %d", highest_comp_level());
   st->print_cr(" - vtable index:      %d",   _vtable_index);
-  st->print_cr(" - i2i entry:         " INTPTR_FORMAT, interpreter_entry());
+  st->print_cr(" - i2i entry:         " INTPTR_FORMAT, p2i(interpreter_entry()));
   st->print(   " - adapters:          ");
   AdapterHandlerEntry* a = ((Method*)this)->adapter();
   if (a == NULL)
-    st->print_cr(INTPTR_FORMAT, a);
+    st->print_cr(INTPTR_FORMAT, p2i(a));
   else
     a->print_adapter_on(st);
-  st->print_cr(" - compiled entry     " INTPTR_FORMAT, from_compiled_entry());
+  st->print_cr(" - compiled entry     " INTPTR_FORMAT, p2i(from_compiled_entry()));
   st->print_cr(" - code size:         %d",   code_size());
   if (code_size() != 0) {
-    st->print_cr(" - code start:        " INTPTR_FORMAT, code_base());
-    st->print_cr(" - code end (excl):   " INTPTR_FORMAT, code_base() + code_size());
+    st->print_cr(" - code start:        " INTPTR_FORMAT, p2i(code_base()));
+    st->print_cr(" - code end (excl):   " INTPTR_FORMAT, p2i(code_base() + code_size()));
   }
   if (method_data() != NULL) {
-    st->print_cr(" - method data:       " INTPTR_FORMAT, (address)method_data());
+    st->print_cr(" - method data:       " INTPTR_FORMAT, p2i(method_data()));
   }
   st->print_cr(" - checked ex length: %d",   checked_exceptions_length());
   if (checked_exceptions_length() > 0) {
     CheckedExceptionElement* table = checked_exceptions_start();
-    st->print_cr(" - checked ex start:  " INTPTR_FORMAT, table);
+    st->print_cr(" - checked ex start:  " INTPTR_FORMAT, p2i(table));
     if (Verbose) {
       for (int i = 0; i < checked_exceptions_length(); i++) {
         st->print_cr("   - throws %s", constants()->printable_name_at(table[i].class_cp_index));
@@ -2068,7 +2074,7 @@
   }
   if (has_linenumber_table()) {
     u_char* table = compressed_linenumber_table();
-    st->print_cr(" - linenumber start:  " INTPTR_FORMAT, table);
+    st->print_cr(" - linenumber start:  " INTPTR_FORMAT, p2i(table));
     if (Verbose) {
       CompressedLineNumberReadStream stream(table);
       while (stream.read_pair()) {
@@ -2079,7 +2085,7 @@
   st->print_cr(" - localvar length:   %d",   localvariable_table_length());
   if (localvariable_table_length() > 0) {
     LocalVariableTableElement* table = localvariable_table_start();
-    st->print_cr(" - localvar start:    " INTPTR_FORMAT, table);
+    st->print_cr(" - localvar start:    " INTPTR_FORMAT, p2i(table));
     if (Verbose) {
       for (int i = 0; i < localvariable_table_length(); i++) {
         int bci = table[i].start_bci;
@@ -2096,8 +2102,8 @@
     code()->print_value_on(st);
   }
   if (is_native()) {
-    st->print_cr(" - native function:   " INTPTR_FORMAT, native_function());
-    st->print_cr(" - signature handler: " INTPTR_FORMAT, signature_handler());
+    st->print_cr(" - native function:   " INTPTR_FORMAT, p2i(native_function()));
+    st->print_cr(" - signature handler: " INTPTR_FORMAT, p2i(signature_handler()));
   }
 }
 
--- a/hotspot/src/share/vm/oops/method.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -685,8 +685,10 @@
                                                    TRAPS);
   static Klass* check_non_bcp_klass(Klass* klass);
 
-  // How many extra stack entries for invokedynamic when it's enabled
-  static const int extra_stack_entries_for_jsr292 = 1;
+  enum {
+    // How many extra stack entries for invokedynamic
+    extra_stack_entries_for_jsr292 = 1
+  };
 
   // this operates only on invoke methods:
   // presize interpreter frames for extra interpreter stack entries, if needed
--- a/hotspot/src/share/vm/oops/methodCounters.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/methodCounters.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,7 +42,7 @@
   // The counter is reset by the sweeper and is decremented by some of the compiled
   // code. The counter values are interpreted as follows:
   // 1. (HotMethodDetection..INT_MAX] - initial value, no counters inserted
-  // 2. (1..HotMethodDetectionLimit)  - the method is warm, the counter is used
+  // 2. [1..HotMethodDetectionLimit)  - the method is warm, the counter is used
   //                                    to figure out which methods can be flushed.
   // 3. (INT_MIN..0]                  - method is hot and will deopt and get
   //                                    recompiled without the counters
--- a/hotspot/src/share/vm/oops/methodData.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,8 +38,6 @@
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/copy.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // ==================================================================
 // DataLayout
 //
@@ -110,7 +108,7 @@
       return ss.as_string();
       break;
     default:
-      fatal(err_msg("unexpected tag %d", dp->tag()));
+      fatal("unexpected tag %d", dp->tag());
     }
   }
   return NULL;
@@ -413,13 +411,39 @@
   }
 }
 
+#if INCLUDE_JVMCI
+void VirtualCallData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+  ReceiverTypeData::clean_weak_klass_links(is_alive_cl);
+  for (uint row = 0; row < method_row_limit(); row++) {
+    Method* p = method(row);
+    if (p != NULL && !p->method_holder()->is_loader_alive(is_alive_cl)) {
+      clear_method_row(row);
+    }
+  }
+}
+
+void VirtualCallData::clean_weak_method_links() {
+  ReceiverTypeData::clean_weak_method_links();
+  for (uint row = 0; row < method_row_limit(); row++) {
+    Method* p = method(row);
+    if (p != NULL && !p->on_stack()) {
+      clear_method_row(row);
+    }
+  }
+}
+#endif // INCLUDE_JVMCI
+
 void ReceiverTypeData::print_receiver_data_on(outputStream* st) const {
   uint row;
   int entries = 0;
   for (row = 0; row < row_limit(); row++) {
     if (receiver(row) != NULL)  entries++;
   }
+#if INCLUDE_JVMCI
+  st->print_cr("count(%u) nonprofiled_count(%u) entries(%u)", count(), nonprofiled_count(), entries);
+#else
   st->print_cr("count(%u) entries(%u)", count(), entries);
+#endif
   int total = count();
   for (row = 0; row < row_limit(); row++) {
     if (receiver(row) != NULL) {
@@ -438,9 +462,36 @@
   print_shared(st, "ReceiverTypeData", extra);
   print_receiver_data_on(st);
 }
+
+#if INCLUDE_JVMCI
+void VirtualCallData::print_method_data_on(outputStream* st) const {
+  uint row;
+  int entries = 0;
+  for (row = 0; row < method_row_limit(); row++) {
+    if (method(row) != NULL) entries++;
+  }
+  tab(st);
+  st->print_cr("method_entries(%u)", entries);
+  int total = count();
+  for (row = 0; row < method_row_limit(); row++) {
+    if (method(row) != NULL) {
+      total += method_count(row);
+    }
+  }
+  for (row = 0; row < method_row_limit(); row++) {
+    if (method(row) != NULL) {
+      tab(st);
+      method(row)->print_value_on(st);
+      st->print_cr("(%u %4.2f)", method_count(row), (float) method_count(row) / (float) total);
+    }
+  }
+}
+#endif // INCLUDE_JVMCI
+
 void VirtualCallData::print_data_on(outputStream* st, const char* extra) const {
   print_shared(st, "VirtualCallData", extra);
   print_receiver_data_on(st);
+  print_method_data_on(st);
 }
 
 // ==================================================================
@@ -665,7 +716,7 @@
 }
 
 int MethodData::bytecode_cell_count(Bytecodes::Code code) {
-#if defined(COMPILER1) && !defined(COMPILER2)
+#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI)
   return no_profile_data;
 #else
   switch (code) {
@@ -797,6 +848,26 @@
 }
 
 int MethodData::compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps) {
+#if INCLUDE_JVMCI
+  if (ProfileTraps) {
+    // Assume that up to 30% of the possibly trapping BCIs with no MDP will need to allocate one.
+    int extra_data_count = MIN2(empty_bc_count, MAX2(4, (empty_bc_count * 30) / 100));
+
+    // Make sure we have a minimum number of extra data slots to
+    // allocate SpeculativeTrapData entries. We would want to have one
+    // entry per compilation that inlines this method and for which
+    // some type speculation assumption fails. So the room we need for
+    // the SpeculativeTrapData entries doesn't directly depend on the
+    // size of the method. Because it's hard to estimate, we reserve
+    // space for an arbitrary number of entries.
+    int spec_data_count = (needs_speculative_traps ? SpecTrapLimitExtraEntries : 0) *
+      (SpeculativeTrapData::static_cell_count() + DataLayout::header_size_in_cells());
+
+    return MAX2(extra_data_count, spec_data_count);
+  } else {
+    return 0;
+  }
+#else // INCLUDE_JVMCI
   if (ProfileTraps) {
     // Assume that up to 3% of BCIs with no MDP will need to allocate one.
     int extra_data_count = (uint)(empty_bc_count * 3) / 128 + 1;
@@ -822,6 +893,7 @@
   } else {
     return 0;
   }
+#endif // INCLUDE_JVMCI
 }
 
 // Compute the size of the MethodData* necessary to store
@@ -835,7 +907,7 @@
   while ((c = stream.next()) >= 0) {
     int size_in_bytes = compute_data_size(&stream);
     data_size += size_in_bytes;
-    if (size_in_bytes == 0)  empty_bc_count += 1;
+    if (size_in_bytes == 0 JVMCI_ONLY(&& Bytecodes::can_trap(c)))  empty_bc_count += 1;
     needs_speculative_traps = needs_speculative_traps || is_speculative_trap_bytecode(c);
   }
   int object_size = in_bytes(data_offset()) + data_size;
@@ -869,7 +941,7 @@
 // the segment in bytes.
 int MethodData::initialize_data(BytecodeStream* stream,
                                        int data_index) {
-#if defined(COMPILER1) && !defined(COMPILER2)
+#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI)
   return 0;
 #else
   int cell_count = -1;
@@ -1060,10 +1132,14 @@
 MethodData::MethodData(methodHandle method, int size, TRAPS)
   : _extra_data_lock(Monitor::leaf, "MDO extra data lock"),
     _parameters_type_data_di(parameters_uninitialized) {
+  // Set the method back-pointer.
+  _method = method();
+  initialize();
+}
+
+void MethodData::initialize() {
   No_Safepoint_Verifier no_safepoint;  // init function atomic wrt GC
   ResourceMark rm;
-  // Set the method back-pointer.
-  _method = method();
 
   init();
   set_creation_mileage(mileage_of(method()));
@@ -1073,13 +1149,13 @@
   int data_size = 0;
   int empty_bc_count = 0;  // number of bytecodes lacking data
   _data[0] = 0;  // apparently not set below.
-  BytecodeStream stream(method);
+  BytecodeStream stream(method());
   Bytecodes::Code c;
   bool needs_speculative_traps = false;
   while ((c = stream.next()) >= 0) {
     int size_in_bytes = initialize_data(&stream, data_size);
     data_size += size_in_bytes;
-    if (size_in_bytes == 0)  empty_bc_count += 1;
+    if (size_in_bytes == 0 JVMCI_ONLY(&& Bytecodes::can_trap(c)))  empty_bc_count += 1;
     needs_speculative_traps = needs_speculative_traps || is_speculative_trap_bytecode(c);
   }
   _data_size = data_size;
@@ -1097,7 +1173,7 @@
   // the code for traps cells works.
   DataLayout *dp = data_layout_at(data_size + extra_size);
 
-  int arg_size = method->size_of_parameters();
+  int arg_size = method()->size_of_parameters();
   dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1);
 
   int arg_data_size = DataLayout::compute_size_in_bytes(arg_size+1);
@@ -1126,6 +1202,7 @@
 
   post_initialize(&stream);
 
+  assert(object_size == compute_allocation_size_in_bytes(methodHandle(_method)), "MethodData: computed size != initialized size");
   set_size(object_size);
 }
 
@@ -1146,6 +1223,10 @@
   _num_blocks = 0;
   _would_profile = unknown;
 
+#if INCLUDE_JVMCI
+  _jvmci_ir_size = 0;
+#endif
+
 #if INCLUDE_RTM_OPT
   _rtm_state = NoRTM; // No RTM lock eliding by default
   if (UseRTMLocking &&
@@ -1239,7 +1320,7 @@
     nb_cells = SpeculativeTrapData::static_cell_count();
     break;
   default:
-    fatal(err_msg("unexpected tag %d", dp->tag()));
+    fatal("unexpected tag %d", dp->tag());
   }
   return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells));
 }
@@ -1279,7 +1360,7 @@
       }
       break;
     default:
-      fatal(err_msg("unexpected tag %d", dp->tag()));
+      fatal("unexpected tag %d", dp->tag());
     }
   }
   return NULL;
@@ -1400,7 +1481,7 @@
       dp = end; // ArgInfoData is at the end of extra data section.
       break;
     default:
-      fatal(err_msg("unexpected tag %d", dp->tag()));
+      fatal("unexpected tag %d", dp->tag());
     }
     st->print("%d", dp_to_di(data->dp()));
     st->fill_to(6);
@@ -1612,7 +1693,7 @@
       clean_extra_data_helper(dp, shift, true);
       return;
     default:
-      fatal(err_msg("unexpected tag %d", dp->tag()));
+      fatal("unexpected tag %d", dp->tag());
     }
   }
 }
@@ -1638,7 +1719,7 @@
     case DataLayout::arg_info_data_tag:
       return;
     default:
-      fatal(err_msg("unexpected tag %d", dp->tag()));
+      fatal("unexpected tag %d", dp->tag());
     }
   }
 #endif
--- a/hotspot/src/share/vm/oops/methodData.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -539,7 +539,11 @@
   enum {
     // null_seen:
     //  saw a null operand (cast/aastore/instanceof)
-    null_seen_flag              = DataLayout::first_flag + 0
+      null_seen_flag              = DataLayout::first_flag + 0
+#if INCLUDE_JVMCI
+    // bytecode threw any exception
+    , exception_seen_flag         = null_seen_flag + 1
+#endif
   };
   enum { bit_cell_count = 0 };  // no additional data fields needed.
 public:
@@ -563,6 +567,11 @@
   bool null_seen()     { return flag_at(null_seen_flag); }
   void set_null_seen()    { set_flag_at(null_seen_flag); }
 
+#if INCLUDE_JVMCI
+  // true if an exception was thrown at the specific BCI
+  bool exception_seen() { return flag_at(exception_seen_flag); }
+  void set_exception_seen() { set_flag_at(exception_seen_flag); }
+#endif
 
   // Code generation support
   static int null_seen_byte_constant() {
@@ -1166,7 +1175,22 @@
 class ReceiverTypeData : public CounterData {
 protected:
   enum {
+#if INCLUDE_JVMCI
+    // Description of the different counters
+    // ReceiverTypeData for instanceof/checkcast/aastore:
+    //   C1/C2: count is incremented on type overflow and decremented for failed type checks
+    //   JVMCI: count decremented for failed type checks and nonprofiled_count is incremented on type overflow
+    //          TODO (chaeubl): in fact, JVMCI should also increment the count for failed type checks to mimic the C1/C2 behavior
+    // VirtualCallData for invokevirtual/invokeinterface:
+    //   C1/C2: count is incremented on type overflow
+    //   JVMCI: count is incremented on type overflow, nonprofiled_count is incremented on method overflow
+
+    // JVMCI is interested in knowing the percentage of type checks involving a type not explicitly in the profile
+    nonprofiled_count_off_set = counter_cell_count,
+    receiver0_offset,
+#else
     receiver0_offset = counter_cell_count,
+#endif
     count0_offset,
     receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset
   };
@@ -1181,7 +1205,7 @@
   virtual bool is_ReceiverTypeData() const { return true; }
 
   static int static_cell_count() {
-    return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count;
+    return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count JVMCI_ONLY(+ 1);
   }
 
   virtual int cell_count() const {
@@ -1243,6 +1267,13 @@
     set_count(0);
     set_receiver(row, NULL);
     set_receiver_count(row, 0);
+#if INCLUDE_JVMCI
+    if (!this->is_VirtualCallData()) {
+      // if this is a ReceiverTypeData for JVMCI, the nonprofiled_count
+      // must also be reset (see "Description of the different counters" above)
+      set_nonprofiled_count(0);
+    }
+#endif
   }
 
   // Code generation support
@@ -1252,6 +1283,17 @@
   static ByteSize receiver_count_offset(uint row) {
     return cell_offset(receiver_count_cell_index(row));
   }
+#if INCLUDE_JVMCI
+  static ByteSize nonprofiled_receiver_count_offset() {
+    return cell_offset(nonprofiled_count_off_set);
+  }
+  uint nonprofiled_count() const {
+    return uint_at(nonprofiled_count_off_set);
+  }
+  void set_nonprofiled_count(uint count) {
+    set_uint_at(nonprofiled_count_off_set, count);
+  }
+#endif // INCLUDE_JVMCI
   static ByteSize receiver_type_data_size() {
     return cell_offset(static_cell_count());
   }
@@ -1316,7 +1358,7 @@
   static int static_cell_count() {
     // At this point we could add more profile state, e.g., for arguments.
     // But for now it's the same size as the base record type.
-    return ReceiverTypeData::static_cell_count();
+    return ReceiverTypeData::static_cell_count() JVMCI_ONLY(+ (uint) MethodProfileWidth * receiver_type_row_cell_count);
   }
 
   virtual int cell_count() const {
@@ -1338,6 +1380,62 @@
   }
 #endif // CC_INTERP
 
+#if INCLUDE_JVMCI
+  static ByteSize method_offset(uint row) {
+    return cell_offset(method_cell_index(row));
+  }
+  static ByteSize method_count_offset(uint row) {
+    return cell_offset(method_count_cell_index(row));
+  }
+  static int method_cell_index(uint row) {
+    return receiver0_offset + (row + TypeProfileWidth) * receiver_type_row_cell_count;
+  }
+  static int method_count_cell_index(uint row) {
+    return count0_offset + (row + TypeProfileWidth) * receiver_type_row_cell_count;
+  }
+  static uint method_row_limit() {
+    return MethodProfileWidth;
+  }
+
+  Method* method(uint row) const {
+    assert(row < method_row_limit(), "oob");
+
+    Method* method = (Method*)intptr_at(method_cell_index(row));
+    assert(method == NULL || method->is_method(), "must be");
+    return method;
+  }
+
+  uint method_count(uint row) const {
+    assert(row < method_row_limit(), "oob");
+    return uint_at(method_count_cell_index(row));
+  }
+
+  void set_method(uint row, Method* m) {
+    assert((uint)row < method_row_limit(), "oob");
+    set_intptr_at(method_cell_index(row), (uintptr_t)m);
+  }
+
+  void set_method_count(uint row, uint count) {
+    assert(row < method_row_limit(), "oob");
+    set_uint_at(method_count_cell_index(row), count);
+  }
+
+  void clear_method_row(uint row) {
+    assert(row < method_row_limit(), "oob");
+    // Clear total count - indicator of polymorphic call site (see comment for clear_row() in ReceiverTypeData).
+    set_nonprofiled_count(0);
+    set_method(row, NULL);
+    set_method_count(row, 0);
+  }
+
+  // GC support
+  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+
+  // Redefinition support
+  virtual void clean_weak_method_links();
+#endif // INCLUDE_JVMCI
+
+  void print_method_data_on(outputStream* st) const NOT_JVMCI_RETURN;
   void print_data_on(outputStream* st, const char* extra = NULL) const;
 };
 
@@ -2053,10 +2151,11 @@
   MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData
 
   bool is_methodData() const volatile { return true; }
+  void initialize();
 
   // Whole-method sticky bits and flags
   enum {
-    _trap_hist_limit    = 22,   // decoupled from Deoptimization::Reason_LIMIT
+    _trap_hist_limit    = 22 JVMCI_ONLY(+5),   // decoupled from Deoptimization::Reason_LIMIT
     _trap_hist_mask     = max_jubyte,
     _extra_data_count   = 4     // extra DataLayout headers, for trap history
   }; // Public flag values
@@ -2104,6 +2203,11 @@
   enum WouldProfile {unknown, no_profile, profile};
   WouldProfile      _would_profile;
 
+#if INCLUDE_JVMCI
+  // Support for HotSpotMethodData.setCompiledIRSize(int)
+  int               _jvmci_ir_size;
+#endif
+
   // Size of _data array in bytes.  (Excludes header and extra_data fields.)
   int _data_size;
 
@@ -2382,7 +2486,7 @@
 
   // Return (uint)-1 for overflow.
   uint trap_count(int reason) const {
-    assert((uint)reason < _trap_hist_limit, "oob");
+    assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob");
     return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;
   }
   // For loops:
@@ -2391,17 +2495,13 @@
   uint inc_trap_count(int reason) {
     // Count another trap, anywhere in this method.
     assert(reason >= 0, "must be single trap");
-    if ((uint)reason < _trap_hist_limit) {
-      uint cnt1 = 1 + _trap_hist._array[reason];
-      if ((cnt1 & _trap_hist_mask) != 0) {  // if no counter overflow...
-        _trap_hist._array[reason] = cnt1;
-        return cnt1;
-      } else {
-        return _trap_hist_mask + (++_nof_overflow_traps);
-      }
+    assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob");
+    uint cnt1 = 1 + _trap_hist._array[reason];
+    if ((cnt1 & _trap_hist_mask) != 0) {  // if no counter overflow...
+      _trap_hist._array[reason] = cnt1;
+      return cnt1;
     } else {
-      // Could not represent the count in the histogram.
-      return (++_nof_overflow_traps);
+      return _trap_hist_mask + (++_nof_overflow_traps);
     }
   }
 
@@ -2446,6 +2546,10 @@
     return byte_offset_of(MethodData, _data[0]);
   }
 
+  static ByteSize trap_history_offset() {
+    return byte_offset_of(MethodData, _trap_hist._array);
+  }
+
   static ByteSize invocation_counter_offset() {
     return byte_offset_of(MethodData, _invocation_counter);
   }
--- a/hotspot/src/share/vm/oops/oop.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/oop.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,8 +31,6 @@
 #include "runtime/thread.inline.hpp"
 #include "utilities/copy.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 bool always_do_update_barrier = false;
 
 BarrierSet* oopDesc::_bs = NULL;
@@ -47,7 +45,7 @@
 
 void oopDesc::print_address_on(outputStream* st) const {
   if (PrintOopAddress) {
-    st->print("{" INTPTR_FORMAT "}", this);
+    st->print("{" INTPTR_FORMAT "}", p2i(this));
   }
 }
 
@@ -123,7 +121,7 @@
 
 template <class T> void VerifyOopClosure::do_oop_work(T* p) {
   oop obj = oopDesc::load_decode_heap_oop(p);
-  guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj)));
+  guarantee(obj->is_oop_or_null(), "invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj));
 }
 
 void VerifyOopClosure::do_oop(oop* p)       { VerifyOopClosure::do_oop_work(p); }
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -126,10 +126,25 @@
 
 inline bool oopDesc::is_a(Klass* k)        const { return klass()->is_subtype_of(k); }
 
-inline bool oopDesc::is_instance()            const { return klass()->oop_is_instance(); }
-inline bool oopDesc::is_instanceClassLoader() const { return klass()->oop_is_instanceClassLoader(); }
-inline bool oopDesc::is_instanceMirror()      const { return klass()->oop_is_instanceMirror(); }
-inline bool oopDesc::is_instanceRef()         const { return klass()->oop_is_instanceRef(); }
+inline bool oopDesc::is_instance() const {
+  return klass()->oop_is_instance();
+}
+
+inline bool oopDesc::is_instanceClassLoader() const {
+  Klass* k = klass();
+  return k->oop_is_instance() && InstanceKlass::cast(k)->is_class_loader_instance_klass();
+}
+
+inline bool oopDesc::is_instanceMirror() const {
+  Klass* k = klass();
+  return k->oop_is_instance() && InstanceKlass::cast(k)->is_mirror_instance_klass();
+}
+
+inline bool oopDesc::is_instanceRef() const {
+  Klass* k = klass();
+  return k->oop_is_instance() && InstanceKlass::cast(k)->is_reference_instance_klass();
+}
+
 inline bool oopDesc::is_array()               const { return klass()->oop_is_array(); }
 inline bool oopDesc::is_objArray()            const { return klass()->oop_is_objArray(); }
 inline bool oopDesc::is_typeArray()           const { return klass()->oop_is_typeArray(); }
@@ -189,7 +204,7 @@
   address base = Universe::narrow_oop_base();
   int    shift = Universe::narrow_oop_shift();
   oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
-  assert(check_obj_alignment(result), err_msg("address not aligned: " INTPTR_FORMAT, p2i((void*) result)));
+  assert(check_obj_alignment(result), "address not aligned: " INTPTR_FORMAT, p2i((void*) result));
   return result;
 }
 
--- a/hotspot/src/share/vm/opto/block.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/block.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -358,6 +358,8 @@
 PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
 : Phase(CFG)
 , _block_arena(arena)
+, _regalloc(NULL)
+, _scheduling_for_pressure(false)
 , _root(root)
 , _matcher(matcher)
 , _node_to_block_mapping(arena)
--- a/hotspot/src/share/vm/opto/block.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/block.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,6 +37,7 @@
 class Matcher;
 class RootNode;
 class VectorSet;
+class PhaseChaitin;
 struct Tarjan;
 
 //------------------------------Block_Array------------------------------------
@@ -383,6 +384,12 @@
   // Arena for the blocks to be stored in
   Arena* _block_arena;
 
+  // Info used for scheduling
+  PhaseChaitin* _regalloc;
+
+  // Register pressure heuristic used?
+  bool _scheduling_for_pressure;
+
   // The matcher for this compilation
   Matcher& _matcher;
 
@@ -433,12 +440,14 @@
   // to late. Helper for schedule_late.
   Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
 
-  bool schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call);
+  bool schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call, intptr_t* recacl_pressure_nodes);
   void set_next_call(Block* block, Node* n, VectorSet& next_call);
   void needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call);
 
   // Perform basic-block local scheduling
-  Node* select(Block* block, Node_List& worklist, GrowableArray<int>& ready_cnt, VectorSet& next_call, uint sched_slot);
+  Node* select(Block* block, Node_List& worklist, GrowableArray<int>& ready_cnt, VectorSet& next_call, uint sched_slot,
+               intptr_t* recacl_pressure_nodes);
+  void adjust_register_pressure(Node* n, Block* block, intptr_t *recalc_pressure_nodes, bool finalize_mode);
 
   // Schedule a call next in the block
   uint sched_call(Block* block, uint node_cnt, Node_List& worklist, GrowableArray<int>& ready_cnt, MachCallNode* mcall, VectorSet& next_call);
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -114,7 +114,7 @@
       CompileTask::print_inline_indent(inline_level());
       tty->print_cr("Inlined method is hot: ");
     }
-    set_msg("force inline by CompilerOracle");
+    set_msg("force inline by CompileCommand");
     _forced_inline = true;
     return true;
   }
@@ -223,12 +223,12 @@
 
   // ignore heuristic controls on inlining
   if (callee_method->should_inline()) {
-    set_msg("force inline by CompilerOracle");
+    set_msg("force inline by CompileCommand");
     return false;
   }
 
   if (callee_method->should_not_inline()) {
-    set_msg("disallowed by CompilerOracle");
+    set_msg("disallowed by CompileCommand");
     return true;
   }
 
@@ -470,11 +470,6 @@
       }
     }
   }
-  // We will attempt to see if a class/field/etc got properly loaded.  If it
-  // did not, it may attempt to throw an exception during our probing.  Catch
-  // and ignore such exceptions and do not attempt to compile the method.
-  if( callee_method->should_exclude() )  return false;
-
   return true;
 }
 
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -69,43 +69,32 @@
   develop(bool, StressGCM, false,                                           \
           "Randomize instruction scheduling in GCM")                        \
                                                                             \
-  notproduct(intx, CompileZapFirst, 0,                                      \
-          "If +ZapDeadCompiledLocals, "                                     \
-          "skip this many before compiling in zap calls")                   \
-                                                                            \
-  notproduct(intx, CompileZapLast, -1,                                      \
-          "If +ZapDeadCompiledLocals, "                                     \
-          "compile this many after skipping (incl. skip count, -1 = all)")  \
-                                                                            \
-  notproduct(intx, ZapDeadCompiledLocalsFirst, 0,                           \
-          "If +ZapDeadCompiledLocals, "                                     \
-          "skip this many before really doing it")                          \
-                                                                            \
-  notproduct(intx, ZapDeadCompiledLocalsLast, -1,                           \
-          "If +ZapDeadCompiledLocals, "                                     \
-          "do this many after skipping (incl. skip count, -1 = all)")       \
-                                                                            \
   develop(intx, OptoPrologueNops, 0,                                        \
           "Insert this many extra nop instructions "                        \
           "in the prologue of every nmethod")                               \
+          range(0, 128)                                                     \
                                                                             \
   product_pd(intx, InteriorEntryAlignment,                                  \
           "Code alignment for interior entry points "                       \
           "in generated code (in bytes)")                                   \
+          constraint(InteriorEntryAlignmentConstraintFunc, AfterErgo)       \
                                                                             \
   product(intx, MaxLoopPad, (OptoLoopAlignment-1),                          \
           "Align a loop if padding size in bytes is less or equal to this " \
           "value")                                                          \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, MaxVectorSize, 64,                                          \
           "Max vector size in bytes, "                                      \
           "actual size could be less depending on elements type")           \
+          range(0, max_jint)                                                \
                                                                             \
   product(bool, AlignVector, true,                                          \
           "Perform vector store/load alignment in loop")                    \
                                                                             \
   product(intx, NumberOfLoopInstrToAlign, 4,                                \
           "Number of first instructions in a loop to align")                \
+          range(0, max_jint)                                                \
                                                                             \
   notproduct(intx, IndexSetWatch, 0,                                        \
           "Trace all operations on this IndexSet (-1 means all, 0 none)")   \
@@ -113,9 +102,11 @@
                                                                             \
   develop(intx, OptoNodeListSize, 4,                                        \
           "Starting allocation size of Node_List data structures")          \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, OptoBlockListSize, 8,                                       \
           "Starting allocation size of Block_List data structures")         \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, OptoPeepholeAt, -1,                                         \
           "Apply peephole optimizations to this peephole rule")             \
@@ -189,9 +180,11 @@
                                                                             \
   product_pd(intx,  LoopUnrollLimit,                                        \
           "Unroll loop bodies with node count less than this")              \
+          range(0, max_jint / 4)                                            \
                                                                             \
   product(intx,  LoopMaxUnroll, 16,                                         \
           "Maximum number of unrolls for main loop")                        \
+          range(0, max_jint)                                                \
                                                                             \
   product(bool,  SuperWordLoopUnrollAnalysis, false,                        \
           "Map number of unrolls for main loop via "                        \
@@ -203,16 +196,19 @@
   product(intx,  LoopUnrollMin, 4,                                          \
           "Minimum number of unroll loop bodies before checking progress"   \
           "of rounds of unroll,optimize,..")                                \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, UnrollLimitForProfileCheck, 1,                              \
           "Don't use profile_trip_cnt() to restrict unrolling until "       \
           "unrolling would push the number of unrolled iterations above "   \
           "UnrollLimitForProfileCheck. A higher value allows more "         \
           "unrolling. Zero acts as a very large value." )                   \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, MultiArrayExpandLimit, 6,                                   \
           "Maximum number of individual allocations in an inline-expanded " \
           "multianewarray instruction")                                     \
+          range(0, max_jint)                                                \
                                                                             \
   notproduct(bool, TraceProfileTripCount, false,                            \
           "Trace profile loop trip count information")                      \
@@ -259,6 +255,7 @@
                                                                             \
   product(intx, TrackedInitializationLimit, 50,                             \
           "When initializing fields, track up to this many words")          \
+          range(0, 65535)                                                   \
                                                                             \
   product(bool, ReduceFieldZeroing, true,                                   \
           "When initializing fields, try to avoid needless zeroing")        \
@@ -293,9 +290,11 @@
                                                                             \
   develop_pd(intx, FLOATPRESSURE,                                           \
           "Number of float LRG's that constitute high register pressure")   \
+          range(0, max_jint)                                                \
                                                                             \
   develop_pd(intx, INTPRESSURE,                                             \
           "Number of integer LRG's that constitute high register pressure") \
+          range(0, max_jint)                                                \
                                                                             \
   notproduct(bool, TraceOptoPipelining, false,                              \
           "Trace pipelining information")                                   \
@@ -306,11 +305,15 @@
   product_pd(bool, OptoScheduling,                                          \
           "Instruction Scheduling after register allocation")               \
                                                                             \
+  product_pd(bool, OptoRegScheduling,                                       \
+          "Instruction Scheduling before register allocation for pressure") \
+                                                                            \
   product(bool, PartialPeelLoop, true,                                      \
           "Partial peel (rotate) loops")                                    \
                                                                             \
   product(intx, PartialPeelNewPhiDelta, 0,                                  \
           "Additional phis that can be created by partial peeling")         \
+          range(0, max_jint)                                                \
                                                                             \
   notproduct(bool, TracePartialPeeling, false,                              \
           "Trace partial peeling (loop rotation) information")              \
@@ -339,6 +342,9 @@
   product(bool, SuperWordReductions, true,                                  \
           "Enable reductions support in superword.")                        \
                                                                             \
+  product(bool, DoReserveCopyInSuperWord, true,                             \
+          "Create reserve copy of graph in SuperWord.")                     \
+                                                                            \
   notproduct(bool, TraceSuperWord, false,                                   \
           "Trace superword transforms")                                     \
                                                                             \
@@ -350,6 +356,7 @@
                                                                             \
   product_pd(intx, ConditionalMoveLimit,                                    \
           "Limit of ops to make speculative when using CMOVE")              \
+          range(0, max_jint)                                                \
                                                                             \
   /* Set BranchOnRegister == false. See 4965987. */                         \
   product(bool, BranchOnRegister, false,                                    \
@@ -374,6 +381,7 @@
                                                                             \
   develop(intx, PrintIdealGraphPort, 4444,                                  \
           "Ideal graph printer to network port")                            \
+          range(0, SHRT_MAX)                                                \
                                                                             \
   notproduct(ccstr, PrintIdealGraphAddress, "127.0.0.1",                    \
           "IP address to connect to visualizer")                            \
@@ -402,50 +410,64 @@
   develop(intx, ImplicitNullCheckThreshold, 3,                              \
           "Don't do implicit null checks if NPE's in a method exceeds "     \
           "limit")                                                          \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, LoopOptsCount, 43,                                          \
           "Set level of loop optimization for tier 1 compiles")             \
+          range(5, 43)                                                      \
                                                                             \
   /* controls for heat-based inlining */                                    \
                                                                             \
   develop(intx, NodeCountInliningCutoff, 18000,                             \
           "If parser node generation exceeds limit stop inlining")          \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, NodeCountInliningStep, 1000,                                \
           "Target size of warm calls inlined between optimization passes")  \
+          range(0, max_jint)                                                \
                                                                             \
   develop(bool, InlineWarmCalls, false,                                     \
           "Use a heat-based priority queue to govern inlining")             \
                                                                             \
   develop(intx, HotCallCountThreshold, 999999,                              \
           "large numbers of calls (per method invocation) force hotness")   \
+          range(0, max_intx)                                                \
                                                                             \
   develop(intx, HotCallProfitThreshold, 999999,                             \
           "highly profitable inlining opportunities force hotness")         \
+          range(0, max_intx)                                                \
                                                                             \
   develop(intx, HotCallTrivialWork, -1,                                     \
           "trivial execution time (no larger than this) forces hotness")    \
+          range(-1, max_intx)                                               \
                                                                             \
   develop(intx, HotCallTrivialSize, -1,                                     \
           "trivial methods (no larger than this) force calls to be hot")    \
+          range(-1, max_intx)                                               \
                                                                             \
   develop(intx, WarmCallMinCount, -1,                                       \
           "number of calls (per method invocation) to enable inlining")     \
+          range(-1, max_intx)                                               \
                                                                             \
   develop(intx, WarmCallMinProfit, -1,                                      \
           "number of calls (per method invocation) to enable inlining")     \
+          range(-1, max_intx)                                               \
                                                                             \
   develop(intx, WarmCallMaxWork, 999999,                                    \
           "execution time of the largest inlinable method")                 \
+          range(0, max_intx)                                                \
                                                                             \
   develop(intx, WarmCallMaxSize, 999999,                                    \
           "size of the largest inlinable method")                           \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, MaxNodeLimit, 80000,                                        \
           "Maximum number of nodes")                                        \
+          range(1000, max_jint / 3)                                         \
                                                                             \
   product(intx, NodeLimitFudgeFactor, 2000,                                 \
           "Fudge Factor for certain optimizations")                         \
+          constraint(NodeLimitFudgeFactorConstraintFunc, AfterErgo)         \
                                                                             \
   product(bool, UseJumpTables, true,                                        \
           "Use JumpTables instead of a binary search tree for switches")    \
@@ -455,12 +477,15 @@
                                                                             \
   product_pd(intx, MinJumpTableSize,                                        \
           "Minimum number of targets in a generated jump table")            \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, MaxJumpTableSize, 65000,                                    \
           "Maximum number of targets in a generated jump table")            \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, MaxJumpTableSparseness, 5,                                  \
           "Maximum sparseness for jumptables")                              \
+          range(0, max_intx / 4)                                            \
                                                                             \
   product(bool, EliminateLocks, true,                                       \
           "Coarsen locks when possible")                                    \
@@ -488,6 +513,7 @@
                                                                             \
   product(intx, AutoBoxCacheMax, 128,                                       \
           "Sets max value cached by the java.lang.Integer autobox cache")   \
+          range(0, max_jint)                                                \
                                                                             \
   experimental(bool, AggressiveUnboxing, false,                             \
           "Control optimizations for aggressive boxing elimination")        \
@@ -500,6 +526,7 @@
                                                                             \
   product(double, EscapeAnalysisTimeout, 20. DEBUG_ONLY(+40.),              \
           "Abort EA when it reaches time limit (in sec)")                   \
+          range(0, DBL_MAX)                                                 \
                                                                             \
   develop(bool, ExitEscapeAnalysisOnTimeout, true,                          \
           "Exit or throw assert in EA when it reaches time limit")          \
@@ -515,6 +542,7 @@
                                                                             \
   product(intx, EliminateAllocationArraySizeLimit, 64,                      \
           "Array size (number of elements) limit for scalar replacement")   \
+          range(0, max_jint)                                                \
                                                                             \
   product(bool, OptimizePtrCompare, true,                                   \
           "Use escape analysis to optimize pointers compare")               \
@@ -536,12 +564,15 @@
                                                                             \
   product(intx, ValueSearchLimit, 1000,                                     \
           "Recursion limit in PhaseMacroExpand::value_from_mem_phi")        \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, MaxLabelRootDepth, 1100,                                    \
           "Maximum times call Label_Root to prevent stack overflow")        \
+          range(100, max_jint)                                              \
                                                                             \
   diagnostic(intx, DominatorSearchLimit, 1000,                              \
           "Iterations limit in Node::dominates")                            \
+          range(0, max_jint)                                                \
                                                                             \
   product(bool, BlockLayoutByFrequency, true,                               \
           "Use edge frequencies to drive block ordering")                   \
@@ -651,6 +682,7 @@
                                                                             \
   develop(intx, FreqCountInvocations,  1,                                   \
           "Scaling factor for branch frequencies (deprecated)")             \
+          range(1, max_intx)                                                \
                                                                             \
   product(intx, AliasLevel,     3,                                          \
           "0 for no aliasing, 1 for oop/field/static/array split, "         \
@@ -669,6 +701,7 @@
                                                                             \
   product(intx, LiveNodeCountInliningCutoff, 40000,                         \
           "max number of live nodes in a method")                           \
+          range(0, max_juint / 8)                                           \
                                                                             \
   diagnostic(bool, OptimizeExpensiveOps, true,                              \
           "Find best control for expensive operations")                     \
@@ -705,6 +738,7 @@
   product(intx, ArrayCopyLoadStoreMaxElem, 8,                               \
           "Maximum number of arraycopy elements inlined as a sequence of"   \
           "loads/stores")                                                   \
+          range(0, max_intx)                                                \
                                                                             \
   develop(bool, StressArrayCopyMacroNode, false,                            \
           "Perform ArrayCopy load/store replacement during IGVN only")
--- a/hotspot/src/share/vm/opto/callGenerator.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -895,7 +895,7 @@
     break;
 
   default:
-    fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+    fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
     break;
   }
   return NULL;
--- a/hotspot/src/share/vm/opto/callnode.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -907,6 +907,18 @@
 
   // Convenience for initialization->maybe_set_complete(phase)
   bool maybe_set_complete(PhaseGVN* phase);
+
+  // Return true if allocation doesn't escape thread, its escape state
+  // needs be noEscape or ArgEscape. InitializeNode._does_not_escape
+  // is true when its allocation's escape state is noEscape or
+  // ArgEscape. In case allocation's InitializeNode is NULL, check
+  // AlllocateNode._is_non_escaping flag.
+  // AlllocateNode._is_non_escaping is true when its escape state is
+  // noEscape.
+  bool does_not_escape_thread() {
+    InitializeNode* init = NULL;
+    return _is_non_escaping || (((init = initialization()) != NULL) && init->does_not_escape());
+  }
 };
 
 //------------------------------AllocateArray---------------------------------
--- a/hotspot/src/share/vm/opto/castnode.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/castnode.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -129,7 +129,7 @@
             } else {
               stringStream ss;
               test.dump_on(&ss);
-              fatal(err_msg_res("unexpected comparison %s", ss.as_string()));
+              fatal("unexpected comparison %s", ss.as_string());
             }
             int lo_int = (int)lo_long;
             int hi_int = (int)hi_long;
--- a/hotspot/src/share/vm/opto/chaitin.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -191,7 +191,7 @@
   return next;
 }
 
-PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
+PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher, bool scheduling_info_generated)
   : PhaseRegAlloc(unique, cfg, matcher,
 #ifndef PRODUCT
        print_chaitin_statistics
@@ -205,6 +205,11 @@
   , _spilled_twice(Thread::current()->resource_area())
   , _lo_degree(0), _lo_stk_degree(0), _hi_degree(0), _simplified(0)
   , _oldphi(unique)
+  , _scheduling_info_generated(scheduling_info_generated)
+  , _sched_int_pressure(0, INTPRESSURE)
+  , _sched_float_pressure(0, FLOATPRESSURE)
+  , _scratch_int_pressure(0, INTPRESSURE)
+  , _scratch_float_pressure(0, FLOATPRESSURE)
 #ifndef PRODUCT
   , _trace_spilling(TraceSpilling || C->method_has_option("TraceSpilling"))
 #endif
@@ -350,7 +355,7 @@
   // all copy-related live ranges low and then using the max copy-related
   // live range as a cut-off for LIVE and the IFG.  In other words, I can
   // build a subset of LIVE and IFG just for copies.
-  PhaseLive live(_cfg, _lrg_map.names(), &live_arena);
+  PhaseLive live(_cfg, _lrg_map.names(), &live_arena, false);
 
   // Need IFG for coalescing and coloring
   PhaseIFG ifg(&live_arena);
@@ -690,6 +695,29 @@
   _lrg_map.reset_uf_map(lr_counter);
 }
 
+void PhaseChaitin::mark_ssa() {
+  // Use ssa names to populate the live range maps or if no mask
+  // is available, use the 0 entry.
+  uint max_idx = 0;
+  for ( uint i = 0; i < _cfg.number_of_blocks(); i++ ) {
+    Block* block = _cfg.get_block(i);
+    uint cnt = block->number_of_nodes();
+
+    // Handle all the normal Nodes in the block
+    for ( uint j = 0; j < cnt; j++ ) {
+      Node *n = block->get_node(j);
+      // Pre-color to the zero live range, or pick virtual register
+      const RegMask &rm = n->out_RegMask();
+      _lrg_map.map(n->_idx, rm.is_NotEmpty() ? n->_idx : 0);
+      max_idx = (n->_idx > max_idx) ? n->_idx : max_idx;
+    }
+  }
+  _lrg_map.set_max_lrg_id(max_idx+1);
+
+  // Reset the Union-Find mapping to be identity
+  _lrg_map.reset_uf_map(max_idx+1);
+}
+
 
 // Gather LiveRanGe information, including register masks.  Modification of
 // cisc spillable in_RegMasks should not be done before AggressiveCoalesce.
@@ -707,7 +735,9 @@
     for (uint j = 1; j < block->number_of_nodes(); j++) {
       Node* n = block->get_node(j);
       uint input_edge_start =1; // Skip control most nodes
+      bool is_machine_node = false;
       if (n->is_Mach()) {
+        is_machine_node = true;
         input_edge_start = n->as_Mach()->oper_input_base();
       }
       uint idx = n->is_Copy();
@@ -929,6 +959,7 @@
           // Convert operand number to edge index number
           inp = n->as_Mach()->operand_index(inp);
       }
+
       // Prepare register mask for each input
       for( uint k = input_edge_start; k < cnt; k++ ) {
         uint vreg = _lrg_map.live_range_id(n->in(k));
@@ -948,6 +979,12 @@
           n->as_Mach()->use_cisc_RegMask();
         }
 
+        if (is_machine_node && _scheduling_info_generated) {
+          MachNode* cur_node = n->as_Mach();
+          // this is cleaned up by register allocation
+          if (k >= cur_node->num_opnds()) continue;
+        }
+
         LRG &lrg = lrgs(vreg);
         // // Testing for floating point code shape
         // Node *test = n->in(k);
@@ -989,7 +1026,7 @@
         // double can interfere with TWO aligned pairs, or effectively
         // FOUR registers!
 #ifdef ASSERT
-        if (is_vect) {
+        if (is_vect && !_scheduling_info_generated) {
           if (lrg.num_regs() != 0) {
             assert(lrgmask.is_aligned_sets(lrg.num_regs()), "vector should be aligned");
             assert(!lrg._fat_proj, "sanity");
@@ -1733,7 +1770,7 @@
 
   // Check for AddP-related opcodes
   if (!derived->is_Phi()) {
-    assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg_res("but is: %s", derived->Name()));
+    assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, "but is: %s", derived->Name());
     Node *base = derived->in(AddPNode::Base);
     derived_base_map[derived->_idx] = base;
     return base;
--- a/hotspot/src/share/vm/opto/chaitin.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -399,7 +399,6 @@
   int _trip_cnt;
   int _alternate;
 
-  LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); }
   PhaseLive *_live;             // Liveness, used in the interference graph
   PhaseIFG *_ifg;               // Interference graph (for original chunk)
   Node_List **_lrg_nodes;       // Array of node; lists for lrgs which spill
@@ -464,16 +463,28 @@
 #endif
 
 public:
-  PhaseChaitin( uint unique, PhaseCFG &cfg, Matcher &matcher );
+  PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher, bool track_liveout_pressure);
   ~PhaseChaitin() {}
 
   LiveRangeMap _lrg_map;
 
+  LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); }
+
   // Do all the real work of allocate
   void Register_Allocate();
 
   float high_frequency_lrg() const { return _high_frequency_lrg; }
 
+  // Used when scheduling info generated, not in general register allocation
+  bool _scheduling_info_generated;
+
+  void set_ifg(PhaseIFG &ifg) { _ifg = &ifg;  }
+  void set_live(PhaseLive &live) { _live = &live; }
+  PhaseLive* get_live() { return _live; }
+
+  // Populate the live range maps with ssa info for scheduling
+  void mark_ssa();
+
 #ifndef PRODUCT
   bool trace_spilling() const { return _trace_spilling; }
 #endif
@@ -516,7 +527,11 @@
       uint _final_pressure;
 
       // number of live ranges that constitute high register pressure
-      const uint _high_pressure_limit;
+      uint _high_pressure_limit;
+
+      // initial pressure observed
+      uint _start_pressure;
+
     public:
 
       // lower the register pressure and look for a low to high pressure
@@ -537,6 +552,14 @@
         }
       }
 
+      void init(int limit) {
+        _current_pressure = 0;
+        _high_pressure_index = 0;
+        _final_pressure = 0;
+        _high_pressure_limit = limit;
+        _start_pressure = 0;
+      }
+
       uint high_pressure_index() const {
         return _high_pressure_index;
       }
@@ -545,6 +568,10 @@
         return _final_pressure;
       }
 
+      uint start_pressure() const {
+        return _start_pressure;
+      }
+
       uint current_pressure() const {
         return _current_pressure;
       }
@@ -561,6 +588,15 @@
         _high_pressure_index = 0;
       }
 
+      void set_start_pressure(int value) {
+        _start_pressure = value;
+        _final_pressure = value;
+      }
+
+      void set_current_pressure(int value) {
+        _current_pressure = value;
+      }
+
       void check_pressure_at_fatproj(uint fatproj_location, RegMask& fatproj_mask) {
         // this pressure is only valid at this instruction, i.e. we don't need to lower
         // the register pressure since the fat proj was never live before (going backwards)
@@ -577,14 +613,13 @@
       }
 
       Pressure(uint high_pressure_index, uint high_pressure_limit)
-      : _current_pressure(0)
-      , _high_pressure_index(high_pressure_index)
-      , _high_pressure_limit(high_pressure_limit)
-      , _final_pressure(0) {}
+        : _current_pressure(0)
+        , _high_pressure_index(high_pressure_index)
+        , _final_pressure(0)
+        , _high_pressure_limit(high_pressure_limit)
+        , _start_pressure(0) {}
   };
 
-  void lower_pressure(Block* b, uint location, LRG& lrg, IndexSet* liveout, Pressure& int_pressure, Pressure& float_pressure);
-  void raise_pressure(Block* b, LRG& lrg, Pressure& int_pressure, Pressure& float_pressure);
   void check_for_high_pressure_transition_at_fatproj(uint& block_reg_pressure, uint location, LRG& lrg, Pressure& pressure, const int op_regtype);
   void add_input_to_liveout(Block* b, Node* n, IndexSet* liveout, double cost, Pressure& int_pressure, Pressure& float_pressure);
   void compute_initial_block_pressure(Block* b, IndexSet* liveout, Pressure& int_pressure, Pressure& float_pressure, double cost);
@@ -600,10 +635,25 @@
   // acceptable register sets do not overlap, then they do not interfere.
   uint build_ifg_physical( ResourceArea *a );
 
+public:
   // Gather LiveRanGe information, including register masks and base pointer/
   // derived pointer relationships.
   void gather_lrg_masks( bool mod_cisc_masks );
 
+  // user visible pressure variables for scheduling
+  Pressure _sched_int_pressure;
+  Pressure _sched_float_pressure;
+  Pressure _scratch_int_pressure;
+  Pressure _scratch_float_pressure;
+
+  // Pressure functions for user context
+  void lower_pressure(Block* b, uint location, LRG& lrg, IndexSet* liveout, Pressure& int_pressure, Pressure& float_pressure);
+  void raise_pressure(Block* b, LRG& lrg, Pressure& int_pressure, Pressure& float_pressure);
+  void compute_entry_block_pressure(Block* b);
+  void compute_exit_block_pressure(Block* b);
+  void print_pressure_info(Pressure& pressure, const char *str);
+
+private:
   // Force the bases of derived pointers to be alive at GC points.
   bool stretch_base_pointer_live_ranges( ResourceArea *a );
   // Helper to stretch above; recursively discover the base Node for
--- a/hotspot/src/share/vm/opto/classes.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/classes.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -131,7 +131,6 @@
 macro(EncodeISOArray)
 macro(EncodeP)
 macro(EncodePKlass)
-macro(ExpD)
 macro(FastLock)
 macro(FastUnlock)
 macro(Goto)
@@ -290,6 +289,10 @@
 macro(MulReductionVD)
 macro(DivVF)
 macro(DivVD)
+macro(AbsVF)
+macro(AbsVD)
+macro(NegVF)
+macro(NegVD)
 macro(SqrtVD)
 macro(LShiftCntV)
 macro(RShiftCntV)
--- a/hotspot/src/share/vm/opto/compile.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -317,7 +317,7 @@
 // Use breadth-first pass that records state in a Unique_Node_List,
 // recursive traversal is slower.
 void Compile::identify_useful_nodes(Unique_Node_List &useful) {
-  int estimated_worklist_size = unique();
+  int estimated_worklist_size = live_nodes();
   useful.map( estimated_worklist_size, NULL );  // preallocate space
 
   // Initialize worklist
@@ -596,7 +596,7 @@
   n->emit(buf, this->regalloc());
 
   // Emitting into the scratch buffer should not fail
-  assert (!failing(), err_msg_res("Must not have pending failure. Reason is: %s", failure_reason()));
+  assert (!failing(), "Must not have pending failure. Reason is: %s", failure_reason());
 
   if (is_branch) // Restore label.
     n->as_MachBranch()->label_set(saveL, save_bnum);
@@ -1189,7 +1189,7 @@
  * the ideal graph.
  */
 StartNode* Compile::start() const {
-  assert (!failing(), err_msg_res("Must not have pending failure. Reason is: %s", failure_reason()));
+  assert (!failing(), "Must not have pending failure. Reason is: %s", failure_reason());
   for (DUIterator_Fast imax, i = root()->fast_outs(imax); i < imax; i++) {
     Node* start = root()->fast_out(i);
     if (start->is_Start()) {
@@ -2254,6 +2254,8 @@
       if (failing())  return;
     }
   }
+  // Ensure that major progress is now clear
+  C->clear_major_progress();
 
   {
     // Verify that all previous optimizations produced a valid graph
@@ -2336,7 +2338,7 @@
     debug_only( cfg.verify(); )
   }
 
-  PhaseChaitin regalloc(unique(), cfg, matcher);
+  PhaseChaitin regalloc(unique(), cfg, matcher, false);
   _regalloc = &regalloc;
   {
     TracePhase tp("regalloc", &timers[_t_registerAllocation]);
@@ -3314,7 +3316,7 @@
   Final_Reshape_Counts frc;
 
   // Visit everybody reachable!
-  // Allocate stack of size C->unique()/2 to avoid frequent realloc
+  // Allocate stack of size C->live_nodes()/2 to avoid frequent realloc
   Node_Stack nstack(live_nodes() >> 1);
   final_graph_reshaping_walk(nstack, root(), frc);
 
@@ -3796,7 +3798,7 @@
     }
     assert(constant_addr, "consts section too small");
     assert((constant_addr - _masm.code()->consts()->start()) == con.offset(),
-            err_msg_res("must be: %d == %d", (int) (constant_addr - _masm.code()->consts()->start()), (int)(con.offset())));
+            "must be: %d == %d", (int) (constant_addr - _masm.code()->consts()->start()), (int)(con.offset()));
   }
 }
 
@@ -3842,7 +3844,7 @@
   case T_OBJECT:
   case T_ADDRESS: value.l = (jobject) oper->constant(); break;
   case T_METADATA: return add((Metadata*)oper->constant()); break;
-  default: guarantee(false, err_msg_res("unhandled type: %s", type2name(type)));
+  default: guarantee(false, "unhandled type: %s", type2name(type));
   }
   return add(n, type, value);
 }
@@ -3864,7 +3866,7 @@
   if (Compile::current()->in_scratch_emit_size())  return;
 
   assert(labels.is_nonempty(), "must be");
-  assert((uint) labels.length() == n->outcnt(), err_msg_res("must be equal: %d == %d", labels.length(), n->outcnt()));
+  assert((uint) labels.length() == n->outcnt(), "must be equal: %d == %d", labels.length(), n->outcnt());
 
   // Since MachConstantNode::constant_offset() also contains
   // table_base_offset() we need to subtract the table_base_offset()
@@ -3876,7 +3878,7 @@
 
   for (uint i = 0; i < n->outcnt(); i++) {
     address* constant_addr = &jump_table_base[i];
-    assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, p2i(*constant_addr), p2i(((address) n) + i)));
+    assert(*constant_addr == (((address) n) + i), "all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, p2i(*constant_addr), p2i(((address) n) + i));
     *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
     cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
   }
@@ -4135,7 +4137,7 @@
   if (n1->Opcode() < n2->Opcode())      return -1;
   else if (n1->Opcode() > n2->Opcode()) return 1;
 
-  assert(n1->req() == n2->req(), err_msg_res("can't compare %s nodes: n1->req() = %d, n2->req() = %d", NodeClassNames[n1->Opcode()], n1->req(), n2->req()));
+  assert(n1->req() == n2->req(), "can't compare %s nodes: n1->req() = %d, n2->req() = %d", NodeClassNames[n1->Opcode()], n1->req(), n2->req());
   for (uint i = 1; i < n1->req(); i++) {
     if (n1->in(i) < n2->in(i))      return -1;
     else if (n1->in(i) > n2->in(i)) return 1;
--- a/hotspot/src/share/vm/opto/compile.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/compile.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -843,7 +843,7 @@
                                            }
   uint          live_nodes() const         {
     int  val = _unique - _dead_node_count;
-    assert (val >= 0, err_msg_res("number of tracked dead nodes %d more than created nodes %d", _unique, _dead_node_count));
+    assert (val >= 0, "number of tracked dead nodes %d more than created nodes %d", _unique, _dead_node_count);
             return (uint) val;
                                            }
 #ifdef ASSERT
@@ -1208,12 +1208,6 @@
   // Compute the name of old_SP.  See <arch>.ad for frame layout.
   OptoReg::Name compute_old_SP();
 
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-  static bool is_node_getting_a_safepoint(Node*);
-  void Insert_zap_nodes();
-  Node* call_zap_node(MachSafePointNode* n, int block_no);
-#endif
-
  private:
   // Phase control:
   void Init(int aliaslevel);                     // Prepare for a single compilation
--- a/hotspot/src/share/vm/opto/doCall.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -599,9 +599,9 @@
           pop_node(rt);  // whatever it was, pop it
         } else if (rt == T_INT || is_subword_type(rt)) {
           // Nothing.  These cases are handled in lambda form bytecode.
-          assert(ct == T_INT || is_subword_type(ct), err_msg_res("must match: rt=%s, ct=%s", type2name(rt), type2name(ct)));
+          assert(ct == T_INT || is_subword_type(ct), "must match: rt=%s, ct=%s", type2name(rt), type2name(ct));
         } else if (rt == T_OBJECT || rt == T_ARRAY) {
-          assert(ct == T_OBJECT || ct == T_ARRAY, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct)));
+          assert(ct == T_OBJECT || ct == T_ARRAY, "rt=%s, ct=%s", type2name(rt), type2name(ct));
           if (ctype->is_loaded()) {
             const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass());
             const Type*       sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
@@ -612,7 +612,7 @@
             }
           }
         } else {
-          assert(rt == ct, err_msg_res("unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct)));
+          assert(rt == ct, "unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct));
           // push a zero; it's better than getting an oop/int mismatch
           pop_node(rt);
           Node* retnode = zerocon(ct);
@@ -628,7 +628,7 @@
       // can appear to be "loaded" by different loaders (depending on
       // the accessing class).
       assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype,
-             err_msg_res("mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name()));
+             "mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name());
     }
 
     // If the return type of the method is not loaded, assert that the
--- a/hotspot/src/share/vm/opto/domgraph.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/domgraph.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -506,7 +506,7 @@
 // Perform DFS search.  Setup 'vertex' as DFS to vertex mapping.  Setup
 // 'semi' as vertex to DFS mapping.  Set 'parent' to DFS parent.
 int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) {
-  // Allocate stack of size C->unique()/8 to avoid frequent realloc
+  // Allocate stack of size C->live_nodes()/8 to avoid frequent realloc
   GrowableArray <Node *> dfstack(pil->C->live_nodes() >> 3);
   Node *b = pil->C->root();
   int dfsnum = 1;
--- a/hotspot/src/share/vm/opto/escape.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -982,7 +982,7 @@
                   strcmp(call->as_CallLeaf()->_name, "montgomery_square") == 0)
                  ))) {
             call->dump();
-            fatal(err_msg_res("EA unexpected CallLeaf %s", call->as_CallLeaf()->_name));
+            fatal("EA unexpected CallLeaf %s", call->as_CallLeaf()->_name);
           }
 #endif
           // Always process arraycopy's destination object since
@@ -1201,8 +1201,8 @@
       C->log()->text("%s", timeout ? "time" : "iterations");
       C->log()->end_elem(" limit'");
     }
-    assert(ExitEscapeAnalysisOnTimeout, err_msg_res("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
-           time.seconds(), iterations, nodes_size(), ptnodes_worklist.length()));
+    assert(ExitEscapeAnalysisOnTimeout, "infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
+           time.seconds(), iterations, nodes_size(), ptnodes_worklist.length());
     // Possible infinite build_connection_graph loop,
     // bailout (no changes to ideal graph were made).
     return false;
--- a/hotspot/src/share/vm/opto/gcm.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -34,6 +34,7 @@
 #include "opto/phaseX.hpp"
 #include "opto/rootnode.hpp"
 #include "opto/runtime.hpp"
+#include "opto/chaitin.hpp"
 #include "runtime/deoptimization.hpp"
 
 // Portions of code courtesy of Clifford Click
@@ -1363,6 +1364,44 @@
     }
   }
 
+  bool block_size_threshold_ok = false;
+  intptr_t *recalc_pressure_nodes = NULL;
+  if (OptoRegScheduling) {
+    for (uint i = 0; i < number_of_blocks(); i++) {
+      Block* block = get_block(i);
+      if (block->number_of_nodes() > 10) {
+        block_size_threshold_ok = true;
+        break;
+      }
+    }
+  }
+
+  // Enabling the scheduler for register pressure plus finding blocks of size to schedule for it
+  // is key to enabling this feature.
+  PhaseChaitin regalloc(C->unique(), *this, _matcher, true);
+  ResourceArea live_arena;      // Arena for liveness
+  ResourceMark rm_live(&live_arena);
+  PhaseLive live(*this, regalloc._lrg_map.names(), &live_arena, true);
+  PhaseIFG ifg(&live_arena);
+  if (OptoRegScheduling && block_size_threshold_ok) {
+    regalloc.mark_ssa();
+    Compile::TracePhase tp("computeLive", &timers[_t_computeLive]);
+    rm_live.reset_to_mark();           // Reclaim working storage
+    IndexSet::reset_memory(C, &live_arena);
+    uint node_size = regalloc._lrg_map.max_lrg_id();
+    ifg.init(node_size); // Empty IFG
+    regalloc.set_ifg(ifg);
+    regalloc.set_live(live);
+    regalloc.gather_lrg_masks(false);    // Collect LRG masks
+    live.compute(node_size); // Compute liveness
+
+    recalc_pressure_nodes = NEW_RESOURCE_ARRAY(intptr_t, node_size);
+    for (uint i = 0; i < node_size; i++) {
+      recalc_pressure_nodes[i] = 0;
+    }
+  }
+  _regalloc = &regalloc;
+
 #ifndef PRODUCT
   if (trace_opto_pipelining()) {
     tty->print("\n---- Start Local Scheduling ----\n");
@@ -1375,13 +1414,15 @@
   visited.Clear();
   for (uint i = 0; i < number_of_blocks(); i++) {
     Block* block = get_block(i);
-    if (!schedule_local(block, ready_cnt, visited)) {
+    if (!schedule_local(block, ready_cnt, visited, recalc_pressure_nodes)) {
       if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
         C->record_method_not_compilable("local schedule failed");
       }
+      _regalloc = NULL;
       return;
     }
   }
+  _regalloc = NULL;
 
   // If we inserted any instructions between a Call and his CatchNode,
   // clone the instructions on all paths below the Catch.
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1251,7 +1251,7 @@
     }
 
     default:
-      fatal(err_msg_res("unexpected type: %s", type2name(type)));
+      fatal("unexpected type: %s", type2name(type));
   }
   assert(chk != NULL, "sanity check");
   chk = _gvn.transform(chk);
@@ -1950,8 +1950,8 @@
     // the current bytecode.
     int inputs, ignored_depth;
     if (compute_stack_effects(inputs, ignored_depth)) {
-      assert(sp() >= inputs, err_msg_res("must have enough JVMS stack to execute %s: sp=%d, inputs=%d",
-             Bytecodes::name(java_bc()), sp(), inputs));
+      assert(sp() >= inputs, "must have enough JVMS stack to execute %s: sp=%d, inputs=%d",
+             Bytecodes::name(java_bc()), sp(), inputs);
     }
   }
 #endif
@@ -1987,7 +1987,7 @@
   case Deoptimization::Action_make_not_compilable:
     break;
   default:
-    fatal(err_msg_res("unknown action %d: %s", action, Deoptimization::trap_action_name(action)));
+    fatal("unknown action %d: %s", action, Deoptimization::trap_action_name(action));
     break;
 #endif
   }
@@ -2509,7 +2509,7 @@
   switch(bt) {
   case T_INT: cmp = new CmpINode(in1, in2); break;
   case T_ADDRESS: cmp = new CmpPNode(in1, in2); break;
-  default: fatal(err_msg("unexpected comparison type %s", type2name(bt)));
+  default: fatal("unexpected comparison type %s", type2name(bt));
   }
   gvn->transform(cmp);
   Node* bol = gvn->transform(new BoolNode(cmp, test));
--- a/hotspot/src/share/vm/opto/graphKit.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -136,7 +136,7 @@
                                         _bci = jvms->bci();
                                         _method = jvms->has_method() ? jvms->method() : NULL; }
   void set_map(SafePointNode* m)      { _map = m; debug_only(verify_map()); }
-  void set_sp(int sp)                 { assert(sp >= 0, err_msg_res("sp must be non-negative: %d", sp)); _sp = sp; }
+  void set_sp(int sp)                 { assert(sp >= 0, "sp must be non-negative: %d", sp); _sp = sp; }
   void clean_stack(int from_sp); // clear garbage beyond from_sp to top
 
   void inc_sp(int i)                  { set_sp(sp() + i); }
@@ -354,12 +354,12 @@
   }
   Node* zero_check_int(Node* value) {
     assert(value->bottom_type()->basic_type() == T_INT,
-        err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type())));
+           "wrong type: %s", type2name(value->bottom_type()->basic_type()));
     return null_check_common(value, T_INT);
   }
   Node* zero_check_long(Node* value) {
     assert(value->bottom_type()->basic_type() == T_LONG,
-        err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type())));
+           "wrong type: %s", type2name(value->bottom_type()->basic_type()));
     return null_check_common(value, T_LONG);
   }
   // Throw an uncommon trap if a given value is __not__ null.
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -157,8 +157,8 @@
     } else {
       // It would be nice if we could shut down cleanly but it should
       // be an error if we can't connect to the visualizer.
-      fatal(err_msg_res("Couldn't connect to visualizer at %s:" INTX_FORMAT,
-                        PrintIdealGraphAddress, PrintIdealGraphPort));
+      fatal("Couldn't connect to visualizer at %s:" INTX_FORMAT,
+            PrintIdealGraphAddress, PrintIdealGraphPort);
     }
   }
 
--- a/hotspot/src/share/vm/opto/ifg.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/ifg.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -439,8 +439,10 @@
       }
     }
   }
-  assert(int_pressure.current_pressure() == count_int_pressure(liveout), "the int pressure is incorrect");
-  assert(float_pressure.current_pressure() == count_float_pressure(liveout), "the float pressure is incorrect");
+  if (_scheduling_info_generated == false) {
+    assert(int_pressure.current_pressure() == count_int_pressure(liveout), "the int pressure is incorrect");
+    assert(float_pressure.current_pressure() == count_float_pressure(liveout), "the float pressure is incorrect");
+  }
 }
 
 /* Go to the first non-phi index in a block */
@@ -518,6 +520,58 @@
 }
 
 /*
+* Computes the entry register pressure of a block, looking at all live
+* ranges in the livein. The register pressure is computed for both float
+* and int/pointer registers.
+*/
+void PhaseChaitin::compute_entry_block_pressure(Block* b) {
+  IndexSet* livein = _live->livein(b);
+  IndexSetIterator elements(livein);
+  uint lid = elements.next();
+  while (lid != 0) {
+    LRG& lrg = lrgs(lid);
+    raise_pressure(b, lrg, _sched_int_pressure, _sched_float_pressure);
+    lid = elements.next();
+  }
+  // Now check phis for locally defined inputs
+  for (uint j = 0; j < b->number_of_nodes(); j++) {
+    Node* n = b->get_node(j);
+    if (n->is_Phi()) {
+      for (uint k = 1; k < n->req(); k++) {
+        Node* phi_in = n->in(k);
+        // Because we are talking about phis, raise register pressure once for each
+        // instance of a phi to account for a single value
+        if (_cfg.get_block_for_node(phi_in) == b) {
+          LRG& lrg = lrgs(phi_in->_idx);
+          raise_pressure(b, lrg, _sched_int_pressure, _sched_float_pressure);
+          break;
+        }
+      }
+    }
+  }
+  _sched_int_pressure.set_start_pressure(_sched_int_pressure.current_pressure());
+  _sched_float_pressure.set_start_pressure(_sched_float_pressure.current_pressure());
+}
+
+/*
+* Computes the exit register pressure of a block, looking at all live
+* ranges in the liveout. The register pressure is computed for both float
+* and int/pointer registers.
+*/
+void PhaseChaitin::compute_exit_block_pressure(Block* b) {
+  IndexSet* livein = _live->live(b);
+  IndexSetIterator elements(livein);
+  _sched_int_pressure.set_current_pressure(0);
+  _sched_float_pressure.set_current_pressure(0);
+  uint lid = elements.next();
+  while (lid != 0) {
+    LRG& lrg = lrgs(lid);
+    raise_pressure(b, lrg, _sched_int_pressure, _sched_float_pressure);
+    lid = elements.next();
+  }
+}
+
+/*
  * Remove dead node if it's not used.
  * We only remove projection nodes if the node "defining" the projection is
  * dead, for example on x86, if we have a dead Add node we remove its
@@ -737,6 +791,16 @@
   block_hrp_index = i;
 }
 
+void PhaseChaitin::print_pressure_info(Pressure& pressure, const char *str) {
+  if (str != NULL) {
+    tty->print_cr("#  *** %s ***", str);
+  }
+  tty->print_cr("#     start pressure is = %d", pressure.start_pressure());
+  tty->print_cr("#     max pressure is = %d", pressure.final_pressure());
+  tty->print_cr("#     end pressure is = %d", pressure.current_pressure());
+  tty->print_cr("#");
+}
+
 /* Build an interference graph:
  *   That is, if 2 live ranges are simultaneously alive but in their acceptable
  *   register sets do not overlap, then they do not interfere. The IFG is built
--- a/hotspot/src/share/vm/opto/lcm.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,6 +31,7 @@
 #include "opto/cfgnode.hpp"
 #include "opto/machnode.hpp"
 #include "opto/runtime.hpp"
+#include "opto/chaitin.hpp"
 #include "runtime/sharedRuntime.hpp"
 
 // Optimization - Graph Style
@@ -443,7 +444,13 @@
 // remaining cases (most), choose the instruction with the greatest latency
 // (that is, the most number of pseudo-cycles required to the end of the
 // routine). If there is a tie, choose the instruction with the most inputs.
-Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot) {
+Node* PhaseCFG::select(
+  Block* block,
+  Node_List &worklist,
+  GrowableArray<int> &ready_cnt,
+  VectorSet &next_call,
+  uint sched_slot,
+  intptr_t* recalc_pressure_nodes) {
 
   // If only a single entry on the stack, use it
   uint cnt = worklist.size();
@@ -458,6 +465,7 @@
   uint score   = 0; // Bigger is better
   int idx = -1;     // Index in worklist
   int cand_cnt = 0; // Candidate count
+  bool block_size_threshold_ok = (block->number_of_nodes() > 10) ? true : false;
 
   for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
     // Order in worklist is used to break ties.
@@ -537,7 +545,47 @@
     }
 
     uint n_latency = get_latency_for_node(n);
-    uint n_score   = n->req();   // Many inputs get high score to break ties
+    uint n_score = n->req();   // Many inputs get high score to break ties
+
+    if (OptoRegScheduling && block_size_threshold_ok) {
+      if (recalc_pressure_nodes[n->_idx] == 0x7fff7fff) {
+        _regalloc->_scratch_int_pressure.init(_regalloc->_sched_int_pressure.high_pressure_limit());
+        _regalloc->_scratch_float_pressure.init(_regalloc->_sched_float_pressure.high_pressure_limit());
+        // simulate the notion that we just picked this node to schedule
+        n->add_flag(Node::Flag_is_scheduled);
+        // now caculate its effect upon the graph if we did
+        adjust_register_pressure(n, block, recalc_pressure_nodes, false);
+        // return its state for finalize in case somebody else wins
+        n->remove_flag(Node::Flag_is_scheduled);
+        // now save the two final pressure components of register pressure, limiting pressure calcs to short size
+        short int_pressure = (short)_regalloc->_scratch_int_pressure.current_pressure();
+        short float_pressure = (short)_regalloc->_scratch_float_pressure.current_pressure();
+        recalc_pressure_nodes[n->_idx] = int_pressure;
+        recalc_pressure_nodes[n->_idx] |= (float_pressure << 16);
+      }
+
+      if (_scheduling_for_pressure) {
+        latency = n_latency;
+        if (n_choice != 3) {
+          // Now evaluate each register pressure component based on threshold in the score.
+          // In general the defining register type will dominate the score, ergo we will not see register pressure grow on both banks
+          // on a single instruction, but we might see it shrink on both banks.
+          // For each use of register that has a register class that is over the high pressure limit, we build n_score up for
+          // live ranges that terminate on this instruction.
+          if (_regalloc->_sched_int_pressure.current_pressure() > _regalloc->_sched_int_pressure.high_pressure_limit()) {
+            short int_pressure = (short)recalc_pressure_nodes[n->_idx];
+            n_score = (int_pressure < 0) ? ((score + n_score) - int_pressure) : (int_pressure > 0) ? 1 : n_score;
+          }
+          if (_regalloc->_sched_float_pressure.current_pressure() > _regalloc->_sched_float_pressure.high_pressure_limit()) {
+            short float_pressure = (short)(recalc_pressure_nodes[n->_idx] >> 16);
+            n_score = (float_pressure < 0) ? ((score + n_score) - float_pressure) : (float_pressure > 0) ? 1 : n_score;
+          }
+        } else {
+          // make sure we choose these candidates
+          score = 0;
+        }
+      }
+    }
 
     // Keep best latency found
     cand_cnt++;
@@ -562,6 +610,100 @@
   return n;
 }
 
+//-------------------------adjust_register_pressure----------------------------
+void PhaseCFG::adjust_register_pressure(Node* n, Block* block, intptr_t* recalc_pressure_nodes, bool finalize_mode) {
+  PhaseLive* liveinfo = _regalloc->get_live();
+  IndexSet* liveout = liveinfo->live(block);
+  // first adjust the register pressure for the sources
+  for (uint i = 1; i < n->req(); i++) {
+    bool lrg_ends = false;
+    Node *src_n = n->in(i);
+    if (src_n == NULL) continue;
+    if (!src_n->is_Mach()) continue;
+    uint src = _regalloc->_lrg_map.find(src_n);
+    if (src == 0) continue;
+    LRG& lrg_src = _regalloc->lrgs(src);
+    // detect if the live range ends or not
+    if (liveout->member(src) == false) {
+      lrg_ends = true;
+      for (DUIterator_Fast jmax, j = src_n->fast_outs(jmax); j < jmax; j++) {
+        Node* m = src_n->fast_out(j); // Get user
+        if (m == n) continue;
+        if (!m->is_Mach()) continue;
+        MachNode *mach = m->as_Mach();
+        bool src_matches = false;
+        int iop = mach->ideal_Opcode();
+
+        switch (iop) {
+        case Op_StoreB:
+        case Op_StoreC:
+        case Op_StoreCM:
+        case Op_StoreD:
+        case Op_StoreF:
+        case Op_StoreI:
+        case Op_StoreL:
+        case Op_StoreP:
+        case Op_StoreN:
+        case Op_StoreVector:
+        case Op_StoreNKlass:
+          for (uint k = 1; k < m->req(); k++) {
+            Node *in = m->in(k);
+            if (in == src_n) {
+              src_matches = true;
+              break;
+            }
+          }
+          break;
+
+        default:
+          src_matches = true;
+          break;
+        }
+
+        // If we have a store as our use, ignore the non source operands
+        if (src_matches == false) continue;
+
+        // Mark every unscheduled use which is not n with a recalculation
+        if ((get_block_for_node(m) == block) && (!m->is_scheduled())) {
+          if (finalize_mode && !m->is_Phi()) {
+            recalc_pressure_nodes[m->_idx] = 0x7fff7fff;
+          }
+          lrg_ends = false;
+        }
+      }
+    }
+    // if none, this live range ends and we can adjust register pressure
+    if (lrg_ends) {
+      if (finalize_mode) {
+        _regalloc->lower_pressure(block, 0, lrg_src, NULL, _regalloc->_sched_int_pressure, _regalloc->_sched_float_pressure);
+      } else {
+        _regalloc->lower_pressure(block, 0, lrg_src, NULL, _regalloc->_scratch_int_pressure, _regalloc->_scratch_float_pressure);
+      }
+    }
+  }
+
+  // now add the register pressure from the dest and evaluate which heuristic we should use:
+  // 1.) The default, latency scheduling
+  // 2.) Register pressure scheduling based on the high pressure limit threshold for int or float register stacks
+  uint dst = _regalloc->_lrg_map.find(n);
+  if (dst != 0) {
+    LRG& lrg_dst = _regalloc->lrgs(dst);
+    if (finalize_mode) {
+      _regalloc->raise_pressure(block, lrg_dst, _regalloc->_sched_int_pressure, _regalloc->_sched_float_pressure);
+      // check to see if we fall over the register pressure cliff here
+      if (_regalloc->_sched_int_pressure.current_pressure() > _regalloc->_sched_int_pressure.high_pressure_limit()) {
+        _scheduling_for_pressure = true;
+      } else if (_regalloc->_sched_float_pressure.current_pressure() > _regalloc->_sched_float_pressure.high_pressure_limit()) {
+        _scheduling_for_pressure = true;
+      } else {
+        // restore latency scheduling mode
+        _scheduling_for_pressure = false;
+      }
+    } else {
+      _regalloc->raise_pressure(block, lrg_dst, _regalloc->_scratch_int_pressure, _regalloc->_scratch_float_pressure);
+    }
+  }
+}
 
 //------------------------------set_next_call----------------------------------
 void PhaseCFG::set_next_call(Block* block, Node* n, VectorSet& next_call) {
@@ -644,7 +786,7 @@
         continue;
       }
       if( m->is_Phi() ) continue;
-      int m_cnt = ready_cnt.at(m->_idx)-1;
+      int m_cnt = ready_cnt.at(m->_idx) - 1;
       ready_cnt.at_put(m->_idx, m_cnt);
       if( m_cnt == 0 )
         worklist.push(m);
@@ -711,7 +853,7 @@
 
 //------------------------------schedule_local---------------------------------
 // Topological sort within a block.  Someday become a real scheduler.
-bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call) {
+bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call, intptr_t *recalc_pressure_nodes) {
   // Already "sorted" are the block start Node (as the first entry), and
   // the block-ending Node and any trailing control projections.  We leave
   // these alone.  PhiNodes and ParmNodes are made to follow the block start
@@ -733,10 +875,24 @@
     return true;
   }
 
+  bool block_size_threshold_ok = (block->number_of_nodes() > 10) ? true : false;
+
+  // We track the uses of local definitions as input dependences so that
+  // we know when a given instruction is avialable to be scheduled.
+  uint i;
+  if (OptoRegScheduling && block_size_threshold_ok) {
+    for (i = 1; i < block->number_of_nodes(); i++) { // setup nodes for pressure calc
+      Node *n = block->get_node(i);
+      n->remove_flag(Node::Flag_is_scheduled);
+      if (!n->is_Phi()) {
+        recalc_pressure_nodes[n->_idx] = 0x7fff7fff;
+      }
+    }
+  }
+
   // Move PhiNodes and ParmNodes from 1 to cnt up to the start
   uint node_cnt = block->end_idx();
   uint phi_cnt = 1;
-  uint i;
   for( i = 1; i<node_cnt; i++ ) { // Scan for Phi
     Node *n = block->get_node(i);
     if( n->is_Phi() ||          // Found a PhiNode or ParmNode
@@ -744,6 +900,10 @@
       // Move guy at 'phi_cnt' to the end; makes a hole at phi_cnt
       block->map_node(block->get_node(phi_cnt), i);
       block->map_node(n, phi_cnt++);  // swap Phi/Parm up front
+      if (OptoRegScheduling && block_size_threshold_ok) {
+        // mark n as scheduled
+        n->add_flag(Node::Flag_is_scheduled);
+      }
     } else {                    // All others
       // Count block-local inputs to 'n'
       uint cnt = n->len();      // Input count
@@ -791,12 +951,18 @@
 
   // All the prescheduled guys do not hold back internal nodes
   uint i3;
-  for(i3 = 0; i3<phi_cnt; i3++ ) {  // For all pre-scheduled
+  for (i3 = 0; i3 < phi_cnt; i3++) {  // For all pre-scheduled
     Node *n = block->get_node(i3);       // Get pre-scheduled
     for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
       Node* m = n->fast_out(j);
       if (get_block_for_node(m) == block) { // Local-block user
         int m_cnt = ready_cnt.at(m->_idx)-1;
+        if (OptoRegScheduling && block_size_threshold_ok) {
+          // mark m as scheduled
+          if (m_cnt < 0) {
+            m->add_flag(Node::Flag_is_scheduled);
+          }
+        }
         ready_cnt.at_put(m->_idx, m_cnt);   // Fix ready count
       }
     }
@@ -827,6 +993,18 @@
     worklist.push(d);
   }
 
+  if (OptoRegScheduling && block_size_threshold_ok) {
+    // To stage register pressure calculations we need to examine the live set variables
+    // breaking them up by register class to compartmentalize the calculations.
+    uint float_pressure = Matcher::float_pressure(FLOATPRESSURE);
+    _regalloc->_sched_int_pressure.init(INTPRESSURE);
+    _regalloc->_sched_float_pressure.init(float_pressure);
+    _regalloc->_scratch_int_pressure.init(INTPRESSURE);
+    _regalloc->_scratch_float_pressure.init(float_pressure);
+
+    _regalloc->compute_entry_block_pressure(block);
+  }
+
   // Warm up the 'next_call' heuristic bits
   needed_for_next_call(block, block->head(), next_call);
 
@@ -858,9 +1036,18 @@
 #endif
 
     // Select and pop a ready guy from worklist
-    Node* n = select(block, worklist, ready_cnt, next_call, phi_cnt);
+    Node* n = select(block, worklist, ready_cnt, next_call, phi_cnt, recalc_pressure_nodes);
     block->map_node(n, phi_cnt++);    // Schedule him next
 
+    if (OptoRegScheduling && block_size_threshold_ok) {
+      n->add_flag(Node::Flag_is_scheduled);
+
+      // Now adjust the resister pressure with the node we selected
+      if (!n->is_Phi()) {
+        adjust_register_pressure(n, block, recalc_pressure_nodes, true);
+      }
+    }
+
 #ifndef PRODUCT
     if (trace_opto_pipelining()) {
       tty->print("#    select %d: %s", n->_idx, n->Name());
@@ -906,7 +1093,7 @@
         assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types");
         continue;
       }
-      int m_cnt = ready_cnt.at(m->_idx)-1;
+      int m_cnt = ready_cnt.at(m->_idx) - 1;
       ready_cnt.at_put(m->_idx, m_cnt);
       if( m_cnt == 0 )
         worklist.push(m);
@@ -925,6 +1112,12 @@
     return false;
   }
 
+  if (OptoRegScheduling && block_size_threshold_ok) {
+    _regalloc->compute_exit_block_pressure(block);
+    block->_reg_pressure = _regalloc->_sched_int_pressure.final_pressure();
+    block->_freg_pressure = _regalloc->_sched_float_pressure.final_pressure();
+  }
+
 #ifndef PRODUCT
   if (trace_opto_pipelining()) {
     tty->print_cr("#");
@@ -933,11 +1126,17 @@
       tty->print("# ");
       block->get_node(i)->fast_dump();
     }
+    tty->print_cr("# ");
+
+    if (OptoRegScheduling && block_size_threshold_ok) {
+      tty->print_cr("# pressure info : %d", block->_pre_order);
+      _regalloc->print_pressure_info(_regalloc->_sched_int_pressure, "int register info");
+      _regalloc->print_pressure_info(_regalloc->_sched_float_pressure, "float register info");
+    }
     tty->cr();
   }
 #endif
 
-
   return true;
 }
 
--- a/hotspot/src/share/vm/opto/library_call.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -133,7 +133,7 @@
 
  private:
   void fatal_unexpected_iid(vmIntrinsics::ID iid) {
-    fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+    fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
   }
 
   void  set_result(Node* n) { assert(_result == NULL, "only set once"); _result = n; }
@@ -222,7 +222,6 @@
   bool inline_math_negateExactL();
   bool inline_math_subtractExactI(bool is_decrement);
   bool inline_math_subtractExactL(bool is_decrement);
-  bool inline_exp();
   bool inline_pow();
   Node* finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
   bool inline_min_max(vmIntrinsics::ID id);
@@ -1535,20 +1534,6 @@
   }
 }
 
-//------------------------------inline_exp-------------------------------------
-// Inline exp instructions, if possible.  The Intel hardware only misses
-// really odd corner cases (+/- Infinity).  Just uncommon-trap them.
-bool LibraryCallKit::inline_exp() {
-  Node* arg = round_double_node(argument(0));
-  Node* n   = _gvn.transform(new ExpDNode(C, control(), arg));
-
-  n = finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
-  set_result(n);
-
-  C->set_has_split_ifs(true); // Has chance for split-if optimization
-  return true;
-}
-
 //------------------------------inline_pow-------------------------------------
 // Inline power instructions, if possible.
 bool LibraryCallKit::inline_pow() {
@@ -1776,8 +1761,10 @@
   case vmIntrinsics::_dsqrt:  return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
   case vmIntrinsics::_dabs:   return Matcher::has_match_rule(Op_AbsD)   ? inline_math(id) : false;
 
-  case vmIntrinsics::_dexp:   return Matcher::has_match_rule(Op_ExpD)   ? inline_exp()    :
-    runtime_math(OptoRuntime::Math_D_D_Type(),  FN_PTR(SharedRuntime::dexp),  "EXP");
+  case vmIntrinsics::_dexp:
+    return StubRoutines::dexp() != NULL ?
+      runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(),  "dexp") :
+      runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp),  "EXP");
   case vmIntrinsics::_dpow:   return Matcher::has_match_rule(Op_PowD)   ? inline_pow()    :
     runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow),  "POW");
 #undef FN_PTR
@@ -2466,7 +2453,7 @@
         p = ConvX2UL(p);
         break;
       default:
-        fatal(err_msg_res("unexpected type %d: %s", type, type2name(type)));
+        fatal("unexpected type %d: %s", type, type2name(type));
         break;
       }
     }
@@ -2755,7 +2742,7 @@
     }
     break;
   default:
-    fatal(err_msg_res("unexpected type %d: %s", type, type2name(type)));
+    fatal("unexpected type %d: %s", type, type2name(type));
     break;
   }
 
@@ -3807,7 +3794,7 @@
   ciMethod* method = callee();
   int vtable_index = method->vtable_index();
   assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
-         err_msg_res("bad index %d", vtable_index));
+         "bad index %d", vtable_index);
   // Get the Method* out of the appropriate vtable entry.
   int entry_offset  = (InstanceKlass::vtable_start_offset() +
                      vtable_index*vtableEntry::size()) * wordSize +
@@ -3859,7 +3846,7 @@
       // No need to use the linkResolver to get it.
        vtable_index = method->vtable_index();
        assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
-              err_msg_res("bad index %d", vtable_index));
+              "bad index %d", vtable_index);
     }
     slow_call = new CallDynamicJavaNode(tf,
                           SharedRuntime::get_resolve_virtual_call_stub(),
@@ -6131,7 +6118,7 @@
     }
     break;
   default:
-    fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
+    fatal("unknown SHA intrinsic predicate: %d", predicate);
   }
   if (klass_SHA_name != NULL) {
     // get DigestBase klass to lookup for SHA klass
@@ -6236,7 +6223,7 @@
     }
     break;
   default:
-    fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
+    fatal("unknown SHA intrinsic predicate: %d", predicate);
   }
 
   ciKlass* klass_SHA = NULL;
--- a/hotspot/src/share/vm/opto/live.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/live.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,7 +41,14 @@
 // block is put on the worklist.
 //   The locally live-in stuff is computed once and added to predecessor
 // live-out sets.  This separate compilation is done in the outer loop below.
-PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
+PhaseLive::PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena, bool keep_deltas)
+  : Phase(LIVE),
+  _cfg(cfg),
+  _names(names),
+  _arena(arena),
+  _live(0),
+  _livein(0),
+  _keep_deltas(keep_deltas) {
 }
 
 void PhaseLive::compute(uint maxlrg) {
@@ -56,6 +63,13 @@
     _live[i].initialize(_maxlrg);
   }
 
+  if (_keep_deltas) {
+    _livein = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks());
+    for (i = 0; i < _cfg.number_of_blocks(); i++) {
+      _livein[i].initialize(_maxlrg);
+    }
+  }
+
   // Init the sparse arrays for delta-sets.
   ResourceMark rm;              // Nuke temp storage on exit
 
@@ -124,7 +138,10 @@
 
       // PhiNode uses go in the live-out set of prior blocks.
       for (uint k = i; k > 0; k--) {
-        add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass);
+        Node *phi = block->get_node(k - 1);
+        if (l < phi->req()) {
+          add_liveout(p, _names.at(phi->in(l)->_idx), first_pass);
+        }
       }
     }
     freeset(block);
@@ -200,8 +217,11 @@
 }
 
 // Free an IndexSet from a block.
-void PhaseLive::freeset( const Block *p ) {
+void PhaseLive::freeset( Block *p ) {
   IndexSet *f = _deltas[p->_pre_order-1];
+  if ( _keep_deltas ) {
+    add_livein(p, f);
+  }
   f->set_next(_free_IndexSet);
   _free_IndexSet = f;           // Drop onto free list
   _deltas[p->_pre_order-1] = NULL;
@@ -249,10 +269,23 @@
   }
 }
 
+// Add a vector of live-in values to a given blocks live-in set.
+void PhaseLive::add_livein(Block *p, IndexSet *lo) {
+  IndexSet *livein = &_livein[p->_pre_order-1];
+  IndexSetIterator elements(lo);
+  uint r;
+  while ((r = elements.next()) != 0) {
+    livein->insert(r);         // Then add to live-in set
+  }
+}
+
 #ifndef PRODUCT
 // Dump the live-out set for a block
 void PhaseLive::dump( const Block *b ) const {
   tty->print("Block %d: ",b->_pre_order);
+  if ( _keep_deltas ) {
+    tty->print("LiveIn: ");  _livein[b->_pre_order-1].dump();
+  }
   tty->print("LiveOut: ");  _live[b->_pre_order-1].dump();
   uint cnt = b->number_of_nodes();
   for( uint i=0; i<cnt; i++ ) {
--- a/hotspot/src/share/vm/opto/live.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/live.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -46,7 +46,8 @@
 class PhaseLive : public Phase {
   // Array of Sets of values live at the start of a block.
   // Indexed by block pre-order number.
-  IndexSet *_live;
+  IndexSet *_live; // live out
+  IndexSet *_livein; // live in
 
   // Array of Sets of values defined locally in the block
   // Indexed by block pre-order number.
@@ -62,15 +63,17 @@
   const LRG_List &_names;       // Mapping from Nodes to live ranges
   uint _maxlrg;                 // Largest live-range number
   Arena *_arena;
+  bool _keep_deltas;            // Retain live in information
 
   IndexSet *getset( Block *p );
   IndexSet *getfreeset( );
-  void freeset( const Block *p );
+  void freeset( Block *p );
   void add_liveout( Block *p, uint r, VectorSet &first_pass );
   void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass );
+  void add_livein( Block *p, IndexSet *lo );
 
 public:
-  PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena);
+  PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena, bool keep_deltas);
   ~PhaseLive() {}
   // Compute liveness info
   void compute(uint maxlrg);
@@ -79,6 +82,7 @@
 
   // Return the live-out set for this block
   IndexSet *live( const Block * b ) { return &_live[b->_pre_order-1]; }
+  IndexSet *livein( const Block * b ) { return &_livein[b->_pre_order - 1]; }
 
 #ifndef PRODUCT
   void dump( const Block *b ) const;
--- a/hotspot/src/share/vm/opto/loopUnswitch.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopUnswitch.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -263,3 +263,136 @@
 
   return iffast;
 }
+
+LoopNode* PhaseIdealLoop::create_reserve_version_of_loop(IdealLoopTree *loop, CountedLoopReserveKit* lk) {
+  Node_List old_new;
+  LoopNode* head  = loop->_head->as_Loop();
+  bool counted_loop = head->is_CountedLoop();
+  Node*     entry = head->in(LoopNode::EntryControl);
+  _igvn.rehash_node_delayed(entry);
+  IdealLoopTree* outer_loop = loop->_parent;
+
+  ConINode* const_1 = _igvn.intcon(1);
+  set_ctrl(const_1, C->root());
+  IfNode* iff = new IfNode(entry, const_1, PROB_MAX, COUNT_UNKNOWN);
+  register_node(iff, outer_loop, entry, dom_depth(entry));
+  ProjNode* iffast = new IfTrueNode(iff);
+  register_node(iffast, outer_loop, iff, dom_depth(iff));
+  ProjNode* ifslow = new IfFalseNode(iff);
+  register_node(ifslow, outer_loop, iff, dom_depth(iff));
+
+  // Clone the loop body.  The clone becomes the fast loop.  The
+  // original pre-header will (illegally) have 3 control users
+  // (old & new loops & new if).
+  clone_loop(loop, old_new, dom_depth(head), iff);
+  assert(old_new[head->_idx]->is_Loop(), "" );
+
+  LoopNode* slow_head = old_new[head->_idx]->as_Loop();
+
+#ifndef PRODUCT
+  if (TraceLoopOpts) {
+    tty->print_cr("PhaseIdealLoop::create_reserve_version_of_loop:");
+    tty->print("\t iff = %d, ", iff->_idx); iff->dump();
+    tty->print("\t iffast = %d, ", iffast->_idx); iffast->dump();
+    tty->print("\t ifslow = %d, ", ifslow->_idx); ifslow->dump();
+    tty->print("\t before replace_input_of: head = %d, ", head->_idx); head->dump();
+    tty->print("\t before replace_input_of: slow_head = %d, ", slow_head->_idx); slow_head->dump();
+  }
+#endif
+
+  // Fast (true) control
+  _igvn.replace_input_of(head, LoopNode::EntryControl, iffast);
+  // Slow (false) control
+  _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow);
+
+  recompute_dom_depth();
+
+  lk->set_iff(iff);
+
+#ifndef PRODUCT
+  if (TraceLoopOpts ) {
+    tty->print("\t after  replace_input_of: head = %d, ", head->_idx); head->dump();
+    tty->print("\t after  replace_input_of: slow_head = %d, ", slow_head->_idx); slow_head->dump();
+  }
+#endif
+
+  return slow_head->as_Loop();
+}
+
+CountedLoopReserveKit::CountedLoopReserveKit(PhaseIdealLoop* phase, IdealLoopTree *loop, bool active = true) :
+  _phase(phase),
+  _lpt(loop),
+  _lp(NULL),
+  _iff(NULL),
+  _lp_reserved(NULL),
+  _has_reserved(false),
+  _use_new(false),
+  _active(active)
+  {
+    create_reserve();
+  };
+
+CountedLoopReserveKit::~CountedLoopReserveKit() {
+  if (!_active) {
+    return;
+  }
+
+  if (_has_reserved && !_use_new) {
+    // intcon(0)->iff-node reverts CF to the reserved copy
+    ConINode* const_0 = _phase->_igvn.intcon(0);
+    _phase->set_ctrl(const_0, _phase->C->root());
+    _iff->set_req(1, const_0);
+
+    #ifndef PRODUCT
+      if (TraceLoopOpts) {
+        tty->print_cr("CountedLoopReserveKit::~CountedLoopReserveKit()");
+        tty->print("\t discard loop %d and revert to the reserved loop clone %d: ", _lp->_idx, _lp_reserved->_idx);
+        _lp_reserved->dump();
+      }
+    #endif
+  }
+}
+
+bool CountedLoopReserveKit::create_reserve() {
+  if (!_active) {
+    return false;
+  }
+
+  if(!_lpt->_head->is_CountedLoop()) {
+    NOT_PRODUCT(if(TraceLoopOpts) {tty->print_cr("CountedLoopReserveKit::create_reserve: %d not counted loop", _lpt->_head->_idx);})
+    return false;
+  }
+  CountedLoopNode *cl = _lpt->_head->as_CountedLoop();
+  if (!cl->is_valid_counted_loop()) {
+    NOT_PRODUCT(if(TraceLoopOpts) {tty->print_cr("CountedLoopReserveKit::create_reserve: %d not valid counted loop", cl->_idx);})
+    return false; // skip malformed counted loop
+  }
+  if (!cl->is_main_loop()) {
+    NOT_PRODUCT(if(TraceLoopOpts) {tty->print_cr("CountedLoopReserveKit::create_reserve: %d not main loop", cl->_idx);})
+    return false; // skip normal, pre, and post loops
+  }
+
+  _lp = _lpt->_head->as_Loop();
+  _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this);
+
+  if (!_lp_reserved->is_CountedLoop()) {
+    return false;
+  }
+
+  Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl);
+
+  if (!ifslow_pred->is_IfFalse()) {
+    return false;
+  }
+
+  Node* iff = ifslow_pred->in(0);
+  if (!iff->is_If() || iff != _iff) {
+    return false;
+  }
+
+  if (iff->in(1)->Opcode() != Op_ConI) {
+    return false;
+  }
+
+  return _has_reserved = true;
+}
--- a/hotspot/src/share/vm/opto/loopnode.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopnode.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,6 +38,7 @@
 class LoopNode;
 class Node;
 class PhaseIdealLoop;
+class CountedLoopReserveKit;
 class VectorSet;
 class Invariance;
 struct small_cache;
@@ -290,6 +291,7 @@
     if (phi() == NULL) {
       return NULL;
     }
+    assert(phi()->is_Phi(), "should be PhiNode");
     Node *ln = phi()->in(0);
     if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) {
       return (CountedLoopNode*)ln;
@@ -528,6 +530,8 @@
 class PhaseIdealLoop : public PhaseTransform {
   friend class IdealLoopTree;
   friend class SuperWord;
+  friend class CountedLoopReserveKit;
+
   // Pre-computed def-use info
   PhaseIterGVN &_igvn;
 
@@ -964,6 +968,16 @@
   ProjNode* create_slow_version_of_loop(IdealLoopTree *loop,
                                         Node_List &old_new);
 
+  // Clone a loop and return the clone head (clone_loop_head).
+  // Added nodes include int(1), int(0) - disconnected, If, IfTrue, IfFalse,
+  // This routine was created for usage in CountedLoopReserveKit.
+  //
+  //    int(1) -> If -> IfTrue -> original_loop_head
+  //              |
+  //              V
+  //           IfFalse -> clone_loop_head (returned by function pointer)
+  //
+  LoopNode* create_reserve_version_of_loop(IdealLoopTree *loop, CountedLoopReserveKit* lk);
   // Clone loop with an invariant test (that does not exit) and
   // insert a clone of the test that selects which version to
   // execute.
@@ -1116,6 +1130,68 @@
 #endif
 };
 
+// This kit may be used for making of a reserved copy of a loop before this loop
+//  goes under non-reversible changes.
+//
+// Function create_reserve() creates a reserved copy (clone) of the loop.
+// The reserved copy is created by calling
+// PhaseIdealLoop::create_reserve_version_of_loop - see there how
+// the original and reserved loops are connected in the outer graph.
+// If create_reserve succeeded, it returns 'true' and _has_reserved is set to 'true'.
+//
+// By default the reserved copy (clone) of the loop is created as dead code - it is
+// dominated in the outer loop by this node chain:
+//   intcon(1)->If->IfFalse->reserved_copy.
+// The original loop is dominated by the the same node chain but IfTrue projection:
+//   intcon(1)->If->IfTrue->original_loop.
+//
+// In this implementation of CountedLoopReserveKit the ctor includes create_reserve()
+// and the dtor, checks _use_new value.
+// If _use_new == false, it "switches" control to reserved copy of the loop
+// by simple replacing of node intcon(1) with node intcon(0).
+//
+// Here is a proposed example of usage (see also SuperWord::output in superword.cpp).
+//
+// void CountedLoopReserveKit_example()
+// {
+//    CountedLoopReserveKit lrk((phase, lpt, DoReserveCopy = true); // create local object
+//    if (DoReserveCopy && !lrk.has_reserved()) {
+//      return; //failed to create reserved loop copy
+//    }
+//    ...
+//    //something is wrong, switch to original loop
+///   if(something_is_wrong) return; // ~CountedLoopReserveKit makes the switch
+//    ...
+//    //everything worked ok, return with the newly modified loop
+//    lrk.use_new();
+//    return; // ~CountedLoopReserveKit does nothing once use_new() was called
+//  }
+//
+// Keep in mind, that by default if create_reserve() is not followed by use_new()
+// the dtor will "switch to the original" loop.
+// NOTE. You you modify outside of the original loop this class is no help.
+//
+class CountedLoopReserveKit {
+  private:
+    PhaseIdealLoop* _phase;
+    IdealLoopTree*  _lpt;
+    LoopNode*       _lp;
+    IfNode*         _iff;
+    LoopNode*       _lp_reserved;
+    bool            _has_reserved;
+    bool            _use_new;
+    const bool      _active; //may be set to false in ctor, then the object is dummy
+
+  public:
+    CountedLoopReserveKit(PhaseIdealLoop* phase, IdealLoopTree *loop, bool active);
+    ~CountedLoopReserveKit();
+    void use_new()                {_use_new = true;}
+    void set_iff(IfNode* x)       {_iff = x;}
+    bool has_reserved()     const { return _active && _has_reserved;}
+  private:
+    bool create_reserve();
+};// class CountedLoopReserveKit
+
 inline Node* IdealLoopTree::tail() {
 // Handle lazy update of _tail field
   Node *n = _tail;
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -447,21 +447,21 @@
     }
 
     // Replace (I1 +p (I2 + V)) with ((I1 +p I2) +p V)
-    if( n2_loop != n_loop && n3_loop == n_loop ) {
-      if( n->in(3)->Opcode() == Op_AddI ) {
+    if (n2_loop != n_loop && n3_loop == n_loop) {
+      if (n->in(3)->Opcode() == Op_AddX) {
         Node *V = n->in(3)->in(1);
         Node *I = n->in(3)->in(2);
-        if( is_member(n_loop,get_ctrl(V)) ) {
+        if (is_member(n_loop,get_ctrl(V))) {
         } else {
           Node *tmp = V; V = I; I = tmp;
         }
-        if( !is_member(n_loop,get_ctrl(I)) ) {
-          Node *add1 = new AddPNode( n->in(1), n->in(2), I );
+        if (!is_member(n_loop,get_ctrl(I))) {
+          Node *add1 = new AddPNode(n->in(1), n->in(2), I);
           // Stuff new AddP in the loop preheader
-          register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) );
-          Node *add2 = new AddPNode( n->in(1), add1, V );
-          register_new_node( add2, n_ctrl );
-          _igvn.replace_node( n, add2 );
+          register_new_node(add1, n_loop->_head->in(LoopNode::EntryControl));
+          Node *add2 = new AddPNode(n->in(1), add1, V);
+          register_new_node(add2, n_ctrl);
+          _igvn.replace_node(n, add2);
           return add2;
         }
       }
@@ -653,7 +653,6 @@
   return iff->in(1);
 }
 
-#ifdef ASSERT
 static void enqueue_cfg_uses(Node* m, Unique_Node_List& wq) {
   for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
     Node* u = m->fast_out(i);
@@ -667,7 +666,6 @@
     }
   }
 }
-#endif
 
 // Try moving a store out of a loop, right before the loop
 Node* PhaseIdealLoop::try_move_store_before_loop(Node* n, Node *n_ctrl) {
@@ -687,11 +685,15 @@
     // written at iteration i by the second store could be overwritten
     // at iteration i+n by the first store: it's not safe to move the
     // first store out of the loop
-    // - nothing must observe the Phi memory: it guarantees no read
-    // before the store and no early exit out of the loop
-    // With those conditions, we are also guaranteed the store post
-    // dominates the loop head. Otherwise there would be extra Phi
-    // involved between the loop's Phi and the store.
+    // - nothing must observe the memory Phi: it guarantees no read
+    // before the store, we are also guaranteed the store post
+    // dominates the loop head (ignoring a possible early
+    // exit). Otherwise there would be extra Phi involved between the
+    // loop's Phi and the store.
+    // - there must be no early exit from the loop before the Store
+    // (such an exit most of the time would be an extra use of the
+    // memory Phi but sometimes is a bottom memory Phi that takes the
+    // store as input).
 
     if (!n_loop->is_member(address_loop) &&
         !n_loop->is_member(value_loop) &&
@@ -699,9 +701,10 @@
         mem->outcnt() == 1 &&
         mem->in(LoopNode::LoopBackControl) == n) {
 
-#ifdef ASSERT
-      // Verify that store's control does post dominate loop entry and
-      // that there's no early exit of the loop before the store.
+      assert(n_loop->_tail != NULL, "need a tail");
+      assert(is_dominator(n_ctrl, n_loop->_tail), "store control must not be in a branch in the loop");
+
+      // Verify that there's no early exit of the loop before the store.
       bool ctrl_ok = false;
       {
         // Follow control from loop head until n, we exit the loop or
@@ -709,7 +712,7 @@
         ResourceMark rm;
         Unique_Node_List wq;
         wq.push(n_loop->_head);
-        assert(n_loop->_tail != NULL, "need a tail");
+
         for (uint next = 0; next < wq.size(); ++next) {
           Node *m = wq.at(next);
           if (m == n->in(0)) {
@@ -722,24 +725,27 @@
             break;
           }
           enqueue_cfg_uses(m, wq);
+          if (wq.size() > 10) {
+            ctrl_ok = false;
+            break;
+          }
         }
       }
-      assert(ctrl_ok, "bad control");
-#endif
+      if (ctrl_ok) {
+        // move the Store
+        _igvn.replace_input_of(mem, LoopNode::LoopBackControl, mem);
+        _igvn.replace_input_of(n, 0, n_loop->_head->in(LoopNode::EntryControl));
+        _igvn.replace_input_of(n, MemNode::Memory, mem->in(LoopNode::EntryControl));
+        // Disconnect the phi now. An empty phi can confuse other
+        // optimizations in this pass of loop opts.
+        _igvn.replace_node(mem, mem->in(LoopNode::EntryControl));
+        n_loop->_body.yank(mem);
 
-      // move the Store
-      _igvn.replace_input_of(mem, LoopNode::LoopBackControl, mem);
-      _igvn.replace_input_of(n, 0, n_loop->_head->in(LoopNode::EntryControl));
-      _igvn.replace_input_of(n, MemNode::Memory, mem->in(LoopNode::EntryControl));
-      // Disconnect the phi now. An empty phi can confuse other
-      // optimizations in this pass of loop opts.
-      _igvn.replace_node(mem, mem->in(LoopNode::EntryControl));
-      n_loop->_body.yank(mem);
+        IdealLoopTree* new_loop = get_loop(n->in(0));
+        set_ctrl_and_loop(n, n->in(0));
 
-      IdealLoopTree* new_loop = get_loop(n->in(0));
-      set_ctrl_and_loop(n, n->in(0));
-
-      return n;
+        return n;
+      }
     }
   }
   return NULL;
@@ -769,13 +775,15 @@
             }
             if (u->is_Phi() && u->in(0) == n_loop->_head) {
               assert(_igvn.type(u) == Type::MEMORY, "bad phi");
-              assert(phi == NULL, "already found");
+              // multiple phis on the same slice are possible
+              if (phi != NULL) {
+                return;
+              }
               phi = u;
               continue;
             }
           }
-          phi = NULL;
-          break;
+          return;
         }
         if (phi != NULL) {
           // Nothing in the loop before the store (next iteration)
--- a/hotspot/src/share/vm/opto/macro.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1512,7 +1512,8 @@
     // MemBarStoreStore so that stores that initialize this object
     // can't be reordered with a subsequent store that makes this
     // object accessible by other threads.
-    if (init == NULL || (!init->is_complete_with_arraycopy() && !init->does_not_escape())) {
+    if (!alloc->does_not_escape_thread() &&
+        (init == NULL || !init->is_complete_with_arraycopy())) {
       if (init == NULL || init->req() < InitializeNode::RawStores) {
         // No InitializeNode or no stores captured by zeroing
         // elimination. Simply add the MemBarStoreStore after object
--- a/hotspot/src/share/vm/opto/matcher.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -326,14 +326,14 @@
   grow_new_node_array(C->unique());
 
   // Reset node counter so MachNodes start with _idx at 0
-  int nodes = C->unique(); // save value
+  int live_nodes = C->live_nodes();
   C->set_unique(0);
   C->reset_dead_node_list();
 
   // Recursively match trees from old space into new space.
   // Correct leaves of new-space Nodes; they point to old-space.
   _visited.Clear();             // Clear visit bits for xform call
-  C->set_cached_top_node(xform( C->top(), nodes ));
+  C->set_cached_top_node(xform( C->top(), live_nodes ));
   if (!C->failing()) {
     Node* xroot =        xform( C->root(), 1 );
     if (xroot == NULL) {
@@ -1001,7 +1001,7 @@
 Node *Matcher::transform( Node *n ) { ShouldNotCallThis(); return n; }
 Node *Matcher::xform( Node *n, int max_stack ) {
   // Use one stack to keep both: child's node/state and parent's node/index
-  MStack mstack(max_stack * 2 * 2); // C->unique() * 2 * 2
+  MStack mstack(max_stack * 2 * 2); // usually: C->live_nodes() * 2 * 2
   mstack.push(n, Visit, NULL, -1);  // set NULL as parent to indicate root
 
   while (mstack.is_nonempty()) {
@@ -2045,11 +2045,38 @@
 // and then expanded into the inline_cache_reg and a method_oop register
 //   defined in ad_<arch>.cpp
 
+// Check for shift by small constant as well
+static bool clone_shift(Node* shift, Matcher* matcher, MStack& mstack, VectorSet& address_visited) {
+  if (shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
+      shift->in(2)->get_int() <= 3 &&
+      // Are there other uses besides address expressions?
+      !matcher->is_visited(shift)) {
+    address_visited.set(shift->_idx); // Flag as address_visited
+    mstack.push(shift->in(2), Visit);
+    Node *conv = shift->in(1);
+#ifdef _LP64
+    // Allow Matcher to match the rule which bypass
+    // ConvI2L operation for an array index on LP64
+    // if the index value is positive.
+    if (conv->Opcode() == Op_ConvI2L &&
+        conv->as_Type()->type()->is_long()->_lo >= 0 &&
+        // Are there other uses besides address expressions?
+        !matcher->is_visited(conv)) {
+      address_visited.set(conv->_idx); // Flag as address_visited
+      mstack.push(conv->in(1), Pre_Visit);
+    } else
+#endif
+      mstack.push(conv, Pre_Visit);
+    return true;
+  }
+  return false;
+}
+
 
 //------------------------------find_shared------------------------------------
 // Set bits if Node is shared or otherwise a root
 void Matcher::find_shared( Node *n ) {
-  // Allocate stack of size C->unique() * 2 to avoid frequent realloc
+  // Allocate stack of size C->live_nodes() * 2 to avoid frequent realloc
   MStack mstack(C->live_nodes() * 2);
   // Mark nodes as address_visited if they are inputs to an address expression
   VectorSet address_visited(Thread::current()->resource_area());
@@ -2205,7 +2232,10 @@
 #endif
 
         // Clone addressing expressions as they are "free" in memory access instructions
-        if( mem_op && i == MemNode::Address && mop == Op_AddP ) {
+        if (mem_op && i == MemNode::Address && mop == Op_AddP &&
+            // When there are other uses besides address expressions
+            // put it on stack and mark as shared.
+            !is_visited(m)) {
           // Some inputs for address expression are not put on stack
           // to avoid marking them as shared and forcing them into register
           // if they are used only in address expressions.
@@ -2213,10 +2243,7 @@
           // besides address expressions.
 
           Node *off = m->in(AddPNode::Offset);
-          if( off->is_Con() &&
-              // When there are other uses besides address expressions
-              // put it on stack and mark as shared.
-              !is_visited(m) ) {
+          if (off->is_Con()) {
             address_visited.test_set(m->_idx); // Flag as address_visited
             Node *adr = m->in(AddPNode::Address);
 
@@ -2229,28 +2256,7 @@
                 !is_visited(adr) ) {
               address_visited.set(adr->_idx); // Flag as address_visited
               Node *shift = adr->in(AddPNode::Offset);
-              // Check for shift by small constant as well
-              if( shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
-                  shift->in(2)->get_int() <= 3 &&
-                  // Are there other uses besides address expressions?
-                  !is_visited(shift) ) {
-                address_visited.set(shift->_idx); // Flag as address_visited
-                mstack.push(shift->in(2), Visit);
-                Node *conv = shift->in(1);
-#ifdef _LP64
-                // Allow Matcher to match the rule which bypass
-                // ConvI2L operation for an array index on LP64
-                // if the index value is positive.
-                if( conv->Opcode() == Op_ConvI2L &&
-                    conv->as_Type()->type()->is_long()->_lo >= 0 &&
-                    // Are there other uses besides address expressions?
-                    !is_visited(conv) ) {
-                  address_visited.set(conv->_idx); // Flag as address_visited
-                  mstack.push(conv->in(1), Pre_Visit);
-                } else
-#endif
-                mstack.push(conv, Pre_Visit);
-              } else {
+              if (!clone_shift(shift, this, mstack, address_visited)) {
                 mstack.push(shift, Pre_Visit);
               }
               mstack.push(adr->in(AddPNode::Address), Pre_Visit);
@@ -2263,6 +2269,12 @@
             mstack.push(off, Visit);
             mstack.push(m->in(AddPNode::Base), Pre_Visit);
             continue; // for(int i = ...)
+          } else if (clone_shift_expressions &&
+                     clone_shift(off, this, mstack, address_visited)) {
+              address_visited.test_set(m->_idx); // Flag as address_visited
+              mstack.push(m->in(AddPNode::Address), Pre_Visit);
+              mstack.push(m->in(AddPNode::Base), Pre_Visit);
+              continue;
           } // if( off->is_Con() )
         }   // if( mem_op &&
         mstack.push(m, Pre_Visit);
--- a/hotspot/src/share/vm/opto/matcher.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -269,6 +269,9 @@
   // should generate this one.
   static const bool match_rule_supported(int opcode);
 
+  // Some uarchs have different sized float register resources
+  static const int float_pressure(int default_pressure_threshold);
+
   // Used to determine if we have fast l2f conversion
   // USII has it, USIII doesn't
   static const bool convL2FSupported(void);
--- a/hotspot/src/share/vm/opto/mathexactnode.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/mathexactnode.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -167,7 +167,7 @@
 }
 
 const Type* OverflowNode::sub(const Type* t1, const Type* t2) const {
-  fatal(err_msg_res("sub() should not be called for '%s'", NodeClassNames[this->Opcode()]));
+  fatal("sub() should not be called for '%s'", NodeClassNames[this->Opcode()]);
   return TypeInt::CC;
 }
 
--- a/hotspot/src/share/vm/opto/memnode.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1139,7 +1139,7 @@
             // Only integer types have boxing cache.
             assert(bt == T_BOOLEAN || bt == T_CHAR  ||
                    bt == T_BYTE    || bt == T_SHORT ||
-                   bt == T_INT     || bt == T_LONG, err_msg_res("wrong type = %s", type2name(bt)));
+                   bt == T_INT     || bt == T_LONG, "wrong type = %s", type2name(bt));
             jlong cache_low = (bt == T_LONG) ? c.as_long() : c.as_int();
             if (cache_low != (int)cache_low) {
               return NULL; // should not happen since cache is array indexed by value
@@ -2394,7 +2394,7 @@
              Opcode() == Op_StoreVector ||
              phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw ||
              (Opcode() == Op_StoreL && st->Opcode() == Op_StoreI), // expanded ClearArrayNode
-             err_msg_res("no mismatched stores, except on raw memory: %s %s", NodeClassNames[Opcode()], NodeClassNames[st->Opcode()]));
+             "no mismatched stores, except on raw memory: %s %s", NodeClassNames[Opcode()], NodeClassNames[st->Opcode()]);
 
       if (st->in(MemNode::Address)->eqv_uncast(address) &&
           st->as_Store()->memory_size() <= this->memory_size()) {
@@ -2945,7 +2945,7 @@
       // Final field stores.
       Node* alloc = AllocateNode::Ideal_allocation(in(MemBarNode::Precedent), phase);
       if ((alloc != NULL) && alloc->is_Allocate() &&
-          alloc->as_Allocate()->_is_non_escaping) {
+          alloc->as_Allocate()->does_not_escape_thread()) {
         // The allocated object does not escape.
         eliminate = true;
       }
@@ -3289,7 +3289,7 @@
                 // the store control then we cannot capture the store.
                 assert(!n->is_Store(), "2 stores to same slice on same control?");
                 Node* base = other_adr;
-                assert(base->is_AddP(), err_msg_res("should be addp but is %s", base->Name()));
+                assert(base->is_AddP(), "should be addp but is %s", base->Name());
                 base = base->in(AddPNode::Base);
                 if (base != NULL) {
                   base = base->uncast();
--- a/hotspot/src/share/vm/opto/node.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/node.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -47,6 +47,10 @@
 #ifndef PRODUCT
 extern int nodes_created;
 #endif
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
 
 #ifdef ASSERT
 
@@ -456,6 +460,10 @@
   _in[6] = n6; if (n6 != NULL) n6->add_out((Node *)this);
 }
 
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
 
 //------------------------------clone------------------------------------------
 // Clone a Node.
--- a/hotspot/src/share/vm/opto/node.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/node.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -353,7 +353,7 @@
 #endif
 
   // Reference to the i'th input Node.  Error if out of bounds.
-  Node* in(uint i) const { assert(i < _max, err_msg_res("oob: i=%d, _max=%d", i, _max)); return _in[i]; }
+  Node* in(uint i) const { assert(i < _max, "oob: i=%d, _max=%d", i, _max); return _in[i]; }
   // Reference to the i'th input Node.  NULL if out of bounds.
   Node* lookup(uint i) const { return ((i < _max) ? _in[i] : NULL); }
   // Reference to the i'th output Node.  Error if out of bounds.
@@ -393,7 +393,7 @@
   void ins_req( uint i, Node *n ); // Insert a NEW required input
   void set_req( uint i, Node *n ) {
     assert( is_not_dead(n), "can not use dead node");
-    assert( i < _cnt, err_msg_res("oob: i=%d, _cnt=%d", i, _cnt));
+    assert( i < _cnt, "oob: i=%d, _cnt=%d", i, _cnt);
     assert( !VerifyHashTableKeys || _hash_lock == 0,
             "remove node from hash table before modifying it");
     Node** p = &_in[i];    // cache this._in, across the del_out call
@@ -674,7 +674,8 @@
     Flag_avoid_back_to_back_after    = Flag_avoid_back_to_back_before << 1,
     Flag_has_call                    = Flag_avoid_back_to_back_after << 1,
     Flag_is_reduction                = Flag_has_call << 1,
-    Flag_is_expensive                = Flag_is_reduction << 1,
+    Flag_is_scheduled                = Flag_is_reduction,
+    Flag_is_expensive                = Flag_is_scheduled << 1,
     _max_flags = (Flag_is_expensive << 1) - 1 // allow flags combination
   };
 
@@ -861,6 +862,9 @@
   // It must have the loop's phi as input and provide a def to the phi.
   bool is_reduction() const { return (_flags & Flag_is_reduction) != 0; }
 
+  // Used in lcm to mark nodes that have scheduled
+  bool is_scheduled() const { return (_flags & Flag_is_scheduled) != 0; }
+
 //----------------- Optimization
 
   // Get the worst-case Type output for this Node.
--- a/hotspot/src/share/vm/opto/output.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -116,12 +116,6 @@
     }
   }
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-  if (ZapDeadCompiledLocals) {
-    Insert_zap_nodes();
-  }
-# endif
-
   uint* blk_starts = NEW_RESOURCE_ARRAY(uint, _cfg->number_of_blocks() + 1);
   blk_starts[0] = 0;
 
@@ -184,113 +178,6 @@
   return (stub_function() == NULL && has_java_calls());
 }
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-
-
-// In order to catch compiler oop-map bugs, we have implemented
-// a debugging mode called ZapDeadCompilerLocals.
-// This mode causes the compiler to insert a call to a runtime routine,
-// "zap_dead_locals", right before each place in compiled code
-// that could potentially be a gc-point (i.e., a safepoint or oop map point).
-// The runtime routine checks that locations mapped as oops are really
-// oops, that locations mapped as values do not look like oops,
-// and that locations mapped as dead are not used later
-// (by zapping them to an invalid address).
-
-int Compile::_CompiledZap_count = 0;
-
-void Compile::Insert_zap_nodes() {
-  bool skip = false;
-
-
-  // Dink with static counts because code code without the extra
-  // runtime calls is MUCH faster for debugging purposes
-
-       if ( CompileZapFirst  ==  0  ) ; // nothing special
-  else if ( CompileZapFirst  >  CompiledZap_count() )  skip = true;
-  else if ( CompileZapFirst  == CompiledZap_count() )
-    warning("starting zap compilation after skipping");
-
-       if ( CompileZapLast  ==  -1  ) ; // nothing special
-  else if ( CompileZapLast  <   CompiledZap_count() )  skip = true;
-  else if ( CompileZapLast  ==  CompiledZap_count() )
-    warning("about to compile last zap");
-
-  ++_CompiledZap_count; // counts skipped zaps, too
-
-  if ( skip )  return;
-
-
-  if ( _method == NULL )
-    return; // no safepoints/oopmaps emitted for calls in stubs,so we don't care
-
-  // Insert call to zap runtime stub before every node with an oop map
-  for( uint i=0; i<_cfg->number_of_blocks(); i++ ) {
-    Block *b = _cfg->get_block(i);
-    for ( uint j = 0;  j < b->number_of_nodes();  ++j ) {
-      Node *n = b->get_node(j);
-
-      // Determining if we should insert a zap-a-lot node in output.
-      // We do that for all nodes that has oopmap info, except for calls
-      // to allocation.  Calls to allocation passes in the old top-of-eden pointer
-      // and expect the C code to reset it.  Hence, there can be no safepoints between
-      // the inlined-allocation and the call to new_Java, etc.
-      // We also cannot zap monitor calls, as they must hold the microlock
-      // during the call to Zap, which also wants to grab the microlock.
-      bool insert = n->is_MachSafePoint() && (n->as_MachSafePoint()->oop_map() != NULL);
-      if ( insert ) { // it is MachSafePoint
-        if ( !n->is_MachCall() ) {
-          insert = false;
-        } else if ( n->is_MachCall() ) {
-          MachCallNode* call = n->as_MachCall();
-          if (call->entry_point() == OptoRuntime::new_instance_Java() ||
-              call->entry_point() == OptoRuntime::new_array_Java() ||
-              call->entry_point() == OptoRuntime::multianewarray2_Java() ||
-              call->entry_point() == OptoRuntime::multianewarray3_Java() ||
-              call->entry_point() == OptoRuntime::multianewarray4_Java() ||
-              call->entry_point() == OptoRuntime::multianewarray5_Java() ||
-              call->entry_point() == OptoRuntime::slow_arraycopy_Java() ||
-              call->entry_point() == OptoRuntime::complete_monitor_locking_Java()
-              ) {
-            insert = false;
-          }
-        }
-        if (insert) {
-          Node *zap = call_zap_node(n->as_MachSafePoint(), i);
-          b->insert_node(zap, j);
-          _cfg->map_node_to_block(zap, b);
-          ++j;
-        }
-      }
-    }
-  }
-}
-
-
-Node* Compile::call_zap_node(MachSafePointNode* node_to_check, int block_no) {
-  const TypeFunc *tf = OptoRuntime::zap_dead_locals_Type();
-  CallStaticJavaNode* ideal_node =
-    new CallStaticJavaNode( tf,
-         OptoRuntime::zap_dead_locals_stub(_method->flags().is_native()),
-                       "call zap dead locals stub", 0, TypePtr::BOTTOM);
-  // We need to copy the OopMap from the site we're zapping at.
-  // We have to make a copy, because the zap site might not be
-  // a call site, and zap_dead is a call site.
-  OopMap* clone = node_to_check->oop_map()->deep_copy();
-
-  // Add the cloned OopMap to the zap node
-  ideal_node->set_oop_map(clone);
-  return _matcher->match_sfpt(ideal_node);
-}
-
-bool Compile::is_node_getting_a_safepoint( Node* n) {
-  // This code duplicates the logic prior to the call of add_safepoint
-  // below in this file.
-  if( n->is_MachSafePoint() ) return true;
-  return false;
-}
-
-# endif // ENABLE_ZAP_DEAD_LOCALS
 
 // Compute the size of first NumberOfLoopInstrToAlign instructions at the top
 // of a loop. When aligning a loop we need to provide enough instructions
@@ -834,10 +721,6 @@
   MachSafePointNode *sfn   = mach->as_MachSafePoint();
   MachCallNode      *mcall;
 
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-  assert( is_node_getting_a_safepoint(mach),  "logic does not match; false negative");
-#endif
-
   int safepoint_pc_offset = current_offset;
   bool is_method_handle_invoke = false;
   bool return_oop = false;
@@ -973,7 +856,9 @@
     assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI");
     assert(!jvms->should_reexecute() || depth == max_depth, "reexecute allowed only for the youngest");
     // Now we can describe the scope.
-    debug_info()->describe_scope(safepoint_pc_offset, scope_method, jvms->bci(), jvms->should_reexecute(), is_method_handle_invoke, return_oop, locvals, expvals, monvals);
+    methodHandle null_mh;
+    bool rethrow_exception = false;
+    debug_info()->describe_scope(safepoint_pc_offset, null_mh, scope_method, jvms->bci(), jvms->should_reexecute(), rethrow_exception, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
   } // End jvms loop
 
   // Mark the end of the scope set.
@@ -1056,7 +941,8 @@
     JVMState* jvms = youngest_jvms->of_depth(depth);
     ciMethod* method = jvms->has_method() ? jvms->method() : NULL;
     assert(!jvms->should_reexecute() || depth==max_depth, "reexecute allowed only for the youngest");
-    debug_info->describe_scope(pc_offset, method, jvms->bci(), jvms->should_reexecute());
+    methodHandle null_mh;
+    debug_info->describe_scope(pc_offset, null_mh, method, jvms->bci(), jvms->should_reexecute());
   }
 
   // Mark the end of the scope set.
@@ -1294,10 +1180,6 @@
       if (Pipeline::requires_bundling() && starts_bundle(n))
         cb->flush_bundle(false);
 
-      // The following logic is duplicated in the code ifdeffed for
-      // ENABLE_ZAP_DEAD_LOCALS which appears above in this file.  It
-      // should be factored out.  Or maybe dispersed to the nodes?
-
       // Special handling for SafePoint/Call Nodes
       bool is_mcall = false;
       if (n->is_Mach()) {
@@ -1364,9 +1246,6 @@
             // !!!!! Stubs only need an oopmap right now, so bail out
             if (sfn->jvms()->method() == NULL) {
               // Write the oopmap directly to the code blob??!!
-#             ifdef ENABLE_ZAP_DEAD_LOCALS
-              assert( !is_node_getting_a_safepoint(sfn),  "logic does not match; false positive");
-#             endif
               continue;
             }
           } // End synchronization
@@ -1554,9 +1433,6 @@
           // !!!!! Stubs only need an oopmap right now, so bail out
           if (!mach->is_MachCall() && mach->as_MachSafePoint()->jvms()->method() == NULL) {
             // Write the oopmap directly to the code blob??!!
-#           ifdef ENABLE_ZAP_DEAD_LOCALS
-            assert( !is_node_getting_a_safepoint(mach),  "logic does not match; false positive");
-#           endif
             delay_slot = NULL;
             continue;
           }
@@ -2611,7 +2487,7 @@
       n->dump();
       tty->print_cr("...");
       prior_use->dump();
-      assert(edge_from_to(prior_use,n),msg);
+      assert(edge_from_to(prior_use,n), "%s", msg);
     }
     _reg_node.map(def,NULL); // Kill live USEs
   }
@@ -2649,11 +2525,11 @@
       OptoReg::Name reg_lo = _regalloc->get_reg_first(def);
       OptoReg::Name reg_hi = _regalloc->get_reg_second(def);
       if( OptoReg::is_valid(reg_lo) ) {
-        assert(!_reg_node[reg_lo] || edge_from_to(_reg_node[reg_lo],def), msg);
+        assert(!_reg_node[reg_lo] || edge_from_to(_reg_node[reg_lo],def), "%s", msg);
         _reg_node.map(reg_lo,n);
       }
       if( OptoReg::is_valid(reg_hi) ) {
-        assert(!_reg_node[reg_hi] || edge_from_to(_reg_node[reg_hi],def), msg);
+        assert(!_reg_node[reg_hi] || edge_from_to(_reg_node[reg_hi],def), "%s", msg);
         _reg_node.map(reg_hi,n);
       }
     }
--- a/hotspot/src/share/vm/opto/parse1.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1476,13 +1476,13 @@
     int pre_bc_sp = sp();
     int inputs, depth;
     bool have_se = !stopped() && compute_stack_effects(inputs, depth);
-    assert(!have_se || pre_bc_sp >= inputs, err_msg_res("have enough stack to execute this BC: pre_bc_sp=%d, inputs=%d", pre_bc_sp, inputs));
+    assert(!have_se || pre_bc_sp >= inputs, "have enough stack to execute this BC: pre_bc_sp=%d, inputs=%d", pre_bc_sp, inputs);
 #endif //ASSERT
 
     do_one_bytecode();
 
     assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth,
-           err_msg_res("incorrect depth prediction: sp=%d, pre_bc_sp=%d, depth=%d", sp(), pre_bc_sp, depth));
+           "incorrect depth prediction: sp=%d, pre_bc_sp=%d, depth=%d", sp(), pre_bc_sp, depth);
 
     do_exceptions();
 
--- a/hotspot/src/share/vm/opto/parse3.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/parse3.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -404,7 +404,7 @@
   // The original expression was of this form: new T[length0][length1]...
   // It is often the case that the lengths are small (except the last).
   // If that happens, use the fast 1-d creator a constant number of times.
-  const jint expand_limit = MIN2((juint)MultiArrayExpandLimit, (juint)100);
+  const jint expand_limit = MIN2((jint)MultiArrayExpandLimit, 100);
   jint expand_count = 1;        // count of allocations in the expansion
   jint expand_fanout = 1;       // running total fanout
   for (j = 0; j < ndimensions-1; j++) {
--- a/hotspot/src/share/vm/opto/runtime.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/runtime.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -102,11 +102,6 @@
 address OptoRuntime::_slow_arraycopy_Java                         = NULL;
 address OptoRuntime::_register_finalizer_Java                     = NULL;
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-address OptoRuntime::_zap_dead_Java_locals_Java                   = NULL;
-address OptoRuntime::_zap_dead_native_locals_Java                 = NULL;
-# endif
-
 ExceptionBlob* OptoRuntime::_exception_blob;
 
 // This should be called in an assertion at the start of OptoRuntime routines
@@ -152,10 +147,6 @@
   gen(env, _slow_arraycopy_Java            , slow_arraycopy_Type          , SharedRuntime::slow_arraycopy_C ,    0 , false, false, false);
   gen(env, _register_finalizer_Java        , register_finalizer_Type      , register_finalizer              ,    0 , false, false, false);
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-  gen(env, _zap_dead_Java_locals_Java      , zap_dead_locals_Type         , zap_dead_Java_locals_C          ,    0 , false, true , false );
-  gen(env, _zap_dead_native_locals_Java    , zap_dead_locals_Type         , zap_dead_native_locals_C        ,    0 , false, true , false );
-# endif
   return true;
 }
 
@@ -604,23 +595,6 @@
   return TypeFunc::make(domain, range);
 }
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-// Type used for stub generation for zap_dead_locals.
-// No inputs or outputs
-const TypeFunc *OptoRuntime::zap_dead_locals_Type() {
-  // create input type (domain)
-  const Type **fields = TypeTuple::fields(0);
-  const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms,fields);
-
-  // create result type (range)
-  fields = TypeTuple::fields(0);
-  const TypeTuple *range = TypeTuple::make(TypeFunc::Parms,fields);
-
-  return TypeFunc::make(domain,range);
-}
-# endif
-
-
 //-----------------------------------------------------------------------------
 // Monitor Handling
 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
@@ -1648,67 +1622,3 @@
 
 #endif  // PRODUCT
 
-
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-// Called from call sites in compiled code with oop maps (actually safepoints)
-// Zaps dead locals in first java frame.
-// Is entry because may need to lock to generate oop maps
-// Currently, only used for compiler frames, but someday may be used
-// for interpreter frames, too.
-
-int OptoRuntime::ZapDeadCompiledLocals_count = 0;
-
-// avoid pointers to member funcs with these helpers
-static bool is_java_frame(  frame* f) { return f->is_java_frame();   }
-static bool is_native_frame(frame* f) { return f->is_native_frame(); }
-
-
-void OptoRuntime::zap_dead_java_or_native_locals(JavaThread* thread,
-                                                bool (*is_this_the_right_frame_to_zap)(frame*)) {
-  assert(JavaThread::current() == thread, "is this needed?");
-
-  if ( !ZapDeadCompiledLocals )  return;
-
-  bool skip = false;
-
-       if ( ZapDeadCompiledLocalsFirst  ==  0  ) ; // nothing special
-  else if ( ZapDeadCompiledLocalsFirst  >  ZapDeadCompiledLocals_count )  skip = true;
-  else if ( ZapDeadCompiledLocalsFirst  == ZapDeadCompiledLocals_count )
-    warning("starting zapping after skipping");
-
-       if ( ZapDeadCompiledLocalsLast  ==  -1  ) ; // nothing special
-  else if ( ZapDeadCompiledLocalsLast  <   ZapDeadCompiledLocals_count )  skip = true;
-  else if ( ZapDeadCompiledLocalsLast  ==  ZapDeadCompiledLocals_count )
-    warning("about to zap last zap");
-
-  ++ZapDeadCompiledLocals_count; // counts skipped zaps, too
-
-  if ( skip )  return;
-
-  // find java frame and zap it
-
-  for (StackFrameStream sfs(thread);  !sfs.is_done();  sfs.next()) {
-    if (is_this_the_right_frame_to_zap(sfs.current()) ) {
-      sfs.current()->zap_dead_locals(thread, sfs.register_map());
-      return;
-    }
-  }
-  warning("no frame found to zap in zap_dead_Java_locals_C");
-}
-
-JRT_LEAF(void, OptoRuntime::zap_dead_Java_locals_C(JavaThread* thread))
-  zap_dead_java_or_native_locals(thread, is_java_frame);
-JRT_END
-
-// The following does not work because for one thing, the
-// thread state is wrong; it expects java, but it is native.
-// Also, the invariants in a native stub are different and
-// I'm not sure it is safe to have a MachCalRuntimeDirectNode
-// in there.
-// So for now, we do not zap in native stubs.
-
-JRT_LEAF(void, OptoRuntime::zap_dead_native_locals_C(JavaThread* thread))
-  zap_dead_java_or_native_locals(thread, is_native_frame);
-JRT_END
-
-# endif
--- a/hotspot/src/share/vm/opto/runtime.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/runtime.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -152,12 +152,6 @@
   static address _slow_arraycopy_Java;
   static address _register_finalizer_Java;
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-  static address _zap_dead_Java_locals_Java;
-  static address _zap_dead_native_locals_Java;
-# endif
-
-
   //
   // Implementation of runtime methods
   // =================================
@@ -212,19 +206,6 @@
 
   static void register_finalizer(oopDesc* obj, JavaThread* thread);
 
-  // zaping dead locals, either from Java frames or from native frames
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-  static void zap_dead_Java_locals_C(   JavaThread* thread);
-  static void zap_dead_native_locals_C( JavaThread* thread);
-
-  static void zap_dead_java_or_native_locals( JavaThread*, bool (*)(frame*));
-
- public:
-   static int ZapDeadCompiledLocals_count;
-
-# endif
-
-
  public:
 
   static bool is_callee_saved_register(MachRegisterNumbers reg);
@@ -256,14 +237,6 @@
   static address slow_arraycopy_Java()                   { return _slow_arraycopy_Java; }
   static address register_finalizer_Java()               { return _register_finalizer_Java; }
 
-
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-  static address zap_dead_locals_stub(bool is_native)    { return is_native
-                                                                  ? _zap_dead_native_locals_Java
-                                                                  : _zap_dead_Java_locals_Java; }
-  static MachNode* node_to_call_zap_dead_locals(Node* n, int block_num, bool is_native);
-# endif
-
   static ExceptionBlob*    exception_blob()                      { return _exception_blob; }
 
   // Leaf routines helping with method data update
@@ -353,10 +326,6 @@
   static const TypeFunc* dtrace_method_entry_exit_Type();
   static const TypeFunc* dtrace_object_alloc_Type();
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-  static const TypeFunc* zap_dead_locals_Type();
-# endif
-
  private:
  static NamedCounter * volatile _named_counters;
 
--- a/hotspot/src/share/vm/opto/stringopts.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/stringopts.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -773,7 +773,7 @@
             return false;
           }
         } else {
-          assert(mem->is_Store() || mem->is_LoadStore(), err_msg_res("unexpected node type: %s", mem->Name()));
+          assert(mem->is_Store() || mem->is_LoadStore(), "unexpected node type: %s", mem->Name());
 #ifndef PRODUCT
           if (PrintOptimizeStringConcat) {
             tty->print("fusion has incorrect memory flow (unexpected source) for ");
@@ -814,7 +814,7 @@
               for (SimpleDUIterator i(true_proj); i.has_next(); i.next()) {
                 Node* use = i.get();
                 assert(use == ctrl || use->is_ConstraintCast(),
-                       err_msg_res("unexpected user: %s", use->Name()));
+                       "unexpected user: %s", use->Name());
               }
 
               iff = ctrl->in(1)->in(0)->as_If();
@@ -838,7 +838,7 @@
         for (SimpleDUIterator i(ctrl); i.has_next(); i.next()) {
           Node* use = i.get();
           assert(use == copy || use == iff || use == curr || use->is_CheckCastPP() || use->is_Load(),
-                 err_msg_res("unexpected user: %s", use->Name()));
+                 "unexpected user: %s", use->Name());
         }
 #endif // ASSERT
       }
--- a/hotspot/src/share/vm/opto/subnode.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/subnode.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1532,18 +1532,6 @@
 
 //=============================================================================
 //------------------------------Value------------------------------------------
-// Compute exp
-const Type *ExpDNode::Value( PhaseTransform *phase ) const {
-  const Type *t1 = phase->type( in(1) );
-  if( t1 == Type::TOP ) return Type::TOP;
-  if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
-  double d = t1->getd();
-  return TypeD::make( StubRoutines::intrinsic_exp( d ) );
-}
-
-
-//=============================================================================
-//------------------------------Value------------------------------------------
 // Compute pow
 const Type *PowDNode::Value( PhaseTransform *phase ) const {
   const Type *t1 = phase->type( in(1) );
--- a/hotspot/src/share/vm/opto/subnode.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/subnode.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -477,20 +477,6 @@
   virtual const Type *Value( PhaseTransform *phase ) const;
 };
 
-//------------------------------ExpDNode---------------------------------------
-//  Exponentiate a double
-class ExpDNode : public Node {
-public:
-  ExpDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
-    init_flags(Flag_is_expensive);
-    C->add_expensive_node(this);
-  }
-  virtual int Opcode() const;
-  const Type *bottom_type() const { return Type::DOUBLE; }
-  virtual uint ideal_reg() const { return Op_RegD; }
-  virtual const Type *Value( PhaseTransform *phase ) const;
-};
-
 //------------------------------LogDNode---------------------------------------
 // Log_e of a double
 class LogDNode : public Node {
--- a/hotspot/src/share/vm/opto/superword.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/superword.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -81,6 +81,10 @@
   if (_phase->C->method() != NULL) {
     _phase->C->method()->has_option_value("VectorizeDebug", _vector_loop_debug);
   }
+  _CountedLoopReserveKit_debug = 0;
+  if (_phase->C->method() != NULL) {
+    _phase->C->method()->has_option_value("DoReserveCopyInSuperWordDebug", _CountedLoopReserveKit_debug);
+  }
 #endif
 }
 
@@ -769,7 +773,7 @@
     // if offset is 0.
     int iv_adjustment_in_bytes = (stride_sign * vw - (offset % vw));
     assert(((ABS(iv_adjustment_in_bytes) % elt_size) == 0),
-           err_msg_res("(%d) should be divisible by (%d)", iv_adjustment_in_bytes, elt_size));
+           "(%d) should be divisible by (%d)", iv_adjustment_in_bytes, elt_size);
     iv_adjustment = iv_adjustment_in_bytes/elt_size;
   } else {
     // This memory op is not dependent on iv (scale == 0)
@@ -914,7 +918,7 @@
     preds.push(n);
     NOT_PRODUCT(if (TraceSuperWord && Verbose) tty->print_cr("SuperWord::mem_slice_preds: added pred(%d)", n->_idx);)
     prev = n;
-    assert(n->is_Mem(), err_msg_res("unexpected node %s", n->Name()));
+    assert(n->is_Mem(), "unexpected node %s", n->Name());
     n = n->in(MemNode::Memory);
   }
 }
@@ -1763,6 +1767,22 @@
   }
 }
 
+#ifndef PRODUCT
+void SuperWord::print_loop(bool whole) {
+  Node_Stack stack(_arena, _phase->C->unique() >> 2);
+  Node_List rpo_list;
+  VectorSet visited(_arena);
+  visited.set(lpt()->_head->_idx);
+  _phase->rpo(lpt()->_head, stack, visited, rpo_list);
+  _phase->dump(lpt(), rpo_list.size(), rpo_list );
+  if(whole) {
+    tty->print_cr("\n Whole loop tree");
+    _phase->dump();
+    tty->print_cr(" End of whole loop tree\n");
+  }
+}
+#endif
+
 //------------------------------output---------------------------
 // Convert packs into vector node operations
 void SuperWord::output() {
@@ -1770,7 +1790,7 @@
 
 #ifndef PRODUCT
   if (TraceLoopOpts) {
-    tty->print("SuperWord    ");
+    tty->print("SuperWord::output    ");
     lpt()->dump_head();
   }
 #endif
@@ -1789,6 +1809,18 @@
   CountedLoopNode *cl = lpt()->_head->as_CountedLoop();
   uint max_vlen_in_bytes = 0;
   uint max_vlen = 0;
+
+  NOT_PRODUCT(if(_CountedLoopReserveKit_debug > 0) {tty->print_cr("SWPointer::output: print loop before create_reserve_version_of_loop"); print_loop(true);})
+
+  CountedLoopReserveKit make_reversable(_phase, _lpt, DoReserveCopyInSuperWord);
+
+  NOT_PRODUCT(if(_CountedLoopReserveKit_debug > 0) {tty->print_cr("SWPointer::output: print loop after create_reserve_version_of_loop"); print_loop(true);})
+
+  if (DoReserveCopyInSuperWord && !make_reversable.has_reserved()) {
+    NOT_PRODUCT({tty->print_cr("SWPointer::output: loop was not reserved correctly, exiting SuperWord");})
+    return;
+  }
+
   for (int i = 0; i < _block.length(); i++) {
     Node* n = _block.at(i);
     Node_List* p = my_pack(n);
@@ -1858,8 +1890,8 @@
           vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n));
           vlen_in_bytes = vn->as_Vector()->length_in_bytes();
         }
-      } else if (opc == Op_SqrtD) {
-        // Promote operand to vector (Sqrt is a 2 address instruction)
+      } else if (opc == Op_SqrtD || opc == Op_AbsF || opc == Op_AbsD || opc == Op_NegF || opc == Op_NegD) {
+        // Promote operand to vector (Sqrt/Abs/Neg are 2 address instructions)
         Node* in = vector_opd(p, 1);
         vn = VectorNode::make(opc, in, NULL, vlen, velt_basic_type(n));
         vlen_in_bytes = vn->as_Vector()->length_in_bytes();
@@ -1888,6 +1920,7 @@
     }
   }
   C->set_max_vector_size(max_vlen_in_bytes);
+
   if (SuperWordLoopUnrollAnalysis) {
     if (cl->has_passed_slp()) {
       uint slp_max_unroll_factor = cl->slp_max_unroll();
@@ -1900,6 +1933,12 @@
       }
     }
   }
+
+  if (DoReserveCopyInSuperWord) {
+    make_reversable.use_new();
+  }
+  NOT_PRODUCT(if(_CountedLoopReserveKit_debug > 0) {tty->print_cr("\n Final loop after SuperWord"); print_loop(true);})
+  return;
 }
 
 //------------------------------vector_opd---------------------------
@@ -2110,7 +2149,7 @@
       Node* n_tail  = n->in(LoopNode::LoopBackControl);
       if (n_tail != n->in(LoopNode::EntryControl)) {
         if (!n_tail->is_Mem()) {
-          assert(n_tail->is_Mem(), err_msg_res("unexpected node for memory slice: %s", n_tail->Name()));
+          assert(n_tail->is_Mem(), "unexpected node for memory slice: %s", n_tail->Name());
           return false; // Bailout
         }
         _mem_slice_head.push(n);
@@ -2690,15 +2729,25 @@
 
 //----------------------------get_pre_loop_end---------------------------
 // Find pre loop end from main loop.  Returns null if none.
-CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) {
-  Node *ctrl = cl->in(LoopNode::EntryControl);
+CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) {
+  Node* ctrl = cl->in(LoopNode::EntryControl);
   if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL;
-  Node *iffm = ctrl->in(0);
+  Node* iffm = ctrl->in(0);
   if (!iffm->is_If()) return NULL;
-  Node *p_f = iffm->in(0);
+  Node* bolzm = iffm->in(1);
+  if (!bolzm->is_Bool()) return NULL;
+  Node* cmpzm = bolzm->in(1);
+  if (!cmpzm->is_Cmp()) return NULL;
+  Node* opqzm = cmpzm->in(2);
+  // Can not optimize a loop if zero-trip Opaque1 node is optimized
+  // away and then another round of loop opts attempted.
+  if (opqzm->Opcode() != Op_Opaque1) {
+    return NULL;
+  }
+  Node* p_f = iffm->in(0);
   if (!p_f->is_IfFalse()) return NULL;
   if (!p_f->in(0)->is_CountedLoopEnd()) return NULL;
-  CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd();
+  CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();
   CountedLoopNode* loop_node = pre_end->loopnode();
   if (loop_node == NULL || !loop_node->is_pre_loop()) return NULL;
   return pre_end;
@@ -3045,6 +3094,9 @@
     }
   }
   if (invariant(n)) {
+    if (opc == Op_ConvI2L) {
+      n = n->in(1);
+    }
     _negate_invar = negate;
     _invar = n;
     NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, _negate_invar, _offset);)
--- a/hotspot/src/share/vm/opto/superword.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/superword.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -200,6 +200,31 @@
   static const SWNodeInfo initial;
 };
 
+// JVMCI: OrderedPair is moved up to deal with compilation issues on Windows
+//------------------------------OrderedPair---------------------------
+// Ordered pair of Node*.
+class OrderedPair VALUE_OBJ_CLASS_SPEC {
+ protected:
+  Node* _p1;
+  Node* _p2;
+ public:
+  OrderedPair() : _p1(NULL), _p2(NULL) {}
+  OrderedPair(Node* p1, Node* p2) {
+    if (p1->_idx < p2->_idx) {
+      _p1 = p1; _p2 = p2;
+    } else {
+      _p1 = p2; _p2 = p1;
+    }
+  }
+
+  bool operator==(const OrderedPair &rhs) {
+    return _p1 == rhs._p1 && _p2 == rhs._p2;
+  }
+  void print() { tty->print("  (%d, %d)", _p1->_idx, _p2->_idx); }
+
+  static const OrderedPair initial;
+};
+
 // -----------------------------SuperWord---------------------------------
 // Transforms scalar operations into packed (superword) operations.
 class SuperWord : public ResourceObj {
@@ -274,6 +299,7 @@
   GrowableArray<int> _ii_order;
 #ifndef PRODUCT
   uintx          _vector_loop_debug; // provide more printing in debug mode
+  uintx          _CountedLoopReserveKit_debug; // for debugging CountedLoopReserveKit
 #endif
 
   // Accessors
@@ -350,6 +376,7 @@
   // Tracing support
   #ifndef PRODUCT
   void find_adjacent_refs_trace_1(Node* best_align_to_mem_ref, int best_iv_adjustment);
+  void print_loop(bool whole);
   #endif
   // Find a memory reference to align the loop induction variable to.
   MemNode* find_align_to_ref(Node_List &memops);
@@ -634,29 +661,4 @@
 #endif
 };
 
-
-//------------------------------OrderedPair---------------------------
-// Ordered pair of Node*.
-class OrderedPair VALUE_OBJ_CLASS_SPEC {
- protected:
-  Node* _p1;
-  Node* _p2;
- public:
-  OrderedPair() : _p1(NULL), _p2(NULL) {}
-  OrderedPair(Node* p1, Node* p2) {
-    if (p1->_idx < p2->_idx) {
-      _p1 = p1; _p2 = p2;
-    } else {
-      _p1 = p2; _p2 = p1;
-    }
-  }
-
-  bool operator==(const OrderedPair &rhs) {
-    return _p1 == rhs._p1 && _p2 == rhs._p2;
-  }
-  void print() { tty->print("  (%d, %d)", _p1->_idx, _p2->_idx); }
-
-  static const OrderedPair initial;
-};
-
 #endif // SHARE_VM_OPTO_SUPERWORD_HPP
--- a/hotspot/src/share/vm/opto/type.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,8 +41,6 @@
 #include "opto/opcodes.hpp"
 #include "opto/type.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Portions of code courtesy of Clifford Click
 
 // Optimization - Graph Style
@@ -2784,7 +2782,7 @@
 #ifndef PRODUCT
 void TypeRawPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
   if( _ptr == Constant )
-    st->print(INTPTR_FORMAT, _bits);
+    st->print(INTPTR_FORMAT, p2i(_bits));
   else
     st->print("rawptr:%s", ptr_msg[_ptr]);
 }
@@ -3187,7 +3185,7 @@
 void TypeOopPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
   st->print("oopptr:%s", ptr_msg[_ptr]);
   if( _klass_is_exact ) st->print(":exact");
-  if( const_oop() ) st->print(INTPTR_FORMAT, const_oop());
+  if( const_oop() ) st->print(INTPTR_FORMAT, p2i(const_oop()));
   switch( _offset ) {
   case OffsetTop: st->print("+top"); break;
   case OffsetBot: st->print("+any"); break;
@@ -3358,7 +3356,7 @@
     case T_LONG:     return TypeLong::make(constant.as_long());
     default:         break;
   }
-  fatal(err_msg_res("Invalid boxed value type '%s'", type2name(bt)));
+  fatal("Invalid boxed value type '%s'", type2name(bt));
   return NULL;
 }
 
@@ -4635,7 +4633,7 @@
 #ifndef PRODUCT
 void TypeMetadataPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
   st->print("metadataptr:%s", ptr_msg[_ptr]);
-  if( metadata() ) st->print(INTPTR_FORMAT, metadata());
+  if( metadata() ) st->print(INTPTR_FORMAT, p2i(metadata()));
   switch( _offset ) {
   case OffsetTop: st->print("+top"); break;
   case OffsetBot: st->print("+any"); break;
@@ -5033,7 +5031,7 @@
     {
       const char *name = klass()->name()->as_utf8();
       if( name ) {
-        st->print("klass %s: " INTPTR_FORMAT, name, klass());
+        st->print("klass %s: " INTPTR_FORMAT, name, p2i(klass()));
       } else {
         ShouldNotReachHere();
       }
--- a/hotspot/src/share/vm/opto/vectornode.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/vectornode.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -92,6 +92,18 @@
   case Op_DivD:
     assert(bt == T_DOUBLE, "must be");
     return Op_DivVD;
+  case Op_AbsF:
+    assert(bt == T_FLOAT, "must be");
+    return Op_AbsVF;
+  case Op_AbsD:
+    assert(bt == T_DOUBLE, "must be");
+    return Op_AbsVD;
+  case Op_NegF:
+    assert(bt == T_FLOAT, "must be");
+    return Op_NegVF;
+  case Op_NegD:
+    assert(bt == T_DOUBLE, "must be");
+    return Op_NegVD;
   case Op_SqrtD:
     assert(bt == T_DOUBLE, "must be");
     return Op_SqrtVD;
@@ -255,7 +267,7 @@
   const TypeVect* vt = TypeVect::make(bt, vlen);
   int vopc = VectorNode::opcode(opc, bt);
   // This method should not be called for unimplemented vectors.
-  guarantee(vopc > 0, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc]));
+  guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]);
   switch (vopc) {
   case Op_AddVB: return new AddVBNode(n1, n2, vt);
   case Op_AddVS: return new AddVSNode(n1, n2, vt);
@@ -280,6 +292,12 @@
   case Op_DivVF: return new DivVFNode(n1, n2, vt);
   case Op_DivVD: return new DivVDNode(n1, n2, vt);
 
+  case Op_AbsVF: return new AbsVFNode(n1, vt);
+  case Op_AbsVD: return new AbsVDNode(n1, vt);
+
+  case Op_NegVF: return new NegVFNode(n1, vt);
+  case Op_NegVD: return new NegVDNode(n1, vt);
+
   // Currently only supports double precision sqrt
   case Op_SqrtVD: return new SqrtVDNode(n1, vt);
 
@@ -302,7 +320,7 @@
   case Op_OrV:  return new OrVNode (n1, n2, vt);
   case Op_XorV: return new XorVNode(n1, n2, vt);
   }
-  fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc]));
+  fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
   return NULL;
 
 }
@@ -328,7 +346,7 @@
   case T_DOUBLE:
     return new ReplicateDNode(s, vt);
   }
-  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
+  fatal("Type '%s' is not supported for vectors", type2name(bt));
   return NULL;
 }
 
@@ -346,7 +364,7 @@
   case Op_URShiftL:
     return new RShiftCntVNode(cnt, vt);
   }
-  fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]));
+  fatal("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]);
   return NULL;
 }
 
@@ -369,7 +387,7 @@
   case T_DOUBLE:
     return new PackDNode(s, vt);
   }
-  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
+  fatal("Type '%s' is not supported for vectors", type2name(bt));
   return NULL;
 }
 
@@ -405,7 +423,7 @@
     case T_DOUBLE:
       return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
     }
-    fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
+    fatal("Type '%s' is not supported for vectors", type2name(bt));
   }
   return NULL;
 }
@@ -448,7 +466,7 @@
   case T_DOUBLE:
     return new ExtractDNode(v, pos);
   }
-  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
+  fatal("Type '%s' is not supported for vectors", type2name(bt));
   return NULL;
 }
 
@@ -500,7 +518,7 @@
   int vopc = opcode(opc, bt);
 
   // This method should not be called for unimplemented vectors.
-  guarantee(vopc != opc, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc]));
+  guarantee(vopc != opc, "Vector for '%s' is not implemented", NodeClassNames[opc]);
 
   switch (vopc) {
   case Op_AddReductionVI: return new AddReductionVINode(ctrl, n1, n2);
@@ -512,7 +530,7 @@
   case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2);
   case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2);
   }
-  fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc]));
+  fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
   return NULL;
 }
 
--- a/hotspot/src/share/vm/opto/vectornode.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/opto/vectornode.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -309,6 +309,38 @@
   virtual int Opcode() const;
 };
 
+//------------------------------AbsVFNode--------------------------------------
+// Vector Abs float
+class AbsVFNode : public VectorNode {
+ public:
+  AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------AbsVDNode--------------------------------------
+// Vector Abs double
+class AbsVDNode : public VectorNode {
+ public:
+  AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------NegVFNode--------------------------------------
+// Vector Neg float
+class NegVFNode : public VectorNode {
+ public:
+  NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------NegVDNode--------------------------------------
+// Vector Neg double
+class NegVDNode : public VectorNode {
+ public:
+  NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
+  virtual int Opcode() const;
+};
+
 //------------------------------SqrtVDNode--------------------------------------
 // Vector Sqrt double
 class SqrtVDNode : public VectorNode {
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -128,6 +128,7 @@
 # include "interpreter/templateInterpreter.hpp"
 # include "interpreter/templateTable.hpp"
 # include "jvmtifiles/jvmti.h"
+# include "logging/log.hpp"
 # include "memory/allocation.hpp"
 # include "memory/allocation.inline.hpp"
 # include "memory/heap.hpp"
@@ -290,6 +291,9 @@
 # include "c1/c1_ValueType.hpp"
 # include "c1/c1_globals.hpp"
 #endif // COMPILER1
+#if INCLUDE_JVMCI
+# include "jvmci/jvmci_globals.hpp"
+#endif // INCLUDE_JVMCI
 #if INCLUDE_ALL_GCS
 # include "gc/cms/compactibleFreeListSpace.hpp"
 # include "gc/cms/concurrentMarkSweepGeneration.hpp"
--- a/hotspot/src/share/vm/prims/jni.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -81,6 +81,10 @@
 #if INCLUDE_ALL_GCS
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
 #endif // INCLUDE_ALL_GCS
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 
 static jint CurrentVersion = JNI_VERSION_1_8;
 
@@ -3986,6 +3990,19 @@
     *vm = (JavaVM *)(&main_vm);
     *(JNIEnv**)penv = thread->jni_environment();
 
+#if INCLUDE_JVMCI
+    if (EnableJVMCI) {
+      if (UseJVMCICompiler) {
+        // JVMCI is initialized on a CompilerThread
+        if (BootstrapJVMCI) {
+          JavaThread* THREAD = thread;
+          JVMCICompiler* compiler = JVMCICompiler::instance(CATCH);
+          compiler->bootstrap();
+        }
+      }
+    }
+#endif
+
     // Tracks the time application was running before GC
     RuntimeService::record_application_start();
 
--- a/hotspot/src/share/vm/prims/jniCheck.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -102,7 +102,8 @@
 #define UNCHECKED() (unchecked_jni_NativeInterface)
 
 static const char * warn_wrong_jnienv = "Using JNIEnv in the wrong thread";
-static const char * warn_bad_class_descriptor = "JNI FindClass received a bad class descriptor \"%s\".  A correct class descriptor " \
+static const char * warn_bad_class_descriptor1 = "JNI FindClass received a bad class descriptor \"";
+static const char * warn_bad_class_descriptor2 = "\".  A correct class descriptor " \
   "has no leading \"L\" or trailing \";\".  Incorrect descriptors will not be accepted in future releases.";
 static const char * fatal_using_jnienv_in_nonjava = "FATAL ERROR in native method: Using JNIEnv in non-Java thread";
 static const char * warn_other_function_in_critical = "Warning: Calling other JNI functions in the scope of " \
@@ -484,7 +485,8 @@
       name[0] == JVM_SIGNATURE_CLASS &&            // 'L'
       name[len-1] == JVM_SIGNATURE_ENDCLASS ) {    // ';'
     char msg[JVM_MAXPATHLEN];
-    jio_snprintf(msg, JVM_MAXPATHLEN, warn_bad_class_descriptor, name);
+    jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s",
+                 warn_bad_class_descriptor1, name, warn_bad_class_descriptor2);
     ReportJNIWarning(thr, msg);
   }
 }
--- a/hotspot/src/share/vm/prims/jvm.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -424,6 +424,8 @@
     const char* compiler_name = "HotSpot " CSIZE "Client Compiler";
 #elif defined(COMPILER2)
     const char* compiler_name = "HotSpot " CSIZE "Server Compiler";
+#elif INCLUDE_JVMCI
+    #error "INCLUDE_JVMCI should imply TIERED"
 #else
     const char* compiler_name = "";
 #endif // compilers
--- a/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -266,7 +266,7 @@
 
     address scopes_data = nm->scopes_data_begin();
     for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) {
-      ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop());
+      ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->rethrow_exception(), pcd->return_oop());
       ScopeDesc *sd  = &sc0;
       while( !sd->is_top() ) { sd = sd->sender(); }
       int bci = sd->bci();
--- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Thu Oct 22 11:13:08 2015 -0700
@@ -44,9 +44,6 @@
 # include "prims/jvmtiRawMonitor.hpp"
 # include "prims/jvmtiUtil.hpp"
 
-// There are known-bad format/arg pairings in the code generated by this file.
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 </xsl:text>
 
   <xsl:if test="$trace = 'Trace'">
@@ -543,8 +540,8 @@
 </xsl:text>
     <xsl:if test="$trace='Trace'">
       <xsl:text>    if (trace_flags) {
-          tty->print_cr("JVMTI [%s] %s %s  env=%d",  curr_thread_name, func_name, 
-                    JvmtiUtil::error_name(JVMTI_ERROR_INVALID_ENVIRONMENT), env);
+          tty->print_cr("JVMTI [%s] %s %s  env=" PTR_FORMAT,  curr_thread_name, func_name, 
+                    JvmtiUtil::error_name(JVMTI_ERROR_INVALID_ENVIRONMENT), p2i(env));
     }
 </xsl:text>
     </xsl:if>
@@ -760,8 +757,8 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_MONITOR</xsl:with-param>
-      <xsl:with-param name="comment"> - not a raw monitor 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, rmonitor</xsl:with-param>
+      <xsl:with-param name="comment"> - not a raw monitor " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(rmonitor)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
   }
@@ -777,8 +774,8 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
-      <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
+      <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
     }
@@ -786,8 +783,8 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
-      <xsl:with-param name="comment"> - oop is not a thread - jthread = 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
+      <xsl:with-param name="comment"> - oop is not a thread - jthread = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
     }
@@ -798,8 +795,8 @@
       <xsl:with-param name="err">
         <xsl:text>JVMTI_ERROR_THREAD_NOT_ALIVE</xsl:text>
       </xsl:with-param>
-      <xsl:with-param name="comment"> - not a Java thread - jthread = 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
+      <xsl:with-param name="comment"> - not a Java thread - jthread = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
     }
@@ -842,7 +839,7 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_ILLEGAL_ARGUMENT</xsl:with-param>
-      <xsl:with-param name="comment"> - negative depth - jthread = 0x%x</xsl:with-param>
+      <xsl:with-param name="comment"> - negative depth - jthread = " INT32_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
@@ -861,8 +858,8 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
-      <xsl:with-param name="comment"> - resolved to NULL - jclass = 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
+      <xsl:with-param name="comment"> - resolved to NULL - jclass = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
   }
@@ -870,8 +867,8 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
-      <xsl:with-param name="comment"> - not a class - jclass = 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
+      <xsl:with-param name="comment"> - not a class - jclass = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
   }
@@ -882,8 +879,8 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
-      <xsl:with-param name="comment"> - is a primitive class - jclass = 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
+      <xsl:with-param name="comment"> - is a primitive class - jclass = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
   }
@@ -892,8 +889,8 @@
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
-      <xsl:with-param name="comment"> - no Klass* - jclass = 0x%x</xsl:with-param>
-      <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
+      <xsl:with-param name="comment"> - no Klass* - jclass = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
   }
@@ -1034,12 +1031,12 @@
   <xsl:text> </xsl:text>
   <xsl:value-of select="$name"/>
   <xsl:variable name="child" select="child::*[position()=1]"/>
-  <xsl:choose>
+  <xsl:choose>g
     <xsl:when test="name($child)='char'">
       <xsl:text>='%s'</xsl:text>
     </xsl:when>
     <xsl:otherwise>
-      <xsl:text>=0x%x</xsl:text>
+      <xsl:text>=" PTR_FORMAT "</xsl:text>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
@@ -1047,7 +1044,15 @@
 <xsl:template match="inbuf" mode="traceInValue">
   <xsl:param name="name"/>
   <xsl:text>, </xsl:text>
-  <xsl:value-of select="$name"/>
+  <xsl:variable name="child" select="child::*[position()=1]"/>
+  <xsl:choose>
+    <xsl:when test="name($child)='char'">
+      <xsl:value-of select="$name"/>
+    </xsl:when>
+    <xsl:otherwise>
+      p2i(<xsl:value-of select="$name"/>)
+    </xsl:otherwise>
+  </xsl:choose>
 </xsl:template>
 
 <xsl:template match="ptrtype" mode="traceInFormat">
@@ -1057,7 +1062,7 @@
     <xsl:when test="name($child)='jclass'">
       <xsl:text> </xsl:text>
       <xsl:value-of select="$name"/>
-      <xsl:text>=0x%x</xsl:text>
+      <xsl:text>=" PTR_FORMAT "</xsl:text>
     </xsl:when>
     <xsl:otherwise>
       <xsl:apply-templates select="$child" mode="traceInFormat"/> 
@@ -1071,7 +1076,7 @@
   <xsl:choose>
     <xsl:when test="name($child)='jclass'">
       <xsl:text>, </xsl:text>
-      <xsl:value-of select="$name"/>
+      p2i(<xsl:value-of select="$name"/>)
     </xsl:when>
     <xsl:otherwise>
       <xsl:apply-templates select="$child" mode="traceInValue"/>
@@ -1083,13 +1088,13 @@
   <xsl:param name="name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="$name"/>
-  <xsl:text>=0x%x</xsl:text>
+  <xsl:text>=" PTR_FORMAT "</xsl:text>
 </xsl:template>
 
 <xsl:template match="inptr" mode="traceInValue">
   <xsl:param name="name"/>
   <xsl:text>, </xsl:text>
-  <xsl:value-of select="$name"/>
+  p2i(<xsl:value-of select="$name"/>)
 </xsl:template>
 
 <xsl:template match="jrawMonitorID|jfieldID" mode="traceInFormat">
@@ -1214,18 +1219,25 @@
   </xsl:choose>
 </xsl:template>
 
-<xsl:template match="jint|jlocation" mode="traceInFormat">
+<xsl:template match="jint" mode="traceInFormat">
   <xsl:param name="name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="$name"/>
-  <xsl:text>=%d</xsl:text>
+  <xsl:text>=" INT32_FORMAT "</xsl:text>
+</xsl:template>
+
+<xsl:template match="jlocation" mode="traceInFormat">
+  <xsl:param name="name"/>
+  <xsl:text> </xsl:text>
+  <xsl:value-of select="$name"/>
+  <xsl:text>=" INT64_FORMAT "</xsl:text>
 </xsl:template>
 
 <xsl:template match="jlong" mode="traceInFormat">
   <xsl:param name="name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="$name"/>
-  <xsl:text>=%ld</xsl:text>
+  <xsl:text>=" INT64_FORMAT "</xsl:text>
 </xsl:template>
 
 <xsl:template match="size_t" mode="traceInFormat">
--- a/hotspot/src/share/vm/prims/jvmtiEventController.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEventController.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,8 +38,6 @@
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef JVMTI_TRACE
 #define EC_TRACE(out) do { \
   if (JvmtiTrace::trace_event_controller()) { \
@@ -564,7 +562,7 @@
   jlong was_any_env_thread_enabled = JvmtiEventController::_universal_global_event_enabled.get_bits();
   jlong any_env_thread_enabled = 0;
 
-  EC_TRACE(("JVMTI [-] # recompute enabled - before %llx", was_any_env_thread_enabled));
+  EC_TRACE(("JVMTI [-] # recompute enabled - before " UINT64_FORMAT_X, was_any_env_thread_enabled));
 
   // compute non-thread-filters events.
   // This must be done separately from thread-filtered events, since some
@@ -646,7 +644,7 @@
 
   }
 
-  EC_TRACE(("JVMTI [-] # recompute enabled - after %llx", any_env_thread_enabled));
+  EC_TRACE(("JVMTI [-] # recompute enabled - after " UINT64_FORMAT_X, any_env_thread_enabled));
 }
 
 
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -58,8 +58,6 @@
 #include "gc/parallel/psMarkSweep.hpp"
 #endif // INCLUDE_ALL_GCS
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef JVMTI_TRACE
 #define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; }
 #define EVT_TRIG_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_TRIGGER) != 0) { SafeResourceMark rm; tty->print_cr out; }
@@ -770,7 +768,7 @@
 
       EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
                 ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
-                 JvmtiTrace::safe_get_thread_name(thread), method));
+                 JvmtiTrace::safe_get_thread_name(thread), p2i(method)));
 
       ResourceMark rm(thread);
 
@@ -805,7 +803,7 @@
     if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) {
       ThreadState old_os_state = thread->osthread()->get_state();
       thread->osthread()->set_state(BREAKPOINTED);
-      EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d",
+      EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ " INTX_FORMAT,
                      JvmtiTrace::safe_get_thread_name(thread),
                      (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
                      (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
@@ -1258,7 +1256,7 @@
   for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
     ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP);
     if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
-      EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Evt Single Step sent %s.%s @ %d",
+      EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Evt Single Step sent %s.%s @ " INTX_FORMAT,
                     JvmtiTrace::safe_get_thread_name(thread),
                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
@@ -1298,7 +1296,7 @@
       if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) {
 
         EVT_TRACE(JVMTI_EVENT_EXCEPTION,
-                     ("JVMTI [%s] Evt Exception thrown sent %s.%s @ %d",
+                     ("JVMTI [%s] Evt Exception thrown sent %s.%s @ " INTX_FORMAT,
                       JvmtiTrace::safe_get_thread_name(thread),
                       (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
                       (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
@@ -1374,7 +1372,7 @@
     return;
   }
   EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,
-                    ("JVMTI [%s] Trg unwind_due_to_exception triggered %s.%s @ %s%d - %s",
+                    ("JVMTI [%s] Trg unwind_due_to_exception triggered %s.%s @ %s" INTX_FORMAT " - %s",
                      JvmtiTrace::safe_get_thread_name(thread),
                      (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
                      (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
@@ -1409,7 +1407,7 @@
       for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
         if (ets->is_enabled(JVMTI_EVENT_EXCEPTION_CATCH) && (exception_handle() != NULL)) {
           EVT_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,
-                     ("JVMTI [%s] Evt ExceptionCatch sent %s.%s @ %d",
+                     ("JVMTI [%s] Evt ExceptionCatch sent %s.%s @ " INTX_FORMAT,
                       JvmtiTrace::safe_get_thread_name(thread),
                       (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
                       (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
@@ -1503,7 +1501,7 @@
   JvmtiEnvThreadStateIterator it(state);
   for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
     if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) {
-      EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Evt Field Access event sent %s.%s @ %d",
+      EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Evt Field Access event sent %s.%s @ " INTX_FORMAT,
                      JvmtiTrace::safe_get_thread_name(thread),
                      (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
                      (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
@@ -1667,7 +1665,7 @@
   for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
     if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) {
       EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
-                   ("JVMTI [%s] Evt Field Modification event sent %s.%s @ %d",
+                   ("JVMTI [%s] Evt Field Modification event sent %s.%s @ " INTX_FORMAT,
                     JvmtiTrace::safe_get_thread_name(thread),
                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
@@ -1807,7 +1805,7 @@
 
     EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
               ("JVMTI [%s] class compile method load event sent (by GenerateEvents), jmethodID=" PTR_FORMAT,
-              JvmtiTrace::safe_get_thread_name(thread), method));
+               JvmtiTrace::safe_get_thread_name(thread), p2i(method)));
 
     JvmtiEventMark jem(thread);
     JvmtiJavaThreadEventTransition jet(thread);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -45,8 +45,6 @@
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/events.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 Array<Method*>* VM_RedefineClasses::_old_methods = NULL;
 Array<Method*>* VM_RedefineClasses::_new_methods = NULL;
 Method**  VM_RedefineClasses::_matching_old_methods = NULL;
@@ -1714,12 +1712,12 @@
             // unless we are trying to stress ldc -> ldc_w rewriting
             RC_TRACE_WITH_THREAD(0x00080000, THREAD,
               ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),
-              bcp, cp_index, new_index));
+              p2i(bcp), cp_index, new_index));
             *(bcp + 1) = new_index;
           } else {
             RC_TRACE_WITH_THREAD(0x00080000, THREAD,
               ("%s->ldc_w@" INTPTR_FORMAT " old=%d, new=%d",
-              Bytecodes::name(c), bcp, cp_index, new_index));
+              Bytecodes::name(c), p2i(bcp), cp_index, new_index));
             // the new value needs ldc_w instead of ldc
             u_char inst_buffer[4]; // max instruction size is 4 bytes
             bcp = (address)inst_buffer;
@@ -1780,7 +1778,7 @@
           // the original index is mapped so update w/ new value
           RC_TRACE_WITH_THREAD(0x00080000, THREAD,
             ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),
-            bcp, cp_index, new_index));
+            p2i(bcp), cp_index, new_index));
           // Rewriter::rewrite_method() uses put_native_u2() in this
           // situation because it is reusing the constant pool index
           // location for a native index into the ConstantPoolCache.
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -588,7 +588,7 @@
     _obj_tag = (_entry == NULL) ? 0 : _entry->tag();
 
     // get the class and the class's tag value
-    assert(SystemDictionary::Class_klass()->oop_is_instanceMirror(), "Is not?");
+    assert(InstanceKlass::cast(SystemDictionary::Class_klass())->is_mirror_instance_klass(), "Is not?");
 
     _klass_tag = tag_for(tag_map, _o->klass()->java_mirror());
   }
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -228,8 +228,8 @@
         { ResourceMark rm;
           Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex);
           assert(m->name() == m2->name() && m->signature() == m2->signature(),
-                 err_msg("at %d, %s != %s", vmindex,
-                         m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string()));
+                 "at %d, %s != %s", vmindex,
+                 m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string());
         }
 #endif //ASSERT
       }
@@ -345,7 +345,7 @@
 
 
 Symbol* MethodHandles::signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid) {
-  assert(is_signature_polymorphic_intrinsic(iid), err_msg("iid=%d", iid));
+  assert(is_signature_polymorphic_intrinsic(iid), "%d %s", iid, vmIntrinsics::name_at(iid));
   switch (iid) {
   case vmIntrinsics::_invokeBasic:      return vmSymbols::invokeBasic_name();
   case vmIntrinsics::_linkToVirtual:    return vmSymbols::linkToVirtual_name();
@@ -353,7 +353,7 @@
   case vmIntrinsics::_linkToSpecial:    return vmSymbols::linkToSpecial_name();
   case vmIntrinsics::_linkToInterface:  return vmSymbols::linkToInterface_name();
   }
-  assert(false, "");
+  fatal("unexpected intrinsic id: %d %s", iid, vmIntrinsics::name_at(iid));
   return 0;
 }
 
@@ -365,7 +365,7 @@
   case vmIntrinsics::_linkToSpecial:    return JVM_REF_invokeSpecial;
   case vmIntrinsics::_linkToInterface:  return JVM_REF_invokeInterface;
   }
-  assert(false, err_msg("iid=%d", iid));
+  fatal("unexpected intrinsic id: %d %s", iid, vmIntrinsics::name_at(iid));
   return 0;
 }
 
@@ -698,7 +698,7 @@
           LinkResolver::resolve_virtual_call(result, Handle(), defc,
                         link_info, false, THREAD);
         } else {
-          assert(false, err_msg("ref_kind=%d", ref_kind));
+          assert(false, "ref_kind=%d", ref_kind);
         }
         if (HAS_PENDING_EXCEPTION) {
           return empty;
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -111,6 +111,10 @@
   void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
   void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
   void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass);
+#if INCLUDE_JVMCI
+  jobject  JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
+  void     JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
+#endif
 }
 
 #define CC (char*)  /* cast a literal from (const char*) */
@@ -121,6 +125,10 @@
   { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
   { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         },
   { CC"Java_sun_hotspot_WhiteBox_registerNatives",                 NULL, FN_PTR(JVM_RegisterWhiteBoxMethods)     },
+#if INCLUDE_JVMCI
+  { CC"Java_jdk_vm_ci_runtime_JVMCI_initializeRuntime",            NULL, FN_PTR(JVM_GetJVMCIRuntime)             },
+  { CC"Java_jdk_vm_ci_hotspot_CompilerToVM_registerNatives",       NULL, FN_PTR(JVM_RegisterJVMCINatives)        },
+#endif
 };
 
 static address lookup_special_native(char* jni_name) {
--- a/hotspot/src/share/vm/prims/privilegedStack.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/privilegedStack.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,8 +30,6 @@
 #include "prims/privilegedStack.hpp"
 #include "runtime/vframe.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 void PrivilegedElement::initialize(vframeStream* vfst, oop context, PrivilegedElement* next, TRAPS) {
   Method* method        = vfst->method();
   _klass                = method->method_holder();
@@ -65,7 +63,7 @@
 #ifndef PRODUCT
 
 void PrivilegedElement::print_on(outputStream* st) const {
-  st->print("   0x%lx ", _frame_id);
+  st->print("   " PTR_FORMAT " ", p2i(_frame_id));
   _klass->print_value_on(st);
   if (protection_domain() != NULL) {
     st->print("   ");
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -44,8 +44,6 @@
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
 #endif // INCLUDE_ALL_GCS
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 /*
  *      Implementation of class sun.misc.Unsafe
  */
@@ -126,7 +124,7 @@
              "raw [ptr+disp] must be consistent with oop::field_base");
     }
     jlong p_size = HeapWordSize * (jlong)(p->size());
-    assert(byte_offset < p_size, err_msg("Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, byte_offset, p_size));
+    assert(byte_offset < p_size, "Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, byte_offset, p_size);
   }
 #endif
   if (sizeof(char*) == sizeof(jint))    // (this constant folds!)
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -29,6 +29,7 @@
 #include "classfile/classLoaderData.hpp"
 #include "classfile/stringTable.hpp"
 #include "code/codeCache.hpp"
+#include "compiler/methodMatcher.hpp"
 #include "jvmtifiles/jvmtiEnv.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceShared.hpp"
@@ -64,8 +65,6 @@
 #endif // INCLUDE_NMT
 
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #define SIZE_T_MAX_VALUE ((size_t) -1)
 
 bool WhiteBox::_used = false;
@@ -200,8 +199,8 @@
                   "\tUniverse::narrow_oop_base() is " PTR_FORMAT "\n"
                   "\tUniverse::narrow_oop_use_implicit_null_checks() is %d",
                   UseCompressedOops,
-                  rhs.base(),
-                  Universe::narrow_oop_base(),
+                  p2i(rhs.base()),
+                  p2i(Universe::narrow_oop_base()),
                   Universe::narrow_oop_use_implicit_null_checks());
     return;
   }
@@ -625,6 +624,32 @@
   return (mh->queued_for_compilation() || nm != NULL);
 WB_END
 
+
+WB_ENTRY(jint, WB_MatchesMethod(JNIEnv* env, jobject o, jobject method, jstring pattern))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
+
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+
+  ResourceMark rm;
+  char* method_str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(pattern));
+
+  const char* error_msg = NULL;
+
+  BasicMatcher* m = BasicMatcher::parse_method_pattern(method_str, error_msg);
+  if (m == NULL) {
+    assert(error_msg != NULL, "Must have error_msg");
+    tty->print_cr("Got error: %s", error_msg);
+    return -1;
+  }
+
+  // Pattern works - now check if it matches
+  int result = m->matches(mh);
+  delete m;
+  assert(result == 0 || result == 1, "Result out of range");
+  return result;
+WB_END
+
 class AlwaysFalseClosure : public BoolObjectClosure {
  public:
   bool do_object_b(oop p) { return false; }
@@ -998,7 +1023,7 @@
   ThreadToNativeFromVM ttn(thread);
   jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
   CHECK_JNI_EXCEPTION_(env, NULL);
-  result = env->NewObjectArray(4, clazz, NULL);
+  result = env->NewObjectArray(5, clazz, NULL);
   if (result == NULL) {
     return result;
   }
@@ -1020,6 +1045,10 @@
   CHECK_JNI_EXCEPTION_(env, NULL);
   env->SetObjectArrayElement(result, 3, id);
 
+  jobject address = longBox(thread, env, (jlong) code);
+  CHECK_JNI_EXCEPTION_(env, NULL);
+  env->SetObjectArrayElement(result, 4, address);
+
   return result;
 WB_END
 
@@ -1106,6 +1135,13 @@
   return codeBlob2objectArray(thread, env, &stub);
 WB_END
 
+WB_ENTRY(jlong, WB_GetMethodData(JNIEnv* env, jobject wv, jobject method))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  CHECK_JNI_EXCEPTION_(env, 0);
+  methodHandle mh(thread, Method::checked_resolve_jmethod_id(jmid));
+  return (jlong) mh->method_data();
+WB_END
+
 WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o))
   return (jlong) Thread::current()->stack_size();
 WB_END
@@ -1115,6 +1151,7 @@
   return (jlong) t->stack_available(os::current_stack_pointer()) - (jlong) StackShadowPages * os::vm_page_size();
 WB_END
 
+
 int WhiteBox::array_bytes_to_length(size_t bytes) {
   return Array<u1>::bytes_to_length(bytes);
 }
@@ -1191,6 +1228,11 @@
   VMThread::execute(&force_safepoint_op);
 WB_END
 
+WB_ENTRY(long, WB_GetConstantPool(JNIEnv* env, jobject wb, jclass klass))
+  instanceKlassHandle ikh(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
+  return (long) ikh->constants();
+WB_END
+
 template <typename T>
 static bool GetMethodOption(JavaThread* thread, JNIEnv* env, jobject method, jstring name, T* value) {
   assert(value != NULL, "sanity");
@@ -1430,6 +1472,9 @@
       CC"(Ljava/lang/reflect/Executable;)V",          (void*)&WB_ClearMethodState},
   {CC"lockCompilation",    CC"()V",                   (void*)&WB_LockCompilation},
   {CC"unlockCompilation",  CC"()V",                   (void*)&WB_UnlockCompilation},
+  {CC"matchesMethod",
+      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)I",
+                                                      (void*)&WB_MatchesMethod},
   {CC"isConstantVMFlag",   CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag},
   {CC"isLockedVMFlag",     CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag},
   {CC"setBooleanVMFlag",   CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
@@ -1479,12 +1524,15 @@
   {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
   {CC"getCompilationActivityMode",
                            CC"()I",                   (void*)&WB_GetCompilationActivityMode},
+  {CC"getMethodData0",     CC"(Ljava/lang/reflect/Executable;)J",
+                                                      (void*)&WB_GetMethodData      },
   {CC"getCodeBlob",        CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob        },
   {CC"getThreadStackSize", CC"()J",                   (void*)&WB_GetThreadStackSize },
   {CC"getThreadRemainingStackSize", CC"()J",          (void*)&WB_GetThreadRemainingStackSize },
   {CC"assertMatchingSafepointCalls", CC"(ZZ)V",       (void*)&WB_AssertMatchingSafepointCalls },
   {CC"isMonitorInflated0", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
   {CC"forceSafepoint",     CC"()V",                   (void*)&WB_ForceSafepoint     },
+  {CC"getConstantPool0",   CC"(Ljava/lang/Class;)J",  (void*)&WB_GetConstantPool    },
   {CC"getMethodBooleanOption",
       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Boolean;",
                                                       (void*)&WB_GetMethodBooleaneOption},
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "code/codeCache.hpp"
+#include "compiler/compileTask.hpp"
 #include "runtime/advancedThresholdPolicy.hpp"
 #include "runtime/simpleThresholdPolicy.inline.hpp"
 
@@ -162,6 +163,9 @@
 
 // Called with the queue locked and with at least one element
 CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) {
+#if INCLUDE_JVMCI
+  CompileTask *max_non_jvmci_task = NULL;
+#endif
   CompileTask *max_task = NULL;
   Method* max_method = NULL;
   jlong t = os::javaTimeMillis();
@@ -179,6 +183,7 @@
         if (PrintTieredEvents) {
           print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level());
         }
+        task->log_task_dequeued("stale");
         compile_queue->remove_and_mark_stale(task);
         method->clear_queued_for_compilation();
         task = next_task;
@@ -194,6 +199,15 @@
     task = next_task;
   }
 
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    if (max_non_jvmci_task != NULL) {
+      max_task = max_non_jvmci_task;
+      max_method = max_task->method();
+    }
+  }
+#endif
+
   if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile
       && is_method_profiled(max_method)) {
     max_task->set_comp_level(CompLevel_limited_profile);
@@ -354,6 +368,14 @@
       if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
         next_level = CompLevel_full_optimization;
       } else if ((this->*p)(i, b, cur_level, method)) {
+#if INCLUDE_JVMCI
+        if (UseJVMCICompiler) {
+          // Since JVMCI takes a while to warm up, its queue inevitably backs up during
+          // early VM execution.
+          next_level = CompLevel_full_profile;
+          break;
+        }
+#endif
         // C1-generated fully profiled code is about 30% slower than the limited profile
         // code that has only invocation and backedge counters. The observation is that
         // if C2 queue is large enough we can spend too much time in the fully profiled code
@@ -362,7 +384,7 @@
         // we choose to compile a limited profiled version and then recompile with full profiling
         // when the load on C2 goes down.
         if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) >
-                                 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
+            Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
           next_level = CompLevel_limited_profile;
         } else {
           next_level = CompLevel_full_profile;
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -32,6 +32,7 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/taskqueue.hpp"
+#include "logging/logConfiguration.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -50,6 +51,9 @@
 #include "utilities/defaultStream.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/stringUtils.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 #if INCLUDE_ALL_GCS
 #include "gc/cms/compactibleFreeListSpace.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
@@ -213,6 +217,8 @@
 
   // Set OS specific system properties values
   os::init_system_properties_values();
+
+  JVMCI_ONLY(JVMCIRuntime::init_system_properties(&_system_properties);)
 }
 
 // Update/Initialize System properties after JDK version number is known
@@ -793,8 +799,10 @@
 }
 
 static bool set_fp_numeric_flag(const char* name, char* value, Flag::Flags origin) {
-  double v;
-  if (sscanf(value, "%lf", &v) != 1) {
+  char* end;
+  errno = 0;
+  double v = strtod(value, &end);
+  if ((errno != 0) || (*end != 0)) {
     return false;
   }
 
@@ -978,9 +986,9 @@
     return set_string_flag(real_name, value, origin);
   }
 
-#define SIGNED_FP_NUMBER_RANGE "[-0123456789.]"
+#define SIGNED_FP_NUMBER_RANGE "[-0123456789.eE+]"
 #define SIGNED_NUMBER_RANGE    "[-0123456789]"
-#define        NUMBER_RANGE    "[0123456789]"
+#define        NUMBER_RANGE    "[0123456789eE+-]"
   char value[BUFLEN + 1];
   char value2[BUFLEN + 1];
   if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) SIGNED_NUMBER_RANGE "." "%" XSTR(BUFLEN) NUMBER_RANGE "%c", name, value, value2, &dummy) == 3) {
@@ -1374,7 +1382,7 @@
   }
 }
 
-#if defined(COMPILER2) || defined(_LP64) || !INCLUDE_CDS
+#if defined(COMPILER2) || INCLUDE_JVMCI || defined(_LP64) || !INCLUDE_CDS
 // Conflict: required to use shared spaces (-Xshare:on), but
 // incompatible command line options were chosen.
 
@@ -1834,7 +1842,7 @@
 void Arguments::set_ergonomics_flags() {
   select_gc();
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   // Shared spaces work fine with other GCs but causes bytecode rewriting
   // to be disabled, which hurts interpreter performance and decreases
   // server performance.  When -server is specified, keep the default off
@@ -1918,7 +1926,7 @@
 
 void Arguments::set_g1_gc_flags() {
   assert(UseG1GC, "Error");
-#ifdef COMPILER1
+#if defined(COMPILER1) || INCLUDE_JVMCI
   FastTLABRefill = false;
 #endif
   FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads());
@@ -2495,6 +2503,22 @@
     }
 #endif
   }
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    if (!ScavengeRootsInCode) {
+      warning("forcing ScavengeRootsInCode non-zero because JVMCI is enabled");
+      ScavengeRootsInCode = 1;
+    }
+    if (FLAG_IS_DEFAULT(TypeProfileLevel)) {
+      TypeProfileLevel = 0;
+    }
+    if (UseJVMCICompiler) {
+      if (FLAG_IS_DEFAULT(TypeProfileWidth)) {
+        TypeProfileWidth = 8;
+      }
+    }
+  }
+#endif
 
   // Check lower bounds of the code cache
   // Template Interpreter code is approximately 3X larger in debug builds.
@@ -3190,6 +3214,26 @@
       if (FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
+    } else if (match_option(option, "-Xlog", &tail)) {
+      bool ret = false;
+      if (strcmp(tail, ":help") == 0) {
+        LogConfiguration::print_command_line_help(defaultStream::output_stream());
+        vm_exit(0);
+      } else if (strcmp(tail, ":disable") == 0) {
+        LogConfiguration::disable_logging();
+        ret = true;
+      } else if (*tail == '\0') {
+        ret = LogConfiguration::parse_command_line_arguments();
+        assert(ret, "-Xlog without arguments should never fail to parse");
+      } else if (*tail == ':') {
+        ret = LogConfiguration::parse_command_line_arguments(tail + 1);
+      }
+      if (ret == false) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "Invalid -Xlog option '-Xlog%s'\n",
+                    tail);
+        return JNI_EINVAL;
+      }
     // JNI hooks
     } else if (match_option(option, "-Xcheck", &tail)) {
       if (!strcmp(tail, ":jni")) {
@@ -3463,6 +3507,37 @@
   const char* fileSep = os::file_separator();
   sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
 
+#if INCLUDE_JVMCI
+  jint res = JVMCIRuntime::save_options(_system_properties);
+  if (res != JNI_OK) {
+    return res;
+  }
+
+  if (EnableJVMCI) {
+    // Append lib/jvmci/*.jar to boot class path
+    char jvmciDir[JVM_MAXPATHLEN];
+    const char* fileSep = os::file_separator();
+    jio_snprintf(jvmciDir, sizeof(jvmciDir), "%s%slib%sjvmci", Arguments::get_java_home(), fileSep, fileSep);
+    DIR* dir = os::opendir(jvmciDir);
+    if (dir != NULL) {
+      struct dirent *entry;
+      char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(jvmciDir), mtInternal);
+      while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
+        const char* name = entry->d_name;
+        const char* ext = name + strlen(name) - 4;
+        if (ext > name && strcmp(ext, ".jar") == 0) {
+          char fileName[JVM_MAXPATHLEN];
+          jio_snprintf(fileName, sizeof(fileName), "%s%s%s", jvmciDir, fileSep, name);
+          scp_p->add_suffix(fileName);
+          scp_assembly_required = true;
+        }
+      }
+      FREE_C_HEAP_ARRAY(char, dbuf);
+      os::closedir(dir);
+    }
+  }
+#endif // INCLUDE_JVMCI
+
   if (CheckEndorsedAndExtDirs) {
     int nonEmptyDirs = 0;
     // check endorsed directory
@@ -3521,7 +3596,7 @@
     FLAG_SET_ERGO(uintx, InitialTenuringThreshold, MaxTenuringThreshold);
   }
 
-#ifndef COMPILER2
+#if !defined(COMPILER2) && !INCLUDE_JVMCI
   // Don't degrade server performance for footprint
   if (FLAG_IS_DEFAULT(UseLargePages) &&
       MaxHeapSize < LargePageHeapSizeThreshold) {
@@ -3531,7 +3606,7 @@
     FLAG_SET_DEFAULT(UseLargePages, false);
   }
 
-#else
+#elif defined(COMPILER2)
   if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) {
     FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1);
   }
@@ -3690,8 +3765,6 @@
   return retcode;
 }
 
-const int OPTION_BUFFER_SIZE = 1024;
-
 jint Arguments::parse_vm_options_file(const char* file_name, ScopedVMInitArgs* vm_args) {
   // read file into buffer
   int fd = ::open(file_name, O_RDONLY);
@@ -3702,8 +3775,24 @@
     return JNI_ERR;
   }
 
+  struct stat stbuf;
+  int retcode = os::stat(file_name, &stbuf);
+  if (retcode != 0) {
+    jio_fprintf(defaultStream::error_stream(),
+                "Could not stat options file '%s'\n",
+                file_name);
+    os::close(fd);
+    return JNI_ERR;
+  }
+
+  if (stbuf.st_size == 0) {
+    // tell caller there is no option data and that is ok
+    os::close(fd);
+    return JNI_OK;
+  }
+
   // '+ 1' for NULL termination even with max bytes
-  int bytes_alloc = OPTION_BUFFER_SIZE + 1;
+  size_t bytes_alloc = stbuf.st_size + 1;
 
   char *buf = NEW_C_HEAP_ARRAY_RETURN_NULL(char, bytes_alloc, mtInternal);
   if (NULL == buf) {
@@ -3713,14 +3802,14 @@
     return JNI_ENOMEM;
   }
 
-  memset(buf, 0, (unsigned)bytes_alloc);
+  memset(buf, 0, bytes_alloc);
 
   // Fill buffer
   // Use ::read() instead of os::read because os::read()
   // might do a thread state transition
   // and it is too early for that here
 
-  int bytes_read = ::read(fd, (void *)buf, (unsigned)bytes_alloc);
+  ssize_t bytes_read = ::read(fd, (void *)buf, (unsigned)bytes_alloc);
   os::close(fd);
   if (bytes_read < 0) {
     FREE_C_HEAP_ARRAY(char, buf);
@@ -3735,16 +3824,7 @@
     return JNI_OK;
   }
 
-  // file is larger than OPTION_BUFFER_SIZE
-  if (bytes_read > bytes_alloc - 1) {
-    FREE_C_HEAP_ARRAY(char, buf);
-    jio_fprintf(defaultStream::error_stream(),
-                "Options file '%s' is larger than %d bytes.\n",
-                file_name, bytes_alloc - 1);
-    return JNI_EINVAL;
-  }
-
-  int retcode = parse_options_buffer(file_name, buf, bytes_read, vm_args);
+  retcode = parse_options_buffer(file_name, buf, bytes_read, vm_args);
 
   FREE_C_HEAP_ARRAY(char, buf);
   return retcode;
@@ -4279,6 +4359,9 @@
 #ifdef COMPILER1
       || !UseFastLocking
 #endif // COMPILER1
+#if INCLUDE_JVMCI
+      || !JVMCIUseFastLocking
+#endif
     ) {
     if (!FLAG_IS_DEFAULT(UseBiasedLocking) && UseBiasedLocking) {
       // flag set to true on command line; warn the user that they
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -33,6 +33,9 @@
 #include "runtime/commandLineFlagConstraintsRuntime.hpp"
 #include "runtime/os.hpp"
 #include "utilities/macros.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/commandLineFlagConstraintsJVMCI.hpp"
+#endif
 
 class CommandLineFlagConstraint_bool : public CommandLineFlagConstraint {
   CommandLineFlagConstraintFunc_bool _constraint;
@@ -220,7 +223,7 @@
 #define EMIT_CONSTRAINT_CHECK(func, type)                               , func, CommandLineFlagConstraint::type
 
 // the "name" argument must be a string literal
-#define INITIAL_CONSTRAINTS_SIZE 16
+#define INITIAL_CONSTRAINTS_SIZE 40
 GrowableArray<CommandLineFlagConstraint*>* CommandLineFlagConstraintList::_constraints = NULL;
 CommandLineFlagConstraint::ConstraintType CommandLineFlagConstraintList::_validating_type = CommandLineFlagConstraint::AtParse;
 
@@ -251,6 +254,18 @@
                                      IGNORE_RANGE,
                                      EMIT_CONSTRAINT_CHECK));
 
+#if INCLUDE_JVMCI
+  emit_constraint_no(NULL JVMCI_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
+                                      EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
+                                      EMIT_CONSTRAINT_PRODUCT_FLAG,
+                                      EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
+                                      EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
+                                      EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
+                                      EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
+                                      IGNORE_RANGE,
+                                      EMIT_CONSTRAINT_CHECK));
+#endif // INCLUDE_JVMCI
+
 #ifdef COMPILER1
   emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
                                    EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
@@ -274,7 +289,7 @@
                                    EMIT_CONSTRAINT_CHECK));
 #endif // COMPILER2
 
-#ifndef INCLUDE_ALL_GCS
+#if INCLUDE_ALL_GCS
   emit_constraint_no(NULL G1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
                                    EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
                                    EMIT_CONSTRAINT_PRODUCT_FLAG,
@@ -305,10 +320,7 @@
 
 // Check constraints for specific constraint type.
 bool CommandLineFlagConstraintList::check_constraints(CommandLineFlagConstraint::ConstraintType type) {
-  // Skip if we already checked.
-  if (type < _validating_type) {
-    return true;
-  }
+  guarantee(type > _validating_type, "Constraint check is out of order.");
   _validating_type = type;
 
   bool status = true;
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -54,9 +54,9 @@
   enum ConstraintType {
     // Will be validated during argument processing (Arguments::parse_argument).
     AtParse         = 0,
-    // Will be validated by CommandLineFlags::check_constraints_of_after_ergo().
-    AfterErgo      = 1,
-    // Will be validated by CommandLineFlags::check_constraints_of_after_memory_init().
+    // Will be validated by CommandLineFlagConstraintList::check_constraints(AfterErgo).
+    AfterErgo       = 1,
+    // Will be validated by CommandLineFlagConstraintList::check_constraints(AfterMemoryInit).
     AfterMemoryInit = 2
   };
 
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -23,6 +23,10 @@
  */
 
 #include "precompiled.hpp"
+#include "oops/metadata.hpp"
+#include "runtime/os.hpp"
+#include "code/relocInfo.hpp"
+#include "interpreter/invocationCounter.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/commandLineFlagConstraintsCompiler.hpp"
 #include "runtime/commandLineFlagRangeList.hpp"
@@ -58,7 +62,7 @@
  */
 Flag::Error CICompilerCountConstraintFunc(intx value, bool verbose) {
   int min_number_of_compiler_threads = 0;
-#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)
+#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) && !INCLUDE_JVMCI
   // case 1
 #else
   if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) {
@@ -84,3 +88,308 @@
     return Flag::SUCCESS;
   }
 }
+
+Flag::Error AllocatePrefetchDistanceConstraintFunc(intx value, bool verbose) {
+  if (value < 0) {
+    CommandLineError::print(verbose,
+                            "Unable to determine system-specific value for AllocatePrefetchDistance. "
+                            "Please provide appropriate value, if unsure, use 0 to disable prefetching\n");
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error AllocatePrefetchInstrConstraintFunc(intx value, bool verbose) {
+  intx max_value = max_intx;
+#if defined(SPARC)
+  max_value = 1;
+#elif defined(X86)
+  max_value = 3;
+#endif
+  if (value < 0 || value > max_value) {
+    CommandLineError::print(verbose,
+                            "AllocatePrefetchInstr (" INTX_FORMAT ") must be "
+                            "between 0 and " INTX_FORMAT "\n", value, max_value);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose) {
+  if (value < 0 || value > max_jint) {
+    CommandLineError::print(verbose,
+                            "AllocatePrefetchStepSize (" INTX_FORMAT ") "
+                            "must be between 0 and %d\n",
+                            AllocatePrefetchStepSize,
+                            max_jint);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  if (AllocatePrefetchDistance % AllocatePrefetchStepSize != 0) {
+     CommandLineError::print(verbose,
+                             "AllocatePrefetchDistance (" INTX_FORMAT ") "
+                             "%% AllocatePrefetchStepSize (" INTX_FORMAT ") "
+                             "= " INTX_FORMAT " "
+                             "must be 0\n",
+                             AllocatePrefetchDistance, AllocatePrefetchStepSize,
+                             AllocatePrefetchDistance % AllocatePrefetchStepSize);
+     return Flag::VIOLATES_CONSTRAINT;
+   }
+
+   return Flag::SUCCESS;
+}
+
+Flag::Error CompileThresholdConstraintFunc(intx value, bool verbose) {
+  if (value < 0 || value > INT_MAX >> InvocationCounter::count_shift) {
+    CommandLineError::print(verbose,
+                            "CompileThreshold (" INTX_FORMAT ") "
+                            "must be between 0 and %d\n",
+                            value,
+                            INT_MAX >> InvocationCounter::count_shift);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error OnStackReplacePercentageConstraintFunc(intx value, bool verbose) {
+  int backward_branch_limit;
+  if (ProfileInterpreter) {
+    if (OnStackReplacePercentage < InterpreterProfilePercentage) {
+      CommandLineError::print(verbose,
+                              "OnStackReplacePercentage (" INTX_FORMAT ") must be "
+                              "larger than InterpreterProfilePercentage (" INTX_FORMAT ")\n",
+                              OnStackReplacePercentage, InterpreterProfilePercentage);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+
+    backward_branch_limit = ((CompileThreshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100)
+                            << InvocationCounter::count_shift;
+
+    if (backward_branch_limit < 0) {
+      CommandLineError::print(verbose,
+                              "CompileThreshold * (InterpreterProfilePercentage - OnStackReplacePercentage) / 100 = "
+                              INTX_FORMAT " "
+                              "must be between 0 and " INTX_FORMAT ", try changing "
+                              "CompileThreshold, InterpreterProfilePercentage, and/or OnStackReplacePercentage\n",
+                              (CompileThreshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100,
+                              INT_MAX >> InvocationCounter::count_shift);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+  } else {
+    if (OnStackReplacePercentage < 0 ) {
+      CommandLineError::print(verbose,
+                              "OnStackReplacePercentage (" INTX_FORMAT ") must be "
+                              "non-negative\n", OnStackReplacePercentage);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+
+    backward_branch_limit = ((CompileThreshold * OnStackReplacePercentage) / 100)
+                            << InvocationCounter::count_shift;
+
+    if (backward_branch_limit < 0) {
+      CommandLineError::print(verbose,
+                              "CompileThreshold * OnStackReplacePercentage / 100 = " INTX_FORMAT " "
+                              "must be between 0 and " INTX_FORMAT ", try changing "
+                              "CompileThreshold and/or OnStackReplacePercentage\n",
+                              (CompileThreshold * OnStackReplacePercentage) / 100,
+                              INT_MAX >> InvocationCounter::count_shift);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+  }
+  return Flag::SUCCESS;
+}
+
+Flag::Error CodeCacheSegmentSizeConstraintFunc(uintx value, bool verbose) {
+  if (CodeCacheSegmentSize < (uintx)CodeEntryAlignment) {
+    CommandLineError::print(verbose,
+                            "CodeCacheSegmentSize  (" UINTX_FORMAT ") must be "
+                            "larger than or equal to CodeEntryAlignment (" INTX_FORMAT ")"
+                            "to align entry points\n",
+                            CodeCacheSegmentSize, CodeEntryAlignment);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  if (CodeCacheSegmentSize < sizeof(jdouble)) {
+    CommandLineError::print(verbose,
+                            "CodeCacheSegmentSize  (" UINTX_FORMAT ") must be "
+                            "at least " SIZE_FORMAT " to align constants\n",
+                            CodeCacheSegmentSize, sizeof(jdouble));
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+#ifdef COMPILER2
+  if (CodeCacheSegmentSize < (uintx)OptoLoopAlignment) {
+    CommandLineError::print(verbose,
+                            "CodeCacheSegmentSize  (" UINTX_FORMAT ") must be "
+                            "larger than or equal to OptoLoopAlignment (" INTX_FORMAT ")"
+                            "to align inner loops\n",
+                            CodeCacheSegmentSize, OptoLoopAlignment);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error CompilerThreadPriorityConstraintFunc(intx value, bool verbose) {
+  if (value < min_jint || value > max_jint) {
+    CommandLineError::print(verbose,
+                            "CompileThreadPriority (" INTX_FORMAT ") "
+                            "must be between %d and %d. "
+                            "Please also make sure to specify values that are "
+                            "meaningful to your operating system\n",
+                            value, min_jint, max_jint);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error CodeEntryAlignmentConstraintFunc(intx value, bool verbose) {
+#ifdef SPARC
+  if (CodeEntryAlignment % relocInfo::addr_unit() != 0) {
+    CommandLineError::print(verbose,
+                            "CodeEntryAlignment (" INTX_FORMAT ") must be "
+                            "multiple of NOP size\n", CodeEntryAlignment);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+
+  if (!is_power_of_2(value)) {
+    CommandLineError::print(verbose,
+                            "CodeEntryAlignment (" INTX_FORMAT ") must be "
+                            "a power of two\n", CodeEntryAlignment);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  if (CodeEntryAlignment < 16) {
+      CommandLineError::print(verbose,
+                              "CodeEntryAlignment (" INTX_FORMAT ") must be "
+                              "greater than or equal to %d\n",
+                              CodeEntryAlignment, 16);
+      return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error OptoLoopAlignmentConstraintFunc(intx value, bool verbose) {
+  if (value < 0 || value > 16) {
+    CommandLineError::print(verbose,
+                            "OptoLoopAlignment (" INTX_FORMAT ") "
+                            "must be between 0 and 16\n",
+                            value);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  if (!is_power_of_2(value)) {
+    CommandLineError::print(verbose,
+                            "OptoLoopAlignment (" INTX_FORMAT ") "
+                            "must be a power of two\n",
+                            value);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+#ifdef SPARC
+  if (OptoLoopAlignment % relocInfo::addr_unit() != 0) {
+    CommandLineError::print(verbose,
+                            "OptoLoopAlignment (" INTX_FORMAT ") must be "
+                            "multiple of NOP size\n");
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error ArraycopyDstPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
+  if (value != 0) {
+    CommandLineError::print(verbose,
+                            "ArraycopyDstPrefetchDistance (" INTX_FORMAT ") must be 0\n");
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error ArraycopySrcPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
+  if (value != 0) {
+    CommandLineError::print(verbose,
+                            "ArraycopySrcPrefetchDistance (" INTX_FORMAT ") must be 0\n");
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error TypeProfileLevelConstraintFunc(uintx value, bool verbose) {
+  for (int i = 0; i < 3; i++) {
+    if (value % 10 > 2) {
+      CommandLineError::print(verbose,
+                              "Invalid value (" UINTX_FORMAT ") "
+                              "in TypeProfileLevel at position %d\n", value, i);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+    value = value / 10;
+  }
+
+  return Flag::SUCCESS;
+}
+
+#ifdef COMPILER2
+Flag::Error InteriorEntryAlignmentConstraintFunc(intx value, bool verbose) {
+  if (InteriorEntryAlignment > CodeEntryAlignment) {
+    CommandLineError::print(verbose,
+                           "InteriorEntryAlignment (" INTX_FORMAT ") must be "
+                           "less than or equal to CodeEntryAlignment (" INTX_FORMAT ")\n",
+                           InteriorEntryAlignment, CodeEntryAlignment);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+#ifdef SPARC
+  if (InteriorEntryAlignment % relocInfo::addr_unit() != 0) {
+    CommandLineError::print(verbose,
+                            "InteriorEntryAlignment (" INTX_FORMAT ") must be "
+                            "multiple of NOP size\n");
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+
+  if (!is_power_of_2(value)) {
+     CommandLineError::print(verbose,
+                             "InteriorEntryAlignment (" INTX_FORMAT ") must be "
+                             "a power of two\n", InteriorEntryAlignment);
+     return Flag::VIOLATES_CONSTRAINT;
+   }
+
+  int minimum_alignment = 16;
+#if defined(SPARC) || (defined(X86) && !defined(AMD64))
+  minimum_alignment = 4;
+#endif
+
+  if (InteriorEntryAlignment < minimum_alignment) {
+    CommandLineError::print(verbose,
+                            "InteriorEntryAlignment (" INTX_FORMAT ") must be "
+                            "greater than or equal to %d\n",
+                            InteriorEntryAlignment, minimum_alignment);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error NodeLimitFudgeFactorConstraintFunc(intx value, bool verbose) {
+  if (value < MaxNodeLimit * 2 / 100 || value > MaxNodeLimit * 40 / 100) {
+    CommandLineError::print(verbose,
+                            "NodeLimitFudgeFactor must be between 2%% and 40%% "
+                            "of MaxNodeLimit (" INTX_FORMAT ")\n",
+                            MaxNodeLimit);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+
+  return Flag::SUCCESS;
+}
+#endif // COMPILER2
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -38,4 +38,34 @@
 
 Flag::Error CICompilerCountConstraintFunc(intx value, bool verbose);
 
+Flag::Error AllocatePrefetchDistanceConstraintFunc(intx value, bool verbose);
+
+Flag::Error AllocatePrefetchInstrConstraintFunc(intx value, bool verbose);
+
+Flag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose);
+
+Flag::Error CompileThresholdConstraintFunc(intx value, bool verbose);
+
+Flag::Error OnStackReplacePercentageConstraintFunc(intx value, bool verbose);
+
+Flag::Error CodeCacheSegmentSizeConstraintFunc(uintx value, bool verbose);
+
+Flag::Error CompilerThreadPriorityConstraintFunc(intx value, bool verbose);
+
+Flag::Error CodeEntryAlignmentConstraintFunc(intx value, bool verbose);
+
+Flag::Error OptoLoopAlignmentConstraintFunc(intx value, bool verbose);
+
+Flag::Error ArraycopyDstPrefetchDistanceConstraintFunc(uintx value, bool verbose);
+
+Flag::Error ArraycopySrcPrefetchDistanceConstraintFunc(uintx value, bool verbose);
+
+Flag::Error TypeProfileLevelConstraintFunc(uintx value, bool verbose);
+
+#ifdef COMPILER2
+Flag::Error InteriorEntryAlignmentConstraintFunc(intx value, bool verbose);
+
+Flag::Error NodeLimitFudgeFactorConstraintFunc(intx value, bool verbose);
+#endif
+
 #endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSCOMPILER_HPP */
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -23,16 +23,19 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/collectorPolicy.hpp"
+#include "gc/shared/threadLocalAllocBuffer.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/commandLineFlagConstraintsGC.hpp"
 #include "runtime/commandLineFlagRangeList.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "utilities/defaultStream.hpp"
 
 #if INCLUDE_ALL_GCS
 #include "gc/g1/g1_globals.hpp"
 #include "gc/g1/heapRegionBounds.inline.hpp"
-#include "gc/parallel/parallelScavengeHeap.hpp"
 #include "gc/shared/plab.hpp"
 #endif // INCLUDE_ALL_GCS
 #ifdef COMPILER1
@@ -42,6 +45,71 @@
 #include "opto/c2_globals.hpp"
 #endif // COMPILER2
 
+// Some flags that have default values that indicate that the
+// JVM should automatically determine an appropriate value
+// for that flag.  In those cases it is only appropriate for the
+// constraint checking to be done if the user has specified the
+// value(s) of the flag(s) on the command line.  In the constraint
+// checking functions,  FLAG_IS_CMDLINE() is used to check if
+// the flag has been set by the user and so should be checked.
+
+#if INCLUDE_ALL_GCS
+static Flag::Error ParallelGCThreadsAndCMSWorkQueueDrainThreshold(uint threads, uintx threshold, bool verbose) {
+  // CMSWorkQueueDrainThreshold is verified to be less than max_juint
+  if (UseConcMarkSweepGC && (threads > (uint)(max_jint / (uint)threshold))) {
+    CommandLineError::print(verbose,
+                            "ParallelGCThreads (" UINT32_FORMAT ") or CMSWorkQueueDrainThreshold ("
+                            UINTX_FORMAT ") is too large\n",
+                            threads, threshold);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  return Flag::SUCCESS;
+}
+#endif
+
+// As ParallelGCThreads differs among GC modes, we need constraint function.
+Flag::Error ParallelGCThreadsConstraintFunc(uint value, bool verbose) {
+  Flag::Error status = Flag::SUCCESS;
+
+#if INCLUDE_ALL_GCS
+  // Parallel GC passes ParallelGCThreads when creating GrowableArray as 'int' type parameter.
+  // So can't exceed with "max_jint"
+  if (UseParallelGC && (value > (uint)max_jint)) {
+    CommandLineError::print(verbose,
+                            "ParallelGCThreads (" UINT32_FORMAT ") must be "
+                            "less than or equal to " UINT32_FORMAT " for Parallel GC\n",
+                            value, max_jint);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  // To avoid overflow at ParScanClosure::do_oop_work.
+  if (UseConcMarkSweepGC && (value > (max_jint / 10))) {
+    CommandLineError::print(verbose,
+                            "ParallelGCThreads (" UINT32_FORMAT ") must be "
+                            "less than or equal to " UINT32_FORMAT " for CMS GC\n",
+                            value, (max_jint / 10));
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  status = ParallelGCThreadsAndCMSWorkQueueDrainThreshold(value, CMSWorkQueueDrainThreshold, verbose);
+#endif
+  return status;
+}
+
+// As ConcGCThreads should be smaller than ParallelGCThreads,
+// we need constraint function.
+Flag::Error ConcGCThreadsConstraintFunc(uint value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  // CMS and G1 GCs use ConcGCThreads.
+  if ((UseConcMarkSweepGC || UseG1GC) && (value > ParallelGCThreads)) {
+    CommandLineError::print(verbose,
+                            "ConcGCThreads (" UINT32_FORMAT ") must be "
+                            "less than or equal to ParallelGCThreads (" UINT32_FORMAT ")\n",
+                            value, ParallelGCThreads);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+  return Flag::SUCCESS;
+}
+
 static Flag::Error MinPLABSizeBounds(const char* name, size_t value, bool verbose) {
 #if INCLUDE_ALL_GCS
   if ((UseConcMarkSweepGC || UseG1GC) && (value < PLAB::min_size())) {
@@ -69,16 +137,40 @@
 }
 
 static Flag::Error MinMaxPLABSizeBounds(const char* name, size_t value, bool verbose) {
-  if (MinPLABSizeBounds(name, value, verbose) == Flag::SUCCESS) {
+  Flag::Error status = MinPLABSizeBounds(name, value, verbose);
+
+  if (status == Flag::SUCCESS) {
     return MaxPLABSizeBounds(name, value, verbose);
   }
-  return Flag::VIOLATES_CONSTRAINT;
+  return status;
 }
 
 Flag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose) {
   return MinMaxPLABSizeBounds("YoungPLABSize", value, verbose);
 }
 
+Flag::Error OldPLABSizeConstraintFunc(size_t value, bool verbose) {
+  Flag::Error status = Flag::SUCCESS;
+
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC) {
+    if (value == 0) {
+      CommandLineError::print(verbose,
+                              "OldPLABSize (" SIZE_FORMAT ") must be greater than 0",
+                              value);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+    // For CMS, OldPLABSize is the number of free blocks of a given size that are used when
+    // replenishing the local per-worker free list caches.
+    // For more details, please refer to Arguments::set_cms_and_parnew_gc_flags().
+    status = MaxPLABSizeBounds("OldPLABSize", value, verbose);
+  } else {
+    status = MinMaxPLABSizeBounds("OldPLABSize", value, verbose);
+  }
+#endif
+  return status;
+}
+
 Flag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose) {
   if (value > MaxHeapFreeRatio) {
     CommandLineError::print(verbose,
@@ -103,6 +195,23 @@
   }
 }
 
+static Flag::Error CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(size_t maxHeap, intx softRef, bool verbose) {
+  if ((softRef > 0) && ((maxHeap / M) > (max_uintx / softRef))) {
+    CommandLineError::print(verbose,
+                            "Desired lifetime of SoftReferences cannot be expressed correctly. "
+                            "MaxHeapSize (" SIZE_FORMAT ") or SoftRefLRUPolicyMSPerMB "
+                            "(" INTX_FORMAT ") is too large\n",
+                            maxHeap, softRef);
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error SoftRefLRUPolicyMSPerMBConstraintFunc(intx value, bool verbose) {
+  return CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(MaxHeapSize, value, verbose);
+}
+
 Flag::Error MinMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose) {
   if (value > MaxMetaspaceFreeRatio) {
     CommandLineError::print(verbose,
@@ -127,45 +236,111 @@
   }
 }
 
-// GC workaround for "-XX:+UseConcMarkSweepGC"
-// which sets InitialTenuringThreshold to 7 but leaves MaxTenuringThreshold remaining at 6
-// and therefore would invalidate the constraint
-#define UseConcMarkSweepGCWorkaroundIfNeeded(initial, max) { \
-  if ((initial == 7) && (max == 6)) { \
-    return Flag::SUCCESS; \
-  } \
+Flag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  // InitialTenuringThreshold is only used for ParallelGC.
+  if (UseParallelGC && (value > MaxTenuringThreshold)) {
+      CommandLineError::print(verbose,
+                              "InitialTenuringThreshold (" UINTX_FORMAT ") must be "
+                              "less than or equal to MaxTenuringThreshold (" UINTX_FORMAT ")\n",
+                              value, MaxTenuringThreshold);
+      return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+  return Flag::SUCCESS;
 }
 
-Flag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose) {
-  UseConcMarkSweepGCWorkaroundIfNeeded(value, MaxTenuringThreshold);
+Flag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  // As only ParallelGC uses InitialTenuringThreshold,
+  // we don't need to compare InitialTenuringThreshold with MaxTenuringThreshold.
+  if (UseParallelGC && (value < InitialTenuringThreshold)) {
+    CommandLineError::print(verbose,
+                            "MaxTenuringThreshold (" UINTX_FORMAT ") must be "
+                            "greater than or equal to InitialTenuringThreshold (" UINTX_FORMAT ")\n",
+                            value, InitialTenuringThreshold);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
 
-  if (value > MaxTenuringThreshold) {
+  // MaxTenuringThreshold=0 means NeverTenure=false && AlwaysTenure=true
+  if ((value == 0) && (NeverTenure || !AlwaysTenure)) {
     CommandLineError::print(verbose,
-                            "InitialTenuringThreshold (" UINTX_FORMAT ") must be "
-                            "less than or equal to MaxTenuringThreshold (" UINTX_FORMAT ")\n",
-                            value, MaxTenuringThreshold);
+                            "MaxTenuringThreshold (0) should match to NeverTenure=false "
+                            "&& AlwaysTenure=true. But we have NeverTenure=%s "
+                            "AlwaysTenure=%s\n",
+                            NeverTenure ? "true" : "false",
+                            AlwaysTenure ? "true" : "false");
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  return Flag::SUCCESS;
+}
+
+#if INCLUDE_ALL_GCS
+Flag::Error G1RSetRegionEntriesConstraintFunc(intx value, bool verbose) {
+  if (!UseG1GC) return Flag::SUCCESS;
+
+  // Default value of G1RSetRegionEntries=0 means will be set ergonomically.
+  // Minimum value is 1.
+  if (FLAG_IS_CMDLINE(G1RSetRegionEntries) && (value < 1)) {
+    CommandLineError::print(verbose,
+                            "G1RSetRegionEntries (" INTX_FORMAT ") must be "
+                            "greater than or equal to 1\n",
+                            value);
     return Flag::VIOLATES_CONSTRAINT;
   } else {
     return Flag::SUCCESS;
   }
 }
 
-Flag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose) {
-  UseConcMarkSweepGCWorkaroundIfNeeded(InitialTenuringThreshold, value);
+Flag::Error G1RSetSparseRegionEntriesConstraintFunc(intx value, bool verbose) {
+  if (!UseG1GC) return Flag::SUCCESS;
 
-  if (value < InitialTenuringThreshold) {
+  // Default value of G1RSetSparseRegionEntries=0 means will be set ergonomically.
+  // Minimum value is 1.
+  if (FLAG_IS_CMDLINE(G1RSetSparseRegionEntries) && (value < 1)) {
     CommandLineError::print(verbose,
-                            "MaxTenuringThreshold (" UINTX_FORMAT ") must be "
-                            "greater than or equal to InitialTenuringThreshold (" UINTX_FORMAT ")\n",
-                            value, InitialTenuringThreshold);
+                            "G1RSetSparseRegionEntries (" INTX_FORMAT ") must be "
+                            "greater than or equal to 1\n",
+                            value);
     return Flag::VIOLATES_CONSTRAINT;
   } else {
     return Flag::SUCCESS;
   }
 }
 
-#if INCLUDE_ALL_GCS
+Flag::Error G1YoungSurvRateNumRegionsSummaryConstraintFunc(intx value, bool verbose) {
+  if (!UseG1GC) return Flag::SUCCESS;
+
+  if (value > (intx)HeapRegionBounds::target_number()) {
+    CommandLineError::print(verbose,
+                            "G1YoungSurvRateNumRegionsSummary (" INTX_FORMAT ") must be "
+                            "less than or equal to region count (" SIZE_FORMAT ")\n",
+                            value, HeapRegionBounds::target_number());
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error G1HeapRegionSizeConstraintFunc(size_t value, bool verbose) {
+  if (!UseG1GC) return Flag::SUCCESS;
+
+  // Default value of G1HeapRegionSize=0 means will be set ergonomically.
+  if (FLAG_IS_CMDLINE(G1HeapRegionSize) && (value < HeapRegionBounds::min_size())) {
+    CommandLineError::print(verbose,
+                            "G1HeapRegionSize (" SIZE_FORMAT ") must be "
+                            "greater than or equal to ergonomic heap region minimum size\n",
+                            value);
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
 Flag::Error G1NewSizePercentConstraintFunc(uintx value, bool verbose) {
+  if (!UseG1GC) return Flag::SUCCESS;
+
   if (value > G1MaxNewSizePercent) {
     CommandLineError::print(verbose,
                             "G1NewSizePercent (" UINTX_FORMAT ") must be "
@@ -178,6 +353,8 @@
 }
 
 Flag::Error G1MaxNewSizePercentConstraintFunc(uintx value, bool verbose) {
+  if (!UseG1GC) return Flag::SUCCESS;
+
   if (value < G1NewSizePercent) {
     CommandLineError::print(verbose,
                             "G1MaxNewSizePercent (" UINTX_FORMAT ") must be "
@@ -188,15 +365,56 @@
     return Flag::SUCCESS;
   }
 }
+#endif // INCLUDE_ALL_GCS
 
-#endif // INCLUDE_ALL_GCS
+Flag::Error ParGCStridesPerThreadConstraintFunc(uintx value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC && (value > ((uintx)max_jint / (uintx)ParallelGCThreads))) {
+    CommandLineError::print(verbose,
+                            "ParGCStridesPerThread (" UINTX_FORMAT ") must be "
+                            "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n",
+                            value, ((uintx)max_jint / (uintx)ParallelGCThreads));
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+  return Flag::SUCCESS;
+}
 
 Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose) {
-  if (value > CMSOldPLABMax) {
+  Flag::Error status = Flag::SUCCESS;
+
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC) {
+    if (value > CMSOldPLABMax) {
+      CommandLineError::print(verbose,
+                              "CMSOldPLABMin (" SIZE_FORMAT ") must be "
+                              "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
+                              value, CMSOldPLABMax);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+    status = MaxPLABSizeBounds("CMSOldPLABMin", value, verbose);
+  }
+#endif
+  return status;
+}
+
+Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose) {
+  Flag::Error status = Flag::SUCCESS;
+
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC) {
+    status = MaxPLABSizeBounds("CMSOldPLABMax", value, verbose);
+  }
+#endif
+  return status;
+}
+
+Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose) {
+  if (value > MarkStackSizeMax) {
     CommandLineError::print(verbose,
-                            "CMSOldPLABMin (" SIZE_FORMAT ") must be "
-                            "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
-                            value, CMSOldPLABMax);
+                            "MarkStackSize (" SIZE_FORMAT ") must be "
+                            "less than or equal to MarkStackSizeMax (" SIZE_FORMAT ")\n",
+                            value, MarkStackSizeMax);
     return Flag::VIOLATES_CONSTRAINT;
   } else {
     return Flag::SUCCESS;
@@ -204,23 +422,212 @@
 }
 
 Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) {
-  if (value <= CMSPrecleanNumerator) {
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) {
     CommandLineError::print(verbose,
                             "CMSPrecleanDenominator (" UINTX_FORMAT ") must be "
                             "strickly greater than CMSPrecleanNumerator (" UINTX_FORMAT ")\n",
                             value, CMSPrecleanNumerator);
     return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+  return Flag::SUCCESS;
+}
+
+Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC && (value >= CMSPrecleanDenominator)) {
+    CommandLineError::print(verbose,
+                            "CMSPrecleanNumerator (" UINTX_FORMAT ") must be "
+                            "less than CMSPrecleanDenominator (" UINTX_FORMAT ")\n",
+                            value, CMSPrecleanDenominator);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+  return Flag::SUCCESS;
+}
+
+Flag::Error CMSWorkQueueDrainThresholdConstraintFunc(uintx value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC) {
+    return ParallelGCThreadsAndCMSWorkQueueDrainThreshold(ParallelGCThreads, value, verbose);
+  }
+#endif
+  return Flag::SUCCESS;
+}
+
+Flag::Error MaxGCPauseMillisConstraintFunc(uintx value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  if (UseG1GC && FLAG_IS_CMDLINE(MaxGCPauseMillis) && (value >= GCPauseIntervalMillis)) {
+    CommandLineError::print(verbose,
+                            "MaxGCPauseMillis (" UINTX_FORMAT ") must be "
+                            "less than GCPauseIntervalMillis (" UINTX_FORMAT ")\n",
+                            value, GCPauseIntervalMillis);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error GCPauseIntervalMillisConstraintFunc(uintx value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  if (UseG1GC) {
+    if (FLAG_IS_CMDLINE(GCPauseIntervalMillis)) {
+      if (value < 1) {
+        CommandLineError::print(verbose,
+                                "GCPauseIntervalMillis (" UINTX_FORMAT ") must be "
+                                "greater than or equal to 1\n",
+                                value);
+        return Flag::VIOLATES_CONSTRAINT;
+      }
+      if (value <= MaxGCPauseMillis) {
+        CommandLineError::print(verbose,
+                                "GCPauseIntervalMillis (" UINTX_FORMAT ") must be "
+                                "greater than MaxGCPauseMillis (" UINTX_FORMAT ")\n",
+                                value, MaxGCPauseMillis);
+        return Flag::VIOLATES_CONSTRAINT;
+      }
+    }
+  }
+#endif
+  return Flag::SUCCESS;
+}
+
+Flag::Error InitialBootClassLoaderMetaspaceSizeConstraintFunc(size_t value, bool verbose) {
+  size_t aligned_max = (size_t)align_size_down(max_uintx/2, Metaspace::reserve_alignment_words());
+  if (value > aligned_max) {
+    CommandLineError::print(verbose,
+                            "InitialBootClassLoaderMetaspaceSize (" SIZE_FORMAT ") must be "
+                            "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n",
+                            value, aligned_max);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  return Flag::SUCCESS;
+}
+
+static Flag::Error MaxSizeForHeapAlignment(const char* name, size_t value, bool verbose) {
+  // For G1 GC, we don't know until G1CollectorPolicy is created.
+  size_t heap_alignment;
+
+#if INCLUDE_ALL_GCS
+  if (UseG1GC) {
+    heap_alignment = HeapRegionBounds::max_size();
+  } else
+#endif
+  {
+    heap_alignment = CollectorPolicy::compute_heap_alignment();
+  }
+
+  // Not to overflow 'align_size_up(value, _heap_alignment) used from CollectorPolicy::initialize_flags()'.
+  size_t aligned_max = ((max_uintx - heap_alignment) & ~(heap_alignment-1));
+  if (value > aligned_max) {
+    CommandLineError::print(verbose,
+                            "%s (" SIZE_FORMAT ") must be "
+                            "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n",
+                            name, value, aligned_max);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  return Flag::SUCCESS;
+}
+
+Flag::Error InitialHeapSizeConstraintFunc(size_t value, bool verbose) {
+  return MaxSizeForHeapAlignment("InitialHeapSize", value, verbose);
+}
+
+Flag::Error MaxHeapSizeConstraintFunc(size_t value, bool verbose) {
+  Flag::Error status = MaxSizeForHeapAlignment("MaxHeapSize", value, verbose);
+
+  if (status == Flag::SUCCESS) {
+    status = CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(value, SoftRefLRUPolicyMSPerMB, verbose);
+  }
+  return status;
+}
+
+Flag::Error NewSizeConstraintFunc(size_t value, bool verbose) {
+#ifdef _LP64
+#if INCLUDE_ALL_GCS
+  // Overflow would happen for uint type variable of YoungGenSizer::_min_desired_young_length
+  // when the value to be assigned exceeds uint range.
+  // i.e. result of '(uint)(NewSize / region size(1~32MB))'
+  // So maximum of NewSize should be 'max_juint * 1M'
+  if (UseG1GC && (value > (max_juint * 1 * M))) {
+    CommandLineError::print(verbose,
+                            "NewSize (" SIZE_FORMAT ") must be less than ergonomic maximum value\n",
+                            value);
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+#endif // INCLUDE_ALL_GCS
+#endif // _LP64
+  return Flag::SUCCESS;
+}
+
+Flag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose) {
+  // At least, alignment reserve area is needed.
+  if (value < ThreadLocalAllocBuffer::alignment_reserve_in_bytes()) {
+    CommandLineError::print(verbose,
+                            "MinTLABSize (" SIZE_FORMAT ") must be "
+                            "greater than or equal to reserved area in TLAB (" SIZE_FORMAT ")\n",
+                            value, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
+    return Flag::VIOLATES_CONSTRAINT;
   } else {
     return Flag::SUCCESS;
   }
 }
 
-Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose) {
-  if (value > (CMSPrecleanDenominator - 1)) {
+Flag::Error TLABSizeConstraintFunc(size_t value, bool verbose) {
+  // Skip for default value of zero which means set ergonomically.
+  if (FLAG_IS_CMDLINE(TLABSize)) {
+    if (value < MinTLABSize) {
+      CommandLineError::print(verbose,
+                              "TLABSize (" SIZE_FORMAT ") must be "
+                              "greater than or equal to MinTLABSize (" SIZE_FORMAT ")\n",
+                              value, MinTLABSize);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+    if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) {
+      CommandLineError::print(verbose,
+                              "TLABSize (" SIZE_FORMAT ") must be "
+                              "less than or equal to ergonomic TLAB maximum size (" SIZE_FORMAT ")\n",
+                              value, (ThreadLocalAllocBuffer::max_size() * HeapWordSize));
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+  }
+  return Flag::SUCCESS;
+}
+
+Flag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose) {
+  if (FLAG_IS_CMDLINE(SurvivorRatio) &&
+      (value > (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment()))) {
     CommandLineError::print(verbose,
-                            "CMSPrecleanNumerator (" UINTX_FORMAT ") must be "
-                            "less than or equal to CMSPrecleanDenominator - 1 (" UINTX_FORMAT ")\n",
-                            value, CMSPrecleanDenominator - 1);
+                            "SurvivorRatio (" UINTX_FORMAT ") must be "
+                            "less than or equal to ergonomic SurvivorRatio maximum (" SIZE_FORMAT ")\n",
+                            value,
+                            (MaxHeapSize / Universe::heap()->collector_policy()->space_alignment()));
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose) {
+  if (value > MaxMetaspaceSize) {
+    CommandLineError::print(verbose,
+                            "MetaspaceSize (" SIZE_FORMAT ") must be "
+                            "less than or equal to MaxMetaspaceSize (" SIZE_FORMAT ")\n",
+                            value, MaxMetaspaceSize);
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose) {
+  if (value < MetaspaceSize) {
+    CommandLineError::print(verbose,
+                            "MaxMetaspaceSize (" SIZE_FORMAT ") must be "
+                            "greater than or equal to MetaspaceSize (" SIZE_FORMAT ")\n",
+                            value, MaxMetaspaceSize);
     return Flag::VIOLATES_CONSTRAINT;
   } else {
     return Flag::SUCCESS;
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -34,27 +34,45 @@
  * an appropriate error value.
  */
 
+Flag::Error ParallelGCThreadsConstraintFunc(uint value, bool verbose);
+Flag::Error ConcGCThreadsConstraintFunc(uint value, bool verbose);
 Flag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose);
-
+Flag::Error OldPLABSizeConstraintFunc(size_t value, bool verbose);
 Flag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose);
 Flag::Error MaxHeapFreeRatioConstraintFunc(uintx value, bool verbose);
-
+Flag::Error SoftRefLRUPolicyMSPerMBConstraintFunc(intx value, bool verbose);
 Flag::Error MinMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose);
 Flag::Error MaxMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose);
-
 Flag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose);
 Flag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose);
 
 #if INCLUDE_ALL_GCS
+Flag::Error G1RSetRegionEntriesConstraintFunc(intx value, bool verbose);
+Flag::Error G1RSetSparseRegionEntriesConstraintFunc(intx value, bool verbose);
+Flag::Error G1YoungSurvRateNumRegionsSummaryConstraintFunc(intx value, bool verbose);
+Flag::Error G1HeapRegionSizeConstraintFunc(size_t value, bool verbose);
 Flag::Error G1NewSizePercentConstraintFunc(uintx value, bool verbose);
 Flag::Error G1MaxNewSizePercentConstraintFunc(uintx value, bool verbose);
 #endif // INCLUDE_ALL_GCS
 
+Flag::Error ParGCStridesPerThreadConstraintFunc(uintx value, bool verbose);
 Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose);
-
+Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose);
+Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose);
 Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose);
 Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose);
-
+Flag::Error CMSWorkQueueDrainThresholdConstraintFunc(uintx value, bool verbose);
+Flag::Error MaxGCPauseMillisConstraintFunc(uintx value, bool verbose);
+Flag::Error GCPauseIntervalMillisConstraintFunc(uintx value, bool verbose);
+Flag::Error InitialBootClassLoaderMetaspaceSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error InitialHeapSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error MaxHeapSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error NewSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error TLABSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose);
+Flag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose);
 Flag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose);
 
 #endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSGC_HPP */
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -278,7 +278,7 @@
 // Generate func argument to pass into emit_range_xxx functions
 #define EMIT_RANGE_CHECK(a, b)                               , a, b
 
-#define INITIAL_RANGES_SIZE 128
+#define INITIAL_RANGES_SIZE 165
 GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
 
 // Check the ranges of all flags that have them
@@ -309,6 +309,18 @@
                                 EMIT_RANGE_CHECK,
                                 IGNORE_CONSTRAINT));
 
+#if INCLUDE_JVMCI
+  emit_range_no(NULL JVMCI_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
+                                 EMIT_RANGE_PD_DEVELOPER_FLAG,
+                                 EMIT_RANGE_PRODUCT_FLAG,
+                                 EMIT_RANGE_PD_PRODUCT_FLAG,
+                                 EMIT_RANGE_DIAGNOSTIC_FLAG,
+                                 EMIT_RANGE_EXPERIMENTAL_FLAG,
+                                 EMIT_RANGE_NOTPRODUCT_FLAG,
+                                 EMIT_RANGE_CHECK,
+                                 IGNORE_CONSTRAINT));
+#endif // INCLUDE_JVMCI
+
 #ifdef COMPILER1
   emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
                               EMIT_RANGE_PD_DEVELOPER_FLAG,
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,6 +37,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/fieldStreams.hpp"
 #include "oops/verifyOopClosure.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/biasedLocking.hpp"
@@ -53,7 +54,11 @@
 #include "utilities/events.hpp"
 #include "utilities/xmlstream.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#endif
+
 
 bool DeoptimizationMarker::_is_active = false;
 
@@ -112,7 +117,7 @@
   tty->print_cr("  size_of_deoptimized_frame = %d", _size_of_deoptimized_frame);
   tty->print(   "  frame_sizes: ");
   for (int index = 0; index < number_of_frames(); index++) {
-    tty->print("%d ", frame_sizes()[index]);
+    tty->print(INTX_FORMAT " ", frame_sizes()[index]);
   }
   tty->cr();
 }
@@ -132,6 +137,9 @@
   // handler. Note this fact before we start generating temporary frames
   // that can confuse an asynchronous stack walker. This counter is
   // decremented at the end of unpack_frames().
+  if (TraceDeoptimization) {
+    tty->print_cr("Deoptimizing thread " INTPTR_FORMAT, p2i(thread));
+  }
   thread->inc_in_deopt_handler();
 
   return fetch_unroll_info_helper(thread);
@@ -159,6 +167,7 @@
   // Set the deoptee nmethod
   assert(thread->deopt_nmethod() == NULL, "Pending deopt!");
   thread->set_deopt_nmethod(deoptee.cb()->as_nmethod_or_null());
+  bool skip_internal = thread->deopt_nmethod() != NULL && !thread->deopt_nmethod()->compiler()->is_jvmci();
 
   if (VerifyStack) {
     thread->validate_frame_layout();
@@ -179,11 +188,13 @@
 
   bool realloc_failures = false;
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   // Reallocate the non-escaping objects and restore their fields. Then
   // relock objects if synchronization on them was eliminated.
+#ifndef INCLUDE_JVMCI
   if (DoEscapeAnalysis || EliminateNestedLocks) {
     if (EliminateAllocations) {
+#endif // INCLUDE_JVMCI
       assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
       GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
 
@@ -206,18 +217,18 @@
         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
         if (TraceDeoptimization) {
           ttyLocker ttyl;
-          tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, (void *)result, thread);
+          tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
         }
       }
       if (objects != NULL) {
         JRT_BLOCK
           realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD);
         JRT_END
-        reassign_fields(&deoptee, &map, objects, realloc_failures);
+        reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal);
 #ifndef PRODUCT
         if (TraceDeoptimization) {
           ttyLocker ttyl;
-          tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread);
+          tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
           print_objects(objects, realloc_failures);
         }
 #endif
@@ -226,8 +237,10 @@
         // Restore result.
         deoptee.set_saved_oop_result(&map, return_value());
       }
+#ifndef INCLUDE_JVMCI
     }
     if (EliminateLocks) {
+#endif // INCLUDE_JVMCI
 #ifndef PRODUCT
       bool first = true;
 #endif
@@ -238,37 +251,40 @@
         if (monitors->is_nonempty()) {
           relock_objects(monitors, thread, realloc_failures);
 #ifndef PRODUCT
-          if (TraceDeoptimization) {
+          if (PrintDeoptimizationDetails) {
             ttyLocker ttyl;
             for (int j = 0; j < monitors->length(); j++) {
               MonitorInfo* mi = monitors->at(j);
               if (mi->eliminated()) {
                 if (first) {
                   first = false;
-                  tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread);
+                  tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
                 }
                 if (mi->owner_is_scalar_replaced()) {
                   Klass* k = java_lang_Class::as_Klass(mi->owner_klass());
                   tty->print_cr("     failed reallocation for klass %s", k->external_name());
                 } else {
-                  tty->print_cr("     object <" INTPTR_FORMAT "> locked", (void *)mi->owner());
+                  tty->print_cr("     object <" INTPTR_FORMAT "> locked", p2i(mi->owner()));
                 }
               }
             }
           }
-#endif
+#endif // !PRODUCT
         }
       }
+#ifndef INCLUDE_JVMCI
     }
   }
-#endif // COMPILER2
+#endif // INCLUDE_JVMCI
+#endif // COMPILER2 || INCLUDE_JVMCI
+
   // Ensure that no safepoint is taken after pointers have been stored
   // in fields of rematerialized objects.  If a safepoint occurs from here on
   // out the java state residing in the vframeArray will be missed.
   No_Safepoint_Verifier no_safepoint;
 
   vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures);
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   if (realloc_failures) {
     pop_frames_failed_reallocs(thread, array);
   }
@@ -318,7 +334,11 @@
     unpack_sp = deoptee.unextended_sp();
 
 #ifdef ASSERT
-  assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking");
+  assert(cb->is_deoptimization_stub() ||
+         cb->is_uncommon_trap_stub() ||
+         strcmp("Stub<DeoptimizationStub.deoptimizationHandler>", cb->name()) == 0 ||
+         strcmp("Stub<UncommonTrapStub.uncommonTrapHandler>", cb->name()) == 0,
+         "unexpected code blob: %s", cb->name());
 #endif
 #else
   intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp();
@@ -550,11 +570,12 @@
 #ifndef PRODUCT
   if (TraceDeoptimization) {
     ttyLocker ttyl;
-    tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode);
+    tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d",
+                  p2i(thread), p2i(array), exec_mode);
   }
 #endif
   Events::log(thread, "DEOPT UNPACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT " mode %d",
-              stub_frame.pc(), stub_frame.sp(), exec_mode);
+              p2i(stub_frame.pc()), p2i(stub_frame.sp()), exec_mode);
 
   UnrollBlock* info = array->unroll_block();
 
@@ -690,7 +711,7 @@
         tty->print_cr("  top_frame_expression_stack_adjustment = %d", top_frame_expression_stack_adjustment);
         tty->print_cr("  exec_mode = %d", exec_mode);
         tty->print_cr("  cur_invoke_parameter_size = %d", cur_invoke_parameter_size);
-        tty->print_cr("  Thread = " INTPTR_FORMAT ", thread ID = " UINTX_FORMAT, thread, thread->osthread()->thread_id());
+        tty->print_cr("  Thread = " INTPTR_FORMAT ", thread ID = %d", p2i(thread), thread->osthread()->thread_id());
         tty->print_cr("  Interpreted frames:");
         for (int k = 0; k < cur_array->frames(); k++) {
           vframeArrayElement* el = cur_array->element(k);
@@ -721,7 +742,7 @@
 Deoptimization::DeoptAction Deoptimization::_unloaded_action
   = Deoptimization::Action_reinterpret;
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
   Handle pending_exception(thread->pending_exception());
   const char* exception_file = thread->exception_file();
@@ -769,77 +790,6 @@
   return failures;
 }
 
-// This assumes that the fields are stored in ObjectValue in the same order
-// they are yielded by do_nonstatic_fields.
-class FieldReassigner: public FieldClosure {
-  frame* _fr;
-  RegisterMap* _reg_map;
-  ObjectValue* _sv;
-  InstanceKlass* _ik;
-  oop _obj;
-
-  int _i;
-public:
-  FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) :
-    _fr(fr), _reg_map(reg_map), _sv(sv), _obj(obj), _i(0) {}
-
-  int i() const { return _i; }
-
-
-  void do_field(fieldDescriptor* fd) {
-    intptr_t val;
-    StackValue* value =
-      StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i()));
-    int offset = fd->offset();
-    switch (fd->field_type()) {
-    case T_OBJECT: case T_ARRAY:
-      assert(value->type() == T_OBJECT, "Agreement.");
-      _obj->obj_field_put(offset, value->get_obj()());
-      break;
-
-    case T_LONG: case T_DOUBLE: {
-      assert(value->type() == T_INT, "Agreement.");
-      StackValue* low =
-        StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i));
-#ifdef _LP64
-      jlong res = (jlong)low->get_int();
-#else
-#ifdef SPARC
-      // For SPARC we have to swap high and low words.
-      jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());
-#else
-      jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
-#endif //SPARC
-#endif
-      _obj->long_field_put(offset, res);
-      break;
-    }
-    // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
-    case T_INT: case T_FLOAT: // 4 bytes.
-      assert(value->type() == T_INT, "Agreement.");
-      val = value->get_int();
-      _obj->int_field_put(offset, (jint)*((jint*)&val));
-      break;
-
-    case T_SHORT: case T_CHAR: // 2 bytes
-      assert(value->type() == T_INT, "Agreement.");
-      val = value->get_int();
-      _obj->short_field_put(offset, (jshort)*((jint*)&val));
-      break;
-
-    case T_BOOLEAN: case T_BYTE: // 1 byte
-      assert(value->type() == T_INT, "Agreement.");
-      val = value->get_int();
-      _obj->bool_field_put(offset, (jboolean)*((jint*)&val));
-      break;
-
-    default:
-      ShouldNotReachHere();
-    }
-    _i++;
-  }
-};
-
 // restore elements of an eliminated type array
 void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) {
   int index = 0;
@@ -867,11 +817,43 @@
     }
 
     // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
-    case T_INT: case T_FLOAT: // 4 bytes.
+    case T_INT: case T_FLOAT: { // 4 bytes.
       assert(value->type() == T_INT, "Agreement.");
-      val = value->get_int();
-      obj->int_at_put(index, (jint)*((jint*)&val));
+      bool big_value = false;
+      if (i + 1 < sv->field_size() && type == T_INT) {
+        if (sv->field_at(i)->is_location()) {
+          Location::Type type = ((LocationValue*) sv->field_at(i))->location().type();
+          if (type == Location::dbl || type == Location::lng) {
+            big_value = true;
+          }
+        } else if (sv->field_at(i)->is_constant_int()) {
+          ScopeValue* next_scope_field = sv->field_at(i + 1);
+          if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) {
+            big_value = true;
+          }
+        }
+      }
+
+      if (big_value) {
+        StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++i));
+  #ifdef _LP64
+        jlong res = (jlong)low->get_int();
+  #else
+  #ifdef SPARC
+        // For SPARC we have to swap high and low words.
+        jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());
+  #else
+        jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
+  #endif //SPARC
+  #endif
+        obj->int_at_put(index, (jint)*((jint*)&res));
+        obj->int_at_put(++index, (jint)*(((jint*)&res) + 1));
+      } else {
+        val = value->get_int();
+        obj->int_at_put(index, (jint)*((jint*)&val));
+      }
       break;
+    }
 
     case T_SHORT: case T_CHAR: // 2 bytes
       assert(value->type() == T_INT, "Agreement.");
@@ -902,22 +884,135 @@
   }
 }
 
+class ReassignedField {
+public:
+  int _offset;
+  BasicType _type;
+public:
+  ReassignedField() {
+    _offset = 0;
+    _type = T_ILLEGAL;
+  }
+};
+
+int compare(ReassignedField* left, ReassignedField* right) {
+  return left->_offset - right->_offset;
+}
+
+// Restore fields of an eliminated instance object using the same field order
+// returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true)
+static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj, bool skip_internal) {
+  if (klass->superklass() != NULL) {
+    svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj, skip_internal);
+  }
+
+  GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>();
+  for (AllFieldStream fs(klass); !fs.done(); fs.next()) {
+    if (!fs.access_flags().is_static() && (!skip_internal || !fs.access_flags().is_internal())) {
+      ReassignedField field;
+      field._offset = fs.offset();
+      field._type = FieldType::basic_type(fs.signature());
+      fields->append(field);
+    }
+  }
+  fields->sort(compare);
+  for (int i = 0; i < fields->length(); i++) {
+    intptr_t val;
+    ScopeValue* scope_field = sv->field_at(svIndex);
+    StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field);
+    int offset = fields->at(i)._offset;
+    BasicType type = fields->at(i)._type;
+    switch (type) {
+      case T_OBJECT: case T_ARRAY:
+        assert(value->type() == T_OBJECT, "Agreement.");
+        obj->obj_field_put(offset, value->get_obj()());
+        break;
+
+      // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
+      case T_INT: case T_FLOAT: { // 4 bytes.
+        assert(value->type() == T_INT, "Agreement.");
+        bool big_value = false;
+        if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) {
+          if (scope_field->is_location()) {
+            Location::Type type = ((LocationValue*) scope_field)->location().type();
+            if (type == Location::dbl || type == Location::lng) {
+              big_value = true;
+            }
+          }
+          if (scope_field->is_constant_int()) {
+            ScopeValue* next_scope_field = sv->field_at(svIndex + 1);
+            if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) {
+              big_value = true;
+            }
+          }
+        }
+
+        if (big_value) {
+          i++;
+          assert(i < fields->length(), "second T_INT field needed");
+          assert(fields->at(i)._type == T_INT, "T_INT field needed");
+        } else {
+          val = value->get_int();
+          obj->int_field_put(offset, (jint)*((jint*)&val));
+          break;
+        }
+      }
+        /* no break */
+
+      case T_LONG: case T_DOUBLE: {
+        assert(value->type() == T_INT, "Agreement.");
+        StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++svIndex));
+#ifdef _LP64
+        jlong res = (jlong)low->get_int();
+#else
+#ifdef SPARC
+        // For SPARC we have to swap high and low words.
+        jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());
+#else
+        jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
+#endif //SPARC
+#endif
+        obj->long_field_put(offset, res);
+        break;
+      }
+
+      case T_SHORT: case T_CHAR: // 2 bytes
+        assert(value->type() == T_INT, "Agreement.");
+        val = value->get_int();
+        obj->short_field_put(offset, (jshort)*((jint*)&val));
+        break;
+
+      case T_BOOLEAN: case T_BYTE: // 1 byte
+        assert(value->type() == T_INT, "Agreement.");
+        val = value->get_int();
+        obj->bool_field_put(offset, (jboolean)*((jint*)&val));
+        break;
+
+      default:
+        ShouldNotReachHere();
+    }
+    svIndex++;
+  }
+  return svIndex;
+}
 
 // restore fields of all eliminated objects and arrays
-void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures) {
+void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal) {
   for (int i = 0; i < objects->length(); i++) {
     ObjectValue* sv = (ObjectValue*) objects->at(i);
     KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
     Handle obj = sv->value();
     assert(obj.not_null() || realloc_failures, "reallocation was missed");
+    if (PrintDeoptimizationDetails) {
+      tty->print_cr("reassign fields for object of type %s!", k->name()->as_C_string());
+    }
     if (obj.is_null()) {
       continue;
     }
 
     if (k->oop_is_instance()) {
       InstanceKlass* ik = InstanceKlass::cast(k());
-      FieldReassigner reassign(fr, reg_map, sv, obj());
-      ik->do_nonstatic_fields(&reassign);
+      reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal);
     } else if (k->oop_is_typeArray()) {
       TypeArrayKlass* ak = TypeArrayKlass::cast(k());
       reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());
@@ -966,7 +1061,7 @@
     KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
     Handle obj = sv->value();
 
-    tty->print("     object <" INTPTR_FORMAT "> of type ", (void *)sv->value()());
+    tty->print("     object <" INTPTR_FORMAT "> of type ", p2i(sv->value()()));
     k->print_value();
     assert(obj.not_null() || realloc_failures, "reallocation was missed");
     if (obj.is_null()) {
@@ -982,15 +1077,15 @@
   }
 }
 #endif
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 
 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
-  Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp());
+  Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, p2i(fr.pc()), p2i(fr.sp()));
 
 #ifndef PRODUCT
-  if (TraceDeoptimization) {
+  if (PrintDeoptimizationDetails) {
     ttyLocker ttyl;
-    tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", thread);
+    tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", p2i(thread));
     fr.print_on(tty);
     tty->print_cr("     Virtual frames (innermost first):");
     for (int index = 0; index < chunk->length(); index++) {
@@ -1033,16 +1128,16 @@
   assert(array->structural_compare(thread, chunk), "just checking");
 
 #ifndef PRODUCT
-  if (TraceDeoptimization) {
+  if (PrintDeoptimizationDetails) {
     ttyLocker ttyl;
-    tty->print_cr("     Created vframeArray " INTPTR_FORMAT, array);
+    tty->print_cr("     Created vframeArray " INTPTR_FORMAT, p2i(array));
   }
 #endif // PRODUCT
 
   return array;
 }
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
 void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) {
   // Reallocation of some scalar replaced objects failed. Record
   // that we need to pop all the interpreter frames for the
@@ -1150,17 +1245,38 @@
 }
 
 
-void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr) {
+void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) {
   assert(fr.can_be_deoptimized(), "checking frame type");
 
-  gather_statistics(Reason_constraint, Action_none, Bytecodes::_illegal);
+  gather_statistics(reason, Action_none, Bytecodes::_illegal);
+
+  if (LogCompilation && xtty != NULL) {
+    nmethod* nm = fr.cb()->as_nmethod_or_null();
+    assert(nm != NULL, "only compiled methods can deopt");
 
-  // Patch the nmethod so that when execution returns to it we will
+    ttyLocker ttyl;
+    xtty->begin_head("deoptimized thread='" UINTX_FORMAT "'", (uintx)thread->osthread()->thread_id());
+    nm->log_identity(xtty);
+    xtty->end_head();
+    for (ScopeDesc* sd = nm->scope_desc_at(fr.pc()); ; sd = sd->sender()) {
+      xtty->begin_elem("jvms bci='%d'", sd->bci());
+      xtty->method(sd->method());
+      xtty->end_elem();
+      if (sd->is_top())  break;
+    }
+    xtty->tail("deoptimized");
+  }
+
+  // Patch the compiled method so that when execution returns to it we will
   // deopt the execution state and return to the interpreter.
   fr.deoptimize(thread);
 }
 
 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) {
+  deoptimize(thread, fr, map, Reason_constraint);
+}
+
+void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) {
   // Deoptimize only if the frame comes from compile code.
   // Do not deoptimize the frame which is already patched
   // during the execution of the loops below.
@@ -1172,12 +1288,12 @@
   if (UseBiasedLocking) {
     revoke_biases_of_monitors(thread, fr, map);
   }
-  deoptimize_single_frame(thread, fr);
+  deoptimize_single_frame(thread, fr, reason);
 
 }
 
 
-void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id) {
+void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason) {
   assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(),
          "can only deoptimize other thread at a safepoint");
   // Compute frame and register map based on thread and sp.
@@ -1186,19 +1302,22 @@
   while (fr.id() != id) {
     fr = fr.sender(&reg_map);
   }
-  deoptimize(thread, fr, &reg_map);
+  deoptimize(thread, fr, &reg_map, reason);
 }
 
 
-void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) {
+void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason) {
   if (thread == Thread::current()) {
-    Deoptimization::deoptimize_frame_internal(thread, id);
+    Deoptimization::deoptimize_frame_internal(thread, id, reason);
   } else {
-    VM_DeoptimizeFrame deopt(thread, id);
+    VM_DeoptimizeFrame deopt(thread, id, reason);
     VMThread::execute(&deopt);
   }
 }
 
+void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) {
+  deoptimize_frame(thread, id, Reason_constraint);
+}
 
 // JVMTI PopFrame support
 JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address))
@@ -1225,7 +1344,7 @@
   return mdo;
 }
 
-#if defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI
 void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
   // in case of an unresolved klass entry, load the class.
   if (constant_pool->tag_at(index).is_unresolved_klass()) {
@@ -1288,7 +1407,12 @@
   thread->inc_in_deopt_handler();
 
   // We need to update the map if we have biased locking.
+#if INCLUDE_JVMCI
+  // JVMCI might need to get an exception from the stack, which in turn requires the register map to be valid
+  RegisterMap reg_map(thread, true);
+#else
   RegisterMap reg_map(thread, UseBiasedLocking);
+#endif
   frame stub_frame = thread->last_frame();
   frame fr = stub_frame.sender(&reg_map);
   // Make sure the calling nmethod is not getting deoptimized and removed
@@ -1296,8 +1420,8 @@
   nmethodLocker nl(fr.pc());
 
   // Log a message
-  Events::log(thread, "Uncommon trap: trap_request=" PTR32_FORMAT " fr.pc=" INTPTR_FORMAT,
-              trap_request, fr.pc());
+  Events::log(thread, "Uncommon trap: trap_request=" PTR32_FORMAT " fr.pc=" INTPTR_FORMAT " relative=" INTPTR_FORMAT,
+              trap_request, p2i(fr.pc()), fr.pc() - fr.cb()->code_begin());
 
   {
     ResourceMark rm;
@@ -1307,6 +1431,9 @@
 
     DeoptReason reason = trap_request_reason(trap_request);
     DeoptAction action = trap_request_action(trap_request);
+#if INCLUDE_JVMCI
+    int debug_id = trap_request_debug_id(trap_request);
+#endif
     jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1
 
     vframe*  vf  = vframe::new_vframe(&fr, &reg_map, thread);
@@ -1315,10 +1442,71 @@
     nmethod* nm = cvf->code();
 
     ScopeDesc*      trap_scope  = cvf->scope();
+
+    if (TraceDeoptimization) {
+      ttyLocker ttyl;
+      tty->print_cr("  bci=%d pc=" INTPTR_FORMAT ", relative_pc=" INTPTR_FORMAT ", method=%s" JVMCI_ONLY(", debug_id=%d"), trap_scope->bci(), p2i(fr.pc()), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string()
+#if INCLUDE_JVMCI
+          , debug_id
+#endif
+          );
+    }
+
     methodHandle    trap_method = trap_scope->method();
     int             trap_bci    = trap_scope->bci();
+#if INCLUDE_JVMCI
+    oop speculation = thread->pending_failed_speculation();
+    if (nm->is_compiled_by_jvmci()) {
+      if (speculation != NULL) {
+        oop speculation_log = nm->speculation_log();
+        if (speculation_log != NULL) {
+          if (TraceDeoptimization || TraceUncollectedSpeculations) {
+            if (SpeculationLog::lastFailed(speculation_log) != NULL) {
+              tty->print_cr("A speculation that was not collected by the compiler is being overwritten");
+            }
+          }
+          if (TraceDeoptimization) {
+            tty->print_cr("Saving speculation to speculation log");
+          }
+          SpeculationLog::set_lastFailed(speculation_log, speculation);
+        } else {
+          if (TraceDeoptimization) {
+            tty->print_cr("Speculation present but no speculation log");
+          }
+        }
+        thread->set_pending_failed_speculation(NULL);
+      } else {
+        if (TraceDeoptimization) {
+          tty->print_cr("No speculation");
+        }
+      }
+    } else {
+      assert(speculation == NULL, "There should not be a speculation for method compiled by non-JVMCI compilers");
+    }
+
+    if (trap_bci == SynchronizationEntryBCI) {
+      trap_bci = 0;
+      thread->set_pending_monitorenter(true);
+    }
+
+    if (reason == Deoptimization::Reason_transfer_to_interpreter) {
+      thread->set_pending_transfer_to_interpreter(true);
+    }
+#endif
+
     Bytecodes::Code trap_bc     = trap_method->java_code_at(trap_bci);
 
+    if (trap_scope->rethrow_exception()) {
+      if (PrintDeoptimizationDetails) {
+        tty->print_cr("Exception to be rethrown in the interpreter for method %s::%s at bci %d", trap_method->method_holder()->name()->as_C_string(), trap_method->name()->as_C_string(), trap_bci);
+      }
+      GrowableArray<ScopeValue*>* expressions = trap_scope->expressions();
+      guarantee(expressions != NULL, "must have exception to throw");
+      ScopeValue* topOfStack = expressions->top();
+      Handle topOfStackObj = StackValue::create_stack_value(&fr, &reg_map, topOfStack)->get_obj();
+      THREAD->set_pending_exception(topOfStackObj(), NULL, 0);
+    }
+
     // Record this event in the histogram.
     gather_statistics(reason, action, trap_bc);
 
@@ -1326,12 +1514,23 @@
     // Need MDO to record RTM code generation state.
     bool create_if_missing = ProfileTraps || UseCodeAging RTM_OPT_ONLY( || UseRTMLocking );
 
+    methodHandle profiled_method;
+#if INCLUDE_JVMCI
+    if (nm->is_compiled_by_jvmci()) {
+      profiled_method = nm->method();
+    } else {
+      profiled_method = trap_method;
+    }
+#else
+    profiled_method = trap_method;
+#endif
+
     MethodData* trap_mdo =
-      get_method_data(thread, trap_method, create_if_missing);
+      get_method_data(thread, profiled_method, create_if_missing);
 
     // Log a message
     Events::log_deopt_message(thread, "Uncommon trap: reason=%s action=%s pc=" INTPTR_FORMAT " method=%s @ %d",
-                              trap_reason_name(reason), trap_action_name(action), fr.pc(),
+                              trap_reason_name(reason), trap_action_name(action), p2i(fr.pc()),
                               trap_method->name_and_sig_as_C_string(), trap_bci);
 
     // Print a bunch of diagnostics, if requested.
@@ -1385,12 +1584,33 @@
       if (TraceDeoptimization) {  // make noise on the tty
         tty->print("Uncommon trap occurred in");
         nm->method()->print_short_name(tty);
-        tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d",
-                   fr.pc(),
+        tty->print(" compiler=%s compile_id=%d", nm->compiler() == NULL ? "" : nm->compiler()->name(), nm->compile_id());
+#if INCLUDE_JVMCI
+        oop installedCode = nm->jvmci_installed_code();
+        if (installedCode != NULL) {
+          oop installedCodeName = NULL;
+          if (installedCode->is_a(InstalledCode::klass())) {
+            installedCodeName = InstalledCode::name(installedCode);
+          }
+          if (installedCodeName != NULL) {
+            tty->print(" (JVMCI: installedCodeName=%s) ", java_lang_String::as_utf8_string(installedCodeName));
+          } else {
+            tty->print(" (JVMCI: installed code has no name) ");
+          }
+        } else if (nm->is_compiled_by_jvmci()) {
+          tty->print(" (JVMCI: no installed code) ");
+        }
+#endif
+        tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d" JVMCI_ONLY(" debug_id=%d"),
+                   p2i(fr.pc()),
                    os::current_thread_id(),
                    trap_reason_name(reason),
                    trap_action_name(action),
-                   unloaded_class_index);
+                   unloaded_class_index
+#if INCLUDE_JVMCI
+                   , debug_id
+#endif
+                   );
         if (class_name != NULL) {
           tty->print(unresolved ? " unresolved class: " : " symbol: ");
           class_name->print_symbol_on(tty);
@@ -1524,11 +1744,14 @@
     bool inc_recompile_count = false;
     ProfileData* pdata = NULL;
     if (ProfileTraps && update_trap_state && trap_mdo != NULL) {
-      assert(trap_mdo == get_method_data(thread, trap_method, false), "sanity");
+      assert(trap_mdo == get_method_data(thread, profiled_method, false), "sanity");
       uint this_trap_count = 0;
       bool maybe_prior_trap = false;
       bool maybe_prior_recompile = false;
-      pdata = query_update_method_data(trap_mdo, trap_bci, reason,
+      pdata = query_update_method_data(trap_mdo, trap_bci, reason, true,
+#if INCLUDE_JVMCI
+                                   nm->is_compiled_by_jvmci() && nm->is_osr_method(),
+#endif
                                    nm->method(),
                                    //outputs:
                                    this_trap_count,
@@ -1660,26 +1883,42 @@
 Deoptimization::query_update_method_data(MethodData* trap_mdo,
                                          int trap_bci,
                                          Deoptimization::DeoptReason reason,
+                                         bool update_total_trap_count,
+#if INCLUDE_JVMCI
+                                         bool is_osr,
+#endif
                                          Method* compiled_method,
                                          //outputs:
                                          uint& ret_this_trap_count,
                                          bool& ret_maybe_prior_trap,
                                          bool& ret_maybe_prior_recompile) {
-  uint prior_trap_count = trap_mdo->trap_count(reason);
-  uint this_trap_count  = trap_mdo->inc_trap_count(reason);
+  bool maybe_prior_trap = false;
+  bool maybe_prior_recompile = false;
+  uint this_trap_count = 0;
+  if (update_total_trap_count) {
+    uint idx = reason;
+#if INCLUDE_JVMCI
+    if (is_osr) {
+      idx += Reason_LIMIT;
+    }
+#endif
+    uint prior_trap_count = trap_mdo->trap_count(idx);
+    this_trap_count  = trap_mdo->inc_trap_count(idx);
 
-  // If the runtime cannot find a place to store trap history,
-  // it is estimated based on the general condition of the method.
-  // If the method has ever been recompiled, or has ever incurred
-  // a trap with the present reason , then this BCI is assumed
-  // (pessimistically) to be the culprit.
-  bool maybe_prior_trap      = (prior_trap_count != 0);
-  bool maybe_prior_recompile = (trap_mdo->decompile_count() != 0);
+    // If the runtime cannot find a place to store trap history,
+    // it is estimated based on the general condition of the method.
+    // If the method has ever been recompiled, or has ever incurred
+    // a trap with the present reason , then this BCI is assumed
+    // (pessimistically) to be the culprit.
+    maybe_prior_trap      = (prior_trap_count != 0);
+    maybe_prior_recompile = (trap_mdo->decompile_count() != 0);
+  }
   ProfileData* pdata = NULL;
 
 
   // For reasons which are recorded per bytecode, we check per-BCI data.
   DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason);
+  assert(per_bc_reason != Reason_none || update_total_trap_count, "must be");
   if (per_bc_reason != Reason_none) {
     // Find the profile data for this BCI.  If there isn't one,
     // try to allocate one from the MDO's set of spares.
@@ -1732,8 +1971,14 @@
   bool ignore_maybe_prior_trap;
   bool ignore_maybe_prior_recompile;
   assert(!reason_is_speculate(reason), "reason speculate only used by compiler");
+  // JVMCI uses the total counts to determine if deoptimizations are happening too frequently -> do not adjust total counts
+  bool update_total_counts = JVMCI_ONLY(false) NOT_JVMCI(true);
   query_update_method_data(trap_mdo, trap_bci,
                            (DeoptReason)reason,
+                           update_total_counts,
+#if INCLUDE_JVMCI
+                           false,
+#endif
                            NULL,
                            ignore_this_trap_count,
                            ignore_maybe_prior_trap,
@@ -1741,7 +1986,9 @@
 }
 
 Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request) {
-
+  if (TraceDeoptimization) {
+    tty->print("Uncommon trap ");
+  }
   // Still in Java no safepoints
   {
     // This enters VM and may safepoint
@@ -1846,12 +2093,12 @@
   // Note:  Keep this in sync. with enum DeoptReason.
   "none",
   "null_check",
-  "null_assert",
+  "null_assert" JVMCI_ONLY("_or_unreached0"),
   "range_check",
   "class_check",
   "array_check",
-  "intrinsic",
-  "bimorphic",
+  "intrinsic" JVMCI_ONLY("_or_type_checked_inlining"),
+  "bimorphic" JVMCI_ONLY("_or_optimized_type_check"),
   "unloaded",
   "uninitialized",
   "unreached",
@@ -1866,6 +2113,13 @@
   "rtm_state_change",
   "unstable_if",
   "unstable_fused_if",
+#if INCLUDE_JVMCI
+  "aliasing",
+  "transfer_to_interpreter",
+  "not_compiled_exception_handler",
+  "unresolved",
+  "jsr_mismatch",
+#endif
   "tenured"
 };
 const char* Deoptimization::_trap_action_name[] = {
@@ -1905,13 +2159,24 @@
   jint unloaded_class_index = trap_request_index(trap_request);
   const char* reason = trap_reason_name(trap_request_reason(trap_request));
   const char* action = trap_action_name(trap_request_action(trap_request));
+#if INCLUDE_JVMCI
+  int debug_id = trap_request_debug_id(trap_request);
+#endif
   size_t len;
   if (unloaded_class_index < 0) {
-    len = jio_snprintf(buf, buflen, "reason='%s' action='%s'",
-                       reason, action);
+    len = jio_snprintf(buf, buflen, "reason='%s' action='%s'" JVMCI_ONLY(" debug_id='%d'"),
+                       reason, action
+#if INCLUDE_JVMCI
+                       ,debug_id
+#endif
+                       );
   } else {
-    len = jio_snprintf(buf, buflen, "reason='%s' action='%s' index='%d'",
-                       reason, action, unloaded_class_index);
+    len = jio_snprintf(buf, buflen, "reason='%s' action='%s' index='%d'" JVMCI_ONLY(" debug_id='%d'"),
+                       reason, action, unloaded_class_index
+#if INCLUDE_JVMCI
+                       ,debug_id
+#endif
+                       );
   }
   if (len >= buflen)
     buf[buflen-1] = '\0';
@@ -2008,7 +2273,7 @@
     if (xtty != NULL)  xtty->tail("statistics");
   }
 }
-#else // COMPILER2 || SHARK
+#else // COMPILER2 || SHARK || INCLUDE_JVMCI
 
 
 // Stubs for C1 only system.
@@ -2044,4 +2309,4 @@
   return buf;
 }
 
-#endif // COMPILER2 || SHARK
+#endif // COMPILER2 || SHARK || INCLUDE_JVMCI
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,7 +41,13 @@
   enum DeoptReason {
     Reason_many = -1,             // indicates presence of several reasons
     Reason_none = 0,              // indicates absence of a relevant deopt.
-    // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits
+    // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits.
+    // This is more complicated for JVMCI as JVMCI may deoptimize to *some* bytecode before the
+    // bytecode that actually caused the deopt (with inlining, JVMCI may even deoptimize to a
+    // bytecode in another method):
+    //  - bytecode y in method b() causes deopt
+    //  - JVMCI deoptimizes to bytecode x in method a()
+    // -> the deopt reason will be recorded for method a() at bytecode x
     Reason_null_check,            // saw unexpected null or zero divisor (@bci)
     Reason_null_assert,           // saw unexpected non-null or non-zero (@bci)
     Reason_range_check,           // saw unexpected array index (@bci)
@@ -50,6 +56,13 @@
     Reason_intrinsic,             // saw unexpected operand to intrinsic (@bci)
     Reason_bimorphic,             // saw unexpected object class in bimorphic inlining (@bci)
 
+#if INCLUDE_JVMCI
+    Reason_unreached0             = Reason_null_assert,
+    Reason_type_checked_inlining  = Reason_intrinsic,
+    Reason_optimized_type_check   = Reason_bimorphic,
+#endif
+
+    // recorded per method
     Reason_unloaded,              // unloaded class or constant pool entry
     Reason_uninitialized,         // bad class state (uninitialized)
     Reason_unreached,             // code is not reached, compiler
@@ -64,11 +77,19 @@
     Reason_rtm_state_change,      // rtm state change detected
     Reason_unstable_if,           // a branch predicted always false was taken
     Reason_unstable_fused_if,     // fused two ifs that had each one untaken branch. One is now taken.
+#if INCLUDE_JVMCI
+    Reason_aliasing,              // optimistic assumption about aliasing failed
+    Reason_transfer_to_interpreter, // explicit transferToInterpreter()
+    Reason_not_compiled_exception_handler,
+    Reason_unresolved,
+    Reason_jsr_mismatch,
+#endif
 
     // Reason_tenured is counted separately, add normal counted Reasons above.
     // Related to MethodData::_trap_hist_limit where Reason_tenured isn't included
     Reason_tenured,               // age of the code has reached the limit
     Reason_LIMIT,
+
     // Note:  Keep this enum in sync. with _trap_reason_name.
     Reason_RECORDED_LIMIT = Reason_bimorphic  // some are not recorded per bc
     // Note:  Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of
@@ -91,8 +112,10 @@
   enum {
     _action_bits = 3,
     _reason_bits = 5,
+    _debug_id_bits = 23,
     _action_shift = 0,
     _reason_shift = _action_shift+_action_bits,
+    _debug_id_shift = _reason_shift+_reason_bits,
     BC_CASE_LIMIT = PRODUCT_ONLY(1) NOT_PRODUCT(4) // for _deoptimization_hist
   };
 
@@ -109,10 +132,11 @@
 
   // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame
   static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map);
+  static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason);
 
   private:
   // Does the actual work for deoptimizing a single frame
-  static void deoptimize_single_frame(JavaThread* thread, frame fr);
+  static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason);
 
   // Helper function to revoke biases of all monitors in frame if UseBiasedLocking
   // is enabled
@@ -121,16 +145,18 @@
   // executing in a particular CodeBlob if UseBiasedLocking is enabled
   static void revoke_biases_of_monitors(CodeBlob* cb);
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
+JVMCI_ONLY(public:)
+
   // Support for restoring non-escaping objects
   static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS);
   static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type);
   static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj);
-  static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures);
+  static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal);
   static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures);
   static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array);
   NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);)
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 
   public:
   static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures);
@@ -140,6 +166,7 @@
   // UnrollBlock is returned by fetch_unroll_info() to the deoptimization handler (blob).
   // This is only a CheapObj to ease debugging after a deopt failure
   class UnrollBlock : public CHeapObj<mtCompiler> {
+    friend class VMStructs;
    private:
     int       _size_of_deoptimized_frame; // Size, in bytes, of current deoptimized frame
     int       _caller_adjustment;         // Adjustment, in bytes, to caller's SP by initial interpreted frame
@@ -243,10 +270,11 @@
   // Only called from VMDeoptimizeFrame
   // @argument thread.     Thread where stub_frame resides.
   // @argument id.         id of frame that should be deoptimized.
-  static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id);
+  static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason);
 
-  // If thread is not the current thread then execute
+  // if thread is not the current thread then execute
   // VM_DeoptimizeFrame otherwise deoptimize directly.
+  static void deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason);
   static void deoptimize_frame(JavaThread* thread, intptr_t* id);
 
   // Statistics
@@ -276,6 +304,14 @@
       // standard action for unloaded CP entry
       return _unloaded_action;
   }
+  static int trap_request_debug_id(int trap_request) {
+    if (trap_request < 0) {
+      return ((~(trap_request) >> _debug_id_shift) & right_n_bits(_debug_id_bits));
+    } else {
+      // standard action for unloaded CP entry
+      return 0;
+    }
+  }
   static int trap_request_index(int trap_request) {
     if (trap_request < 0)
       return -1;
@@ -374,6 +410,10 @@
   static ProfileData* query_update_method_data(MethodData* trap_mdo,
                                                int trap_bci,
                                                DeoptReason reason,
+                                               bool update_total_trap_count,
+#if INCLUDE_JVMCI
+                                               bool is_osr,
+#endif
                                                Method* compiled_method,
                                                //outputs:
                                                uint& ret_this_trap_count,
--- a/hotspot/src/share/vm/runtime/fprofiler.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/fprofiler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,8 +42,6 @@
 #include "runtime/vframe.hpp"
 #include "utilities/macros.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Static fields of FlatProfiler
 int               FlatProfiler::received_gc_ticks   = 0;
 int               FlatProfiler::vm_operation_ticks  = 0;
@@ -186,7 +184,7 @@
   if (counters == NULL) return;
 
   tty->cr();
-  tty->print_cr("Printing compiled methods with PC buckets having more than %d ticks", ProfilerPCTickThreshold);
+  tty->print_cr("Printing compiled methods with PC buckets having more than " INTX_FORMAT " ticks", ProfilerPCTickThreshold);
   tty->print_cr("===================================================================");
   tty->cr();
 
@@ -1494,7 +1492,7 @@
   }
 
   if (WizardMode) {
-    tty->print_cr("Node area used: %dKb", (area_top - area_bottom) / 1024);
+    tty->print_cr("Node area used: " INTX_FORMAT " Kb", (area_top - area_bottom) / 1024);
   }
   reset();
 }
--- a/hotspot/src/share/vm/runtime/frame.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -50,9 +50,6 @@
 #include "runtime/thread.inline.hpp"
 #include "utilities/decoder.hpp"
 
-
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 RegisterMap::RegisterMap(JavaThread *thread, bool update_map) {
   _thread         = thread;
   _update_map     = update_map;
@@ -112,7 +109,7 @@
     if (src != NULL) {
 
       r->print_on(st);
-      st->print(" [" INTPTR_FORMAT "] = ", src);
+      st->print(" [" INTPTR_FORMAT "] = ", p2i(src));
       if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
         st->print_cr("<misaligned>");
       } else {
@@ -494,9 +491,10 @@
   NOT_PRODUCT(address begin = pc()-40;)
   NOT_PRODUCT(address end   = NULL;)
 
-  st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
+  st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), p2i(sp()), p2i(unextended_sp()));
   if (sp() != NULL)
-    st->print(", fp=" INTPTR_FORMAT ", real_fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), real_fp(), pc());
+    st->print(", fp=" INTPTR_FORMAT ", real_fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT,
+              p2i(fp()), p2i(real_fp()), p2i(pc()));
 
   if (StubRoutines::contains(pc())) {
     st->print_cr(")");
@@ -569,15 +567,15 @@
     st->print_cr("]");
   }
   // monitor
-  st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin());
+  st->print_cr(" - monitor[" INTPTR_FORMAT "]", p2i(interpreter_frame_monitor_begin()));
   // bcp
-  st->print(" - bcp    [" INTPTR_FORMAT "]", interpreter_frame_bcp());
+  st->print(" - bcp    [" INTPTR_FORMAT "]", p2i(interpreter_frame_bcp()));
   st->fill_to(23);
   st->print_cr("; @%d", interpreter_frame_bci());
   // locals
-  st->print_cr(" - locals [" INTPTR_FORMAT "]", interpreter_frame_local_at(0));
+  st->print_cr(" - locals [" INTPTR_FORMAT "]", p2i(interpreter_frame_local_at(0)));
   // method
-  st->print(" - method [" INTPTR_FORMAT "]", (address)interpreter_frame_method());
+  st->print(" - method [" INTPTR_FORMAT "]", p2i(interpreter_frame_method()));
   st->fill_to(23);
   st->print("; ");
   interpreter_frame_method()->print_name(st);
@@ -606,7 +604,7 @@
     while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
     st->print("  [%s+0x%x]", p1, offset);
   } else {
-    st->print("  " PTR_FORMAT, pc);
+    st->print("  " PTR_FORMAT, p2i(pc));
   }
 
   // function name - os::dll_address_to_function_name() may return confusing
@@ -645,14 +643,14 @@
         st->print("j  %s", buf);
         st->print("+%d", this->interpreter_frame_bci());
       } else {
-        st->print("j  " PTR_FORMAT, pc());
+        st->print("j  " PTR_FORMAT, p2i(pc()));
       }
     } else if (StubRoutines::contains(pc())) {
       StubCodeDesc* desc = StubCodeDesc::desc_for(pc());
       if (desc != NULL) {
         st->print("v  ~StubRoutines::%s", desc->name());
       } else {
-        st->print("v  ~StubRoutines::" PTR_FORMAT, pc());
+        st->print("v  ~StubRoutines::" PTR_FORMAT, p2i(pc()));
       }
     } else if (_cb->is_buffer_blob()) {
       st->print("v  ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
@@ -661,12 +659,19 @@
       Method* m = nm->method();
       if (m != NULL) {
         m->name_and_sig_as_C_string(buf, buflen);
-        st->print("J %d%s %s %s (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+0x%x]",
+        st->print("J %d%s %s ",
                   nm->compile_id(), (nm->is_osr_method() ? "%" : ""),
-                  ((nm->compiler() != NULL) ? nm->compiler()->name() : ""),
-                  buf, m->code_size(), _pc, _cb->code_begin(), _pc - _cb->code_begin());
+                  ((nm->compiler() != NULL) ? nm->compiler()->name() : ""));
+#if INCLUDE_JVMCI
+        char* jvmciName = nm->jvmci_installed_code_name(buf, buflen);
+        if (jvmciName != NULL) {
+          st->print(" (%s)", jvmciName);
+        }
+#endif
+        st->print("%s (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+" INTPTR_FORMAT "]",
+                  buf, m->code_size(), p2i(_pc), p2i(_cb->code_begin()), _pc - _cb->code_begin());
       } else {
-        st->print("J  " PTR_FORMAT, pc());
+        st->print("J  " PTR_FORMAT, p2i(pc()));
       }
     } else if (_cb->is_runtime_stub()) {
       st->print("v  ~RuntimeStub::%s", ((RuntimeStub *)_cb)->name());
@@ -677,7 +682,7 @@
     } else if (_cb->is_safepoint_stub()) {
       st->print("v  ~SafepointBlob");
     } else {
-      st->print("v  blob " PTR_FORMAT, pc());
+      st->print("v  blob " PTR_FORMAT, p2i(pc()));
     }
   } else {
     print_C_frame(st, buf, buflen, pc());
@@ -998,7 +1003,8 @@
   }
 };
 
-void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, 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, has_appendix, f, *this, reg_map);
   finder.oops_do();
@@ -1022,7 +1028,7 @@
     return NULL;
   }
   oop r = *oop_adr;
-  assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (void *) r, (void *) r));
+  assert(Universe::heap()->is_in_or_null(r), "bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", p2i(r), p2i(r));
   return r;
 }
 
@@ -1111,104 +1117,6 @@
   }
 }
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-
-void frame::CheckValueClosure::do_oop(oop* p) {
-  if (CheckOopishValues && Universe::heap()->is_in_reserved(*p)) {
-    warning("value @ " INTPTR_FORMAT " looks oopish (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
-  }
-}
-frame::CheckValueClosure frame::_check_value;
-
-
-void frame::CheckOopClosure::do_oop(oop* p) {
-  if (*p != NULL && !(*p)->is_oop()) {
-    warning("value @ " INTPTR_FORMAT " should be an oop (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
- }
-}
-frame::CheckOopClosure frame::_check_oop;
-
-void frame::check_derived_oop(oop* base, oop* derived) {
-  _check_oop.do_oop(base);
-}
-
-
-void frame::ZapDeadClosure::do_oop(oop* p) {
-  if (TraceZapDeadLocals) tty->print_cr("zapping @ " INTPTR_FORMAT " containing " INTPTR_FORMAT, p, (address)*p);
-  *p = cast_to_oop<intptr_t>(0xbabebabe);
-}
-frame::ZapDeadClosure frame::_zap_dead;
-
-void frame::zap_dead_locals(JavaThread* thread, const RegisterMap* map) {
-  assert(thread == Thread::current(), "need to synchronize to do this to another thread");
-  // Tracing - part 1
-  if (TraceZapDeadLocals) {
-    ResourceMark rm(thread);
-    tty->print_cr("--------------------------------------------------------------------------------");
-    tty->print("Zapping dead locals in ");
-    print_on(tty);
-    tty->cr();
-  }
-  // Zapping
-       if (is_entry_frame      ()) zap_dead_entry_locals      (thread, map);
-  else if (is_interpreted_frame()) zap_dead_interpreted_locals(thread, map);
-  else if (is_compiled_frame()) zap_dead_compiled_locals   (thread, map);
-
-  else
-    // could be is_runtime_frame
-    // so remove error: ShouldNotReachHere();
-    ;
-  // Tracing - part 2
-  if (TraceZapDeadLocals) {
-    tty->cr();
-  }
-}
-
-
-void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) {
-  // get current interpreter 'pc'
-  assert(is_interpreted_frame(), "Not an interpreted frame");
-  Method* m   = interpreter_frame_method();
-  int       bci = interpreter_frame_bci();
-
-  int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
-
-  // process dynamic part
-  InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(),
-                                    &_check_value);
-  InterpreterFrameClosure   oop_blk(this, max_locals, m->max_stack(),
-                                    &_check_oop  );
-  InterpreterFrameClosure  dead_blk(this, max_locals, m->max_stack(),
-                                    &_zap_dead   );
-
-  // get frame map
-  InterpreterOopMap mask;
-  m->mask_for(bci, &mask);
-  mask.iterate_all( &oop_blk, &value_blk, &dead_blk);
-}
-
-
-void frame::zap_dead_compiled_locals(JavaThread* thread, const RegisterMap* reg_map) {
-
-  ResourceMark rm(thread);
-  assert(_cb != NULL, "sanity check");
-  if (_cb->oop_maps() != NULL) {
-    OopMapSet::all_do(this, reg_map, &_check_oop, check_derived_oop, &_check_value);
-  }
-}
-
-
-void frame::zap_dead_entry_locals(JavaThread*, const RegisterMap*) {
-  if (TraceZapDeadLocals) warning("frame::zap_dead_entry_locals unimplemented");
-}
-
-
-void frame::zap_dead_deoptimized_locals(JavaThread*, const RegisterMap*) {
-  if (TraceZapDeadLocals) warning("frame::zap_dead_deoptimized_locals unimplemented");
-}
-
-# endif // ENABLE_ZAP_DEAD_LOCALS
-
 void frame::verify(const RegisterMap* map) {
   // for now make sure receiver type is correct
   if (is_interpreted_frame()) {
@@ -1220,7 +1128,9 @@
       // make sure we have the right receiver type
     }
   }
-  COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");)
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  assert(DerivedPointerTable::is_empty(), "must be empty before verify");
+#endif
   oops_do_internal(&VerifyOopClosure::verify_oop, NULL, NULL, (RegisterMap*)map, false);
 }
 
@@ -1321,7 +1231,7 @@
     nmethod* nm = cb()->as_nmethod_or_null();
     values.describe(-1, info_address,
                     FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method %s%s", frame_no,
-                                       nm, nm->method()->name_and_sig_as_C_string(),
+                                       p2i(nm), nm->method()->name_and_sig_as_C_string(),
                                        (_deopt_state == is_deoptimized) ?
                                        " (deoptimized)" :
                                        ((_deopt_state == unknown) ? " (state unknown)" : "")),
@@ -1331,7 +1241,7 @@
     nmethod* nm = cb()->as_nmethod_or_null();
     values.describe(-1, info_address,
                     FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for native method %s", frame_no,
-                                       nm, nm->method()->name_and_sig_as_C_string()), 2);
+                                       p2i(nm), nm->method()->name_and_sig_as_C_string()), 2);
   } else {
     // provide default info if not handled before
     char *info = (char *) "special frame";
@@ -1388,8 +1298,8 @@
     if (prev.location == fv.location) {
       if (fv.owner != prev.owner) {
         tty->print_cr("overlapping storage");
-        tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", prev.location, *prev.location, prev.description);
-        tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", fv.location, *fv.location, fv.description);
+        tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", p2i(prev.location), *prev.location, prev.description);
+        tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", p2i(fv.location), *fv.location, fv.description);
         error = true;
       }
     } else {
@@ -1433,14 +1343,14 @@
   for (int i = max_index; i >= min_index; i--) {
     FrameValue fv = _values.at(i);
     while (cur > fv.location) {
-      tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT, cur, *cur);
+      tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT, p2i(cur), *cur);
       cur--;
     }
     if (last == fv.location) {
       const char* spacer = "          " LP64_ONLY("        ");
       tty->print_cr(" %s  %s %s", spacer, spacer, fv.description);
     } else {
-      tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", fv.location, *fv.location, fv.description);
+      tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", p2i(fv.location), *fv.location, fv.description);
       last = fv.location;
       cur--;
     }
--- a/hotspot/src/share/vm/runtime/frame.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -405,39 +405,6 @@
   // RedefineClasses support for finding live interpreted methods on the stack
   void metadata_do(void f(Metadata*));
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
- private:
-  class CheckValueClosure: public OopClosure {
-   public:
-    void do_oop(oop* p);
-    void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-  };
-  static CheckValueClosure _check_value;
-
-  class CheckOopClosure: public OopClosure {
-   public:
-    void do_oop(oop* p);
-    void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-  };
-  static CheckOopClosure _check_oop;
-
-  static void check_derived_oop(oop* base, oop* derived);
-
-  class ZapDeadClosure: public OopClosure {
-   public:
-    void do_oop(oop* p);
-    void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-  };
-  static ZapDeadClosure _zap_dead;
-
- public:
-  // Zapping
-  void zap_dead_locals            (JavaThread* thread, const RegisterMap* map);
-  void zap_dead_interpreted_locals(JavaThread* thread, const RegisterMap* map);
-  void zap_dead_compiled_locals   (JavaThread* thread, const RegisterMap* map);
-  void zap_dead_entry_locals      (JavaThread* thread, const RegisterMap* map);
-  void zap_dead_deoptimized_locals(JavaThread* thread, const RegisterMap* map);
-# endif
   // Verification
   void verify(const RegisterMap* map);
   static bool verify_return_pc(address x);
--- a/hotspot/src/share/vm/runtime/globals.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,6 +42,9 @@
 #ifdef COMPILER1
 #include "c1/c1_globals.hpp"
 #endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
 #ifdef COMPILER2
 #include "opto/c2_globals.hpp"
 #endif
@@ -49,8 +52,6 @@
 #include "shark/shark_globals.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
               MATERIALIZE_PD_DEVELOPER_FLAG, \
               MATERIALIZE_PRODUCT_FLAG, \
@@ -93,7 +94,7 @@
 
 void Flag::check_writable() {
   if (is_constant_in_binary()) {
-    fatal(err_msg("flag is constant: %s", _name));
+    fatal("flag is constant: %s", _name);
   }
 }
 
@@ -369,11 +370,11 @@
     } else if (is_uint()) {
       st->print("%-16u", get_uint());
     } else if (is_intx()) {
-      st->print("%-16ld", get_intx());
+      st->print(INTX_FORMAT_W(-16), get_intx());
     } else if (is_uintx()) {
-      st->print("%-16lu", get_uintx());
+      st->print(UINTX_FORMAT_W(-16), get_uintx());
     } else if (is_uint64_t()) {
-      st->print("%-16lu", get_uint64_t());
+      st->print(UINT64_FORMAT_W(-16), get_uint64_t());
     } else if (is_size_t()) {
       st->print(SIZE_FORMAT_W(-16), get_size_t());
     } else if (is_double()) {
@@ -441,6 +442,7 @@
   };
 
   Data data[] = {
+      { KIND_JVMCI, "JVMCI" },
       { KIND_C1, "C1" },
       { KIND_C2, "C2" },
       { KIND_ARCH, "ARCH" },
@@ -548,6 +550,14 @@
 #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(  type, name,        doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
 #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_NOT_PRODUCT) },
 
+#define JVMCI_PRODUCT_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_PRODUCT) },
+#define JVMCI_PD_PRODUCT_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) },
+#define JVMCI_DEVELOP_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DEVELOP) },
+#define JVMCI_PD_DEVELOP_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
+#define JVMCI_DIAGNOSTIC_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DIAGNOSTIC) },
+#define JVMCI_EXPERIMENTAL_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_EXPERIMENTAL) },
+#define JVMCI_NOTPRODUCT_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_NOT_PRODUCT) },
+
 #ifdef _LP64
 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_LP64_PRODUCT) },
 #else
@@ -616,6 +626,17 @@
           IGNORE_RANGE, \
           IGNORE_CONSTRAINT)
 #endif // INCLUDE_ALL_GCS
+#if INCLUDE_JVMCI
+ JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \
+             JVMCI_PD_DEVELOP_FLAG_STRUCT, \
+             JVMCI_PRODUCT_FLAG_STRUCT, \
+             JVMCI_PD_PRODUCT_FLAG_STRUCT, \
+             JVMCI_DIAGNOSTIC_FLAG_STRUCT, \
+             JVMCI_EXPERIMENTAL_FLAG_STRUCT, \
+             JVMCI_NOTPRODUCT_FLAG_STRUCT, \
+             IGNORE_RANGE, \
+             IGNORE_CONSTRAINT)
+#endif // INCLUDE_JVMCI
 #ifdef COMPILER1
  C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \
           C1_PD_DEVELOP_FLAG_STRUCT, \
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -25,7 +25,9 @@
 #ifndef SHARE_VM_RUNTIME_GLOBALS_HPP
 #define SHARE_VM_RUNTIME_GLOBALS_HPP
 
+#include <float.h>
 #include "utilities/debug.hpp"
+#include <float.h> // for DBL_MAX
 
 // use this for flags that are true per default in the tiered build
 // but false in non-tiered builds, and vice versa
@@ -176,7 +178,7 @@
 #endif
 #endif
 
-#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)
+#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) && !INCLUDE_JVMCI
 define_pd_global(bool, BackgroundCompilation,        false);
 define_pd_global(bool, UseTLAB,                      false);
 define_pd_global(bool, CICompileOSR,                 false);
@@ -211,11 +213,11 @@
 #define CI_COMPILER_COUNT 0
 #else
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
 #define CI_COMPILER_COUNT 2
 #else
 #define CI_COMPILER_COUNT 1
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 
 #endif // no compilers
 
@@ -254,6 +256,7 @@
     KIND_SHARK              = 1 << 15,
     KIND_LP64_PRODUCT       = 1 << 16,
     KIND_COMMERCIAL         = 1 << 17,
+    KIND_JVMCI              = 1 << 18,
 
     KIND_MASK = ~VALUE_ORIGIN_MASK
   };
@@ -527,7 +530,7 @@
 // notproduct flags are settable / visible only during development and are not declared in the PRODUCT version
 
 // A flag must be declared with one of the following types:
-// bool, intx, uintx, size_t, ccstr, double, or uint64_t.
+// bool, int, uint, intx, uintx, size_t, ccstr, double, or uint64_t.
 // The type "ccstr" is an alias for "const char*" and is used
 // only in this file, because the macrology requires single-token type names.
 
@@ -700,6 +703,7 @@
                                                                             \
   product(intx, UseSSE, 99,                                                 \
           "Highest supported SSE instructions set on x86/x64")              \
+          range(0, 99)                                                      \
                                                                             \
   product(bool, UseAES, false,                                              \
           "Control whether AES instructions can be used on x86/x64")        \
@@ -937,16 +941,6 @@
   notproduct(bool, VerifyCodeCache, false,                                  \
           "Verify code cache on memory allocation/deallocation")            \
                                                                             \
-  develop(bool, ZapDeadCompiledLocals, false,                               \
-          "Zap dead locals in compiler frames")                             \
-                                                                            \
-  notproduct(bool, ZapDeadLocalsOld, false,                                 \
-          "Zap dead locals (old version, zaps all frames when "             \
-          "entering the VM")                                                \
-                                                                            \
-  notproduct(bool, CheckOopishValues, false,                                \
-          "Warn if value contains oop (requires ZapDeadLocals)")            \
-                                                                            \
   develop(bool, UseMallocOnly, false,                                       \
           "Use only malloc/free for allocation (no resource area/arena)")   \
                                                                             \
@@ -1108,9 +1102,15 @@
   diagnostic(ccstr, PrintAssemblyOptions, NULL,                             \
           "Print options string passed to disassembler.so")                 \
                                                                             \
+  notproduct(bool, PrintNMethodStatistics, false,                           \
+          "Print a summary statistic for the generated nmethods")           \
+                                                                            \
   diagnostic(bool, PrintNMethods, false,                                    \
           "Print assembly code for nmethods when generated")                \
                                                                             \
+  diagnostic(intx, PrintNMethodsAtLevel, -1,                                \
+          "Only print code for nmethods at the given compilation level")    \
+                                                                            \
   diagnostic(bool, PrintNativeNMethods, false,                              \
           "Print assembly code for native nmethods when generated")         \
                                                                             \
@@ -1258,6 +1258,7 @@
                "Control emission of inline sync fast-path code")            \
                                                                             \
   product(intx, MonitorBound, 0, "Bound Monitor population")                \
+          range(0, max_jint)                                                \
                                                                             \
   product(bool, MonitorInUseLists, false, "Track Monitors for Deflation")   \
                                                                             \
@@ -1489,9 +1490,6 @@
   develop(bool, TraceCompiledIC, false,                                     \
           "Trace changes of compiled IC")                                   \
                                                                             \
-  notproduct(bool, TraceZapDeadLocals, false,                               \
-          "Trace zapping dead locals")                                      \
-                                                                            \
   develop(bool, TraceStartupTime, false,                                    \
           "Trace setup time")                                               \
                                                                             \
@@ -1547,6 +1545,7 @@
                                                                             \
   product(uint, ParallelGCThreads, 0,                                       \
           "Number of parallel threads parallel gc will use")                \
+          constraint(ParallelGCThreadsConstraintFunc,AfterErgo)             \
                                                                             \
   diagnostic(bool, UseSemaphoreGCThreadsSynchronization, true,              \
             "Use semaphore synchronization for the GC Threads, "            \
@@ -1578,14 +1577,7 @@
                                                                             \
   product(uint, ConcGCThreads, 0,                                           \
           "Number of threads concurrent gc will use")                       \
-                                                                            \
-  product(size_t, YoungPLABSize, 4096,                                      \
-          "Size of young gen promotion LAB's (in HeapWords)")               \
-          constraint(YoungPLABSizeConstraintFunc,AfterMemoryInit)           \
-                                                                            \
-  product(size_t, OldPLABSize, 1024,                                        \
-          "Size of old gen promotion LAB's (in HeapWords), or Number        \
-          of blocks to attempt to claim when refilling CMS LAB's")          \
+          constraint(ConcGCThreadsConstraintFunc,AfterErgo)                 \
                                                                             \
   product(uintx, GCTaskTimeStampEntries, 200,                               \
           "Number of time stamp entries per gc worker thread")              \
@@ -1693,6 +1685,7 @@
           "The number of strides per worker thread that we divide up the "  \
           "card table scanning work into")                                  \
           range(1, max_uintx)                                               \
+          constraint(ParGCStridesPerThreadConstraintFunc,AfterErgo)         \
                                                                             \
   diagnostic(intx, ParGCCardsPerStrideChunk, 256,                           \
           "The number of cards in each chunk of the parallel chunks used "  \
@@ -1715,12 +1708,13 @@
           "Maximum size of CMS gen promotion LAB caches per worker "        \
           "per block size")                                                 \
           range(1, max_uintx)                                               \
+          constraint(CMSOldPLABMaxConstraintFunc,AfterMemoryInit)           \
                                                                             \
   product(size_t, CMSOldPLABMin, 16,                                        \
           "Minimum size of CMS gen promotion LAB caches per worker "        \
           "per block size")                                                 \
           range(1, max_uintx)                                               \
-          constraint(CMSOldPLABMinConstraintFunc,AfterErgo)                 \
+          constraint(CMSOldPLABMinConstraintFunc,AfterMemoryInit)           \
                                                                             \
   product(uintx, CMSOldPLABNumRefills, 4,                                   \
           "Nominal number of refills of CMS gen promotion LAB cache "       \
@@ -1779,24 +1773,29 @@
   product(double, FLSLargestBlockCoalesceProximity, 0.99,                   \
           "CMS: the smaller the percentage the greater the coalescing "     \
           "force")                                                          \
+          range(0.0, 1.0)                                                   \
                                                                             \
   product(double, CMSSmallCoalSurplusPercent, 1.05,                         \
           "CMS: the factor by which to inflate estimated demand of small "  \
           "block sizes to prevent coalescing with an adjoining block")      \
+          range(0.0, DBL_MAX)                                               \
                                                                             \
   product(double, CMSLargeCoalSurplusPercent, 0.95,                         \
           "CMS: the factor by which to inflate estimated demand of large "  \
           "block sizes to prevent coalescing with an adjoining block")      \
+          range(0.0, DBL_MAX)                                               \
                                                                             \
   product(double, CMSSmallSplitSurplusPercent, 1.10,                        \
           "CMS: the factor by which to inflate estimated demand of small "  \
           "block sizes to prevent splitting to supply demand for smaller "  \
           "blocks")                                                         \
+          range(0.0, DBL_MAX)                                               \
                                                                             \
   product(double, CMSLargeSplitSurplusPercent, 1.00,                        \
           "CMS: the factor by which to inflate estimated demand of large "  \
           "block sizes to prevent splitting to supply demand for smaller "  \
           "blocks")                                                         \
+          range(0.0, DBL_MAX)                                               \
                                                                             \
   product(bool, CMSExtrapolateSweep, false,                                 \
           "CMS: cushion for block demand during sweep")                     \
@@ -1824,9 +1823,11 @@
                                                                             \
   develop(intx, CMSDictionaryChoice, 0,                                     \
           "Use BinaryTreeDictionary as default in the CMS generation")      \
+          range(0, 2)                                                       \
                                                                             \
   product(uintx, CMSIndexedFreeListReplenish, 4,                            \
           "Replenish an indexed free list with this number of chunks")      \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, CMSReplenishIntermediate, true,                             \
           "Replenish all intermediate free-list caches")                    \
@@ -1841,14 +1842,15 @@
   develop(bool, CMSOverflowEarlyRestoration, false,                         \
           "Restore preserved marks early")                                  \
                                                                             \
-  product(size_t, MarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M),             \
-          "Size of marking stack")                                          \
-                                                                            \
   /* where does the range max value of (max_jint - 1) come from? */         \
   product(size_t, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M),         \
           "Maximum size of marking stack")                                  \
           range(1, (max_jint - 1))                                          \
                                                                             \
+  product(size_t, MarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M),             \
+          "Size of marking stack")                                          \
+          constraint(MarkStackSizeConstraintFunc,AfterErgo)                 \
+                                                                            \
   notproduct(bool, CMSMarkStackOverflowALot, false,                         \
           "Simulate frequent marking stack / work queue overflow")          \
                                                                             \
@@ -1861,6 +1863,7 @@
                                                                             \
   product(intx, CMSMaxAbortablePrecleanTime, 5000,                          \
           "Maximum time in abortable preclean (in milliseconds)")           \
+          range(0, max_intx)                                                \
                                                                             \
   product(uintx, CMSAbortablePrecleanMinWorkPerIteration, 100,              \
           "Nominal minimum work per abortable preclean iteration")          \
@@ -1868,6 +1871,7 @@
   manageable(intx, CMSAbortablePrecleanWaitMillis, 100,                     \
           "Time that we sleep between iterations when not given "           \
           "enough work per iteration")                                      \
+          range(0, max_intx)                                                \
                                                                             \
   product(size_t, CMSRescanMultiple, 32,                                    \
           "Size (in cards) of CMS parallel rescan task")                    \
@@ -1974,6 +1978,8 @@
                                                                             \
   product(uintx, CMSWorkQueueDrainThreshold, 10,                            \
           "Don't drain below this size per parallel worker/thief")          \
+          range(1, max_juint)                                               \
+          constraint(CMSWorkQueueDrainThresholdConstraintFunc,AfterErgo)    \
                                                                             \
   manageable(intx, CMSWaitDuration, 2000,                                   \
           "Time in milliseconds that CMS thread waits for young GC")        \
@@ -2225,9 +2231,11 @@
                                                                             \
   develop(intx, PSAdaptiveSizePolicyResizeVirtualSpaceAlot, -1,             \
           "Resize the virtual spaces of the young or old generations")      \
+          range(-1, 1)                                                      \
                                                                             \
   product(uintx, AdaptiveSizeThroughPutPolicy, 0,                           \
           "Policy for changing generation size for throughput goals")       \
+          range(0, 1)                                                       \
                                                                             \
   develop(bool, PSAdjustTenuredGenForMinorPause, false,                     \
           "Adjust tenured generation to achieve a minor pause goal")        \
@@ -2299,9 +2307,12 @@
   product(uintx, MaxGCPauseMillis, max_uintx,                               \
           "Adaptive size policy maximum GC pause time goal in millisecond, "\
           "or (G1 Only) the maximum GC time per MMU time slice")            \
+          range(1, max_uintx)                                               \
+          constraint(MaxGCPauseMillisConstraintFunc,AfterMemoryInit)        \
                                                                             \
   product(uintx, GCPauseIntervalMillis, 0,                                  \
           "Time slice for MMU specification")                               \
+          constraint(GCPauseIntervalMillisConstraintFunc,AfterMemoryInit)   \
                                                                             \
   product(uintx, MaxGCMinorPauseMillis, max_uintx,                          \
           "Adaptive size policy maximum GC minor pause time goal "          \
@@ -2322,6 +2333,7 @@
                                                                             \
   product(uintx, MinSurvivorRatio, 3,                                       \
           "Minimum ratio of young generation/survivor space size")          \
+          range(3, max_uintx)                                               \
                                                                             \
   product(uintx, InitialSurvivorRatio, 8,                                   \
           "Initial ratio of young generation/survivor space size")          \
@@ -2345,6 +2357,7 @@
                                                                             \
   develop(uintx, AdaptiveSizePolicyGCTimeLimitThreshold, 5,                 \
           "Number of consecutive collections before gc time limit fires")   \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, PrintAdaptiveSizePolicy, false,                             \
           "Print information about AdaptiveSizePolicy")                     \
@@ -2444,6 +2457,7 @@
   develop(intx, ConcGCYieldTimeout, 0,                                      \
           "If non-zero, assert that GC threads yield within this "          \
           "number of milliseconds")                                         \
+          range(0, max_intx)                                                \
                                                                             \
   product(bool, PrintReferenceGC, false,                                    \
           "Print times spent handling reference objects during GC "         \
@@ -2482,6 +2496,8 @@
   product(size_t, InitialBootClassLoaderMetaspaceSize,                      \
           NOT_LP64(2200*K) LP64_ONLY(4*M),                                  \
           "Initial size of the boot class loader data metaspace")           \
+          range(30*K, max_uintx/BytesPerWord)                               \
+          constraint(InitialBootClassLoaderMetaspaceSizeConstraintFunc, AfterErgo)\
                                                                             \
   product(bool, TraceYoungGenTime, false,                                   \
           "Trace accumulated time for young collection")                    \
@@ -2558,6 +2574,7 @@
   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")            \
+          range(0.0, 100.0)                                                 \
                                                                             \
   /* GC log rotation setting */                                             \
                                                                             \
@@ -2718,6 +2735,7 @@
   diagnostic(intx, HotMethodDetectionLimit, 100000,                         \
           "Number of compiled code invocations after which "                \
           "the method is considered as hot by the flusher")                 \
+          range(1, max_jint)                                                \
                                                                             \
   diagnostic(intx, MinPassesBeforeFlush, 10,                                \
           "Minimum number of sweeper passes before an nmethod "             \
@@ -2838,7 +2856,7 @@
                                                                             \
   develop(bool, CompileTheWorld, false,                                     \
           "Compile all methods in all classes in bootstrap class path "     \
-          "(stress test)")                                                  \
+            "(stress test)")                                                \
                                                                             \
   develop(bool, CompileTheWorldPreloadClasses, true,                        \
           "Preload all classes used by a class before start loading")       \
@@ -2876,13 +2894,16 @@
                      "Y: Type profiling of return value at call; "          \
                      "X: Type profiling of parameters to methods; "         \
           "X, Y and Z in 0=off ; 1=jsr292 only; 2=all methods")             \
+          constraint(TypeProfileLevelConstraintFunc, AfterErgo)             \
                                                                             \
   product(intx, TypeProfileArgsLimit,     2,                                \
           "max number of call arguments to consider for type profiling")    \
+          range(0, 16)                                                      \
                                                                             \
   product(intx, TypeProfileParmsLimit,    2,                                \
           "max number of incoming parameters to consider for type profiling"\
           ", -1 for all")                                                   \
+          range(-1, 64)                                                     \
                                                                             \
   /* statistics */                                                          \
   develop(bool, CountCompiledCalls, false,                                  \
@@ -3041,13 +3062,17 @@
           "Analyze bytecodes to estimate escape state of arguments")        \
                                                                             \
   product(intx, BCEATraceLevel, 0,                                          \
-          "How much tracing to do of bytecode escape analysis estimates")   \
+          "How much tracing to do of bytecode escape analysis estimates "   \
+          "(0-3)")                                                          \
+          range(0, 3)                                                       \
                                                                             \
   product(intx, MaxBCEAEstimateLevel, 5,                                    \
           "Maximum number of nested calls that are analyzed by BC EA")      \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, MaxBCEAEstimateSize, 150,                                   \
           "Maximum bytecode size of a method to be analyzed by BC EA")      \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx,  AllocatePrefetchStyle, 1,                                  \
           "0 = no prefetch, "                                               \
@@ -3057,25 +3082,34 @@
           range(0, 3)                                                       \
                                                                             \
   product(intx,  AllocatePrefetchDistance, -1,                              \
-          "Distance to prefetch ahead of allocation pointer")               \
+          "Distance to prefetch ahead of allocation pointer. "              \
+          "-1: use system-specific value (automatically determined")        \
+          constraint(AllocatePrefetchDistanceConstraintFunc, AfterMemoryInit)\
                                                                             \
   product(intx,  AllocatePrefetchLines, 3,                                  \
           "Number of lines to prefetch ahead of array allocation pointer")  \
+          range(1, max_jint / 2)                                            \
                                                                             \
   product(intx,  AllocateInstancePrefetchLines, 1,                          \
           "Number of lines to prefetch ahead of instance allocation "       \
           "pointer")                                                        \
+          range(1, max_jint / 2)                                            \
                                                                             \
   product(intx,  AllocatePrefetchStepSize, 16,                              \
           "Step size in bytes of sequential prefetch instructions")         \
+          constraint(AllocatePrefetchStepSizeConstraintFunc,AfterMemoryInit)\
                                                                             \
   product(intx,  AllocatePrefetchInstr, 0,                                  \
           "Prefetch instruction to prefetch ahead of allocation pointer")   \
+          constraint(AllocatePrefetchInstrConstraintFunc, AfterErgo)        \
                                                                             \
   /* deoptimization */                                                      \
   develop(bool, TraceDeoptimization, false,                                 \
           "Trace deoptimization")                                           \
                                                                             \
+  develop(bool, PrintDeoptimizationDetails, false,                          \
+          "Print more information about deoptimization")                    \
+                                                                            \
   develop(bool, DebugDeoptimization, false,                                 \
           "Tracing various information while debugging deoptimization")     \
                                                                             \
@@ -3137,30 +3171,38 @@
                                                                             \
   product(intx, MaxInlineLevel, 9,                                          \
           "maximum number of nested calls that are inlined")                \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, MaxRecursiveInlineLevel, 1,                                 \
           "maximum number of nested recursive calls that are inlined")      \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, MaxForceInlineLevel, 100,                                   \
           "maximum number of nested calls that are forced for inlining "    \
-          "(using CompilerOracle or marked w/ @ForceInline)")               \
+          "(using CompileCommand or marked w/ @ForceInline)")               \
+          range(0, max_jint)                                                \
                                                                             \
   product_pd(intx, InlineSmallCode,                                         \
           "Only inline already compiled methods if their code size is "     \
           "less than this")                                                 \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, MaxInlineSize, 35,                                          \
           "The maximum bytecode size of a method to be inlined")            \
+          range(0, max_jint)                                                \
                                                                             \
   product_pd(intx, FreqInlineSize,                                          \
           "The maximum bytecode size of a frequent method to be inlined")   \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, MaxTrivialSize, 6,                                          \
           "The maximum bytecode size of a trivial method to be inlined")    \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, MinInliningThreshold, 250,                                  \
           "The minimum invocation count a method needs to have to be "      \
           "inlined")                                                        \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, MethodHistogramCutoff, 100,                                 \
           "The cutoff value for method invocation histogram (+CountCalls)") \
@@ -3222,8 +3264,12 @@
           "If non-zero, maximum number of words that malloc/realloc can "   \
           "allocate (for testing only)")                                    \
                                                                             \
-  product(intx, TypeProfileWidth,     2,                                    \
+  product(intx, TypeProfileWidth, 2,                                        \
           "Number of receiver types to record in call/cast profile")        \
+          range(0, 8)                                                       \
+                                                                            \
+  experimental(intx, MethodProfileWidth, 0,                                 \
+          "Number of methods to record in call profile")                    \
                                                                             \
   develop(intx, BciProfileWidth,      2,                                    \
           "Number of return bci's to record in ret profile")                \
@@ -3238,45 +3284,56 @@
                                                                             \
   product(intx, PerMethodTrapLimit,  100,                                   \
           "Limit on traps (of one kind) in a method (includes inlines)")    \
+          range(0, max_jint)                                                \
                                                                             \
   experimental(intx, PerMethodSpecTrapLimit,  5000,                         \
           "Limit on speculative traps (of one kind) in a method "           \
           "(includes inlines)")                                             \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, PerBytecodeTrapLimit,  4,                                   \
           "Limit on traps (of one kind) at a particular BCI")               \
+          range(0, max_jint)                                                \
                                                                             \
   experimental(intx, SpecTrapLimitExtraEntries,  3,                         \
           "Extra method data trap entries for speculation")                 \
                                                                             \
   develop(intx, InlineFrequencyRatio,    20,                                \
           "Ratio of call site execution to caller method invocation")       \
+          range(0, max_jint)                                                \
                                                                             \
   develop_pd(intx, InlineFrequencyCount,                                    \
           "Count of call site execution necessary to trigger frequent "     \
           "inlining")                                                       \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, InlineThrowCount,    50,                                    \
           "Force inlining of interpreted methods that throw this often")    \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, InlineThrowMaxSize,   200,                                  \
           "Force inlining of throwing methods smaller than this")           \
+          range(0, max_jint)                                                \
                                                                             \
   develop(intx, ProfilerNodeSize,  1024,                                    \
           "Size in K to allocate for the Profile Nodes of each thread")     \
+          range(0, 1024)                                                    \
                                                                             \
   /* gc parameters */                                                       \
   product(size_t, InitialHeapSize, 0,                                       \
           "Initial heap size (in bytes); zero means use ergonomics")        \
+          constraint(InitialHeapSizeConstraintFunc,AfterErgo)               \
                                                                             \
   product(size_t, MaxHeapSize, ScaleForWordSize(96*M),                      \
           "Maximum heap size (in bytes)")                                   \
+          constraint(MaxHeapSizeConstraintFunc,AfterErgo)                   \
                                                                             \
   product(size_t, OldSize, ScaleForWordSize(4*M),                           \
           "Initial tenured generation size (in bytes)")                     \
                                                                             \
   product(size_t, NewSize, ScaleForWordSize(1*M),                           \
           "Initial new generation size (in bytes)")                         \
+          constraint(NewSizeConstraintFunc,AfterErgo)                       \
                                                                             \
   product(size_t, MaxNewSize, max_uintx,                                    \
           "Maximum new generation size (in bytes), max_uintx means set "    \
@@ -3286,12 +3343,23 @@
           "Maximum size in bytes of objects allocated in DefNew "           \
           "generation; zero means no maximum")                              \
                                                                             \
-  product(size_t, TLABSize, 0,                                              \
-          "Starting TLAB size (in bytes); zero means set ergonomically")    \
-                                                                            \
   product(size_t, MinTLABSize, 2*K,                                         \
           "Minimum allowed TLAB size (in bytes)")                           \
           range(1, max_uintx)                                               \
+          constraint(MinTLABSizeConstraintFunc,AfterMemoryInit)             \
+                                                                            \
+  product(size_t, TLABSize, 0,                                              \
+          "Starting TLAB size (in bytes); zero means set ergonomically")    \
+          constraint(TLABSizeConstraintFunc,AfterMemoryInit)                \
+                                                                            \
+  product(size_t, YoungPLABSize, 4096,                                      \
+          "Size of young gen promotion LAB's (in HeapWords)")               \
+          constraint(YoungPLABSizeConstraintFunc,AfterMemoryInit)           \
+                                                                            \
+  product(size_t, OldPLABSize, 1024,                                        \
+          "Size of old gen promotion LAB's (in HeapWords), or Number "      \
+          "of blocks to attempt to claim when refilling CMS LAB's")         \
+          constraint(OldPLABSizeConstraintFunc,AfterMemoryInit)             \
                                                                             \
   product(uintx, TLABAllocationWeight, 35,                                  \
           "Allocation averaging weight")                                    \
@@ -3312,9 +3380,12 @@
                                                                             \
   product(uintx, SurvivorRatio, 8,                                          \
           "Ratio of eden/survivor space size")                              \
+          range(1, max_uintx-2)                                             \
+          constraint(SurvivorRatioConstraintFunc,AfterMemoryInit)           \
                                                                             \
   product(uintx, NewRatio, 2,                                               \
           "Ratio of old/new generation sizes")                              \
+          range(0, max_uintx-1)                                             \
                                                                             \
   product_pd(size_t, NewSizeThreadIncrease,                                 \
           "Additional size added to desired new generation size per "       \
@@ -3322,9 +3393,11 @@
                                                                             \
   product_pd(size_t, MetaspaceSize,                                         \
           "Initial size of Metaspaces (in bytes)")                          \
+          constraint(MetaspaceSizeConstraintFunc,AfterErgo)                 \
                                                                             \
   product(size_t, MaxMetaspaceSize, max_uintx,                              \
           "Maximum size of Metaspaces (in bytes)")                          \
+          constraint(MaxMetaspaceSizeConstraintFunc,AfterErgo)              \
                                                                             \
   product(size_t, CompressedClassSpaceSize, 1*G,                            \
           "Maximum size of class area in Metaspace when compressed "        \
@@ -3347,6 +3420,8 @@
                                                                             \
   product(intx, SoftRefLRUPolicyMSPerMB, 1000,                              \
           "Number of milliseconds per MB of free space in the heap")        \
+          range(0, max_intx)                                                \
+          constraint(SoftRefLRUPolicyMSPerMBConstraintFunc,AfterMemoryInit) \
                                                                             \
   product(size_t, MinHeapDeltaBytes, ScaleForWordSize(128*K),               \
           "The minimum change in heap space due to GC (in bytes)")          \
@@ -3378,6 +3453,7 @@
                                                                             \
   diagnostic(intx, VerifyGCLevel,     0,                                    \
           "Generation level at which to start +VerifyBefore/AfterGC")       \
+          range(0, 1)                                                       \
                                                                             \
   product(uintx, MaxTenuringThreshold,    15,                               \
           "Maximum value for tenuring threshold")                           \
@@ -3436,6 +3512,7 @@
           "before changing safepoint polling page to RO ")                  \
                                                                             \
   product(intx, SafepointSpinBeforeYield, 2000, "(Unstable)")               \
+          range(0, max_intx)                                                \
                                                                             \
   product(bool, PSChunkLargeArrays, true,                                   \
           "Process large arrays in chunks")                                 \
@@ -3467,6 +3544,7 @@
                                                                             \
   product_pd(intx, CompilerThreadStackSize,                                 \
           "Compiler Thread Stack Size (in Kbytes)")                         \
+          range(0, max_intx)                                                \
                                                                             \
   develop_pd(size_t, JVMInvokeMethodSlack,                                  \
           "Stack space (bytes) required for JVM_InvokeMethod to complete")  \
@@ -3477,36 +3555,46 @@
           "Code cache segment size (in bytes) - smallest unit of "          \
           "allocation")                                                     \
           range(1, 1024)                                                    \
+          constraint(CodeCacheSegmentSizeConstraintFunc, AfterErgo)         \
                                                                             \
   develop_pd(intx, CodeEntryAlignment,                                      \
           "Code entry alignment for generated code (in bytes)")             \
+          constraint(CodeEntryAlignmentConstraintFunc, AfterErgo)           \
                                                                             \
   product_pd(intx, OptoLoopAlignment,                                       \
           "Align inner loops to zero relative to this modulus")             \
+          constraint(OptoLoopAlignmentConstraintFunc, AfterErgo)            \
                                                                             \
   product_pd(uintx, InitialCodeCacheSize,                                   \
           "Initial code cache size (in bytes)")                             \
+          range(0, max_uintx)                                               \
                                                                             \
   develop_pd(uintx, CodeCacheMinimumUseSpace,                               \
           "Minimum code cache size (in bytes) required to start VM.")       \
+          range(0, max_uintx)                                               \
                                                                             \
   product(bool, SegmentedCodeCache, false,                                  \
           "Use a segmented code cache")                                     \
                                                                             \
   product_pd(uintx, ReservedCodeCacheSize,                                  \
           "Reserved code cache size (in bytes) - maximum code cache size")  \
+          range(0, max_uintx)                                               \
                                                                             \
   product_pd(uintx, NonProfiledCodeHeapSize,                                \
           "Size of code heap with non-profiled methods (in bytes)")         \
+          range(0, max_uintx)                                               \
                                                                             \
   product_pd(uintx, ProfiledCodeHeapSize,                                   \
           "Size of code heap with profiled methods (in bytes)")             \
+          range(0, max_uintx)                                               \
                                                                             \
   product_pd(uintx, NonNMethodCodeHeapSize,                                 \
           "Size of code heap with non-nmethods (in bytes)")                 \
+          range(0, max_uintx)                                               \
                                                                             \
   product_pd(uintx, CodeCacheExpansionSize,                                 \
           "Code cache expansion size (in bytes)")                           \
+          range(0, max_uintx)                                               \
                                                                             \
   develop_pd(uintx, CodeCacheMinBlockLength,                                \
           "Minimum number of segments in a code cache block")               \
@@ -3636,6 +3724,7 @@
   product(intx, CompilerThreadPriority, -1,                                 \
           "The native priority at which compiler threads should run "       \
           "(-1 means no change)")                                           \
+          constraint(CompilerThreadPriorityConstraintFunc, AfterErgo)       \
                                                                             \
   product(intx, VMThreadPriority, -1,                                       \
           "The native priority at which the VM thread should run "          \
@@ -3708,6 +3797,7 @@
   /* recompilation */                                                       \
   product_pd(intx, CompileThreshold,                                        \
           "number of interpreted method invocations before (re-)compiling") \
+          constraint(CompileThresholdConstraintFunc, AfterErgo)             \
                                                                             \
   product(double, CompileThresholdScaling, 1.0,                             \
           "Factor to control when first compilation happens "               \
@@ -3721,90 +3811,115 @@
           "If a value is specified for a method, compilation thresholds "   \
           "for that method are scaled by both the value of the global flag "\
           "and the value of the per-method flag.")                          \
+          range(0.0, DBL_MAX)                                               \
                                                                             \
   product(intx, Tier0InvokeNotifyFreqLog, 7,                                \
           "Interpreter (tier 0) invocation notification frequency")         \
+          range(0, 30)                                                      \
                                                                             \
   product(intx, Tier2InvokeNotifyFreqLog, 11,                               \
           "C1 without MDO (tier 2) invocation notification frequency")      \
+          range(0, 30)                                                      \
                                                                             \
   product(intx, Tier3InvokeNotifyFreqLog, 10,                               \
           "C1 with MDO profiling (tier 3) invocation notification "         \
           "frequency")                                                      \
+          range(0, 30)                                                      \
                                                                             \
   product(intx, Tier23InlineeNotifyFreqLog, 20,                             \
           "Inlinee invocation (tiers 2 and 3) notification frequency")      \
+          range(0, 30)                                                      \
                                                                             \
   product(intx, Tier0BackedgeNotifyFreqLog, 10,                             \
           "Interpreter (tier 0) invocation notification frequency")         \
+          range(0, 30)                                                      \
                                                                             \
   product(intx, Tier2BackedgeNotifyFreqLog, 14,                             \
           "C1 without MDO (tier 2) invocation notification frequency")      \
+          range(0, 30)                                                      \
                                                                             \
   product(intx, Tier3BackedgeNotifyFreqLog, 13,                             \
           "C1 with MDO profiling (tier 3) invocation notification "         \
           "frequency")                                                      \
+          range(0, 30)                                                      \
                                                                             \
   product(intx, Tier2CompileThreshold, 0,                                   \
           "threshold at which tier 2 compilation is invoked")               \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier2BackEdgeThreshold, 0,                                  \
           "Back edge threshold at which tier 2 compilation is invoked")     \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier3InvocationThreshold, 200,                              \
           "Compile if number of method invocations crosses this "           \
           "threshold")                                                      \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier3MinInvocationThreshold, 100,                           \
           "Minimum invocation to compile at tier 3")                        \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier3CompileThreshold, 2000,                                \
           "Threshold at which tier 3 compilation is invoked (invocation "   \
-          "minimum must be satisfied")                                      \
+          "minimum must be satisfied)")                                     \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier3BackEdgeThreshold,  60000,                             \
           "Back edge threshold at which tier 3 OSR compilation is invoked") \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier4InvocationThreshold, 5000,                             \
           "Compile if number of method invocations crosses this "           \
           "threshold")                                                      \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier4MinInvocationThreshold, 600,                           \
           "Minimum invocation to compile at tier 4")                        \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier4CompileThreshold, 15000,                               \
           "Threshold at which tier 4 compilation is invoked (invocation "   \
           "minimum must be satisfied")                                      \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier4BackEdgeThreshold, 40000,                              \
           "Back edge threshold at which tier 4 OSR compilation is invoked") \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier3DelayOn, 5,                                            \
           "If C2 queue size grows over this amount per compiler thread "    \
           "stop compiling at tier 3 and start compiling at tier 2")         \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier3DelayOff, 2,                                           \
           "If C2 queue size is less than this amount per compiler thread "  \
           "allow methods compiled at tier 2 transition to tier 3")          \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier3LoadFeedback, 5,                                       \
           "Tier 3 thresholds will increase twofold when C1 queue size "     \
           "reaches this amount per compiler thread")                        \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, Tier4LoadFeedback, 3,                                       \
           "Tier 4 thresholds will increase twofold when C2 queue size "     \
           "reaches this amount per compiler thread")                        \
+          range(0, max_jint)                                                \
                                                                             \
   product(intx, TieredCompileTaskTimeout, 50,                               \
           "Kill compile task if method was not used within "                \
           "given timeout in milliseconds")                                  \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, TieredStopAtLevel, 4,                                       \
           "Stop at given compilation level")                                \
+          range(0, 4)                                                       \
                                                                             \
   product(intx, Tier0ProfilingStartPercentage, 200,                         \
           "Start profiling in interpreter if the counters exceed tier 3 "   \
           "thresholds by the specified percentage")                         \
+          range(0, max_jint)                                                \
                                                                             \
   product(uintx, IncreaseFirstTierCompileThresholdAt, 50,                   \
           "Increase the compile threshold for C1 compilation if the code "  \
@@ -3813,9 +3928,11 @@
                                                                             \
   product(intx, TieredRateUpdateMinTime, 1,                                 \
           "Minimum rate sampling interval (in milliseconds)")               \
+          range(0, max_intx)                                                \
                                                                             \
   product(intx, TieredRateUpdateMaxTime, 25,                                \
           "Maximum rate sampling interval (in milliseconds)")               \
+          range(0, max_intx)                                                \
                                                                             \
   product_pd(bool, TieredCompilation,                                       \
           "Enable tiered compilation")                                      \
@@ -3826,6 +3943,7 @@
   product_pd(intx, OnStackReplacePercentage,                                \
           "NON_TIERED number of method invocations/branches (expressed as " \
           "% of CompileThreshold) before (re-)compiling OSR code")          \
+          constraint(OnStackReplacePercentageConstraintFunc, AfterErgo)     \
                                                                             \
   product(intx, InterpreterProfilePercentage, 33,                           \
           "NON_TIERED number of method invocations/branches (expressed as " \
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -44,6 +44,14 @@
 #define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)          FLAG_MEMBER(name),
 #define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
 
+#define JVMCI_PRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
+#define JVMCI_PD_PRODUCT_FLAG_MEMBER(type, name, doc)            FLAG_MEMBER(name),
+#define JVMCI_DEVELOP_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
+#define JVMCI_PD_DEVELOP_FLAG_MEMBER(type, name, doc)            FLAG_MEMBER(name),
+#define JVMCI_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)     FLAG_MEMBER(name),
+#define JVMCI_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
+#define JVMCI_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)     FLAG_MEMBER(name),
+
 #ifdef _LP64
 #define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
 #else
@@ -105,6 +113,17 @@
           IGNORE_RANGE, \
           IGNORE_CONSTRAINT)
 #endif // INCLUDE_ALL_GCS
+#if INCLUDE_JVMCI
+ JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER, \
+             JVMCI_PD_DEVELOP_FLAG_MEMBER, \
+             JVMCI_PRODUCT_FLAG_MEMBER, \
+             JVMCI_PD_PRODUCT_FLAG_MEMBER, \
+             JVMCI_DIAGNOSTIC_FLAG_MEMBER, \
+             JVMCI_EXPERIMENTAL_FLAG_MEMBER, \
+             JVMCI_NOTPRODUCT_FLAG_MEMBER, \
+             IGNORE_RANGE, \
+             IGNORE_CONSTRAINT)
+#endif // INCLUDE_JVMCI
 #ifdef COMPILER1
  C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, \
           C1_PD_DEVELOP_FLAG_MEMBER, \
@@ -151,6 +170,14 @@
 #define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)          FLAG_MEMBER_WITH_TYPE(name,type),
 #define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
 
+#define JVMCI_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
+#define JVMCI_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)            FLAG_MEMBER_WITH_TYPE(name,type),
+#define JVMCI_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
+#define JVMCI_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)            FLAG_MEMBER_WITH_TYPE(name,type),
+#define JVMCI_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     FLAG_MEMBER_WITH_TYPE(name,type),
+#define JVMCI_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
+#define JVMCI_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     FLAG_MEMBER_WITH_TYPE(name,type),
+
 #define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
 #define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
 #define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
@@ -212,6 +239,17 @@
           IGNORE_RANGE,
           IGNORE_CONSTRAINT)
 #endif // INCLUDE_ALL_GCS
+#if INCLUDE_JVMCI
+ JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER_WITH_TYPE,
+             JVMCI_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
+             JVMCI_PRODUCT_FLAG_MEMBER_WITH_TYPE,
+             JVMCI_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
+             JVMCI_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
+             JVMCI_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
+             JVMCI_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
+             IGNORE_RANGE,
+             IGNORE_CONSTRAINT)
+#endif // INCLUDE_JVMCI
 #ifdef COMPILER1
  C1_FLAGS(C1_DEVELOP_FLAG_MEMBER_WITH_TYPE,
           C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
--- a/hotspot/src/share/vm/runtime/handles.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/handles.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,13 +30,11 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef ASSERT
 oop* HandleArea::allocate_handle(oop obj) {
   assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark");
   assert(_no_handle_mark_nesting == 0, "allocating handle inside NoHandleMark");
-  assert(obj->is_oop(), err_msg("not an oop: " INTPTR_FORMAT, (intptr_t*) obj));
+  assert(obj->is_oop(), "not an oop: " INTPTR_FORMAT, p2i(obj));
   return real_allocate_handle(obj);
 }
 
@@ -85,10 +83,9 @@
   // The thread local handle areas should not get very large
   if (TraceHandleAllocation && (size_t)handles_visited > TotalHandleAllocationLimit) {
 #ifdef ASSERT
-    warning("%d: Visited in HandleMark : %d",
-      _nof_handlemarks, handles_visited);
+    warning("%d: Visited in HandleMark : " SIZE_FORMAT, _nof_handlemarks, handles_visited);
 #else
-    warning("Visited in HandleMark : %d", handles_visited);
+    warning("Visited in HandleMark : " SIZE_FORMAT, handles_visited);
 #endif
   }
   if (_prev != NULL) _prev->oops_do(f);
@@ -137,10 +134,10 @@
     handles /= sizeof(void *); // Adjust for size of a handle
     if (handles > HandleAllocationLimit) {
       // Note: _nof_handlemarks is only set in debug mode
-      warning("%d: Allocated in HandleMark : %d", _nof_handlemarks, handles);
+      warning("%d: Allocated in HandleMark : " SIZE_FORMAT, _nof_handlemarks, handles);
     }
 
-    tty->print_cr("Handles %d", handles);
+    tty->print_cr("Handles " SIZE_FORMAT, handles);
   }
 #endif
 
--- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,8 +36,6 @@
 #include "runtime/vframe.hpp"
 #include "utilities/preserveException.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Implementation of InterfaceSupport
 
 #ifdef ASSERT
@@ -73,7 +71,7 @@
 }
 
 void InterfaceSupport::trace(const char* result_type, const char* header) {
-  tty->print_cr("%6d  %s", _number_of_calls, header);
+  tty->print_cr("%6ld  %s", _number_of_calls, header);
 }
 
 void InterfaceSupport::gc_alot() {
@@ -109,8 +107,7 @@
       if (FullGCALotInterval > 1) {
         _fullgc_alot_counter = 1+(long)((double)FullGCALotInterval*os::random()/(max_jint+1.0));
         if (PrintGCDetails && Verbose) {
-          tty->print_cr("Full gc no: %u\tInterval: %d", invocations,
-                        _fullgc_alot_counter);
+          tty->print_cr("Full gc no: %u\tInterval: %ld", invocations, _fullgc_alot_counter);
         }
       } else {
         _fullgc_alot_counter = 1;
@@ -130,8 +127,7 @@
         if (ScavengeALotInterval > 1) {
           _scavenge_alot_counter = 1+(long)((double)ScavengeALotInterval*os::random()/(max_jint+1.0));
           if (PrintGCDetails && Verbose) {
-            tty->print_cr("Scavenge no: %u\tInterval: %d", invocations,
-                          _scavenge_alot_counter);
+            tty->print_cr("Scavenge no: %u\tInterval: %ld", invocations, _scavenge_alot_counter);
           }
         } else {
           _scavenge_alot_counter = 1;
@@ -167,25 +163,6 @@
   walk_stack_from(thread->last_java_vframe(&reg_map));
 }
 
-
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-
-static int zap_traversals = 0;
-
-void InterfaceSupport::zap_dead_locals_old() {
-  JavaThread* thread = JavaThread::current();
-  if (zap_traversals == -1) // edit constant for debugging
-    warning("I am here");
-  int zap_frame_count = 0; // count frames to help debugging
-  for (StackFrameStream sfs(thread); !sfs.is_done(); sfs.next()) {
-    sfs.current()->zap_dead_locals(thread, sfs.register_map());
-    ++zap_frame_count;
-  }
-  ++zap_traversals;
-}
-
-# endif
-
 // invocation counter for InterfaceSupport::deoptimizeAll/zombieAll functions
 int deoptimizeAllCounter = 0;
 int zombieAllCounter = 0;
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -84,10 +84,6 @@
   static void walk_stack_from(vframe* start_vf);
   static void walk_stack();
 
-# ifdef ENABLE_ZAP_DEAD_LOCALS
-  static void zap_dead_locals_old();
-# endif
-
   static void zombieAll();
   static void unlinkSymbols();
   static void deoptimizeAll();
@@ -357,11 +353,6 @@
     if (WalkStackALot) {
       InterfaceSupport::walk_stack();
     }
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-    if (ZapDeadLocalsOld) {
-      InterfaceSupport::zap_dead_locals_old();
-    }
-#endif
 #ifdef COMPILER2
     // This option is not used by Compiler 1
     if (StressDerivedPointers) {
--- a/hotspot/src/share/vm/runtime/java.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/java.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,6 +31,10 @@
 #include "compiler/compilerOracle.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "interpreter/bytecodeHistogram.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 #include "memory/oopFactory.hpp"
 #include "memory/universe.hpp"
 #include "oops/constantPool.hpp"
@@ -80,8 +84,6 @@
 #include "opto/runtime.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 GrowableArray<Method*>* collected_profiled_methods;
 
 int compare_methods(Method** a, Method** b) {
@@ -159,7 +161,7 @@
   collected_invoked_methods->sort(&compare_methods);
   //
   tty->cr();
-  tty->print_cr("Histogram Over MethodOop Invocation Counters (cutoff = %d):", MethodHistogramCutoff);
+  tty->print_cr("Histogram Over MethodOop Invocation Counters (cutoff = " INTX_FORMAT "):", MethodHistogramCutoff);
   tty->cr();
   tty->print_cr("____Count_(I+C)____Method________________________Module_________________");
   unsigned total = 0, int_total = 0, comp_total = 0, static_total = 0, final_total = 0,
@@ -236,7 +238,6 @@
     Runtime1::print_statistics();
     Deoptimization::print_statistics();
     SharedRuntime::print_statistics();
-    nmethod::print_statistics();
   }
 #endif /* COMPILER1 */
 
@@ -246,7 +247,6 @@
     Compile::print_statistics();
 #ifndef COMPILER1
     Deoptimization::print_statistics();
-    nmethod::print_statistics();
     SharedRuntime::print_statistics();
 #endif //COMPILER1
     os::print_statistics();
@@ -264,7 +264,21 @@
     IndexSet::print_statistics();
   }
 #endif // ASSERT
-#endif // COMPILER2
+#else
+#ifdef INCLUDE_JVMCI
+#ifndef COMPILER1
+  if ((TraceDeoptimization || LogVMOutput || LogCompilation) && UseCompiler) {
+    FlagSetting fs(DisplayVMOutput, DisplayVMOutput && TraceDeoptimization);
+    Deoptimization::print_statistics();
+    SharedRuntime::print_statistics();
+  }
+#endif
+#endif
+#endif
+
+  if (PrintNMethodStatistics) {
+    nmethod::print_statistics();
+  }
   if (CountCompiledCalls) {
     print_method_invocation_histogram();
   }
@@ -331,14 +345,6 @@
     BiasedLocking::print_counters();
   }
 
-#ifdef ENABLE_ZAP_DEAD_LOCALS
-#ifdef COMPILER2
-  if (ZapDeadCompiledLocals) {
-    tty->print_cr("Compile::CompiledZap_count = %d", Compile::CompiledZap_count);
-    tty->print_cr("OptoRuntime::ZapDeadCompiledLocals_count = %d", OptoRuntime::ZapDeadCompiledLocals_count);
-  }
-#endif // COMPILER2
-#endif // ENABLE_ZAP_DEAD_LOCALS
   // Native memory tracking data
   if (PrintNMTStatistics) {
     MemTracker::final_report(tty);
@@ -417,6 +423,10 @@
     }
   }
 
+#if INCLUDE_JVMCI
+  JVMCIRuntime::shutdown();
+#endif
+
   // Hang forever on exit if we're reporting an error.
   if (ShowMessageBoxOnError && is_error_reported()) {
     os::infinite_sleep();
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,6 +41,10 @@
 #include "runtime/signature.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 
 // -----------------------------------------------------
 // Implementation of JavaCallWrapper
@@ -51,7 +55,7 @@
 
   guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code");
   assert(!thread->owns_locks(), "must release all locks when leaving VM");
-  guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler");
+  guarantee(thread->can_call_java(), "cannot make java calls from the native compiler");
   _result   = result;
 
   // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub,
@@ -309,19 +313,27 @@
 
   CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 
-  // Verify the arguments
+#if INCLUDE_JVMCI
+  // Gets the nmethod (if any) that should be called instead of normal target
+  nmethod* alternative_target = args->alternative_target();
+  if (alternative_target == NULL) {
+#endif
+// Verify the arguments
 
   if (CheckJNICalls)  {
     args->verify(method, result->get_type(), thread);
   }
   else debug_only(args->verify(method, result->get_type(), thread));
+#if INCLUDE_JVMCI
+  }
+#else
 
   // Ignore call if method is empty
   if (method->is_empty_method()) {
     assert(result->get_type() == T_VOID, "an empty method must return a void value");
     return;
   }
-
+#endif
 
 #ifdef ASSERT
   { InstanceKlass* holder = method->method_holder();
@@ -333,7 +345,7 @@
 #endif
 
 
-  assert(!thread->is_Compiler_thread(), "cannot compile from the compiler");
+  assert(thread->can_call_java(), "cannot compile from the native compiler");
   if (CompilationPolicy::must_be_compiled(method)) {
     CompileBroker::compile_method(method, InvocationEntryBci,
                                   CompilationPolicy::policy()->initial_compile_level(),
@@ -377,6 +389,17 @@
     os::bang_stack_shadow_pages();
   }
 
+#if INCLUDE_JVMCI
+  if (alternative_target != NULL) {
+    if (alternative_target->is_alive()) {
+      thread->set_jvmci_alternate_call_target(alternative_target->verified_entry_point());
+      entry_point = method->adapter()->get_i2c_entry();
+    } else {
+      THROW(vmSymbols::jdk_vm_ci_code_InvalidInstalledCodeException());
+    }
+  }
+#endif
+
   // do call
   { JavaCallWrapper link(method, receiver, result, CHECK);
     { HandleMark hm(thread);  // HandleMark used by HandleMarkCleaner
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -103,6 +103,7 @@
   int         _size;
   int         _max_size;
   bool        _start_at_zero;      // Support late setting of receiver
+  JVMCI_ONLY(nmethod*    _alternative_target;) // Nmethod that should be called instead of normal target
 
   void initialize() {
     // Starts at first element to support set_receiver.
@@ -112,6 +113,7 @@
     _max_size = _default_size;
     _size = 0;
     _start_at_zero = false;
+    JVMCI_ONLY(_alternative_target = NULL;)
   }
 
  public:
@@ -133,11 +135,22 @@
       _max_size = max_size;
       _size = 0;
       _start_at_zero = false;
+      JVMCI_ONLY(_alternative_target = NULL;)
     } else {
       initialize();
     }
   }
 
+#if INCLUDE_JVMCI
+  void set_alternative_target(nmethod* target) {
+    _alternative_target = target;
+  }
+
+  nmethod* alternative_target() {
+    return _alternative_target;
+  }
+#endif
+
   inline void push_oop(Handle h)    { _is_oop[_size] = true;
                                JNITypes::put_obj((oop)h.raw_value(), _value, _size); }
 
--- a/hotspot/src/share/vm/runtime/jniHandles.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,8 +30,6 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 JNIHandleBlock* JNIHandles::_global_handles       = NULL;
 JNIHandleBlock* JNIHandles::_weak_global_handles  = NULL;
 oop             JNIHandles::_deleted_handle       = NULL;
@@ -281,7 +279,7 @@
       _blocks_allocated++;
       if (TraceJNIHandleAllocation) {
         tty->print_cr("JNIHandleBlock " INTPTR_FORMAT " allocated (%d total blocks)",
-                      block, _blocks_allocated);
+                      p2i(block), _blocks_allocated);
       }
       if (ZapJNIHandleArea) block->zap();
       #ifndef PRODUCT
@@ -396,7 +394,7 @@
         } else {
           // The weakly referenced object is not alive, clear the reference by storing NULL
           if (TraceReferenceGC) {
-            tty->print_cr("Clearing JNI weak reference (" INTPTR_FORMAT ")", root);
+            tty->print_cr("Clearing JNI weak reference (" INTPTR_FORMAT ")", p2i(root));
           }
           *root = NULL;
         }
@@ -504,7 +502,7 @@
   }
   if (TraceJNIHandleAllocation) {
     tty->print_cr("Rebuild free list JNIHandleBlock " INTPTR_FORMAT " blocks=%d used=%d free=%d add=%d",
-      this, blocks, total-free, free, _allocate_before_rebuild);
+                  p2i(this), blocks, total-free, free, _allocate_before_rebuild);
   }
 }
 
--- a/hotspot/src/share/vm/runtime/memprofiler.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/memprofiler.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -75,7 +75,7 @@
     // Create log file
     _log_fp = fopen(log_name , "w+");
     if (_log_fp == NULL) {
-      fatal(err_msg("MemProfiler: Cannot create log file: %s", log_name));
+      fatal("MemProfiler: Cannot create log file: %s", log_name);
     }
     fprintf(_log_fp, "MemProfiler: sizes are in Kb, time is in seconds since startup\n\n");
     fprintf(_log_fp, "  time, #thr, #cls,  heap,  heap,  perm,  perm,  code, hndls, rescs, oopmp\n");
--- a/hotspot/src/share/vm/runtime/mutex.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/mutex.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,8 +42,6 @@
 # include "mutex_bsd.inline.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
 //
 // Native Monitor-Mutex locking - theory of operations
@@ -897,8 +895,7 @@
 void Monitor::lock(Thread * Self) {
   // Ensure that the Monitor requires/allows safepoint checks.
   assert(_safepoint_check_required != Monitor::_safepoint_check_never,
-         err_msg("This lock should never have a safepoint check: %s",
-                 name()));
+         "This lock should never have a safepoint check: %s", name());
 
 #ifdef CHECK_UNHANDLED_OOPS
   // Clear unhandled oops so we get a crash right away.  Only clear for non-vm
@@ -960,8 +957,7 @@
 void Monitor::lock_without_safepoint_check(Thread * Self) {
   // Ensure that the Monitor does not require or allow safepoint checks.
   assert(_safepoint_check_required != Monitor::_safepoint_check_always,
-         err_msg("This lock should always have a safepoint check: %s",
-                 name()));
+         "This lock should always have a safepoint check: %s", name());
   assert(_owner != Self, "invariant");
   ILock(Self);
   assert(_owner == NULL, "invariant");
@@ -1093,9 +1089,9 @@
                    bool as_suspend_equivalent) {
   // Make sure safepoint checking is used properly.
   assert(!(_safepoint_check_required == Monitor::_safepoint_check_never && no_safepoint_check == false),
-         err_msg("This lock should never have a safepoint check: %s", name()));
+         "This lock should never have a safepoint check: %s", name());
   assert(!(_safepoint_check_required == Monitor::_safepoint_check_always && no_safepoint_check == true),
-         err_msg("This lock should always have a safepoint check: %s", name()));
+         "This lock should always have a safepoint check: %s", name());
 
   Thread * const Self = Thread::current();
   assert(_owner == Self, "invariant");
@@ -1214,9 +1210,9 @@
 }
 
 void Monitor::print_on_error(outputStream* st) const {
-  st->print("[" PTR_FORMAT, this);
+  st->print("[" PTR_FORMAT, p2i(this));
   st->print("] %s", _name);
-  st->print(" - owner thread: " PTR_FORMAT, _owner);
+  st->print(" - owner thread: " PTR_FORMAT, p2i(_owner));
 }
 
 
@@ -1227,7 +1223,8 @@
 
 #ifndef PRODUCT
 void Monitor::print_on(outputStream* st) const {
-  st->print_cr("Mutex: [0x%lx/0x%lx] %s - owner: 0x%lx", this, _LockWord.FullWord, _name, _owner);
+  st->print_cr("Mutex: [" PTR_FORMAT "/" PTR_FORMAT "] %s - owner: " PTR_FORMAT,
+               p2i(this), _LockWord.FullWord, _name, p2i(_owner));
 }
 #endif
 
@@ -1335,9 +1332,9 @@
         !(this == Safepoint_lock && contains(locks, Terminator_lock) &&
         SafepointSynchronize::is_synchronizing())) {
       new_owner->print_owned_locks();
-      fatal(err_msg("acquiring lock %s/%d out of order with lock %s/%d -- "
-                    "possible deadlock", this->name(), this->rank(),
-                    locks->name(), locks->rank()));
+      fatal("acquiring lock %s/%d out of order with lock %s/%d -- "
+            "possible deadlock", this->name(), this->rank(),
+            locks->name(), locks->rank());
     }
 
     this->_next = new_owner->_owned_locks;
@@ -1386,8 +1383,7 @@
          || rank() == Mutex::special, "wrong thread state for using locks");
   if (StrictSafepointChecks) {
     if (thread->is_VM_thread() && !allow_vm_block()) {
-      fatal(err_msg("VM thread using lock %s (not allowed to block on)",
-                    name()));
+      fatal("VM thread using lock %s (not allowed to block on)", name());
     }
     debug_only(if (rank() != Mutex::special) \
                thread->check_for_valid_safepoint_state(false);)
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -127,6 +127,7 @@
 Mutex*   Management_lock              = NULL;
 Monitor* Service_lock                 = NULL;
 Monitor* PeriodicTask_lock            = NULL;
+Mutex*   LogConfiguration_lock        = NULL;
 
 #ifdef INCLUDE_TRACE
 Mutex*   JfrStacktrace_lock           = NULL;
@@ -155,7 +156,7 @@
   // see if invoker of VM operation owns it
   VM_Operation* op = VMThread::vm_operation();
   if (op != NULL && op->calling_thread() == lock->owner()) return;
-  fatal(err_msg("must own lock %s", lock->name()));
+  fatal("must own lock %s", lock->name());
 }
 
 // a stronger assertion than the above
@@ -163,7 +164,7 @@
   if (IgnoreLockingAssertions) return;
   assert(lock != NULL, "Need non-NULL lock");
   if (lock->owned_by_self()) return;
-  fatal(err_msg("must own lock %s", lock->name()));
+  fatal("must own lock %s", lock->name());
 }
 #endif
 
@@ -282,6 +283,7 @@
   if (WhiteBoxAPI) {
     def(Compilation_lock           , Monitor, leaf,        false, Monitor::_safepoint_check_never);
   }
+  def(LogConfiguration_lock        , Mutex,   nonleaf,     false, Monitor::_safepoint_check_always);
 
 #ifdef INCLUDE_TRACE
   def(JfrMsg_lock                  , Monitor, leaf,        true,  Monitor::_safepoint_check_always);
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -126,6 +126,7 @@
 extern Mutex*   Management_lock;                 // a lock used to serialize JVM management
 extern Monitor* Service_lock;                    // a lock used for service thread operation
 extern Monitor* PeriodicTask_lock;               // protects the periodic task structure
+extern Mutex*   LogConfiguration_lock;           // protects configuration of logging
 
 #ifdef INCLUDE_TRACE
 extern Mutex*   JfrStacktrace_lock;              // used to guard access to the JFR stacktrace table
--- a/hotspot/src/share/vm/runtime/os.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -61,8 +61,6 @@
 
 # include <signal.h>
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 OSThread*         os::_starting_thread    = NULL;
 address           os::_polling_page       = NULL;
 volatile int32_t* os::_mem_serialize_page = NULL;
@@ -621,12 +619,12 @@
   ptr = guarded.get_user_ptr();
 #endif
   if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
-    tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
+    tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, p2i(ptr));
     breakpoint();
   }
   debug_only(if (paranoid) verify_memory(ptr));
   if (PrintMalloc && tty != NULL) {
-    tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
+    tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, p2i(ptr));
   }
 
   // we do not track guard memory
@@ -658,7 +656,7 @@
     return os::malloc(size, memflags, stack);
   }
   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
-    tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
+    tty->print_cr("os::realloc caught " PTR_FORMAT, p2i(memblock));
     breakpoint();
   }
   // NMT support
@@ -671,7 +669,7 @@
   // always move the block
   void* ptr = os::malloc(size, memflags, stack);
   if (PrintMalloc && tty != NULL) {
-    tty->print_cr("os::realloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
+    tty->print_cr("os::realloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, p2i(memblock), p2i(ptr));
   }
   // Copy to new memory if malloc didn't fail
   if ( ptr != NULL ) {
@@ -681,7 +679,7 @@
     memcpy(ptr, memblock, MIN2(size, memblock_size));
     if (paranoid) verify_memory(MemTracker::malloc_base(ptr));
     if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
-      tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
+      tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, p2i(ptr));
       breakpoint();
     }
     os::free(memblock);
@@ -696,7 +694,7 @@
 #ifdef ASSERT
   if (memblock == NULL) return;
   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
-    if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
+    if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, p2i(memblock));
     breakpoint();
   }
   void* membase = MemTracker::record_free(memblock);
@@ -796,7 +794,7 @@
   }
 
   address p = start;
-  st->print(PTR_FORMAT ":   ", start);
+  st->print(PTR_FORMAT ":   ", p2i(start));
   while (p < end) {
     switch (unitsize) {
       case 1: st->print("%02x", *(u1*)p); break;
@@ -809,7 +807,7 @@
     if (cols >= cols_per_line && p < end) {
        cols = 0;
        st->cr();
-       st->print(PTR_FORMAT ":   ", p);
+       st->print(PTR_FORMAT ":   ", p2i(p));
     } else {
        st->print(" ");
     }
@@ -856,9 +854,9 @@
   size_t mem = physical_memory()/G;
   if (mem == 0) {  // for low memory systems
     mem = physical_memory()/M;
-    st->print("%d cores, %dM, ", processor_count(), mem);
+    st->print("%d cores, " SIZE_FORMAT "M, ", processor_count(), mem);
   } else {
-    st->print("%d cores, %dG, ", processor_count(), mem);
+    st->print("%d cores, " SIZE_FORMAT "G, ", processor_count(), mem);
   }
   get_summary_os_info(buf, buflen);
   st->print_raw(buf);
@@ -914,41 +912,40 @@
       // the interpreter is generated into a buffer blob
       InterpreterCodelet* i = Interpreter::codelet_containing(addr);
       if (i != NULL) {
-        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an Interpreter codelet", addr, (int)(addr - i->code_begin()));
+        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an Interpreter codelet", p2i(addr), (int)(addr - i->code_begin()));
         i->print_on(st);
         return;
       }
       if (Interpreter::contains(addr)) {
         st->print_cr(INTPTR_FORMAT " is pointing into interpreter code"
-                     " (not bytecode specific)", addr);
+                     " (not bytecode specific)", p2i(addr));
         return;
       }
       //
       if (AdapterHandlerLibrary::contains(b)) {
-        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an AdapterHandler", addr, (int)(addr - b->code_begin()));
+        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an AdapterHandler", p2i(addr), (int)(addr - b->code_begin()));
         AdapterHandlerLibrary::print_handler_on(st, b);
       }
       // the stubroutines are generated into a buffer blob
       StubCodeDesc* d = StubCodeDesc::desc_for(addr);
       if (d != NULL) {
-        st->print_cr(INTPTR_FORMAT " is at begin+%d in a stub", addr, (int)(addr - d->begin()));
+        st->print_cr(INTPTR_FORMAT " is at begin+%d in a stub", p2i(addr), (int)(addr - d->begin()));
         d->print_on(st);
         st->cr();
         return;
       }
       if (StubRoutines::contains(addr)) {
-        st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) "
-                     "stub routine", addr);
+        st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", p2i(addr));
         return;
       }
       // the InlineCacheBuffer is using stubs generated into a buffer blob
       if (InlineCacheBuffer::contains(addr)) {
-        st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
+        st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", p2i(addr));
         return;
       }
       VtableStub* v = VtableStubs::stub_containing(addr);
       if (v != NULL) {
-        st->print_cr(INTPTR_FORMAT " is at entry_point+%d in a vtable stub", addr, (int)(addr - v->entry_point()));
+        st->print_cr(INTPTR_FORMAT " is at entry_point+%d in a vtable stub", p2i(addr), (int)(addr - v->entry_point()));
         v->print_on(st);
         st->cr();
         return;
@@ -958,7 +955,7 @@
     if (nm != NULL) {
       ResourceMark rm;
       st->print(INTPTR_FORMAT " is at entry_point+%d in (nmethod*)" INTPTR_FORMAT,
-                addr, (int)(addr - nm->entry_point()), nm);
+                p2i(addr), (int)(addr - nm->entry_point()), p2i(nm));
       if (verbose) {
         st->print(" for ");
         nm->method()->print_value_on(st);
@@ -967,7 +964,7 @@
       nm->print_nmethod(verbose);
       return;
     }
-    st->print_cr(INTPTR_FORMAT " is at code_begin+%d in ", addr, (int)(addr - b->code_begin()));
+    st->print_cr(INTPTR_FORMAT " is at code_begin+%d in ", p2i(addr), (int)(addr - b->code_begin()));
     b->print_on(st);
     return;
   }
@@ -985,9 +982,9 @@
     }
     if (print) {
       if (p == (HeapWord*) addr) {
-        st->print_cr(INTPTR_FORMAT " is an oop", addr);
+        st->print_cr(INTPTR_FORMAT " is an oop", p2i(addr));
       } else {
-        st->print_cr(INTPTR_FORMAT " is pointing into object: " INTPTR_FORMAT, addr, p);
+        st->print_cr(INTPTR_FORMAT " is pointing into object: " INTPTR_FORMAT, p2i(addr), p2i(p));
       }
       oop(p)->print_on(st);
       return;
@@ -995,22 +992,22 @@
   } else {
     if (Universe::heap()->is_in_reserved(addr)) {
       st->print_cr(INTPTR_FORMAT " is an unallocated location "
-                   "in the heap", addr);
+                   "in the heap", p2i(addr));
       return;
     }
   }
   if (JNIHandles::is_global_handle((jobject) addr)) {
-    st->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
+    st->print_cr(INTPTR_FORMAT " is a global jni handle", p2i(addr));
     return;
   }
   if (JNIHandles::is_weak_global_handle((jobject) addr)) {
-    st->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
+    st->print_cr(INTPTR_FORMAT " is a weak global jni handle", p2i(addr));
     return;
   }
 #ifndef PRODUCT
   // we don't keep the block list in product mode
   if (JNIHandleBlock::any_contains((jobject) addr)) {
-    st->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
+    st->print_cr(INTPTR_FORMAT " is a local jni handle", p2i(addr));
     return;
   }
 #endif
@@ -1020,7 +1017,7 @@
     if (thread->privileged_stack_top() != NULL &&
         thread->privileged_stack_top()->contains(addr)) {
       st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack "
-                   "for thread: " INTPTR_FORMAT, addr, thread);
+                   "for thread: " INTPTR_FORMAT, p2i(addr), p2i(thread));
       if (verbose) thread->print_on(st);
       return;
     }
@@ -1029,7 +1026,7 @@
       if (verbose) {
         thread->print_on(st);
       } else {
-        st->print_cr(INTPTR_FORMAT " is a thread", addr);
+        st->print_cr(INTPTR_FORMAT " is a thread", p2i(addr));
       }
       return;
     }
@@ -1038,7 +1035,7 @@
     if (thread->stack_base() >= addr &&
         addr > (thread->stack_base() - thread->stack_size())) {
       st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: "
-                   INTPTR_FORMAT, addr, thread);
+                   INTPTR_FORMAT, p2i(addr), p2i(thread));
       if (verbose) thread->print_on(st);
       return;
     }
@@ -1052,7 +1049,7 @@
       st->cr();
     } else {
       // Use addr->print() from the debugger instead (not here)
-      st->print_cr(INTPTR_FORMAT " is pointing into metadata", addr);
+      st->print_cr(INTPTR_FORMAT " is pointing into metadata", p2i(addr));
     }
     return;
   }
@@ -1062,7 +1059,7 @@
     return;
   }
 
-  st->print_cr(INTPTR_FORMAT " is an unknown value", addr);
+  st->print_cr(INTPTR_FORMAT " is an unknown value", p2i(addr));
 }
 
 // Looks like all platforms except IA64 can use the same function to check
@@ -1461,7 +1458,7 @@
                   " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT
                   " size=" SIZE_FORMAT,
                   str, region_min_size, region_max_size,
-                  page_size, base, size);
+                  page_size, p2i(base), size);
   }
 }
 #endif  // #ifndef PRODUCT
@@ -1679,7 +1676,7 @@
 
 #ifndef PRODUCT
 
-#define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b))
+#define assert_eq(a,b) assert(a == b, SIZE_FORMAT " != " SIZE_FORMAT, a, b)
 
 class TestOS : AllStatic {
   static size_t small_page_size() {
--- a/hotspot/src/share/vm/runtime/osThread.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/osThread.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,8 +26,6 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/osThread.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 OSThread::OSThread(OSThreadStartFunc start_proc, void* start_parm) {
   pd_initialize();
   set_start_proc(start_proc);
@@ -41,7 +39,7 @@
 
 // Printing
 void OSThread::print_on(outputStream *st) const {
-  st->print("nid=0x%lx ", thread_id());
+  st->print("nid=0x%x ", thread_id());
   switch (_state) {
     case ALLOCATED:               st->print("allocated ");                 break;
     case INITIALIZED:             st->print("initialized ");               break;
--- a/hotspot/src/share/vm/runtime/perfData.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/perfData.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -34,8 +34,6 @@
 #include "utilities/exceptions.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 PerfDataList*   PerfDataManager::_all = NULL;
 PerfDataList*   PerfDataManager::_sampled = NULL;
 PerfDataList*   PerfDataManager::_constants = NULL;
@@ -170,14 +168,14 @@
 
   if (PerfTraceDataCreation) {
     tty->print("name = %s, dtype = %d, variability = %d,"
-               " units = %d, dsize = %d, vlen = %d,"
-               " pad_length = %d, size = %d, on_c_heap = %s,"
+               " units = %d, dsize = " SIZE_FORMAT ", vlen = " SIZE_FORMAT ","
+               " pad_length = " SIZE_FORMAT ", size = " SIZE_FORMAT ", on_c_heap = %s,"
                " address = " INTPTR_FORMAT ","
                " data address = " INTPTR_FORMAT "\n",
                cname, dtype, variability(),
                units(), dsize, vlen,
                pad_length, size, is_on_c_heap() ? "TRUE":"FALSE",
-               psmp, valuep);
+               p2i(psmp), p2i(valuep));
   }
 
   // record the start of the entry and the location of the data field.
--- a/hotspot/src/share/vm/runtime/perfMemory.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/perfMemory.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,8 +36,6 @@
 #include "runtime/statSampler.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Prefix of performance data file.
 const char               PERFDATA_NAME[] = "hsperfdata";
 
@@ -96,7 +94,7 @@
 
   if (PerfTraceMemOps) {
     tty->print("PerfDataMemorySize = " SIZE_FORMAT ","
-               " os::vm_allocation_granularity = " SIZE_FORMAT ","
+               " os::vm_allocation_granularity = %d,"
                " adjusted size = " SIZE_FORMAT "\n",
                PerfDataMemorySize,
                os::vm_allocation_granularity(),
@@ -129,7 +127,7 @@
     if (PerfTraceMemOps) {
       tty->print("PerfMemory created: address = " INTPTR_FORMAT ","
                  " size = " SIZE_FORMAT "\n",
-                 (void*)_start,
+                 p2i(_start),
                  _capacity);
     }
 
--- a/hotspot/src/share/vm/runtime/rframe.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/rframe.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -155,7 +155,7 @@
 
 void RFrame::print(const char* kind) {
 #ifndef PRODUCT
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
   int cnt = top_method()->interpreter_invocation_count();
 #else
   int cnt = top_method()->invocation_count();
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -63,8 +63,6 @@
 #include "c1/c1_globals.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // --------------------------------------------------------------------------------------------------
 // Implementation of Safepoint begin/end
 
@@ -689,7 +687,7 @@
       break;
 
     default:
-     fatal(err_msg("Illegal threadstate encountered: %d", state));
+     fatal("Illegal threadstate encountered: %d", state);
   }
 
   // Check for pending. async. exceptions or suspends - except if the
@@ -773,12 +771,10 @@
   // To debug the long safepoint, specify both DieOnSafepointTimeout &
   // ShowMessageBoxOnError.
   if (DieOnSafepointTimeout) {
-    char msg[1024];
     VM_Operation *op = VMThread::vm_operation();
-    sprintf(msg, "Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
-            SafepointTimeoutDelay,
-            op != NULL ? op->name() : "no vm operation");
-    fatal(msg);
+    fatal("Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
+          SafepointTimeoutDelay,
+          op != NULL ? op->name() : "no vm operation");
   }
 }
 
@@ -895,7 +891,7 @@
     case _running:
     default:
        tty->print_cr("restart thread " INTPTR_FORMAT " with state %d",
-                      _thread, _type);
+                     p2i(_thread), _type);
        _thread->print();
       ShouldNotReachHere();
   }
@@ -917,7 +913,7 @@
 
   st->print_cr("Thread: " INTPTR_FORMAT
               "  [0x%2x] State: %s _has_called_back %d _at_poll_safepoint %d",
-               _thread, _thread->osthread()->thread_id(), s, _has_called_back,
+               p2i(_thread), _thread->osthread()->thread_id(), s, _has_called_back,
                _at_poll_safepoint);
 
   _thread->print_thread_state_on(st);
@@ -936,7 +932,7 @@
 
   // Step 1: Find the nmethod from the return address
   if (ShowSafepointMsgs && Verbose) {
-    tty->print_cr("Polling page exception at " INTPTR_FORMAT, thread()->saved_exception_pc());
+    tty->print_cr("Polling page exception at " INTPTR_FORMAT, p2i(thread()->saved_exception_pc()));
   }
   address real_return_addr = thread()->saved_exception_pc();
 
@@ -1243,8 +1239,8 @@
   if (!need_to_track_page_armed_status) {
     tty->print_cr("Polling page always armed");
   } else {
-    tty->print_cr("Defer polling page loop count = %d\n",
-                 DeferPollingPageLoopCount);
+    tty->print_cr("Defer polling page loop count = " INTX_FORMAT "\n",
+                  DeferPollingPageLoopCount);
   }
 
   for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) {
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
@@ -46,6 +47,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/biasedLocking.hpp"
+#include "runtime/compilationPolicy.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.hpp"
@@ -64,8 +66,6 @@
 #include "c1/c1_Runtime1.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Shared stub locations
 RuntimeStub*        SharedRuntime::_wrong_method_blob;
 RuntimeStub*        SharedRuntime::_wrong_method_abstract_blob;
@@ -93,12 +93,13 @@
   _resolve_virtual_call_blob           = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C),       "resolve_virtual_call");
   _resolve_static_call_blob            = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),        "resolve_static_call");
 
-#ifdef COMPILER2
-  // Vectors are generated only by C2.
-  if (is_wide_vector(MaxVectorSize)) {
+#if defined(COMPILER2) || INCLUDE_JVMCI
+  // Vectors are generated only by C2 and JVMCI.
+  bool support_wide = is_wide_vector(MaxVectorSize);
+  if (support_wide) {
     _polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP);
   }
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
   _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP);
   _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN);
 
@@ -183,7 +184,7 @@
     tty->print_cr("IC Miss Histogram:");
     int tot_misses = 0;
     for (int i = 0; i < _ICmiss_index; i++) {
-      tty->print_cr("  at: " INTPTR_FORMAT "  nof: %d", _ICmiss_at[i], _ICmiss_count[i]);
+      tty->print_cr("  at: " INTPTR_FORMAT "  nof: %d", p2i(_ICmiss_at[i]), _ICmiss_count[i]);
       tot_misses += _ICmiss_count[i];
     }
     tty->print_cr("Total IC misses: %7d", tot_misses);
@@ -455,12 +456,18 @@
 // previous frame depending on the return address.
 
 address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) {
-  assert(frame::verify_return_pc(return_address), err_msg("must be a return address: " INTPTR_FORMAT, return_address));
+  assert(frame::verify_return_pc(return_address), "must be a return address: " INTPTR_FORMAT, p2i(return_address));
   assert(thread->frames_to_pop_failed_realloc() == 0 || Interpreter::contains(return_address), "missed frames to pop?");
 
   // Reset method handle flag.
   thread->set_is_method_handle_return(false);
 
+#if INCLUDE_JVMCI
+  // JVMCI's ExceptionHandlerStub expects the thread local exception PC to be clear
+  // and other exception handler continuations do not read it
+  thread->set_exception_pc(NULL);
+#endif
+
   // The fastest case first
   CodeBlob* blob = CodeCache::find_blob(return_address);
   nmethod* nm = (blob != NULL) ? blob->as_nmethod_or_null() : NULL;
@@ -498,7 +505,7 @@
 
 #ifndef PRODUCT
   { ResourceMark rm;
-    tty->print_cr("No exception handler found for exception at " INTPTR_FORMAT " - potential problems:", return_address);
+    tty->print_cr("No exception handler found for exception at " INTPTR_FORMAT " - potential problems:", p2i(return_address));
     tty->print_cr("a) exception happened in (new?) code stubs/buffers that is not handled here");
     tty->print_cr("b) other problem");
   }
@@ -526,8 +533,13 @@
   assert(((nmethod*)cb)->is_at_poll_or_poll_return(pc),
     "safepoint polling: type must be poll");
 
-  assert(((NativeInstruction*)pc)->is_safepoint_poll(),
-    "Only polling locations are used for safepoint");
+#ifdef ASSERT
+  if (!((NativeInstruction*)pc)->is_safepoint_poll()) {
+    tty->print_cr("bad pc: " PTR_FORMAT, p2i(pc));
+    Disassembler::decode(cb);
+    fatal("Only polling locations are used for safepoint");
+  }
+#endif
 
   bool at_poll_return = ((nmethod*)cb)->is_at_poll_return(pc);
   bool has_wide_vectors = ((nmethod*)cb)->has_wide_vectors();
@@ -617,6 +629,33 @@
   assert(nm != NULL, "must exist");
   ResourceMark rm;
 
+#if INCLUDE_JVMCI
+  if (nm->is_compiled_by_jvmci()) {
+    // lookup exception handler for this pc
+    int catch_pco = ret_pc - nm->code_begin();
+    ExceptionHandlerTable table(nm);
+    HandlerTableEntry *t = table.entry_for(catch_pco, -1, 0);
+    if (t != NULL) {
+      return nm->code_begin() + t->pco();
+    } else {
+      // there is no exception handler for this pc => deoptimize
+      nm->make_not_entrant();
+
+      // Use Deoptimization::deoptimize for all of its side-effects:
+      // revoking biases of monitors, gathering traps statistics, logging...
+      // it also patches the return pc but we do not care about that
+      // since we return a continuation to the deopt_blob below.
+      JavaThread* thread = JavaThread::current();
+      RegisterMap reg_map(thread, UseBiasedLocking);
+      frame runtime_frame = thread->last_frame();
+      frame caller_frame = runtime_frame.sender(&reg_map);
+      Deoptimization::deoptimize(thread, caller_frame, &reg_map, Deoptimization::Reason_not_compiled_exception_handler);
+
+      return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+    }
+  }
+#endif // INCLUDE_JVMCI
+
   ScopeDesc* sd = nm->scope_desc_at(ret_pc);
   // determine handler bci, if any
   EXCEPTION_MARK;
@@ -685,7 +724,7 @@
 #endif
 
   if (t == NULL) {
-    tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci);
+    tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", p2i(ret_pc), handler_bci);
     tty->print_cr("   Exception:");
     exception->print();
     tty->cr();
@@ -737,6 +776,15 @@
   throw_and_post_jvmti_exception(thread, exception);
 JRT_END
 
+#if INCLUDE_JVMCI
+address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason) {
+  assert(deopt_reason > Deoptimization::Reason_none && deopt_reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
+  thread->set_jvmci_implicit_exception_pc(pc);
+  thread->set_pending_deoptimization(Deoptimization::make_trap_request((Deoptimization::DeoptReason)deopt_reason, Deoptimization::Action_reinterpret));
+  return (SharedRuntime::deopt_blob()->implicit_exception_uncommon_trap());
+}
+#endif // INCLUDE_JVMCI
+
 address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
                                                            address pc,
                                                            SharedRuntime::ImplicitExceptionKind exception_kind)
@@ -769,7 +817,7 @@
         // in a debug VM to verify the correctness of the compiled
         // method stack banging.
         assert(thread->deopt_mark() == NULL, "no stack overflow from deopt blob/uncommon trap");
-        Events::log_exception(thread, "StackOverflowError at " INTPTR_FORMAT, pc);
+        Events::log_exception(thread, "StackOverflowError at " INTPTR_FORMAT, p2i(pc));
         return StubRoutines::throw_StackOverflowError_entry();
       }
 
@@ -786,10 +834,10 @@
 
           if (vt_stub->is_abstract_method_error(pc)) {
             assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs");
-            Events::log_exception(thread, "AbstractMethodError at " INTPTR_FORMAT, pc);
+            Events::log_exception(thread, "AbstractMethodError at " INTPTR_FORMAT, p2i(pc));
             return StubRoutines::throw_AbstractMethodError_entry();
           } else {
-            Events::log_exception(thread, "NullPointerException at vtable entry " INTPTR_FORMAT, pc);
+            Events::log_exception(thread, "NullPointerException at vtable entry " INTPTR_FORMAT, p2i(pc));
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
         } else {
@@ -806,10 +854,10 @@
           if (!cb->is_nmethod()) {
             bool is_in_blob = cb->is_adapter_blob() || cb->is_method_handles_adapter_blob();
             if (!is_in_blob) {
-              cb->print();
-              fatal(err_msg("exception happened outside interpreter, nmethods and vtable stubs at pc " INTPTR_FORMAT, pc));
+              // Allow normal crash reporting to handle this
+              return NULL;
             }
-            Events::log_exception(thread, "NullPointerException in code blob at " INTPTR_FORMAT, pc);
+            Events::log_exception(thread, "NullPointerException in code blob at " INTPTR_FORMAT, p2i(pc));
             // There is no handler here, so we will simply unwind.
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
@@ -821,20 +869,32 @@
             // => the nmethod is not yet active (i.e., the frame
             // is not set up yet) => use return address pushed by
             // caller => don't push another return address
-            Events::log_exception(thread, "NullPointerException in IC check " INTPTR_FORMAT, pc);
+            Events::log_exception(thread, "NullPointerException in IC check " INTPTR_FORMAT, p2i(pc));
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
 
           if (nm->method()->is_method_handle_intrinsic()) {
             // exception happened inside MH dispatch code, similar to a vtable stub
-            Events::log_exception(thread, "NullPointerException in MH adapter " INTPTR_FORMAT, pc);
+            Events::log_exception(thread, "NullPointerException in MH adapter " INTPTR_FORMAT, p2i(pc));
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
 
 #ifndef PRODUCT
           _implicit_null_throws++;
 #endif
+#if INCLUDE_JVMCI
+          if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) {
+            // If there's no PcDesc then we'll die way down inside of
+            // deopt instead of just getting normal error reporting,
+            // so only go there if it will succeed.
+            return deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_null_check);
+          } else {
+#endif // INCLUDE_JVMCI
+          assert (nm->is_nmethod(), "Expect nmethod");
           target_pc = nm->continuation_for_implicit_exception(pc);
+#if INCLUDE_JVMCI
+          }
+#endif // INCLUDE_JVMCI
           // If there's an unexpected fault, target_pc might be NULL,
           // in which case we want to fall through into the normal
           // error handling code.
@@ -846,11 +906,19 @@
 
       case IMPLICIT_DIVIDE_BY_ZERO: {
         nmethod* nm = CodeCache::find_nmethod(pc);
-        guarantee(nm != NULL, "must have containing nmethod for implicit division-by-zero exceptions");
+        guarantee(nm != NULL, "must have containing compiled method for implicit division-by-zero exceptions");
 #ifndef PRODUCT
         _implicit_div0_throws++;
 #endif
+#if INCLUDE_JVMCI
+        if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) {
+          return deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_div0_check);
+        } else {
+#endif // INCLUDE_JVMCI
         target_pc = nm->continuation_for_implicit_exception(pc);
+#if INCLUDE_JVMCI
+        }
+#endif // INCLUDE_JVMCI
         // If there's an unexpected fault, target_pc might be NULL,
         // in which case we want to fall through into the normal
         // error handling code.
@@ -862,12 +930,18 @@
 
     assert(exception_kind == IMPLICIT_NULL || exception_kind == IMPLICIT_DIVIDE_BY_ZERO, "wrong implicit exception kind");
 
-    // for AbortVMOnException flag
-    NOT_PRODUCT(Exceptions::debug_check_abort("java.lang.NullPointerException"));
     if (exception_kind == IMPLICIT_NULL) {
-      Events::log_exception(thread, "Implicit null exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc);
+#ifndef PRODUCT
+      // for AbortVMOnException flag
+      Exceptions::debug_check_abort("java.lang.NullPointerException");
+#endif //PRODUCT
+      Events::log_exception(thread, "Implicit null exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, p2i(pc), p2i(target_pc));
     } else {
-      Events::log_exception(thread, "Implicit division by zero exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc);
+#ifndef PRODUCT
+      // for AbortVMOnException flag
+      Exceptions::debug_check_abort("java.lang.ArithmeticException");
+#endif //PRODUCT
+      Events::log_exception(thread, "Implicit division by zero exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, p2i(pc), p2i(target_pc));
     }
     return target_pc;
   }
@@ -916,6 +990,16 @@
 
 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
   assert(obj->is_oop(), "must be a valid oop");
+#if INCLUDE_JVMCI
+  // This removes the requirement for JVMCI compilers to emit code
+  // performing a dynamic check that obj has a finalizer before
+  // calling this routine. There should be no performance impact
+  // for C1 since it emits a dynamic check. C2 and the interpreter
+  // uses other runtime routines for registering finalizers.
+  if (!obj->klass()->has_finalizer()) {
+    return;
+  }
+#endif // INCLUDE_JVMCI
   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
 JRT_END
@@ -1157,6 +1241,7 @@
   methodHandle callee_method = call_info.selected_method();
 
   assert((!is_virtual && invoke_code == Bytecodes::_invokestatic ) ||
+         (!is_virtual && invoke_code == Bytecodes::_invokespecial) ||
          (!is_virtual && invoke_code == Bytecodes::_invokehandle ) ||
          (!is_virtual && invoke_code == Bytecodes::_invokedynamic) ||
          ( is_virtual && invoke_code != Bytecodes::_invokestatic ), "inconsistent bytecode");
@@ -1176,7 +1261,8 @@
       (is_optimized) ? "optimized " : "", (is_virtual) ? "virtual" : "static",
       Bytecodes::name(invoke_code));
     callee_method->print_short_name(tty);
-    tty->print_cr(" at pc: " INTPTR_FORMAT " to code: " INTPTR_FORMAT, caller_frame.pc(), callee_method->code());
+    tty->print_cr(" at pc: " INTPTR_FORMAT " to code: " INTPTR_FORMAT,
+                  p2i(caller_frame.pc()), p2i(callee_method->code()));
   }
 #endif
 
@@ -1367,9 +1453,6 @@
 JRT_END
 
 
-
-
-
 methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) {
   ResourceMark rm(thread);
   CallInfo call_info;
@@ -1397,8 +1480,8 @@
       ResourceMark rm(thread);
       tty->print("converting IC miss to reresolve (%s) call to", Bytecodes::name(bc));
       callee_method->print_short_name(tty);
-      tty->print_cr(" from pc: " INTPTR_FORMAT, caller_frame.pc());
-      tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
+      tty->print_cr(" from pc: " INTPTR_FORMAT, p2i(caller_frame.pc()));
+      tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
     }
     return callee_method;
   }
@@ -1415,7 +1498,7 @@
     ResourceMark rm(thread);
     tty->print("IC miss (%s) call to", Bytecodes::name(bc));
     callee_method->print_short_name(tty);
-    tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
+    tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
   }
 
   if (ICMissHistogram) {
@@ -1447,7 +1530,7 @@
           ResourceMark rm(thread);
           tty->print("OPTIMIZED IC miss (%s) call to", Bytecodes::name(bc));
           callee_method->print_short_name(tty);
-          tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
+          tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
         }
         should_be_mono = true;
       } else if (inline_cache->is_icholder_call()) {
@@ -1464,7 +1547,7 @@
               ResourceMark rm(thread);
               tty->print("FALSE IC miss (%s) converting to compiled call to", Bytecodes::name(bc));
               callee_method->print_short_name(tty);
-              tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
+              tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
             }
             should_be_mono = true;
           }
@@ -1493,6 +1576,8 @@
       } else {
         // Either clean or megamorphic
       }
+    } else {
+      fatal("Unimplemented");
     }
   } // Release CompiledIC_lock
 
@@ -1520,6 +1605,10 @@
 
     address pc = caller.pc();
 
+    // Check for static or virtual call
+    bool is_static_call = false;
+    nmethod* caller_nm = CodeCache::find_nmethod(pc);
+
     // Default call_addr is the location of the "basic" call.
     // Determine the address of the call we a reresolving. With
     // Inline Caches we will always find a recognizable call.
@@ -1549,10 +1638,6 @@
         call_addr = ncall->instruction_address();
       }
     }
-
-    // Check for static or virtual call
-    bool is_static_call = false;
-    nmethod* caller_nm = CodeCache::find_nmethod(pc);
     // Make sure nmethod doesn't get deoptimized and removed until
     // this is done with it.
     // CLEANUP - with lazy deopt shouldn't need this lock
@@ -1604,7 +1689,7 @@
     ResourceMark rm(thread);
     tty->print("handle_wrong_method reresolving call to");
     callee_method->print_short_name(tty);
-    tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
+    tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
   }
 #endif
 
@@ -1630,7 +1715,7 @@
   for (int i = 0; i < member_arg_pos; i++) {
     VMReg a =    regs_with_member_name[i].first();
     VMReg b = regs_without_member_name[i].first();
-    assert(a->value() == b->value(), err_msg_res("register allocation mismatch: a=%d, b=%d", a->value(), b->value()));
+    assert(a->value() == b->value(), "register allocation mismatch: a=" INTX_FORMAT ", b=" INTX_FORMAT, a->value(), b->value());
   }
   assert(regs_with_member_name[member_arg_pos].first()->is_valid(), "bad member arg");
 }
@@ -1712,25 +1797,25 @@
         if (callee == cb || callee->is_adapter_blob()) {
           // static call or optimized virtual
           if (TraceCallFixup) {
-            tty->print("fixup callsite           at " INTPTR_FORMAT " to compiled code for", caller_pc);
+            tty->print("fixup callsite           at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
             moop->print_short_name(tty);
-            tty->print_cr(" to " INTPTR_FORMAT, entry_point);
+            tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
           }
           call->set_destination_mt_safe(entry_point);
         } else {
           if (TraceCallFixup) {
-            tty->print("failed to fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc);
+            tty->print("failed to fixup callsite at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
             moop->print_short_name(tty);
-            tty->print_cr(" to " INTPTR_FORMAT, entry_point);
+            tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
           }
           // assert is too strong could also be resolve destinations.
           // assert(InlineCacheBuffer::contains(destination) || VtableStubs::contains(destination), "must be");
         }
       } else {
           if (TraceCallFixup) {
-            tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", caller_pc);
+            tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
             moop->print_short_name(tty);
-            tty->print_cr(" to " INTPTR_FORMAT, entry_point);
+            tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
           }
       }
     }
@@ -2567,8 +2652,7 @@
     // Perform the work while holding the lock, but perform any printing outside the lock
     MutexLocker mu(AdapterHandlerLibrary_lock);
     // See if somebody beat us to it
-    nm = method->code();
-    if (nm != NULL) {
+    if (method->code() != NULL) {
       return;
     }
 
@@ -2810,7 +2894,7 @@
   FREE_C_HEAP_ARRAY(intptr_t, buf);
 JRT_END
 
-bool AdapterHandlerLibrary::contains(CodeBlob* b) {
+bool AdapterHandlerLibrary::contains(const CodeBlob* b) {
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
     AdapterHandlerEntry* a = iter.next();
@@ -2819,7 +2903,7 @@
   return false;
 }
 
-void AdapterHandlerLibrary::print_handler_on(outputStream* st, CodeBlob* b) {
+void AdapterHandlerLibrary::print_handler_on(outputStream* st, const CodeBlob* b) {
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
     AdapterHandlerEntry* a = iter.next();
@@ -2834,8 +2918,8 @@
 
 void AdapterHandlerEntry::print_adapter_on(outputStream* st) const {
   st->print_cr("AHE@" INTPTR_FORMAT ": %s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
-               (intptr_t) this, fingerprint()->as_string(),
-               get_i2c_entry(), get_c2i_entry(), get_c2i_unverified_entry());
+               p2i(this), fingerprint()->as_string(),
+               p2i(get_i2c_entry()), p2i(get_c2i_entry()), p2i(get_c2i_unverified_entry()));
 
 }
 
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -199,6 +199,9 @@
   static address continuation_for_implicit_exception(JavaThread* thread,
                                                      address faulting_pc,
                                                      ImplicitExceptionKind exception_kind);
+#if INCLUDE_JVMCI
+  static address deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason);
+#endif
 
   // Shared stub locations
   static address get_poll_stub(address pc);
@@ -417,6 +420,12 @@
                                                       const VMRegPair *regs,
                                                       AdapterFingerPrint* fingerprint);
 
+  static void gen_i2c_adapter(MacroAssembler *_masm,
+                              int total_args_passed,
+                              int comp_args_on_stack,
+                              const BasicType *sig_bt,
+                              const VMRegPair *regs);
+
   // OSR support
 
   // OSR_migration_begin will extract the jvm state from an interpreter
@@ -475,6 +484,7 @@
   // A compiled caller has just called the interpreter, but compiled code
   // exists.  Patch the caller so he no longer calls into the interpreter.
   static void fixup_callers_callsite(Method* moop, address ret_pc);
+  static bool should_fixup_call_destination(address destination, address entry_point, address caller_pc, Method* moop, CodeBlob* cb);
 
   // Slow-path Locking and Unlocking
   static void complete_monitor_locking_C(oopDesc* obj, BasicLock* lock, JavaThread* thread);
@@ -673,9 +683,9 @@
   static void create_native_wrapper(methodHandle method);
   static AdapterHandlerEntry* get_adapter(methodHandle method);
 
-  static void print_handler(CodeBlob* b) { print_handler_on(tty, b); }
-  static void print_handler_on(outputStream* st, CodeBlob* b);
-  static bool contains(CodeBlob* b);
+  static void print_handler(const CodeBlob* b) { print_handler_on(tty, b); }
+  static void print_handler_on(outputStream* st, const CodeBlob* b);
+  static bool contains(const CodeBlob* b);
 #ifndef PRODUCT
   static void print_statistics();
 #endif // PRODUCT
--- a/hotspot/src/share/vm/runtime/signature.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/signature.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -32,8 +32,6 @@
 #include "oops/typeArrayKlass.hpp"
 #include "runtime/signature.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Implementation of SignatureIterator
 
 // Signature syntax:
@@ -51,7 +49,7 @@
 }
 
 void SignatureIterator::expect(char c) {
-  if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c));
+  if (_signature->byte_at(_index) != c) fatal("expecting %c", c);
   _index++;
 }
 
@@ -209,7 +207,7 @@
         return;
         break;
       default:
-        tty->print_cr("*** parameter is %d", fingerprint & parameter_feature_mask);
+        tty->print_cr("*** parameter is " UINT64_FORMAT, fingerprint & parameter_feature_mask);
         tty->print_cr("*** fingerprint is " PTR64_FORMAT, saved_fingerprint);
         ShouldNotReachHere();
         break;
--- a/hotspot/src/share/vm/runtime/stackValueCollection.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/stackValueCollection.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -25,8 +25,6 @@
 #include "precompiled.hpp"
 #include "runtime/stackValueCollection.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 jint StackValueCollection::int_at(int slot) const {
   intptr_t val =  at(slot)->get_int();
   jint ival = *((jint*) (&val));
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -136,8 +136,9 @@
 address StubRoutines::_sha512_implCompressMB = NULL;
 
 address StubRoutines::_updateBytesCRC32 = NULL;
-address StubRoutines::_crc_table_adr = NULL;
+address StubRoutines::_crc_table_adr =    NULL;
 
+address StubRoutines::_crc32c_table_addr = NULL;
 address StubRoutines::_updateBytesCRC32C = NULL;
 address StubRoutines::_updateBytesAdler32 = NULL;
 
@@ -147,9 +148,10 @@
 address StubRoutines::_montgomeryMultiply = NULL;
 address StubRoutines::_montgomerySquare = NULL;
 
+address StubRoutines::_dexp = NULL;
+
 double (* StubRoutines::_intrinsic_log   )(double) = NULL;
 double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
-double (* StubRoutines::_intrinsic_exp   )(double) = NULL;
 double (* StubRoutines::_intrinsic_pow   )(double, double) = NULL;
 double (* StubRoutines::_intrinsic_sin   )(double) = NULL;
 double (* StubRoutines::_intrinsic_cos   )(double) = NULL;
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -197,6 +197,7 @@
   static address _updateBytesCRC32;
   static address _crc_table_adr;
 
+  static address _crc32c_table_addr;
   static address _updateBytesCRC32C;
   static address _updateBytesAdler32;
 
@@ -206,6 +207,8 @@
   static address _montgomeryMultiply;
   static address _montgomerySquare;
 
+  static address _dexp;
+
   // These are versions of the java.lang.Math methods which perform
   // the same operations as the intrinsic version.  They are used for
   // constant folding in the compiler to ensure equivalence.  If the
@@ -214,7 +217,6 @@
   // SharedRuntime.
   static double (*_intrinsic_log)(double);
   static double (*_intrinsic_log10)(double);
-  static double (*_intrinsic_exp)(double);
   static double (*_intrinsic_pow)(double, double);
   static double (*_intrinsic_sin)(double);
   static double (*_intrinsic_cos)(double);
@@ -364,6 +366,7 @@
   static address updateBytesCRC32()    { return _updateBytesCRC32; }
   static address crc_table_addr()      { return _crc_table_adr; }
 
+  static address crc32c_table_addr()   { return _crc32c_table_addr; }
   static address updateBytesCRC32C()   { return _updateBytesCRC32C; }
   static address updateBytesAdler32()  { return _updateBytesAdler32; }
 
@@ -373,6 +376,8 @@
   static address montgomeryMultiply()  { return _montgomeryMultiply; }
   static address montgomerySquare()    { return _montgomerySquare; }
 
+  static address dexp()                {return _dexp; }
+
   static address select_fill_function(BasicType t, bool aligned, const char* &name);
 
   static address zero_aligned_words()   { return _zero_aligned_words; }
@@ -385,10 +390,6 @@
     assert(_intrinsic_log != NULL, "must be defined");
     return _intrinsic_log10(d);
   }
-  static double  intrinsic_exp(double d) {
-    assert(_intrinsic_exp != NULL, "must be defined");
-    return _intrinsic_exp(d);
-  }
   static double  intrinsic_pow(double d, double d2) {
     assert(_intrinsic_pow != NULL, "must be defined");
     return _intrinsic_pow(d, d2);
--- a/hotspot/src/share/vm/runtime/sweeper.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -43,8 +43,6 @@
 #include "utilities/ticks.inline.hpp"
 #include "utilities/xmlstream.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef ASSERT
 
 #define SWEEP(nm) record_sweep(nm, __LINE__)
@@ -62,12 +60,12 @@
 
   void print() {
       tty->print_cr("traversal = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
-                    PTR_FORMAT " state = %d traversal_mark %d line = %d",
+                    PTR_FORMAT " state = %d traversal_mark %ld line = %d",
                     traversal,
                     compile_id,
                     kind == NULL ? "" : kind,
-                    uep,
-                    vep,
+                    p2i(uep),
+                    p2i(vep),
                     state,
                     traversal_mark,
                     line);
@@ -223,7 +221,7 @@
     _total_time_this_sweep = Tickspan();
 
     if (PrintMethodFlushing) {
-      tty->print_cr("### Sweep: stack traversal %d", _traversals);
+      tty->print_cr("### Sweep: stack traversal %ld", _traversals);
     }
     Threads::nmethods_do(&mark_activation_closure);
 
@@ -482,7 +480,7 @@
 
 #ifdef ASSERT
   if(PrintMethodFlushing) {
-    tty->print_cr("### sweeper:      sweep time(%d): ", (jlong)sweep_time.value());
+    tty->print_cr("### sweeper:      sweep time(" JLONG_FORMAT "): ", sweep_time.value());
   }
 #endif
 
@@ -592,14 +590,14 @@
     if (nm->is_marked_for_reclamation()) {
       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
       if (PrintMethodFlushing && Verbose) {
-        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
+        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), p2i(nm));
       }
       release_nmethod(nm);
       assert(result == None, "sanity");
       result = Flushed;
     } else {
       if (PrintMethodFlushing && Verbose) {
-        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
+        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), p2i(nm));
       }
       nm->mark_for_reclamation();
       // Keep track of code cache state change
@@ -619,7 +617,7 @@
         nm->clear_ic_stubs();
       }
       if (PrintMethodFlushing && Verbose) {
-        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
+        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), p2i(nm));
       }
       // Code cache state change is tracked in make_zombie()
       nm->make_zombie();
@@ -636,7 +634,7 @@
   } else if (nm->is_unloaded()) {
     // 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);
+      tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), p2i(nm));
     }
     if (nm->is_osr_method()) {
       SWEEP(nm);
@@ -743,7 +741,7 @@
         // Code cache state change is tracked in make_not_entrant()
         if (PrintMethodFlushing && Verbose) {
           tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f",
-              nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold);
+              nm->compile_id(), p2i(nm), nm->hotness_counter(), reset_val, threshold);
         }
       }
     }
--- a/hotspot/src/share/vm/runtime/sweeper.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/sweeper.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -27,7 +27,9 @@
 
 class WhiteBox;
 
+#include "code/codeCache.hpp"
 #include "utilities/ticks.hpp"
+
 // An NmethodSweeper is an incremental cleaner for:
 //    - cleanup inline caches
 //    - reclamation of nmethods
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -52,8 +52,6 @@
   #define NOINLINE
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // The "core" versions of monitor enter and exit reside in this file.
 // The interpreter and compilers contain specialized transliterated
 // variants of the enter-exit fast-path operations.  See i486.ad fast_lock(),
@@ -1417,7 +1415,7 @@
         if (object->is_instance()) {
           ResourceMark rm;
           tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
-                        (void *) object, (intptr_t) object->mark(),
+                        p2i(object), p2i(object->mark()),
                         object->klass()->external_name());
         }
       }
@@ -1465,7 +1463,7 @@
       if (object->is_instance()) {
         ResourceMark rm;
         tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
-                      (void *) object, (intptr_t) object->mark(),
+                      p2i(object), p2i(object->mark()),
                       object->klass()->external_name());
       }
     }
@@ -1529,7 +1527,7 @@
       if (obj->is_instance()) {
         ResourceMark rm;
         tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
-                      (void *) obj, (intptr_t) obj->mark(), obj->klass()->external_name());
+                      p2i(obj), p2i(obj->mark()), obj->klass()->external_name());
       }
     }
 
@@ -1702,9 +1700,9 @@
         Handle obj((oop) mid->object());
         tty->print("INFO: unexpected locked object:");
         javaVFrame::print_locked_object_class_name(tty, obj, "locked");
-        fatal(err_msg("exiting JavaThread=" INTPTR_FORMAT
-                      " unexpectedly owns ObjectMonitor=" INTPTR_FORMAT,
-                      THREAD, mid));
+        fatal("exiting JavaThread=" INTPTR_FORMAT
+              " unexpectedly owns ObjectMonitor=" INTPTR_FORMAT,
+              p2i(THREAD), p2i(mid));
       }
       (void)mid->complete_exit(CHECK);
     }
--- a/hotspot/src/share/vm/runtime/thread.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,12 +31,14 @@
 #include "code/codeCacheExtensions.hpp"
 #include "code/scopeDesc.hpp"
 #include "compiler/compileBroker.hpp"
+#include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/linkResolver.hpp"
 #include "interpreter/oopMapCache.hpp"
 #include "jvmtifiles/jvmtiEnv.hpp"
+#include "logging/logConfiguration.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/universe.inline.hpp"
@@ -99,6 +101,10 @@
 #include "gc/g1/concurrentMarkThread.inline.hpp"
 #include "gc/parallel/pcTasks.hpp"
 #endif // INCLUDE_ALL_GCS
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 #ifdef COMPILER1
 #include "c1/c1_Compiler.hpp"
 #endif
@@ -110,8 +116,6 @@
 #include "runtime/rtmLocking.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef DTRACE_ENABLED
 
 // Only bother with this argument setup if dtrace is available
@@ -163,7 +167,7 @@
     if (TraceBiasedLocking) {
       if (aligned_addr != real_malloc_addr) {
         tty->print_cr("Aligned thread " INTPTR_FORMAT " to " INTPTR_FORMAT,
-                      real_malloc_addr, aligned_addr);
+                      p2i(real_malloc_addr), p2i(aligned_addr));
       }
     }
     ((Thread*) aligned_addr)->_real_malloc_address = real_malloc_addr;
@@ -797,7 +801,7 @@
     if (os::get_native_priority(this, &os_prio) == OS_OK) {
       st->print("os_prio=%d ", os_prio);
     }
-    st->print("tid=" INTPTR_FORMAT " ", this);
+    st->print("tid=" INTPTR_FORMAT " ", p2i(this));
     ext().print_on(st);
     osthread()->print_on(st);
   }
@@ -816,7 +820,7 @@
   else                                st->print("Thread");
 
   st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
-            _stack_base - _stack_size, _stack_base);
+            p2i(_stack_base - _stack_size), p2i(_stack_base));
 
   if (osthread()) {
     st->print(" [id=%d]", osthread()->thread_id());
@@ -879,7 +883,7 @@
            cur != VMOperationRequest_lock &&
            cur != VMOperationQueue_lock) ||
            cur->rank() == Mutex::special) {
-        fatal(err_msg("Thread holding lock at safepoint that vm can block on: %s", cur->name()));
+        fatal("Thread holding lock at safepoint that vm can block on: %s", cur->name());
       }
     }
   }
@@ -1148,6 +1152,7 @@
 NamedThread::NamedThread() : Thread() {
   _name = NULL;
   _processed_thread = NULL;
+  _gc_id = GCId::undefined();
 }
 
 NamedThread::~NamedThread() {
@@ -1386,6 +1391,33 @@
 
 // ======= JavaThread ========
 
+#if INCLUDE_JVMCI
+
+jlong* JavaThread::_jvmci_old_thread_counters;
+
+bool jvmci_counters_include(JavaThread* thread) {
+  oop threadObj = thread->threadObj();
+  return !JVMCICountersExcludeCompiler || !thread->is_Compiler_thread();
+}
+
+void JavaThread::collect_counters(typeArrayOop array) {
+  if (JVMCICounterSize > 0) {
+    MutexLocker tl(Threads_lock);
+    for (int i = 0; i < array->length(); i++) {
+      array->long_at_put(i, _jvmci_old_thread_counters[i]);
+    }
+    for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
+      if (jvmci_counters_include(tp)) {
+        for (int i = 0; i < array->length(); i++) {
+          array->long_at_put(i, array->long_at(i) + tp->_jvmci_counters[i]);
+        }
+      }
+    }
+  }
+}
+
+#endif // INCLUDE_JVMCI
+
 // A JavaThread is a normal Java thread
 
 void JavaThread::initialize() {
@@ -1418,6 +1450,20 @@
   _in_deopt_handler = 0;
   _doing_unsafe_access = false;
   _stack_guard_state = stack_guard_unused;
+#if INCLUDE_JVMCI
+  _pending_monitorenter = false;
+  _pending_deoptimization = -1;
+  _pending_failed_speculation = NULL;
+  _pending_transfer_to_interpreter = false;
+  _jvmci._alternate_call_target = NULL;
+  assert(_jvmci._implicit_exception_pc == NULL, "must be");
+  if (JVMCICounterSize > 0) {
+    _jvmci_counters = NEW_C_HEAP_ARRAY(jlong, JVMCICounterSize, mtInternal);
+    memset(_jvmci_counters, 0, sizeof(jlong) * JVMCICounterSize);
+  } else {
+    _jvmci_counters = NULL;
+  }
+#endif // INCLUDE_JVMCI
   (void)const_cast<oop&>(_exception_oop = oop(NULL));
   _exception_pc  = 0;
   _exception_handler_pc = 0;
@@ -1592,6 +1638,17 @@
   ThreadSafepointState::destroy(this);
   if (_thread_profiler != NULL) delete _thread_profiler;
   if (_thread_stat != NULL) delete _thread_stat;
+
+#if INCLUDE_JVMCI
+  if (JVMCICounterSize > 0) {
+    if (jvmci_counters_include(this)) {
+      for (int i = 0; i < JVMCICounterSize; i++) {
+        _jvmci_old_thread_counters[i] += _jvmci_counters[i];
+      }
+    }
+    FREE_C_HEAP_ARRAY(jlong, _jvmci_counters);
+  }
+#endif // INCLUDE_JVMCI
 }
 
 
@@ -2039,10 +2096,10 @@
 
       if (TraceExceptions) {
         ResourceMark rm;
-        tty->print("Async. exception installed at runtime exit (" INTPTR_FORMAT ")", this);
+        tty->print("Async. exception installed at runtime exit (" INTPTR_FORMAT ")", p2i(this));
         if (has_last_Java_frame()) {
           frame f = last_frame();
-          tty->print(" (pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " )", f.pc(), f.sp());
+          tty->print(" (pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " )", p2i(f.pc()), p2i(f.sp()));
         }
         tty->print_cr(" of type: %s", InstanceKlass::cast(_pending_async_exception->klass())->external_name());
       }
@@ -2135,7 +2192,7 @@
 
   // Do not throw asynchronous exceptions against the compiler thread
   // (the compiler thread should not be a Java thread -- fix in 1.4.2)
-  if (is_Compiler_thread()) return;
+  if (!can_call_java()) return;
 
   {
     // Actually throw the Throwable against the target Thread - however
@@ -2614,12 +2671,6 @@
   StackFrameStream fst(this, UseBiasedLocking);
   for (; !fst.is_done(); fst.next()) {
     if (fst.current()->should_be_deoptimized()) {
-      if (LogCompilation && xtty != NULL) {
-        nmethod* nm = fst.current()->cb()->as_nmethod_or_null();
-        xtty->elem("deoptimized thread='" UINTX_FORMAT "' compile_id='%d'",
-                   this->name(), nm != NULL ? nm->compile_id() : -1);
-      }
-
       Deoptimization::deoptimize(this, *fst.current(), fst.register_map());
     }
   }
@@ -2658,6 +2709,8 @@
   // Traverse the GCHandles
   Thread::oops_do(f, cld_f, cf);
 
+  JVMCI_ONLY(f->do_oop((oop*)&_pending_failed_speculation);)
+
   assert((!has_last_Java_frame() && java_call_counter() == 0) ||
          (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
 
@@ -2809,7 +2862,7 @@
     st->print(", id=%d", osthread()->thread_id());
   }
   st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
-            _stack_base - _stack_size, _stack_base);
+            p2i(_stack_base - _stack_size), p2i(_stack_base));
   st->print("]");
   return;
 }
@@ -3047,15 +3100,15 @@
   template <class T> inline void do_oop_work(T* p) {
     oop obj = oopDesc::load_decode_heap_oop(p);
     if (obj == NULL) return;
-    tty->print(INTPTR_FORMAT ": ", p);
+    tty->print(INTPTR_FORMAT ": ", p2i(p));
     if (obj->is_oop_or_null()) {
       if (obj->is_objArray()) {
-        tty->print_cr("valid objArray: " INTPTR_FORMAT, (oopDesc*) obj);
+        tty->print_cr("valid objArray: " INTPTR_FORMAT, p2i(obj));
       } else {
         obj->print();
       }
     } else {
-      tty->print_cr("invalid oop: " INTPTR_FORMAT, (oopDesc*) obj);
+      tty->print_cr("invalid oop: " INTPTR_FORMAT, p2i(obj));
     }
     tty->cr();
   }
@@ -3175,6 +3228,10 @@
 #endif
 }
 
+bool CompilerThread::can_call_java() const {
+  return _compiler != NULL && _compiler->is_jvmci();
+}
+
 // Create sweeper thread
 CodeCacheSweeperThread::CodeCacheSweeperThread()
 : JavaThread(&sweeper_thread_entry) {
@@ -3306,6 +3363,10 @@
   // Initialize the os module before using TLS
   os::init();
 
+  // Record VM creation timing statistics
+  TraceVmCreationTime create_vm_timer;
+  create_vm_timer.start();
+
   // Initialize system properties.
   Arguments::init_system_properties();
 
@@ -3315,6 +3376,9 @@
   // Update/Initialize System properties after JDK version number is known
   Arguments::init_version_specific_system_properties();
 
+  // Make sure to initialize log configuration *before* parsing arguments
+  LogConfiguration::initialize(create_vm_timer.begin_time());
+
   // Parse arguments
   jint parse_result = Arguments::parse(args);
   if (parse_result != JNI_OK) return parse_result;
@@ -3341,10 +3405,6 @@
 
   HOTSPOT_VM_INIT_BEGIN();
 
-  // Record VM creation timing statistics
-  TraceVmCreationTime create_vm_timer;
-  create_vm_timer.start();
-
   // Timing (must come after argument parsing)
   TraceTime timer("Create VM", TraceStartupTime);
 
@@ -3380,6 +3440,15 @@
   // Initialize global data structures and create system classes in heap
   vm_init_globals();
 
+#if INCLUDE_JVMCI
+  if (JVMCICounterSize > 0) {
+    JavaThread::_jvmci_old_thread_counters = NEW_C_HEAP_ARRAY(jlong, JVMCICounterSize, mtInternal);
+    memset(JavaThread::_jvmci_old_thread_counters, 0, sizeof(jlong) * JVMCICounterSize);
+  } else {
+    JavaThread::_jvmci_old_thread_counters = NULL;
+  }
+#endif // INCLUDE_JVMCI
+
   // Attach the main thread to this os thread
   JavaThread* main_thread = new JavaThread();
   main_thread->set_thread_state(_thread_in_vm);
@@ -3492,6 +3561,7 @@
   // debug stuff, that does not work until all basic classes have been initialized.
   set_init_completed();
 
+  LogConfiguration::post_initialize();
   Metaspace::post_initialize();
 
   HOTSPOT_VM_INIT_END();
@@ -3506,7 +3576,7 @@
   // Note that we do not use CHECK_0 here since we are inside an EXCEPTION_MARK and
   // set_init_completed has just been called, causing exceptions not to be shortcut
   // anymore. We call vm_exit_during_initialization directly instead.
-  SystemDictionary::compute_java_system_loader(CHECK_JNI_ERR);
+  SystemDictionary::compute_java_system_loader(CHECK_(JNI_ERR));
 
 #if INCLUDE_ALL_GCS
   // Support for ConcurrentMarkSweep. This should be cleaned up
@@ -3554,8 +3624,17 @@
     Chunk::start_chunk_pool_cleaner_task();
   }
 
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    const char* jvmciCompiler = Arguments::PropertyList_get_value(Arguments::system_properties(), "jvmci.compiler");
+    if (jvmciCompiler != NULL) {
+      JVMCIRuntime::save_compiler(jvmciCompiler);
+    }
+  }
+#endif // INCLUDE_JVMCI
+
   // initialize compiler(s)
-#if defined(COMPILER1) || defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER1) || defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI
   CompileBroker::compilation_init();
 #endif
 
@@ -3963,9 +4042,17 @@
 
   delete thread;
 
+#if INCLUDE_JVMCI
+  if (JVMCICounterSize > 0) {
+    FREE_C_HEAP_ARRAY(jlong, JavaThread::_jvmci_old_thread_counters);
+  }
+#endif
+
   // exit_globals() will delete tty
   exit_globals();
 
+  LogConfiguration::finalize();
+
   return true;
 }
 
@@ -4007,7 +4094,7 @@
   ThreadService::add_thread(p, daemon);
 
   // Possible GC point.
-  Events::log(p, "Thread added: " INTPTR_FORMAT, p);
+  Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p));
 }
 
 void Threads::remove(JavaThread* p) {
@@ -4053,7 +4140,7 @@
   } // unlock Threads_lock
 
   // Since Events::log uses a lock, we grab it outside the Threads_lock
-  Events::log(p, "Thread exited: " INTPTR_FORMAT, p);
+  Events::log(p, "Thread exited: " INTPTR_FORMAT, p2i(p));
 }
 
 // Threads_lock must be held when this is called (or must be called during a safepoint)
@@ -4096,7 +4183,7 @@
   ALL_JAVA_THREADS(p) {
     const int thread_parity = p->oops_do_parity();
     assert((thread_parity == _thread_claim_parity),
-        err_msg("Thread " PTR_FORMAT " has incorrect parity %d != %d", p2i(p), thread_parity, _thread_claim_parity));
+           "Thread " PTR_FORMAT " has incorrect parity %d != %d", p2i(p), thread_parity, _thread_claim_parity);
   }
 }
 #endif // ASSERT
@@ -4179,7 +4266,7 @@
   {
     MutexLockerEx ml(doLock ? Threads_lock : NULL);
     ALL_JAVA_THREADS(p) {
-      if (p->is_Compiler_thread()) continue;
+      if (!p->can_call_java()) continue;
 
       address pending = (address)p->current_pending_monitor();
       if (pending == monitor) {             // found a match
@@ -4236,7 +4323,7 @@
 void Threads::print_on(outputStream* st, bool print_stacks,
                        bool internal_format, bool print_concurrent_locks) {
   char buf[32];
-  st->print_cr("%s", os::local_time_string(buf, sizeof(buf)));
+  st->print_raw_cr(os::local_time_string(buf, sizeof(buf)));
 
   st->print_cr("Full thread dump %s (%s %s):",
                Abstract_VM_Version::vm_name(),
@@ -4296,7 +4383,7 @@
 
     st->print("%s", is_current ? "=>" : "  ");
 
-    st->print(PTR_FORMAT, thread);
+    st->print(PTR_FORMAT, p2i(thread));
     st->print(" ");
     thread->print_on_error(st, buf, buflen);
     st->cr();
@@ -4309,7 +4396,7 @@
     found_current = found_current || is_current;
     st->print("%s", current == VMThread::vm_thread() ? "=>" : "  ");
 
-    st->print(PTR_FORMAT, VMThread::vm_thread());
+    st->print(PTR_FORMAT, p2i(VMThread::vm_thread()));
     st->print(" ");
     VMThread::vm_thread()->print_on_error(st, buf, buflen);
     st->cr();
@@ -4320,14 +4407,14 @@
     found_current = found_current || is_current;
     st->print("%s", is_current ? "=>" : "  ");
 
-    st->print(PTR_FORMAT, wt);
+    st->print(PTR_FORMAT, p2i(wt));
     st->print(" ");
     wt->print_on_error(st, buf, buflen);
     st->cr();
   }
   if (!found_current) {
     st->cr();
-    st->print("=>" PTR_FORMAT " (exited) ", current);
+    st->print("=>" PTR_FORMAT " (exited) ", p2i(current));
     current->print_on_error(st, buf, buflen);
     st->cr();
   }
--- a/hotspot/src/share/vm/runtime/thread.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -329,6 +329,9 @@
   virtual bool is_Named_thread() const               { return false; }
   virtual bool is_Worker_thread() const              { return false; }
 
+  // Can this thread make Java upcalls
+  virtual bool can_call_java() const                 { return false; }
+
   // Casts
   virtual WorkerThread* as_Worker_thread() const     { return NULL; }
 
@@ -678,6 +681,7 @@
   char* _name;
   // log JavaThread being processed by oops_do
   JavaThread* _processed_thread;
+  uint _gc_id; // The current GC id when a thread takes part in GC
 
  public:
   NamedThread();
@@ -690,6 +694,9 @@
   JavaThread *processed_thread() { return _processed_thread; }
   void set_processed_thread(JavaThread *thread) { _processed_thread = thread; }
   virtual void print_on(outputStream* st) const;
+
+  void set_gc_id(uint gc_id) { _gc_id = gc_id; }
+  uint gc_id() { return _gc_id; }
 };
 
 // Worker threads are named and have an id of an assigned work.
@@ -900,6 +907,43 @@
 
  private:
 
+#if INCLUDE_JVMCI
+  // The _pending_* fields below are used to communicate extra information
+  // from an uncommon trap in JVMCI compiled code to the uncommon trap handler.
+
+  // Communicates the DeoptReason and DeoptAction of the uncommon trap
+  int       _pending_deoptimization;
+
+  // Specifies whether the uncommon trap is to bci 0 of a synchronized method
+  // before the monitor has been acquired.
+  bool      _pending_monitorenter;
+
+  // Specifies if the DeoptReason for the last uncommon trap was Reason_transfer_to_interpreter
+  bool      _pending_transfer_to_interpreter;
+
+  // An object that JVMCI compiled code can use to further describe and
+  // uniquely identify the  speculative optimization guarded by the uncommon trap
+  oop       _pending_failed_speculation;
+
+  // These fields are mutually exclusive in terms of live ranges.
+  union {
+    // Communicates the pc at which the most recent implicit exception occurred
+    // from the signal handler to a deoptimization stub.
+    address   _implicit_exception_pc;
+
+    // Communicates an alternative call target to an i2c stub from a JavaCall .
+    address   _alternate_call_target;
+  } _jvmci;
+
+  // Support for high precision, thread sensitive counters in JVMCI compiled code.
+  jlong*    _jvmci_counters;
+
+ public:
+  static jlong* _jvmci_old_thread_counters;
+  static void collect_counters(typeArrayOop array);
+ private:
+#endif // INCLUDE_JVMCI
+
   StackGuardState  _stack_guard_state;
 
   // Precompute the limit of the stack as used in stack overflow checks.
@@ -914,6 +958,7 @@
   volatile address _exception_handler_pc;        // PC for handler of exception
   volatile int     _is_method_handle_return;     // true (== 1) if the current exception PC is a MethodHandle call site.
 
+ private:
   // support for JNI critical regions
   jint    _jni_active_critical;                  // count of entries into JNI critical region
 
@@ -1001,6 +1046,7 @@
 
   // Testers
   virtual bool is_Java_thread() const            { return true;  }
+  virtual bool can_call_java() const             { return true; }
 
   // Thread chain operations
   JavaThread* next() const                       { return _next; }
@@ -1259,6 +1305,18 @@
   MemRegion deferred_card_mark() const           { return _deferred_card_mark; }
   void set_deferred_card_mark(MemRegion mr)      { _deferred_card_mark = mr;   }
 
+#if INCLUDE_JVMCI
+  int  pending_deoptimization() const             { return _pending_deoptimization; }
+  oop  pending_failed_speculation() const         { return _pending_failed_speculation; }
+  bool has_pending_monitorenter() const           { return _pending_monitorenter; }
+  void set_pending_monitorenter(bool b)           { _pending_monitorenter = b; }
+  void set_pending_deoptimization(int reason)     { _pending_deoptimization = reason; }
+  void set_pending_failed_speculation(oop failed_speculation) { _pending_failed_speculation = failed_speculation; }
+  void set_pending_transfer_to_interpreter(bool b) { _pending_transfer_to_interpreter = b; }
+  void set_jvmci_alternate_call_target(address a) { assert(_jvmci._alternate_call_target == NULL, "must be"); _jvmci._alternate_call_target = a; }
+  void set_jvmci_implicit_exception_pc(address a) { assert(_jvmci._implicit_exception_pc == NULL, "must be"); _jvmci._implicit_exception_pc = a; }
+#endif // INCLUDE_JVMCI
+
   // Exception handling for compiled methods
   oop      exception_oop() const                 { return _exception_oop; }
   address  exception_pc() const                  { return _exception_pc; }
@@ -1359,6 +1417,14 @@
   static ByteSize thread_state_offset()          { return byte_offset_of(JavaThread, _thread_state); }
   static ByteSize saved_exception_pc_offset()    { return byte_offset_of(JavaThread, _saved_exception_pc); }
   static ByteSize osthread_offset()              { return byte_offset_of(JavaThread, _osthread); }
+#if INCLUDE_JVMCI
+  static ByteSize pending_deoptimization_offset() { return byte_offset_of(JavaThread, _pending_deoptimization); }
+  static ByteSize pending_monitorenter_offset()  { return byte_offset_of(JavaThread, _pending_monitorenter); }
+  static ByteSize pending_failed_speculation_offset() { return byte_offset_of(JavaThread, _pending_failed_speculation); }
+  static ByteSize jvmci_alternate_call_target_offset() { return byte_offset_of(JavaThread, _jvmci._alternate_call_target); }
+  static ByteSize jvmci_implicit_exception_pc_offset() { return byte_offset_of(JavaThread, _jvmci._implicit_exception_pc); }
+  static ByteSize jvmci_counters_offset()        { return byte_offset_of(JavaThread, _jvmci_counters); }
+#endif // INCLUDE_JVMCI
   static ByteSize exception_oop_offset()         { return byte_offset_of(JavaThread, _exception_oop); }
   static ByteSize exception_pc_offset()          { return byte_offset_of(JavaThread, _exception_pc); }
   static ByteSize exception_handler_pc_offset()  { return byte_offset_of(JavaThread, _exception_handler_pc); }
@@ -1828,8 +1894,11 @@
   CompilerThread(CompileQueue* queue, CompilerCounters* counters);
 
   bool is_Compiler_thread() const                { return true; }
-  // Hide this compiler thread from external view.
-  bool is_hidden_from_external_view() const      { return true; }
+
+  virtual bool can_call_java() const;
+
+  // Hide native compiler threads from external view.
+  bool is_hidden_from_external_view() const      { return !can_call_java(); }
 
   void set_compiler(AbstractCompiler* c)         { _compiler = c; }
   AbstractCompiler* compiler() const             { return _compiler; }
--- a/hotspot/src/share/vm/runtime/timer.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/timer.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,6 +36,22 @@
   return counter_to_seconds(counter) * 1000.0;
 }
 
+elapsedTimer::elapsedTimer(jlong time, jlong timeUnitsPerSecond) {
+  _active = false;
+  jlong osTimeUnitsPerSecond = os::elapsed_frequency();
+  assert(osTimeUnitsPerSecond % 1000 == 0, "must be");
+  assert(timeUnitsPerSecond % 1000 == 0, "must be");
+  while (osTimeUnitsPerSecond < timeUnitsPerSecond) {
+    timeUnitsPerSecond /= 1000;
+    time *= 1000;
+  }
+  while (osTimeUnitsPerSecond > timeUnitsPerSecond) {
+    timeUnitsPerSecond *= 1000;
+    time /= 1000;
+  }
+  _counter = time;
+}
+
 void elapsedTimer::add(elapsedTimer t) {
   _counter += t._counter;
 }
--- a/hotspot/src/share/vm/runtime/timer.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/timer.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -37,6 +37,7 @@
   bool  _active;
  public:
   elapsedTimer()             { _active = false; reset(); }
+  elapsedTimer(jlong time, jlong timeUnitsPerSecond);
   void add(elapsedTimer t);
   void start();
   void stop();
--- a/hotspot/src/share/vm/runtime/unhandledOops.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/unhandledOops.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -31,8 +31,6 @@
 #include "runtime/unhandledOops.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #ifdef CHECK_UNHANDLED_OOPS
 const int free_list_size = 256;
 
@@ -52,7 +50,7 @@
 void UnhandledOops::dump_oops(UnhandledOops *list) {
   for (int k = 0; k < list->_oop_list->length(); k++) {
     UnhandledOopEntry entry = list->_oop_list->at(k);
-    tty->print(" " INTPTR_FORMAT, entry._oop_ptr);
+    tty->print(" " INTPTR_FORMAT, p2i(entry._oop_ptr));
   }
   tty->cr();
 }
@@ -68,7 +66,7 @@
   _level ++;
   if (unhandled_oop_print) {
     for (int i=0; i<_level; i++) tty->print(" ");
-    tty->print_cr("r " INTPTR_FORMAT, op);
+    tty->print_cr("r " INTPTR_FORMAT, p2i(op));
   }
   UnhandledOopEntry entry(op, pc);
   _oop_list->push(entry);
@@ -105,7 +103,7 @@
   _level --;
   if (unhandled_oop_print) {
     for (int i=0; i<_level; i++) tty->print(" ");
-    tty->print_cr("u " INTPTR_FORMAT, op);
+    tty->print_cr("u " INTPTR_FORMAT, p2i(op));
   }
 
   int i = _oop_list->find_from_end(op, match_oop_entry);
@@ -122,9 +120,9 @@
     // anymore, it must not have gotten unregistered properly and it's a bug
     // in the unhandled oop generator.
     if(!_thread->is_in_stack((address)entry._oop_ptr)) {
-      tty->print_cr("oop_ptr is " INTPTR_FORMAT, (address)entry._oop_ptr);
+      tty->print_cr("oop_ptr is " INTPTR_FORMAT, p2i(entry._oop_ptr));
       tty->print_cr("thread is " INTPTR_FORMAT " from pc " INTPTR_FORMAT,
-                     (address)_thread, (address)entry._pc);
+                     p2i(_thread), p2i(entry._pc));
       assert(false, "heap is corrupted by the unhandled oop detector");
     }
     // Set unhandled oops to a pattern that will crash distinctively
--- a/hotspot/src/share/vm/runtime/vframe.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vframe.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -46,8 +46,6 @@
 #include "runtime/vframeArray.hpp"
 #include "runtime/vframe_hp.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 vframe::vframe(const frame* fr, const RegisterMap* reg_map, JavaThread* thread)
 : _reg_map(reg_map), _thread(thread) {
   assert(fr != NULL, "must have frame");
@@ -146,7 +144,7 @@
 
 void javaVFrame::print_locked_object_class_name(outputStream* st, Handle obj, const char* lock_state) {
   if (obj.not_null()) {
-    st->print("\t- %s <" INTPTR_FORMAT "> ", lock_state, (address)obj());
+    st->print("\t- %s <" INTPTR_FORMAT "> ", lock_state, p2i(obj()));
     if (obj->klass() == SystemDictionary::Class_klass()) {
       st->print_cr("(a java.lang.Class for %s)", java_lang_Class::as_external_name(obj()));
     } else {
@@ -186,7 +184,7 @@
     } else if (thread()->current_park_blocker() != NULL) {
       oop obj = thread()->current_park_blocker();
       Klass* k = obj->klass();
-      st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", (address)obj, k->external_name());
+      st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", p2i(obj), k->external_name());
     }
   }
 
@@ -400,7 +398,7 @@
 
   InterpreterOopMap oop_mask;
   // oopmap for current bci
-  if (TraceDeoptimization && Verbose) {
+  if ((TraceDeoptimization && Verbose) JVMCI_ONLY( || PrintDeoptimizationDetails)) {
     methodHandle m_h(Thread::current(), method());
     OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
   } else {
@@ -493,7 +491,7 @@
 // This function is used in Class.forName, Class.newInstance, Method.Invoke,
 // AccessController.doPrivileged.
 void vframeStreamCommon::security_get_caller_frame(int depth) {
-  assert(depth >= 0, err_msg("invalid depth: %d", depth));
+  assert(depth >= 0, "invalid depth: %d", depth);
   for (int n = 0; !at_end(); security_next()) {
     if (!method()->is_ignored_by_security_stack_walk()) {
       if (n == depth) {
@@ -583,7 +581,7 @@
 void entryVFrame::print() {
   vframe::print();
   tty->print_cr("C Chunk inbetween Java");
-  tty->print_cr("C     link " INTPTR_FORMAT, _fr.link());
+  tty->print_cr("C     link " INTPTR_FORMAT, p2i(_fr.link()));
 }
 
 
@@ -620,7 +618,7 @@
       tty->print("( null )");
     } else {
       monitor->owner()->print_value();
-      tty->print("(owner=" INTPTR_FORMAT ")", (address)monitor->owner());
+      tty->print("(owner=" INTPTR_FORMAT ")", p2i(monitor->owner()));
     }
     if (monitor->eliminated()) {
       if(is_compiled_frame()) {
@@ -641,7 +639,7 @@
   Method*    m = method();
   InstanceKlass*     k = m->method_holder();
   tty->print_cr("frame( sp=" INTPTR_FORMAT ", unextended_sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")",
-                _fr.sp(),  _fr.unextended_sp(), _fr.fp(), _fr.pc());
+                p2i(_fr.sp()),  p2i(_fr.unextended_sp()), p2i(_fr.fp()), p2i(_fr.pc()));
   tty->print("%s.%s", k->internal_name(), m->name()->as_C_string());
 
   if (!m->is_native()) {
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -44,8 +44,6 @@
 #include "opto/runtime.hpp"
 #endif
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 int vframeArrayElement:: bci(void) const { return (_bci == SynchronizationEntryBCI ? 0 : _bci); }
 
 void vframeArrayElement::free_monitors(JavaThread* jt) {
@@ -294,7 +292,7 @@
 
   _frame.patch_pc(thread, pc);
 
-  assert (!method()->is_synchronized() || locks > 0 || _removed_monitors, "synchronized methods must have monitors");
+  assert (!method()->is_synchronized() || locks > 0 || _removed_monitors || raw_bci() == SynchronizationEntryBCI, "synchronized methods must have monitors");
 
   BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin();
   for (int index = 0; index < locks; index++) {
@@ -317,6 +315,10 @@
     }
   }
 
+  if (PrintDeoptimizationDetails) {
+    tty->print_cr("Expressions size: %d", expressions()->size());
+  }
+
   // Unpack expression stack
   // If this is an intermediate frame (i.e. not top frame) then this
   // only unpacks the part of the expression stack not used by callee
@@ -329,9 +331,26 @@
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print("Reconstructed expression %d (OBJECT): ", i);
+          oop o = (oop)(address)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            ResourceMark rm;
+            tty->print_raw_cr(o->klass()->name()->as_C_string());
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead stack slot.  Initialize to null in case it is an oop.
@@ -350,9 +369,26 @@
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print("Reconstructed local %d (OBJECT): ", i);
+          oop o = (oop)(address)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            ResourceMark rm;
+            tty->print_raw_cr(o->klass()->name()->as_C_string());
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead location. If it is an oop then we need a NULL to prevent GC from following it
@@ -394,7 +430,7 @@
   }
 
 #ifndef PRODUCT
-  if (TraceDeoptimization && Verbose) {
+  if (PrintDeoptimizationDetails) {
     ttyLocker ttyl;
     tty->print_cr("[%d Interpreted Frame]", ++unpack_counter);
     iframe()->print_on(tty);
@@ -415,7 +451,7 @@
     int bci = method()->bci_from(bcp);
     tty->print(" - %s", Bytecodes::name(code));
     tty->print(" @ bci %d ", bci);
-    tty->print_cr("sp = " PTR_FORMAT, iframe()->sp());
+    tty->print_cr("sp = " PTR_FORMAT, p2i(iframe()->sp()));
   }
 #endif // PRODUCT
 
@@ -605,7 +641,7 @@
 
 // Note: we cannot have print_on as const, as we allocate inside the method
 void vframeArray::print_on_2(outputStream* st)  {
-  st->print_cr(" - sp: " INTPTR_FORMAT, sp());
+  st->print_cr(" - sp: " INTPTR_FORMAT, p2i(sp()));
   st->print(" - thread: ");
   Thread::current()->print();
   st->print_cr(" - frame size: %d", frame_size());
@@ -615,7 +651,7 @@
 }
 
 void vframeArrayElement::print(outputStream* st) {
-  st->print_cr(" - interpreter_frame -> sp: " INTPTR_FORMAT, iframe()->sp());
+  st->print_cr(" - interpreter_frame -> sp: " INTPTR_FORMAT, p2i(iframe()->sp()));
 }
 
 void vframeArray::print_value_on(outputStream* st) const {
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -107,6 +107,22 @@
 #include "utilities/hashtable.hpp"
 #include "utilities/macros.hpp"
 
+#ifdef TARGET_OS_FAMILY_linux
+# include "vmStructs_linux.hpp"
+#endif
+#ifdef TARGET_OS_FAMILY_solaris
+# include "vmStructs_solaris.hpp"
+#endif
+#ifdef TARGET_OS_FAMILY_windows
+# include "vmStructs_windows.hpp"
+#endif
+#ifdef TARGET_OS_FAMILY_aix
+# include "vmStructs_aix.hpp"
+#endif
+#ifdef TARGET_OS_FAMILY_bsd
+# include "vmStructs_bsd.hpp"
+#endif
+
 #ifdef TARGET_ARCH_x86
 # include "vmStructs_x86.hpp"
 #endif
@@ -125,6 +141,7 @@
 #ifdef TARGET_ARCH_aarch64
 # include "vmStructs_aarch64.hpp"
 #endif
+
 #ifdef TARGET_OS_ARCH_linux_x86
 # include "vmStructs_linux_x86.hpp"
 #endif
@@ -161,6 +178,7 @@
 #ifdef TARGET_OS_ARCH_bsd_zero
 # include "vmStructs_bsd_zero.hpp"
 #endif
+
 #if INCLUDE_ALL_GCS
 #include "gc/cms/compactibleFreeListSpace.hpp"
 #include "gc/cms/concurrentMarkSweepGeneration.hpp"
@@ -178,6 +196,10 @@
 #include "gc/parallel/vmStructs_parallelgc.hpp"
 #endif // INCLUDE_ALL_GCS
 
+#if INCLUDE_JVMCI
+# include "jvmci/vmStructs_jvmci.hpp"
+#endif
+
 #if INCLUDE_TRACE
 #include "runtime/vmStructs_trace.hpp"
 #endif
@@ -311,6 +333,7 @@
   nonstatic_field(InstanceKlass,               _static_oop_field_count,                       u2)                                    \
   nonstatic_field(InstanceKlass,               _nonstatic_oop_map_size,                       int)                                   \
   nonstatic_field(InstanceKlass,               _is_marked_dependent,                          bool)                                  \
+  nonstatic_field(InstanceKlass,               _misc_flags,                                   u2)                                    \
   nonstatic_field(InstanceKlass,               _minor_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _major_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _init_state,                                   u1)                                    \
@@ -384,6 +407,7 @@
   nonstatic_field(Method,                      _vtable_index,                                 int)                                   \
   nonstatic_field(Method,                      _method_size,                                  u2)                                    \
   nonstatic_field(Method,                      _intrinsic_id,                                 u2)                                    \
+  nonstatic_field(Method,                      _flags,                                        u1)                                    \
   nonproduct_nonstatic_field(Method,           _compiled_invocation_count,                    int)                                   \
   volatile_nonstatic_field(Method,             _code,                                         nmethod*)                              \
   nonstatic_field(Method,                      _i2i_entry,                                    address)                               \
@@ -408,6 +432,7 @@
   nonstatic_field(Symbol,                      _identity_hash,                                short)                                 \
   nonstatic_field(Symbol,                      _length,                                       unsigned short)                        \
   unchecked_nonstatic_field(Symbol,            _body,                                         sizeof(jbyte)) /* NOTE: no type */     \
+  nonstatic_field(Symbol,                      _body[0],                                      jbyte)                                 \
   nonstatic_field(TypeArrayKlass,              _max_length,                                   int)                                   \
                                                                                                                                      \
   /***********************/                                                                                                          \
@@ -470,6 +495,8 @@
      static_field(Universe,                    _bootstrapping,                                bool)                                  \
      static_field(Universe,                    _fully_initialized,                            bool)                                  \
      static_field(Universe,                    _verify_count,                                 int)                                   \
+     static_field(Universe,                    _verify_oop_mask,                              uintptr_t)                             \
+     static_field(Universe,                    _verify_oop_bits,                              uintptr_t)                             \
      static_field(Universe,                    _non_oop_bits,                                 intptr_t)                              \
      static_field(Universe,                    _narrow_oop._base,                             address)                               \
      static_field(Universe,                    _narrow_oop._shift,                            int)                                   \
@@ -489,6 +516,10 @@
                                                                                                                                      \
   unchecked_nonstatic_field(ageTable,          sizes,                                         sizeof(ageTable::sizes))               \
                                                                                                                                      \
+  nonstatic_field(BarrierSet,                  _fake_rtti,                                    BarrierSet::FakeRtti)                  \
+                                                                                                                                     \
+  nonstatic_field(BarrierSet::FakeRtti,        _concrete_tag,                                 BarrierSet::Name)                      \
+                                                                                                                                     \
   nonstatic_field(BlockOffsetTable,            _bottom,                                       HeapWord*)                             \
   nonstatic_field(BlockOffsetTable,            _end,                                          HeapWord*)                             \
                                                                                                                                      \
@@ -578,6 +609,7 @@
   nonstatic_field(ThreadLocalAllocBuffer,      _start,                                        HeapWord*)                             \
   nonstatic_field(ThreadLocalAllocBuffer,      _top,                                          HeapWord*)                             \
   nonstatic_field(ThreadLocalAllocBuffer,      _end,                                          HeapWord*)                             \
+  nonstatic_field(ThreadLocalAllocBuffer,      _pf_top,                                       HeapWord*)                             \
   nonstatic_field(ThreadLocalAllocBuffer,      _desired_size,                                 size_t)                                \
   nonstatic_field(ThreadLocalAllocBuffer,      _refill_waste_limit,                           size_t)                                \
      static_field(ThreadLocalAllocBuffer,      _target_refills,                               unsigned)                              \
@@ -787,6 +819,8 @@
   /********************************/                                                                                                 \
                                                                                                                                      \
      static_field(CodeCache,                   _heaps,                                        GrowableArray<CodeHeap*>*)             \
+     static_field(CodeCache,                   _low_bound,                                    address)                               \
+     static_field(CodeCache,                   _high_bound,                                   address)                               \
      static_field(CodeCache,                   _scavenge_root_nmethods,                       nmethod*)                              \
                                                                                                                                      \
   /*******************************/                                                                                                  \
@@ -832,16 +866,48 @@
      static_field(StubRoutines,                _ghash_processBlocks,                          address)                               \
      static_field(StubRoutines,                _updateBytesCRC32,                             address)                               \
      static_field(StubRoutines,                _crc_table_adr,                                address)                               \
+     static_field(StubRoutines,                _crc32c_table_addr,                            address)                               \
      static_field(StubRoutines,                _updateBytesCRC32C,                            address)                               \
      static_field(StubRoutines,                _multiplyToLen,                                address)                               \
      static_field(StubRoutines,                _squareToLen,                                  address)                               \
      static_field(StubRoutines,                _mulAdd,                                       address)                               \
+     static_field(StubRoutines,                _dexp,                                         address)                               \
+     static_field(StubRoutines,                _jbyte_arraycopy,                              address)                               \
+     static_field(StubRoutines,                _jshort_arraycopy,                             address)                               \
+     static_field(StubRoutines,                _jint_arraycopy,                               address)                               \
+     static_field(StubRoutines,                _jlong_arraycopy,                              address)                               \
+     static_field(StubRoutines,                _oop_arraycopy,                                address)                               \
+     static_field(StubRoutines,                _oop_arraycopy_uninit,                         address)                               \
+     static_field(StubRoutines,                _jbyte_disjoint_arraycopy,                     address)                               \
+     static_field(StubRoutines,                _jshort_disjoint_arraycopy,                    address)                               \
+     static_field(StubRoutines,                _jint_disjoint_arraycopy,                      address)                               \
+     static_field(StubRoutines,                _jlong_disjoint_arraycopy,                     address)                               \
+     static_field(StubRoutines,                _oop_disjoint_arraycopy,                       address)                               \
+     static_field(StubRoutines,                _oop_disjoint_arraycopy_uninit,                address)                               \
+     static_field(StubRoutines,                _arrayof_jbyte_arraycopy,                      address)                               \
+     static_field(StubRoutines,                _arrayof_jshort_arraycopy,                     address)                               \
+     static_field(StubRoutines,                _arrayof_jint_arraycopy,                       address)                               \
+     static_field(StubRoutines,                _arrayof_jlong_arraycopy,                      address)                               \
+     static_field(StubRoutines,                _arrayof_oop_arraycopy,                        address)                               \
+     static_field(StubRoutines,                _arrayof_oop_arraycopy_uninit,                 address)                               \
+     static_field(StubRoutines,                _arrayof_jbyte_disjoint_arraycopy,             address)                               \
+     static_field(StubRoutines,                _arrayof_jshort_disjoint_arraycopy,            address)                               \
+     static_field(StubRoutines,                _arrayof_jint_disjoint_arraycopy,              address)                               \
+     static_field(StubRoutines,                _arrayof_jlong_disjoint_arraycopy,             address)                               \
+     static_field(StubRoutines,                _arrayof_oop_disjoint_arraycopy,               address)                               \
+     static_field(StubRoutines,                _arrayof_oop_disjoint_arraycopy_uninit,        address)                               \
+     static_field(StubRoutines,                _checkcast_arraycopy,                          address)                               \
+     static_field(StubRoutines,                _checkcast_arraycopy_uninit,                   address)                               \
+     static_field(StubRoutines,                _unsafe_arraycopy,                             address)                               \
+     static_field(StubRoutines,                _generic_arraycopy,                            address)                               \
                                                                                                                                      \
   /*****************/                                                                                                                \
   /* SharedRuntime */                                                                                                                \
   /*****************/                                                                                                                \
                                                                                                                                      \
+     static_field(SharedRuntime,               _wrong_method_blob,                            RuntimeStub*)                          \
      static_field(SharedRuntime,               _ic_miss_blob,                                 RuntimeStub*)                          \
+     static_field(SharedRuntime,               _deopt_blob,                                   DeoptimizationBlob*)                   \
                                                                                                                                      \
   /***************************************/                                                                                          \
   /* PcDesc and other compiled code info */                                                                                          \
@@ -856,16 +922,18 @@
   /* CodeBlobs (NOTE: incomplete, but only a little) */                                                                              \
   /***************************************************/                                                                              \
                                                                                                                                      \
-  nonstatic_field(CodeBlob,                    _name,                                         const char*)                           \
-  nonstatic_field(CodeBlob,                    _size,                                         int)                                   \
-  nonstatic_field(CodeBlob,                    _header_size,                                  int)                                   \
-  nonstatic_field(CodeBlob,                    _relocation_size,                              int)                                   \
-  nonstatic_field(CodeBlob,                    _content_offset,                               int)                                   \
-  nonstatic_field(CodeBlob,                    _code_offset,                                  int)                                   \
-  nonstatic_field(CodeBlob,                    _frame_complete_offset,                        int)                                   \
-  nonstatic_field(CodeBlob,                    _data_offset,                                  int)                                   \
-  nonstatic_field(CodeBlob,                    _frame_size,                                   int)                                   \
-  nonstatic_field(CodeBlob,                    _oop_maps,                                     ImmutableOopMapSet*)                   \
+  nonstatic_field(CodeBlob,                    _name,                                   const char*)                                 \
+  nonstatic_field(CodeBlob,                    _size,                                   int)                                         \
+  nonstatic_field(CodeBlob,                    _header_size,                            int)                                         \
+  nonstatic_field(CodeBlob,                    _relocation_size,                        int)                                         \
+  nonstatic_field(CodeBlob,                    _content_offset,                         int)                                         \
+  nonstatic_field(CodeBlob,                    _code_offset,                            int)                                         \
+  nonstatic_field(CodeBlob,                    _frame_complete_offset,                  int)                                         \
+  nonstatic_field(CodeBlob,                    _data_offset,                            int)                                         \
+  nonstatic_field(CodeBlob,                    _frame_size,                             int)                                         \
+  nonstatic_field(CodeBlob,                    _oop_maps,                               ImmutableOopMapSet*)                         \
+                                                                                                                                     \
+  nonstatic_field(DeoptimizationBlob,          _unpack_offset,                                int)                                   \
                                                                                                                                      \
   nonstatic_field(RuntimeStub,                 _caller_must_gc_arguments,                     bool)                                  \
                                                                                                                                      \
@@ -905,6 +973,17 @@
                                                                                                                                      \
   unchecked_c2_static_field(Deoptimization,    _trap_reason_name,                             void*)                                 \
                                                                                                                                      \
+  nonstatic_field(Deoptimization::UnrollBlock, _size_of_deoptimized_frame,                    int)                                   \
+  nonstatic_field(Deoptimization::UnrollBlock, _caller_adjustment,                            int)                                   \
+  nonstatic_field(Deoptimization::UnrollBlock, _number_of_frames,                             int)                                   \
+  nonstatic_field(Deoptimization::UnrollBlock, _total_frame_sizes,                            int)                                   \
+  nonstatic_field(Deoptimization::UnrollBlock, _frame_sizes,                                  intptr_t*)                             \
+  nonstatic_field(Deoptimization::UnrollBlock, _frame_pcs,                                    address*)                              \
+  nonstatic_field(Deoptimization::UnrollBlock, _register_block,                               intptr_t*)                             \
+  nonstatic_field(Deoptimization::UnrollBlock, _return_type,                                  BasicType)                             \
+  nonstatic_field(Deoptimization::UnrollBlock, _initial_info,                                 intptr_t)                              \
+  nonstatic_field(Deoptimization::UnrollBlock, _caller_actual_parameters,                     int)                                   \
+                                                                                                                                     \
   /********************************/                                                                                                 \
   /* JavaCalls (NOTE: incomplete) */                                                                                                 \
   /********************************/                                                                                                 \
@@ -1294,6 +1373,7 @@
   nonstatic_field(CompileTask,                 _osr_bci,                                      int)                                   \
   nonstatic_field(CompileTask,                 _comp_level,                                   int)                                   \
   nonstatic_field(CompileTask,                 _compile_id,                                   uint)                                  \
+  nonstatic_field(CompileTask,                 _num_inlined_bytecodes,                        int)                                   \
   nonstatic_field(CompileTask,                 _next,                                         CompileTask*)                          \
   nonstatic_field(CompileTask,                 _prev,                                         CompileTask*)                          \
                                                                                                                                      \
@@ -1473,6 +1553,8 @@
     declare_type(MethodCounters, MetaspaceObj)                            \
     declare_type(ConstMethod, MetaspaceObj)                               \
                                                                           \
+  declare_toplevel_type(narrowKlass)                                      \
+                                                                          \
   declare_toplevel_type(vtableEntry)                                      \
                                                                           \
            declare_toplevel_type(Symbol)                                  \
@@ -1572,6 +1654,8 @@
   declare_toplevel_type(TenuredGeneration*)                               \
   declare_toplevel_type(ThreadLocalAllocBuffer*)                          \
                                                                           \
+  declare_toplevel_type(BarrierSet::FakeRtti)                             \
+                                                                          \
   /************************/                                              \
   /* PerfMemory - jvmstat */                                              \
   /************************/                                              \
@@ -1694,6 +1778,7 @@
   declare_toplevel_type(Dependencies)                                     \
   declare_toplevel_type(CompileTask)                                      \
   declare_toplevel_type(Deoptimization)                                   \
+  declare_toplevel_type(Deoptimization::UnrollBlock)                      \
                                                                           \
   /************************/                                              \
   /* OopMap and OopMapSet */                                              \
@@ -1991,7 +2076,6 @@
   declare_c2_type(TanDNode, Node)                                         \
   declare_c2_type(AtanDNode, Node)                                        \
   declare_c2_type(SqrtDNode, Node)                                        \
-  declare_c2_type(ExpDNode, Node)                                         \
   declare_c2_type(LogDNode, Node)                                         \
   declare_c2_type(Log10DNode, Node)                                       \
   declare_c2_type(PowDNode, Node)                                         \
@@ -2276,6 +2360,8 @@
                                                                           \
   declare_constant(CardTableRS::youngergen_card)                          \
                                                                           \
+  declare_constant(G1SATBCardTableModRefBS::g1_young_gen)                 \
+                                                                          \
   declare_constant(CollectedHeap::GenCollectedHeap)                       \
   declare_constant(CollectedHeap::ParallelScavengeHeap)                   \
   declare_constant(CollectedHeap::G1CollectedHeap)                        \
@@ -2334,6 +2420,36 @@
   declare_constant(JVM_ACC_PROMOTED_FLAGS)                                \
   declare_constant(JVM_ACC_FIELD_ACCESS_WATCHED)                          \
   declare_constant(JVM_ACC_FIELD_MODIFICATION_WATCHED)                    \
+  declare_constant(JVM_ACC_FIELD_INTERNAL)                                \
+  declare_constant(JVM_ACC_FIELD_STABLE)                                  \
+  declare_constant(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE)                   \
+                                                                          \
+  declare_constant(JVM_CONSTANT_Utf8)                                     \
+  declare_constant(JVM_CONSTANT_Unicode)                                  \
+  declare_constant(JVM_CONSTANT_Integer)                                  \
+  declare_constant(JVM_CONSTANT_Float)                                    \
+  declare_constant(JVM_CONSTANT_Long)                                     \
+  declare_constant(JVM_CONSTANT_Double)                                   \
+  declare_constant(JVM_CONSTANT_Class)                                    \
+  declare_constant(JVM_CONSTANT_String)                                   \
+  declare_constant(JVM_CONSTANT_Fieldref)                                 \
+  declare_constant(JVM_CONSTANT_Methodref)                                \
+  declare_constant(JVM_CONSTANT_InterfaceMethodref)                       \
+  declare_constant(JVM_CONSTANT_NameAndType)                              \
+  declare_constant(JVM_CONSTANT_MethodHandle)                             \
+  declare_constant(JVM_CONSTANT_MethodType)                               \
+  declare_constant(JVM_CONSTANT_InvokeDynamic)                            \
+  declare_constant(JVM_CONSTANT_ExternalMax)                              \
+                                                                          \
+  declare_constant(JVM_CONSTANT_Invalid)                                  \
+  declare_constant(JVM_CONSTANT_InternalMin)                              \
+  declare_constant(JVM_CONSTANT_UnresolvedClass)                          \
+  declare_constant(JVM_CONSTANT_ClassIndex)                               \
+  declare_constant(JVM_CONSTANT_StringIndex)                              \
+  declare_constant(JVM_CONSTANT_UnresolvedClassInError)                   \
+  declare_constant(JVM_CONSTANT_MethodHandleInError)                      \
+  declare_constant(JVM_CONSTANT_MethodTypeInError)                        \
+  declare_constant(JVM_CONSTANT_InternalMax)                              \
                                                                           \
   /*****************************/                                         \
   /* Thread::SuspendFlags enum */                                         \
@@ -2364,6 +2480,7 @@
   /******************************/                                        \
                                                                           \
   declare_constant(Klass::_primary_super_limit)                           \
+  declare_constant(Klass::_lh_neutral_value)                              \
   declare_constant(Klass::_lh_instance_slow_path_bit)                     \
   declare_constant(Klass::_lh_log2_element_size_shift)                    \
   declare_constant(Klass::_lh_log2_element_size_mask)                     \
@@ -2385,6 +2502,10 @@
   declare_constant(Method::_dont_inline)                                  \
   declare_constant(Method::_hidden)                                       \
                                                                           \
+  declare_constant(Method::nonvirtual_vtable_index)                       \
+                                                                          \
+  declare_constant(Method::extra_stack_entries_for_jsr292)                \
+                                                                          \
   declare_constant(ConstMethod::_has_linenumber_table)                    \
   declare_constant(ConstMethod::_has_checked_exceptions)                  \
   declare_constant(ConstMethod::_has_localvariable_table)                 \
@@ -2401,6 +2522,20 @@
   /**************/                                                        \
                                                                           \
   declare_constant(DataLayout::cell_size)                                 \
+  declare_constant(DataLayout::no_tag)                                    \
+  declare_constant(DataLayout::bit_data_tag)                              \
+  declare_constant(DataLayout::counter_data_tag)                          \
+  declare_constant(DataLayout::jump_data_tag)                             \
+  declare_constant(DataLayout::receiver_type_data_tag)                    \
+  declare_constant(DataLayout::virtual_call_data_tag)                     \
+  declare_constant(DataLayout::ret_data_tag)                              \
+  declare_constant(DataLayout::branch_data_tag)                           \
+  declare_constant(DataLayout::multi_branch_data_tag)                     \
+  declare_constant(DataLayout::arg_info_data_tag)                         \
+  declare_constant(DataLayout::call_type_data_tag)                        \
+  declare_constant(DataLayout::virtual_call_type_data_tag)                \
+  declare_constant(DataLayout::parameters_type_data_tag)                  \
+  declare_constant(DataLayout::speculative_trap_data_tag)                 \
                                                                           \
   /*************************************/                                 \
   /* InstanceKlass enum                */                                 \
@@ -2454,13 +2589,14 @@
                                                                           \
   declare_constant(Symbol::max_symbol_length)                             \
                                                                           \
-  /*************************************************/                     \
-  /* ConstantPool* layout enum for InvokeDynamic */                     \
-  /*************************************************/                     \
+  /***********************************************/                       \
+  /* ConstantPool* layout enum for InvokeDynamic */                       \
+  /***********************************************/                       \
                                                                           \
-  declare_constant(ConstantPool::_indy_bsm_offset)                 \
-  declare_constant(ConstantPool::_indy_argc_offset)                \
-  declare_constant(ConstantPool::_indy_argv_offset)                \
+  declare_constant(ConstantPool::_indy_bsm_offset)                        \
+  declare_constant(ConstantPool::_indy_argc_offset)                       \
+  declare_constant(ConstantPool::_indy_argv_offset)                       \
+  declare_constant(ConstantPool::CPCACHE_INDEX_TAG)                       \
                                                                           \
   /********************************/                                      \
   /* ConstantPoolCacheEntry enums */                                      \
@@ -2555,6 +2691,18 @@
                                                                           \
   declare_constant(DEFAULT_CACHE_LINE_SIZE)                               \
                                                                           \
+  declare_constant(Deoptimization::Unpack_deopt)                          \
+  declare_constant(Deoptimization::Unpack_exception)                      \
+  declare_constant(Deoptimization::Unpack_uncommon_trap)                  \
+  declare_constant(Deoptimization::Unpack_reexecute)                      \
+                                                                          \
+  declare_constant(Deoptimization::_action_bits)                          \
+  declare_constant(Deoptimization::_reason_bits)                          \
+  declare_constant(Deoptimization::_debug_id_bits)                        \
+  declare_constant(Deoptimization::_action_shift)                         \
+  declare_constant(Deoptimization::_reason_shift)                         \
+  declare_constant(Deoptimization::_debug_id_shift)                       \
+                                                                          \
   /*********************/                                                 \
   /* Matcher (C2 only) */                                                 \
   /*********************/                                                 \
@@ -2567,6 +2715,18 @@
                                                                           \
   declare_constant(InvocationEntryBci)                                    \
                                                                           \
+  /*************/                                                         \
+  /* CompLevel */                                                         \
+  /*************/                                                         \
+                                                                          \
+  declare_constant(CompLevel_any)                                         \
+  declare_constant(CompLevel_all)                                         \
+  declare_constant(CompLevel_none)                                        \
+  declare_constant(CompLevel_simple)                                      \
+  declare_constant(CompLevel_limited_profile)                             \
+  declare_constant(CompLevel_full_profile)                                \
+  declare_constant(CompLevel_full_optimization)                           \
+                                                                          \
   /***************/                                                       \
   /* OopMapValue */                                                       \
   /***************/                                                       \
@@ -2581,7 +2741,6 @@
   declare_constant(OopMapValue::register_mask_in_place)                   \
   declare_constant(OopMapValue::unused_value)                             \
   declare_constant(OopMapValue::oop_value)                                \
-  declare_constant(OopMapValue::value_value)                              \
   declare_constant(OopMapValue::narrowoop_value)                          \
   declare_constant(OopMapValue::callee_saved_value)                       \
   declare_constant(OopMapValue::derived_oop_value)                        \
@@ -2698,8 +2857,38 @@
   /* Constants in markOop used by CMS. */                                 \
   declare_constant(markOopDesc::cms_shift)                                \
   declare_constant(markOopDesc::cms_mask)                                 \
-  declare_constant(markOopDesc::size_shift)
+  declare_constant(markOopDesc::size_shift)                               \
+                                                                          \
+  /* InvocationCounter constants */                                       \
+  declare_constant(InvocationCounter::count_increment)                    \
+  declare_constant(InvocationCounter::count_shift)
+
+
+//--------------------------------------------------------------------------------
+// VM_ADDRESSES
+//
 
+#define VM_ADDRESSES(declare_address, declare_preprocessor_address, declare_function) \
+                                                                          \
+  declare_function(SharedRuntime::register_finalizer)                     \
+  declare_function(SharedRuntime::exception_handler_for_return_address)   \
+  declare_function(SharedRuntime::OSR_migration_end)                      \
+  declare_function(SharedRuntime::dsin)                                   \
+  declare_function(SharedRuntime::dcos)                                   \
+  declare_function(SharedRuntime::dtan)                                   \
+  declare_function(SharedRuntime::dexp)                                   \
+  declare_function(SharedRuntime::dlog)                                   \
+  declare_function(SharedRuntime::dlog10)                                 \
+  declare_function(SharedRuntime::dpow)                                   \
+                                                                          \
+  declare_function(os::dll_load)                                          \
+  declare_function(os::dll_lookup)                                        \
+  declare_function(os::javaTimeMillis)                                    \
+  declare_function(os::javaTimeNanos)                                     \
+                                                                          \
+  declare_function(Deoptimization::fetch_unroll_info)                     \
+  COMPILER2_PRESENT(declare_function(Deoptimization::uncommon_trap))      \
+  declare_function(Deoptimization::unpack_frames)
 
 //--------------------------------------------------------------------------------
 // Macros operating on the above lists
@@ -2932,6 +3121,23 @@
 # define GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY(name, value)
 #endif /* COMPILER1 */
 
+//--------------------------------------------------------------------------------
+// VMAddressEntry macros
+//
+
+#define GENERATE_VM_ADDRESS_ENTRY(name) \
+  { QUOTE(name), (void*) (name) },
+
+#define GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY(name, value) \
+  { name, (void*) (value) },
+
+#define GENERATE_VM_FUNCTION_ENTRY(name) \
+  { QUOTE(name), CAST_FROM_FN_PTR(void*, &(name)) },
+
+// This macro generates the sentinel value indicating the end of the list
+#define GENERATE_VM_ADDRESS_LAST_ENTRY() \
+ { NULL, NULL }
+
 //
 // Instantiation of VMStructEntries, VMTypeEntries and VMIntConstantEntries
 //
@@ -2950,6 +3156,11 @@
              GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
              GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
 
+#if INCLUDE_JVMCI
+  VM_STRUCTS_JVMCI(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+                   GENERATE_STATIC_VM_STRUCT_ENTRY)
+#endif
+
 #if INCLUDE_ALL_GCS
   VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
                         GENERATE_STATIC_VM_STRUCT_ENTRY)
@@ -2970,6 +3181,15 @@
   VM_STRUCTS_EXT(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
                  GENERATE_STATIC_VM_STRUCT_ENTRY)
 
+  VM_STRUCTS_OS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+                GENERATE_STATIC_VM_STRUCT_ENTRY,
+                GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
+                GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+                GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
+                GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
+                GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
+                GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
+
   VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
                  GENERATE_STATIC_VM_STRUCT_ENTRY,
                  GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3002,6 +3222,11 @@
            GENERATE_C2_VM_TYPE_ENTRY,
            GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
 
+#if INCLUDE_JVMCI
+  VM_TYPES_JVMCI(GENERATE_VM_TYPE_ENTRY,
+                 GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
+#endif
+
 #if INCLUDE_ALL_GCS
   VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY,
                       GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
@@ -3023,6 +3248,15 @@
   VM_TYPES_EXT(GENERATE_VM_TYPE_ENTRY,
                GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
 
+  VM_TYPES_OS(GENERATE_VM_TYPE_ENTRY,
+              GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
+              GENERATE_OOP_VM_TYPE_ENTRY,
+              GENERATE_INTEGER_VM_TYPE_ENTRY,
+              GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
+              GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
+              GENERATE_C2_VM_TYPE_ENTRY,
+              GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
+
   VM_TYPES_CPU(GENERATE_VM_TYPE_ENTRY,
                GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
                GENERATE_OOP_VM_TYPE_ENTRY,
@@ -3052,6 +3286,12 @@
                    GENERATE_C2_VM_INT_CONSTANT_ENTRY,
                    GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
 
+#if INCLUDE_JVMCI
+  VM_INT_CONSTANTS_JVMCI(GENERATE_VM_INT_CONSTANT_ENTRY,
+                         GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
+
+#endif
+
 #if INCLUDE_ALL_GCS
   VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
 
@@ -3062,6 +3302,12 @@
   VM_INT_CONSTANTS_TRACE(GENERATE_VM_INT_CONSTANT_ENTRY)
 #endif
 
+  VM_INT_CONSTANTS_OS(GENERATE_VM_INT_CONSTANT_ENTRY,
+                      GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
+                      GENERATE_C1_VM_INT_CONSTANT_ENTRY,
+                      GENERATE_C2_VM_INT_CONSTANT_ENTRY,
+                      GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
+
   VM_INT_CONSTANTS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY,
                        GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
                        GENERATE_C1_VM_INT_CONSTANT_ENTRY,
@@ -3085,6 +3331,12 @@
                     GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
                     GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
 
+  VM_LONG_CONSTANTS_OS(GENERATE_VM_LONG_CONSTANT_ENTRY,
+                       GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
+                       GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
+                       GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
+                       GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
+
   VM_LONG_CONSTANTS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
                         GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
                         GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
@@ -3100,6 +3352,25 @@
   GENERATE_VM_LONG_CONSTANT_LAST_ENTRY()
 };
 
+VMAddressEntry VMStructs::localHotSpotVMAddresses[] = {
+
+  VM_ADDRESSES(GENERATE_VM_ADDRESS_ENTRY,
+               GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY,
+               GENERATE_VM_FUNCTION_ENTRY)
+
+  VM_ADDRESSES_OS(GENERATE_VM_ADDRESS_ENTRY,
+                  GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY,
+                  GENERATE_VM_FUNCTION_ENTRY)
+
+#if INCLUDE_JVMCI
+  VM_ADDRESSES_JVMCI(GENERATE_VM_ADDRESS_ENTRY,
+                     GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY,
+                     GENERATE_VM_FUNCTION_ENTRY)
+#endif
+
+  GENERATE_VM_ADDRESS_LAST_ENTRY()
+};
+
 // This is used both to check the types of referenced fields and, in
 // debug builds, to ensure that all of the field types are present.
 void
@@ -3308,6 +3579,11 @@
 ASSIGN_OFFSET_TO_64BIT_VAR(gHotSpotVMLongConstantEntryNameOffset, VMLongConstantEntry, name);
 ASSIGN_OFFSET_TO_64BIT_VAR(gHotSpotVMLongConstantEntryValueOffset, VMLongConstantEntry, value);
 ASSIGN_STRIDE_TO_64BIT_VAR(gHotSpotVMLongConstantEntryArrayStride, gHotSpotVMLongConstants);
+
+JNIEXPORT VMAddressEntry* gHotSpotVMAddresses = VMStructs::localHotSpotVMAddresses;
+ASSIGN_OFFSET_TO_64BIT_VAR(gHotSpotVMAddressEntryNameOffset, VMAddressEntry, name);
+ASSIGN_OFFSET_TO_64BIT_VAR(gHotSpotVMAddressEntryValueOffset, VMAddressEntry, value);
+ASSIGN_STRIDE_TO_64BIT_VAR(gHotSpotVMAddressEntryArrayStride, gHotSpotVMAddresses);
 }
 
 #ifdef ASSERT
@@ -3415,6 +3691,11 @@
                 &long_last_entry,
                 sizeof(VMLongConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMLongConstants");
 
+  static VMAddressEntry address_last_entry = GENERATE_VM_ADDRESS_LAST_ENTRY();
+  assert(memcmp(&localHotSpotVMAddresses[sizeof(localHotSpotVMAddresses) / sizeof(VMAddressEntry) - 1],
+                &address_last_entry,
+                sizeof(VMAddressEntry)) == 0, "Incorrect last entry in localHotSpotVMAddresses");
+
 
   // Check for duplicate entries in type array
   for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {
--- a/hotspot/src/share/vm/runtime/vmStructs.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -95,6 +95,11 @@
   uint64_t value;                  // Value of constant
 } VMLongConstantEntry;
 
+typedef struct {
+  const char* name;                // Name of address (example: "SharedRuntime::register_finalizer")
+  void* value;                     // Value of address
+} VMAddressEntry;
+
 // This class is a friend of most classes, to be able to access
 // private fields
 class VMStructs {
@@ -117,6 +122,11 @@
   // the fact that it has a NULL typeName
   static VMLongConstantEntry localHotSpotVMLongConstants[];
 
+  /**
+   * Table of addresses.
+   */
+  static VMAddressEntry localHotSpotVMAddresses[];
+
   // This is used to run any checking code necessary for validation of
   // the data structure (debug build only)
   static void init();
--- a/hotspot/src/share/vm/runtime/vmThread.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -41,8 +41,6 @@
 #include "utilities/events.hpp"
 #include "utilities/xmlstream.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Dummy VM operation to act as first element in our circular double-linked list
 class VM_Dummy: public VM_Operation {
   VMOp_Type type() const { return VMOp_Dummy; }
@@ -410,7 +408,7 @@
           !_cur_vm_operation->evaluate_concurrently()) {
         long stall = os::javaTimeMillis() - _cur_vm_operation->timestamp();
         if (stall > 0)
-          tty->print_cr("%s stall: %Ld",  _cur_vm_operation->name(), stall);
+          tty->print_cr("%s stall: %ld",  _cur_vm_operation->name(), stall);
       }
 
       while (!should_terminate() && _cur_vm_operation == NULL) {
@@ -630,8 +628,8 @@
       // Check the VM operation allows nested VM operation. This normally not the case, e.g., the compiler
       // does not allow nested scavenges or compiles.
       if (!prev_vm_operation->allow_nested_vm_operations()) {
-        fatal(err_msg("Nested VM operation %s requested by operation %s",
-                      op->name(), vm_operation()->name()));
+        fatal("Nested VM operation %s requested by operation %s",
+              op->name(), vm_operation()->name());
       }
       op->set_calling_thread(prev_vm_operation->calling_thread(), prev_vm_operation->priority());
     }
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,8 +42,6 @@
 #include "services/threadService.hpp"
 #include "trace/tracing.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 #define VM_OP_NAME_INITIALIZE(name) #name,
 
 const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \
@@ -79,14 +77,14 @@
 }
 // Called by fatal error handler.
 void VM_Operation::print_on_error(outputStream* st) const {
-  st->print("VM_Operation (" PTR_FORMAT "): ", this);
+  st->print("VM_Operation (" PTR_FORMAT "): ", p2i(this));
   st->print("%s", name());
 
   const char* mode = mode_to_string(evaluation_mode());
   st->print(", mode: %s", mode);
 
   if (calling_thread()) {
-    st->print(", requested by thread " PTR_FORMAT, calling_thread());
+    st->print(", requested by thread " PTR_FORMAT, p2i(calling_thread()));
   }
 }
 
@@ -117,14 +115,16 @@
   NMethodSweeper::mark_active_nmethods();
 }
 
-VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id) {
+VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason) {
   _thread = thread;
   _id     = id;
+  _reason = reason;
 }
 
 
 void VM_DeoptimizeFrame::doit() {
-  Deoptimization::deoptimize_frame_internal(_thread, _id);
+  assert(_reason > Deoptimization::Reason_none && _reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
+  Deoptimization::deoptimize_frame_internal(_thread, _id, (Deoptimization::DeoptReason)_reason);
 }
 
 
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -272,7 +272,8 @@
  private:
   JavaThread* _thread;
   intptr_t*   _id;
-  VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id);
+  int _reason;
+  VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason);
 
  public:
   VMOp_Type type() const                         { return VMOp_DeoptimizeFrame; }
--- a/hotspot/src/share/vm/runtime/vm_version.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -85,7 +85,7 @@
 #ifdef ASSERT
 static void assert_digits(const char * s, const char * message) {
   for (int i = 0; s[i] != '\0'; i++) {
-    assert(isdigit(s[i]), message);
+    assert(isdigit(s[i]), "%s", message);
   }
 }
 #endif
@@ -154,7 +154,6 @@
 #endif
 }
 
-
 const char* Abstract_VM_Version::vm_info_string() {
   if (CodeCacheExtensions::use_pregenerated_interpreter()) {
     return "interpreted mode, pregenerated";
--- a/hotspot/src/share/vm/services/classLoadingService.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/classLoadingService.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -182,7 +182,7 @@
 
   // verbose will be set to the previous value
   Flag::Error error = CommandLineFlags::boolAtPut("TraceClassLoading", &verbose, Flag::MANAGEMENT);
-  assert(error==Flag::SUCCESS, err_msg("Setting TraceClassLoading flag failed with error %s", Flag::flag_error_str(error)));
+  assert(error==Flag::SUCCESS, "Setting TraceClassLoading flag failed with error %s", Flag::flag_error_str(error));
   reset_trace_class_unloading();
 
   return verbose;
@@ -193,7 +193,7 @@
   assert(Management_lock->owned_by_self(), "Must own the Management_lock");
   bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
   Flag::Error error = CommandLineFlags::boolAtPut("TraceClassUnloading", &value, Flag::MANAGEMENT);
-  assert(error==Flag::SUCCESS, err_msg("Setting TraceClassUnLoading flag failed with error %s", Flag::flag_error_str(error)));
+  assert(error==Flag::SUCCESS, "Setting TraceClassUnLoading flag failed with error %s", Flag::flag_error_str(error));
 }
 
 GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL;
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -39,8 +39,6 @@
 #include "utilities/macros.hpp"
 #include "oops/objArrayOop.inline.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 void DCmdRegistrant::register_dcmds(){
   // Registration of the diagnostic commands
   // First argument specifies which interfaces will export the command
@@ -695,12 +693,17 @@
     // command line with -D or by managmenent.properties
     // file.
 #define PUT_OPTION(a) \
-    if ( (a).is_set() ){ \
-        options.print(\
-               ( *((a).type()) == 'I' ) ? "%scom.sun.management.%s=%d" : "%scom.sun.management.%s=%s",\
-                comma, (a).name(), (a).value()); \
-        comma[0] = ','; \
-    }
+    do { \
+        if ( (a).is_set() ){ \
+            if ( *((a).type()) == 'I' ) { \
+                options.print("%scom.sun.management.%s=" JLONG_FORMAT, comma, (a).name(), (jlong)((a).value())); \
+            } else { \
+                options.print("%scom.sun.management.%s=%s", comma, (a).name(), (char*)((a).value())); \
+            } \
+            comma[0] = ','; \
+        }\
+    } while(0);
+
 
     PUT_OPTION(_config_file);
     PUT_OPTION(_jmxremote_port);
--- a/hotspot/src/share/vm/services/heapDumper.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/heapDumper.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -724,7 +724,7 @@
 
       // reflection and sun.misc.Unsafe classes may have a reference to a
       // Klass* so filter it out.
-      assert(o->is_oop_or_null(), err_msg("Expected an oop or NULL at " PTR_FORMAT, p2i(o)));
+      assert(o->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
       writer->write_objectID(o);
       break;
     }
--- a/hotspot/src/share/vm/services/management.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/management.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -58,8 +58,6 @@
 #include "services/threadService.hpp"
 #include "utilities/macros.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 PerfVariable* Management::_begin_vm_creation_time = NULL;
 PerfVariable* Management::_end_vm_creation_time = NULL;
 PerfVariable* Management::_vm_init_done_time = NULL;
@@ -752,7 +750,7 @@
 
   if ((size_t)threshold > max_uintx) {
     stringStream st;
-    st.print("Invalid valid threshold value. Threshold value (" UINT64_FORMAT ") > max value of size_t (" SIZE_FORMAT ")", (size_t)threshold, max_uintx);
+    st.print("Invalid valid threshold value. Threshold value (" JLONG_FORMAT ") > max value of size_t (" UINTX_FORMAT ")", threshold, max_uintx);
     THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), st.as_string(), -1);
   }
 
--- a/hotspot/src/share/vm/services/management.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/management.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -118,6 +118,10 @@
   void start()
   { _timer.update_to(0); _begin_time = os::javaTimeMillis(); }
 
+  jlong begin_time() const {
+    return _begin_time;
+  }
+
   /**
    * Only call this if initialization completes successfully; it will
    * crash if PerfMemory_exit() has already been called (usually by
--- a/hotspot/src/share/vm/services/memoryService.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/memoryService.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -518,7 +518,7 @@
   MutexLocker m(Management_lock);
   // verbose will be set to the previous value
   Flag::Error error = CommandLineFlags::boolAtPut("PrintGC", &verbose, Flag::MANAGEMENT);
-  assert(error==Flag::SUCCESS, err_msg("Setting PrintGC flag failed with error %s", Flag::flag_error_str(error)));
+  assert(error==Flag::SUCCESS, "Setting PrintGC flag failed with error %s", Flag::flag_error_str(error));
   ClassLoadingService::reset_trace_class_unloading();
 
   return verbose;
--- a/hotspot/src/share/vm/services/nmtCommon.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/nmtCommon.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -40,6 +40,7 @@
   "Arena Chunk",
   "Test",
   "Tracing",
+  "Logging",
   "Unknown"
 };
 
--- a/hotspot/src/share/vm/services/threadService.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/threadService.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -39,8 +39,6 @@
 #include "runtime/vm_operations.hpp"
 #include "services/threadService.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // TODO: we need to define a naming convention for perf counters
 // to distinguish counters for:
 //   - standard JSR174 use
@@ -508,7 +506,7 @@
   for (int i = 0; i < len; i++) {
     oop o = _locked_monitors->at(i);
     InstanceKlass* ik = InstanceKlass::cast(o->klass());
-    st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", (address)o, ik->external_name());
+    st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", p2i(o), ik->external_name());
   }
 
 }
@@ -732,7 +730,7 @@
   for (int i = 0; i < locks->length(); i++) {
     instanceOop obj = locks->at(i);
     InstanceKlass* ik = InstanceKlass::cast(obj->klass());
-    st->print_cr("\t- <" INTPTR_FORMAT "> (a %s)", (address)obj, ik->external_name());
+    st->print_cr("\t- <" INTPTR_FORMAT "> (a %s)", p2i(obj), ik->external_name());
   }
   st->cr();
 }
@@ -885,10 +883,10 @@
     st->print_cr("\"%s\":", currentThread->get_thread_name());
     const char* owner_desc = ",\n  which is held by";
     if (waitingToLockMonitor != NULL) {
-      st->print("  waiting to lock monitor " INTPTR_FORMAT, waitingToLockMonitor);
+      st->print("  waiting to lock monitor " INTPTR_FORMAT, p2i(waitingToLockMonitor));
       oop obj = (oop)waitingToLockMonitor->object();
       if (obj != NULL) {
-        st->print(" (object " INTPTR_FORMAT ", a %s)", (address)obj,
+        st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
                    (InstanceKlass::cast(obj->klass()))->external_name());
 
         if (!currentThread->current_pending_monitor_is_from_java()) {
@@ -907,12 +905,12 @@
         // if it is not findable, then the previous currentThread is
         // blocked permanently.
         st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
-                  (address)waitingToLockMonitor->owner());
+                  p2i(waitingToLockMonitor->owner()));
         continue;
       }
     } else {
       st->print("  waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
-                (address)waitingToLockBlocker,
+                p2i(waitingToLockBlocker),
                 (InstanceKlass::cast(waitingToLockBlocker->klass()))->external_name());
       assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()),
              "Must be an AbstractOwnableSynchronizer");
--- a/hotspot/src/share/vm/services/writeableFlags.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/services/writeableFlags.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -89,10 +89,7 @@
       break;
   }
 
-  PRAGMA_DIAG_PUSH
-  PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
-  err_msg.print(buffer);
-  PRAGMA_DIAG_POP
+  err_msg.print("%s", buffer);
 }
 
 // set a boolean global flag
@@ -295,7 +292,8 @@
 }
 
 // a writeable flag setter accepting 'jvalue' values
-Flag::Error WriteableFlags::set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin,
+                                                 FormatBuffer<80>& err_msg) {
   jvalue new_value = *(jvalue*)value;
   if (f->is_bool()) {
     bool bvalue = (new_value.z == JNI_TRUE ? true : false);
--- a/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -150,8 +150,10 @@
 
 void SharkDecacher::end_frame() {
   // Record the scope
+  methodHandle null_mh;
   debug_info()->describe_scope(
     pc_offset(),
+    null_mh,
     target(),
     bci(),
     true,
--- a/hotspot/src/share/vm/utilities/array.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/array.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -341,13 +341,13 @@
     assert(is_size_aligned(left, sizeof(T)), "Must be");
 
     size_t elements = left / sizeof(T);
-    assert(elements <= (size_t)INT_MAX, err_msg("number of elements " SIZE_FORMAT "doesn't fit into an int.", elements));
+    assert(elements <= (size_t)INT_MAX, "number of elements " SIZE_FORMAT "doesn't fit into an int.", elements);
 
     int length = (int)elements;
 
     assert((size_t)size(length) * BytesPerWord == bytes,
-        err_msg("Expected: " SIZE_FORMAT " got: " SIZE_FORMAT,
-                bytes, (size_t)size(length) * BytesPerWord));
+           "Expected: " SIZE_FORMAT " got: " SIZE_FORMAT,
+           bytes, (size_t)size(length) * BytesPerWord);
 
     return length;
   }
@@ -380,9 +380,9 @@
   // sort the array.
   bool contains(const T& x) const      { return index_of(x) >= 0; }
 
-  T    at(int i) const                 { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return _data[i]; }
-  void at_put(const int i, const T& x) { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); _data[i] = x; }
-  T*   adr_at(const int i)             { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return &_data[i]; }
+  T    at(int i) const                 { assert(i >= 0 && i< _length, "oob: 0 <= %d < %d", i, _length); return _data[i]; }
+  void at_put(const int i, const T& x) { assert(i >= 0 && i< _length, "oob: 0 <= %d < %d", i, _length); _data[i] = x; }
+  T*   adr_at(const int i)             { assert(i >= 0 && i< _length, "oob: 0 <= %d < %d", i, _length); return &_data[i]; }
   int  find(const T& x)                { return index_of(x); }
 
   T at_acquire(const int which)              { return OrderAccess::load_acquire(adr_at(which)); }
--- a/hotspot/src/share/vm/utilities/chunkedList.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/chunkedList.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -73,7 +73,7 @@
   }
 
   T at(size_t i) {
-    assert(i < size(), err_msg("IOOBE i: " SIZE_FORMAT " size(): " SIZE_FORMAT, i, size()));
+    assert(i < size(), "IOOBE i: " SIZE_FORMAT " size(): " SIZE_FORMAT, i, size());
     return _values[i];
   }
 };
--- a/hotspot/src/share/vm/utilities/debug.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -78,13 +78,11 @@
 #  endif
 #endif // PRODUCT
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 FormatBufferResource::FormatBufferResource(const char * format, ...)
-  : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) {
+  : FormatBufferBase((char*)resource_allocate_bytes(FormatBufferBase::BufferSize)) {
   va_list argp;
   va_start(argp, format);
-  jio_vsnprintf(_buf, RES_BUFSZ, format, argp);
+  jio_vsnprintf(_buf, FormatBufferBase::BufferSize, format, argp);
   va_end(argp);
 }
 
@@ -207,26 +205,36 @@
 
 #endif // !PRODUCT
 
-void report_vm_error(const char* file, int line, const char* error_msg,
-                     const char* detail_msg)
+void report_vm_error(const char* file, int line, const char* error_msg)
+{
+  report_vm_error(file, line, error_msg, "%s", "");
+}
+
+void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
 {
   if (Debugging || error_is_suppressed(file, line)) return;
-  Thread* const thread = ThreadLocalStorage::get_thread_slow();
-  VMError err(thread, file, line, error_msg, detail_msg);
-  err.report_and_die();
+  va_list detail_args;
+  va_start(detail_args, detail_fmt);
+  VMError::report_and_die(ThreadLocalStorage::get_thread_slow(), file, line, error_msg, detail_fmt, detail_args);
+  va_end(detail_args);
 }
 
-void report_fatal(const char* file, int line, const char* message)
+void report_fatal(const char* file, int line, const char* detail_fmt, ...)
 {
-  report_vm_error(file, line, "fatal error", message);
+  if (Debugging || error_is_suppressed(file, line)) return;
+  va_list detail_args;
+  va_start(detail_args, detail_fmt);
+  VMError::report_and_die(ThreadLocalStorage::get_thread_slow(), file, line, "fatal error", detail_fmt, detail_args);
+  va_end(detail_args);
 }
 
 void report_vm_out_of_memory(const char* file, int line, size_t size,
-                             VMErrorType vm_err_type, const char* message) {
+                             VMErrorType vm_err_type, const char* detail_fmt, ...) {
   if (Debugging) return;
-
-  Thread* thread = ThreadLocalStorage::get_thread_slow();
-  VMError(thread, file, line, size, vm_err_type, message).report_and_die();
+  va_list detail_args;
+  va_start(detail_args, detail_fmt);
+  VMError::report_and_die(ThreadLocalStorage::get_thread_slow(), file, line, size, vm_err_type, detail_fmt, detail_args);
+  va_end(detail_args);
 
   // The UseOSErrorReporting option in report_and_die() may allow a return
   // to here. If so then we'll have to figure out how to handle it.
@@ -295,8 +303,7 @@
     }
 
     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
-      VMError err(message);
-      err.report_java_out_of_memory();
+      VMError::report_java_out_of_memory(message);
     }
   }
 }
@@ -365,22 +372,22 @@
   char * const dataPtr = NULL;  // bad data pointer
   const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer
 
-  // Keep this in sync with test/runtime/6888954/vmerrors.sh.
+  // Keep this in sync with test/runtime/ErrorHandling/ErrorHandler.java
   switch (how) {
     case  1: vmassert(str == NULL, "expected null");
     case  2: vmassert(num == 1023 && *str == 'X',
-                      err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
+                      "num=" SIZE_FORMAT " str=\"%s\"", num, str);
     case  3: guarantee(str == NULL, "expected null");
     case  4: guarantee(num == 1023 && *str == 'X',
-                       err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
+                       "num=" SIZE_FORMAT " str=\"%s\"", num, str);
     case  5: fatal("expected null");
-    case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
-    case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
-                           "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
-                           "%s%s#    %s%s#    %s%s#    %s%s#    %s",
-                           msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
-                           msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
-                           msg, eol, msg, eol, msg, eol, msg, eol, msg));
+    case  6: fatal("num=" SIZE_FORMAT " str=\"%s\"", num, str);
+    case  7: fatal("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
+                   "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
+                   "%s%s#    %s%s#    %s%s#    %s%s#    %s",
+                   msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
+                   msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
+                   msg, eol, msg, eol, msg, eol, msg, eol, msg);
     case  8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate");
     case  9: ShouldNotCallThis();
     case 10: ShouldNotReachHere();
@@ -515,7 +522,7 @@
     oop obj = oop(p);
     obj->print();
   } else {
-    tty->print(PTR_FORMAT, p);
+    tty->print(PTR_FORMAT, p2i(p));
   }
 }
 
@@ -550,7 +557,7 @@
     frame f = os::current_frame();
     RegisterMap reg_map(p);
     f = f.sender(&reg_map);
-    tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
+    tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id()));
     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
   pd_ps(f);
 #endif // PRODUCT
--- a/hotspot/src/share/vm/utilities/debug.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/debug.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -36,21 +36,21 @@
   char* _buf;
   inline FormatBufferBase(char* buf) : _buf(buf) {}
  public:
+  static const int BufferSize = 256;
   operator const char *() const { return _buf; }
 };
 
 // Use resource area for buffer
-#define RES_BUFSZ 256
 class FormatBufferResource : public FormatBufferBase {
  public:
   FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3);
 };
 
 // Use stack for buffer
-template <size_t bufsz = 256>
+template <size_t bufsz = FormatBufferBase::BufferSize>
 class FormatBuffer : public FormatBufferBase {
  public:
-  inline FormatBuffer(const char * format, ...) ATTRIBUTE_PRINTF(2, 3);
+  inline FormatBuffer(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
   inline void append(const char* format, ...)  ATTRIBUTE_PRINTF(2, 3);
   inline void print(const char* format, ...)  ATTRIBUTE_PRINTF(2, 3);
   inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
@@ -105,27 +105,29 @@
   va_end(argp);
 }
 
-// Used to format messages for vmassert(), guarantee(), fatal(), etc.
+// Used to format messages.
 typedef FormatBuffer<> err_msg;
-typedef FormatBufferResource err_msg_res;
 
 // assertions
 #ifndef ASSERT
-#define vmassert(p, msg)
+#define vmassert(p, ...)
 #else
 // Note: message says "assert" rather than "vmassert" for backward
 // compatibility with tools that parse/match the message text.
-#define vmassert(p, msg)                                                     \
-do {                                                                         \
-  if (!(p)) {                                                                \
-    report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg);       \
-    BREAKPOINT;                                                              \
-  }                                                                          \
+// Note: The signature is vmassert(p, format, ...), but the solaris
+// compiler can't handle an empty ellipsis in a macro without a warning.
+#define vmassert(p, ...)                                                       \
+do {                                                                           \
+  if (!(p)) {                                                                  \
+    report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", __VA_ARGS__); \
+    BREAKPOINT;                                                                \
+  }                                                                            \
 } while (0)
+
 #endif
 
 // For backward compatibility.
-#define assert(p, msg) vmassert(p, msg)
+#define assert(p, ...) vmassert(p, __VA_ARGS__)
 
 // This version of vmassert is for use with checking return status from
 // library calls that return actual error values eg. EINVAL,
@@ -135,7 +137,7 @@
 // an extra arg and use strerror to convert it to a meaningful string
 // like "Invalid argument", "out of memory" etc
 #define vmassert_status(p, status, msg) \
-  vmassert(p, err_msg("error %s(%d), %s", strerror(status), status, msg))
+  vmassert(p, "error %s(%d), %s", strerror(status), status, msg)
 
 // For backward compatibility.
 #define assert_status(p, status, msg) vmassert_status(p, status, msg)
@@ -143,49 +145,49 @@
 // guarantee is like vmassert except it's always executed -- use it for
 // cheap tests that catch errors that would otherwise be hard to find.
 // guarantee is also used for Verify options.
-#define guarantee(p, msg)                                                    \
-do {                                                                         \
-  if (!(p)) {                                                                \
-    report_vm_error(__FILE__, __LINE__, "guarantee(" #p ") failed", msg);    \
-    BREAKPOINT;                                                              \
-  }                                                                          \
+#define guarantee(p, ...)                                                         \
+do {                                                                              \
+  if (!(p)) {                                                                     \
+    report_vm_error(__FILE__, __LINE__, "guarantee(" #p ") failed", __VA_ARGS__); \
+    BREAKPOINT;                                                                   \
+  }                                                                               \
 } while (0)
 
-#define fatal(msg)                                                           \
-do {                                                                         \
-  report_fatal(__FILE__, __LINE__, msg);                                     \
-  BREAKPOINT;                                                                \
+#define fatal(...)                                                                \
+do {                                                                              \
+  report_fatal(__FILE__, __LINE__, __VA_ARGS__);                                  \
+  BREAKPOINT;                                                                     \
 } while (0)
 
 // out of memory
-#define vm_exit_out_of_memory(size, vm_err_type, msg)                        \
-do {                                                                         \
-  report_vm_out_of_memory(__FILE__, __LINE__, size, vm_err_type, msg);       \
-  BREAKPOINT;                                                                \
+#define vm_exit_out_of_memory(size, vm_err_type, ...)                             \
+do {                                                                              \
+  report_vm_out_of_memory(__FILE__, __LINE__, size, vm_err_type, __VA_ARGS__);    \
+  BREAKPOINT;                                                                     \
 } while (0)
 
-#define ShouldNotCallThis()                                                  \
-do {                                                                         \
-  report_should_not_call(__FILE__, __LINE__);                                \
-  BREAKPOINT;                                                                \
+#define ShouldNotCallThis()                                                       \
+do {                                                                              \
+  report_should_not_call(__FILE__, __LINE__);                                     \
+  BREAKPOINT;                                                                     \
 } while (0)
 
-#define ShouldNotReachHere()                                                 \
-do {                                                                         \
-  report_should_not_reach_here(__FILE__, __LINE__);                          \
-  BREAKPOINT;                                                                \
+#define ShouldNotReachHere()                                                      \
+do {                                                                              \
+  report_should_not_reach_here(__FILE__, __LINE__);                               \
+  BREAKPOINT;                                                                     \
 } while (0)
 
-#define Unimplemented()                                                      \
-do {                                                                         \
-  report_unimplemented(__FILE__, __LINE__);                                  \
-  BREAKPOINT;                                                                \
+#define Unimplemented()                                                           \
+do {                                                                              \
+  report_unimplemented(__FILE__, __LINE__);                                       \
+  BREAKPOINT;                                                                     \
 } while (0)
 
-#define Untested(msg)                                                        \
-do {                                                                         \
-  report_untested(__FILE__, __LINE__, msg);                                  \
-  BREAKPOINT;                                                                \
+#define Untested(msg)                                                             \
+do {                                                                              \
+  report_untested(__FILE__, __LINE__, msg);                                       \
+  BREAKPOINT;                                                                     \
 } while (0);
 
 
@@ -197,11 +199,19 @@
 };
 
 // error reporting helper functions
+void report_vm_error(const char* file, int line, const char* error_msg);
+#if !defined(__GNUC__) || defined (__clang_major__) || (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || __GNUC__ > 4)
+// ATTRIBUTE_PRINTF works with gcc >= 4.8 and any other compiler.
 void report_vm_error(const char* file, int line, const char* error_msg,
-                     const char* detail_msg = NULL);
-void report_fatal(const char* file, int line, const char* message);
-void report_vm_out_of_memory(const char* file, int line, size_t size,
-                             VMErrorType vm_err_type, const char* message);
+                     const char* detail_fmt, ...) ATTRIBUTE_PRINTF(4, 5);
+#else
+// GCC < 4.8 warns because of empty format string.  Warning can not be switched off selectively.
+void report_vm_error(const char* file, int line, const char* error_msg,
+                     const char* detail_fmt, ...);
+#endif
+void report_fatal(const char* file, int line, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(3, 4);
+void report_vm_out_of_memory(const char* file, int line, size_t size, VMErrorType vm_err_type,
+                             const char* detail_fmt, ...) ATTRIBUTE_PRINTF(5, 6);
 void report_should_not_call(const char* file, int line);
 void report_should_not_reach_here(const char* file, int line);
 void report_unimplemented(const char* file, int line);
--- a/hotspot/src/share/vm/utilities/exceptions.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -35,8 +35,6 @@
 #include "utilities/events.hpp"
 #include "utilities/exceptions.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // Implementation of ThreadShadow
 void check_ThreadShadow() {
   const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception);
@@ -85,7 +83,7 @@
 #endif // ASSERT
 
   if (thread->is_VM_thread()
-      || thread->is_Compiler_thread()
+      || !thread->can_call_java()
       || DumpSharedSpaces ) {
     // We do not care what kind of exception we get for the vm-thread or a thread which
     // is compiling.  We just install a dummy exception object
@@ -112,7 +110,7 @@
   }
 
   if (thread->is_VM_thread()
-      || thread->is_Compiler_thread()
+      || !thread->can_call_java()
       || DumpSharedSpaces ) {
     // We do not care what kind of exception we get for the vm-thread or a thread which
     // is compiling.  We just install a dummy exception object
@@ -144,7 +142,7 @@
                   "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
                   h_exception->print_value_string(),
                   message ? ": " : "", message ? message : "",
-                  (address)h_exception(), file, line, thread);
+                  p2i(h_exception()), file, line, p2i(thread));
   }
   // for AbortVMOnException flag
   NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
@@ -167,7 +165,7 @@
   if (LogEvents){
     Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]",
                           h_exception->print_value_string(), message ? ": " : "", message ? message : "",
-                          (address)h_exception(), file, line);
+                          p2i(h_exception()), file, line);
   }
 }
 
@@ -486,7 +484,7 @@
       strstr(value_string, AbortVMOnException)) {
     if (AbortVMOnExceptionMessage == NULL || message == NULL ||
         strcmp(message, AbortVMOnExceptionMessage) == 0) {
-      fatal(err_msg("Saw %s, aborting", value_string));
+      fatal("Saw %s, aborting", value_string);
     }
   }
 }
--- a/hotspot/src/share/vm/utilities/fakeRttiSupport.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/fakeRttiSupport.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -50,6 +50,7 @@
 // with.
 template<typename T, typename TagType>
 class FakeRttiSupport VALUE_OBJ_CLASS_SPEC {
+  friend class VMStructs;
 public:
   // Construct with the indicated concrete tag, and include the
   // concrete tag in the associated tag set.
@@ -76,8 +77,8 @@
   FakeRttiSupport add_tag(TagType tag) const {
     uintx tbit = tag_bit(tag);
     assert((_tag_set & tbit) == 0,
-           err_msg("Tag " UINTX_FORMAT " is already present in tag set: " UINTX_FORMAT,
-                   (uintx)tag, _tag_set));
+           "Tag " UINTX_FORMAT " is already present in tag set: " UINTX_FORMAT,
+           (uintx)tag, _tag_set);
     return FakeRttiSupport(_concrete_tag, _tag_set | tbit);
   }
 
@@ -90,9 +91,9 @@
   }
 
   static TagType validate_tag(TagType tag) {
-    assert(0 <= tag, err_msg("Tag " INTX_FORMAT " is negative", (intx)tag));
+    assert(0 <= tag, "Tag " INTX_FORMAT " is negative", (intx)tag);
     assert(tag < BitsPerWord,
-           err_msg("Tag " UINTX_FORMAT " is too large", (uintx)tag));
+           "Tag " UINTX_FORMAT " is too large", (uintx)tag);
     return tag;
   }
 };
--- a/hotspot/src/share/vm/utilities/globalDefinitions.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -50,7 +50,7 @@
 uint64_t OopEncodingHeapMax = 0;
 
 void basic_fatal(const char* msg) {
-  fatal(msg);
+  fatal("%s", msg);
 }
 
 // Something to help porters sleep at night
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -60,9 +60,6 @@
 #ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
 #define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
 #endif
-#ifndef PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-#endif
 #ifndef ATTRIBUTE_PRINTF
 #define ATTRIBUTE_PRINTF(fmt, vargs)
 #endif
@@ -903,20 +900,20 @@
   CompLevel_simple            = 1,         // C1
   CompLevel_limited_profile   = 2,         // C1, invocation & backedge counters
   CompLevel_full_profile      = 3,         // C1, invocation & backedge counters + mdo
-  CompLevel_full_optimization = 4,         // C2 or Shark
+  CompLevel_full_optimization = 4,         // C2, Shark or JVMCI
 
-#if defined(COMPILER2) || defined(SHARK)
-  CompLevel_highest_tier      = CompLevel_full_optimization,  // pure C2 and tiered
+#if defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI
+  CompLevel_highest_tier      = CompLevel_full_optimization,  // pure C2 and tiered or JVMCI and tiered
 #elif defined(COMPILER1)
-  CompLevel_highest_tier      = CompLevel_simple,             // pure C1
+  CompLevel_highest_tier      = CompLevel_simple,             // pure C1 or JVMCI
 #else
   CompLevel_highest_tier      = CompLevel_none,
 #endif
 
 #if defined(TIERED)
   CompLevel_initial_compile   = CompLevel_full_profile        // tiered
-#elif defined(COMPILER1)
-  CompLevel_initial_compile   = CompLevel_simple              // pure C1
+#elif defined(COMPILER1) || INCLUDE_JVMCI
+  CompLevel_initial_compile   = CompLevel_simple              // pure C1 or JVMCI
 #elif defined(COMPILER2) || defined(SHARK)
   CompLevel_initial_compile   = CompLevel_full_optimization   // pure C2
 #else
@@ -1413,14 +1410,6 @@
 #define UINTX_FORMAT_W(width) "%" #width PRIuPTR
 
 
-// Enable zap-a-lot if in debug version.
-
-# ifdef ASSERT
-# ifdef COMPILER2
-#   define ENABLE_ZAP_DEAD_LOCALS
-#endif /* COMPILER2 */
-# endif /* ASSERT */
-
 #define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
 
 // Dereference vptr
--- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -301,10 +301,6 @@
 #define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
 #endif
 
-#ifndef __clang_major__
-#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC _Pragma("GCC diagnostic ignored \"-Wformat\"") _Pragma("GCC diagnostic error \"-Wformat-nonliteral\"") _Pragma("GCC diagnostic error \"-Wformat-security\"")
-#endif
-
 #if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
 #define TEMPLATE_TABLE_BUG
 #endif
--- a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -171,6 +171,12 @@
 #define strdup _strdup
 #endif
 
+// Visual Studio 2013 introduced strtoull(); before, one has to use _strtoui64() instead.
+#if _MSC_VER < 1800
+#define strtoull _strtoui64
+#endif
+
+
 #pragma warning( disable : 4100 ) // unreferenced formal parameter
 #pragma warning( disable : 4127 ) // conditional expression is constant
 #pragma warning( disable : 4514 ) // unreferenced inline function has been removed
--- a/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -374,6 +374,40 @@
   void sort(int f(E*,E*), int stride) {
     qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f);
   }
+
+  // Binary search and insertion utility.  Search array for element
+  // matching key according to the static compare function.  Insert
+  // that element is not already in the list.  Assumes the list is
+  // already sorted according to compare function.
+  template <int compare(const E&, const E&)> E insert_sorted(E& key) {
+    bool found;
+    int location = find_sorted<E, compare>(key, found);
+    if (!found) {
+      insert_before(location, key);
+    }
+    return at(location);
+  }
+
+  template <typename K, int compare(const K&, const E&)> int find_sorted(const K& key, bool& found) {
+    found = false;
+    int min = 0;
+    int max = length() - 1;
+
+    while (max >= min) {
+      int mid = (max + min) / 2;
+      E value = at(mid);
+      int diff = compare(key, value);
+      if (diff > 0) {
+        min = mid + 1;
+      } else if (diff < 0) {
+        max = mid - 1;
+      } else {
+        found = true;
+        return mid;
+      }
+    }
+    return min;
+  }
 };
 
 // Global GrowableArray methods (one instance in the library per each 'E' type).
--- a/hotspot/src/share/vm/utilities/macros.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/macros.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -173,6 +173,20 @@
 #define INCLUDE_TRACE 1
 #endif // INCLUDE_TRACE
 
+#ifndef INCLUDE_JVMCI
+#define INCLUDE_JVMCI 1
+#endif
+
+#if INCLUDE_JVMCI
+#define JVMCI_ONLY(code) code
+#define NOT_JVMCI(code)
+#define NOT_JVMCI_RETURN /* next token must be ; */
+#else
+#define JVMCI_ONLY(code)
+#define NOT_JVMCI(code) code
+#define NOT_JVMCI_RETURN {}
+#endif // INCLUDE_JVMCI
+
 // COMPILER1 variant
 #ifdef COMPILER1
 #ifdef COMPILER2
@@ -195,7 +209,7 @@
 #ifdef TIERED
 #define TIERED_ONLY(code) code
 #define NOT_TIERED(code)
-#else
+#else // TIERED
 #define TIERED_ONLY(code)
 #define NOT_TIERED(code) code
 #endif // TIERED
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "compiler/compileLog.hpp"
 #include "gc/shared/gcId.hpp"
+#include "gc/shared/gcId.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/os.hpp"
@@ -238,11 +239,11 @@
   return;
 }
 
-void outputStream::gclog_stamp(const GCId& gc_id) {
+void outputStream::gclog_stamp() {
   date_stamp(PrintGCDateStamps);
   stamp(PrintGCTimeStamps);
   if (PrintGCID) {
-    print("#%u: ", gc_id.id());
+    print("#%u: ", GCId::current());
   }
 }
 
@@ -543,7 +544,7 @@
     memset(longest_name, 'a', sizeof(longest_name));
     longest_name[JVM_MAXPATHLEN - 1] = '\0';
     o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
-    assert(strcmp(longest_name, o_result) == 0, err_msg("longest name does not match. expected '%s' but got '%s'", longest_name, o_result));
+    assert(strcmp(longest_name, o_result) == 0, "longest name does not match. expected '%s' but got '%s'", longest_name, o_result);
     FREE_C_HEAP_ARRAY(char, o_result);
   }
 
@@ -554,7 +555,7 @@
     memset(too_long_name, 'a', too_long_length);
     too_long_name[too_long_length - 1] = '\0';
     o_result = make_log_name_internal((const char*)&too_long_name, NULL, pid, tms);
-    assert(o_result == NULL, err_msg("Too long file name should return NULL, but got '%s'", o_result));
+    assert(o_result == NULL, "Too long file name should return NULL, but got '%s'", o_result);
   }
 
   {
@@ -565,7 +566,7 @@
     longest_name[JVM_MAXPATHLEN - 2] = 't';
     longest_name[JVM_MAXPATHLEN - 1] = '\0';
     o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
-    assert(o_result == NULL, err_msg("Too long file name after timestamp expansion should return NULL, but got '%s'", o_result));
+    assert(o_result == NULL, "Too long file name after timestamp expansion should return NULL, but got '%s'", o_result);
   }
 
   {
@@ -576,7 +577,7 @@
     longest_name[JVM_MAXPATHLEN - 2] = 'p';
     longest_name[JVM_MAXPATHLEN - 1] = '\0';
     o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
-    assert(o_result == NULL, err_msg("Too long file name after pid expansion should return NULL, but got '%s'", o_result));
+    assert(o_result == NULL, "Too long file name after pid expansion should return NULL, but got '%s'", o_result);
   }
 }
 #endif // PRODUCT
@@ -1440,3 +1441,14 @@
 }
 
 #endif
+
+void logStream::write(const char* s, size_t len) {
+  if (len > 0 && s[len - 1] == '\n') {
+    _current_line.write(s, len - 1);
+    _log_func(_current_line.as_string());
+    _current_line.reset();
+  } else {
+    _current_line.write(s, len);
+    update_position(s, len);
+  }
+}
--- a/hotspot/src/share/vm/utilities/ostream.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -108,7 +108,7 @@
    void date_stamp(bool guard) {
      date_stamp(guard, "", ": ");
    }
-   void gclog_stamp(const GCId& gc_id);
+   void gclog_stamp();
 
    // portable printing of 64 bit integers
    void print_jlong(jlong value);
@@ -235,6 +235,18 @@
   void flush() {};
 };
 
+class logStream : public outputStream {
+private:
+  stringStream _current_line;
+  void (*_log_func)(const char* fmt, ...);
+public:
+  void write(const char* s, size_t len);
+  logStream(void (*log_func)(const char* fmt, ...)) : _log_func(log_func) {}
+  ~logStream() {
+    guarantee(_current_line.size() == 0, "Buffer not flushed. Missing call to print_cr()?");
+  }
+};
+
 class gcLogFileStream : public fileStream {
  protected:
   const char*  _file_name;
--- a/hotspot/src/share/vm/utilities/top.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/top.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -42,6 +42,9 @@
 #ifdef COMPILER2
 #include "opto/c2_globals.hpp"
 #endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
 
 // THIS FILE IS INTESIONALLY LEFT EMPTY
 // IT IS USED TO MINIMIZE THE NUMBER OF DEPENDENCIES IN includeDB
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Thu Oct 22 11:13:08 2015 -0700
@@ -26,6 +26,7 @@
 #include "precompiled.hpp"
 #include "code/codeCache.hpp"
 #include "compiler/compileBroker.hpp"
+#include "compiler/disassembler.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "prims/whitebox.hpp"
 #include "runtime/arguments.hpp"
@@ -45,8 +46,6 @@
 #include "utilities/top.hpp"
 #include "utilities/vmError.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
 // List of environment variables that should be reported in error log file.
 const char *env_list[] = {
   // All platforms
@@ -71,108 +70,6 @@
   (const char *)0
 };
 
-// Fatal error handler for internal errors and crashes.
-//
-// The default behavior of fatal error handler is to print a brief message
-// to standard out (defaultStream::output_fd()), then save detailed information
-// into an error report file (hs_err_pid<pid>.log) and abort VM. If multiple
-// threads are having troubles at the same time, only one error is reported.
-// The thread that is reporting error will abort VM when it is done, all other
-// threads are blocked forever inside report_and_die().
-
-// Constructor for crashes
-VMError::VMError(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context) {
-    _thread = thread;
-    _id = sig;
-    _pc   = pc;
-    _siginfo = siginfo;
-    _context = context;
-
-    _verbose = false;
-    _current_step = 0;
-    _current_step_info = NULL;
-
-    _message = NULL;
-    _detail_msg = NULL;
-    _filename = NULL;
-    _lineno = 0;
-
-    _size = 0;
-}
-
-// Constructor for internal errors
-VMError::VMError(Thread* thread, const char* filename, int lineno,
-                 const char* message, const char * detail_msg)
-{
-  _thread = thread;
-  _id = INTERNAL_ERROR;     // Value that's not an OS exception/signal
-  _filename = filename;
-  _lineno = lineno;
-  _message = message;
-  _detail_msg = detail_msg;
-
-  _verbose = false;
-  _current_step = 0;
-  _current_step_info = NULL;
-
-  _pc = NULL;
-  _siginfo = NULL;
-  _context = NULL;
-
-  _size = 0;
-}
-
-// Constructor for OOM errors
-VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size,
-                 VMErrorType vm_err_type, const char* message) {
-    _thread = thread;
-    _id = vm_err_type; // Value that's not an OS exception/signal
-    _filename = filename;
-    _lineno = lineno;
-    _message = message;
-    _detail_msg = NULL;
-
-    _verbose = false;
-    _current_step = 0;
-    _current_step_info = NULL;
-
-    _pc = NULL;
-    _siginfo = NULL;
-    _context = NULL;
-
-    _size = size;
-}
-
-
-// Constructor for non-fatal errors
-VMError::VMError(const char* message) {
-    _thread = NULL;
-    _id = INTERNAL_ERROR;     // Value that's not an OS exception/signal
-    _filename = NULL;
-    _lineno = 0;
-    _message = message;
-    _detail_msg = NULL;
-
-    _verbose = false;
-    _current_step = 0;
-    _current_step_info = NULL;
-
-    _pc = NULL;
-    _siginfo = NULL;
-    _context = NULL;
-
-    _size = 0;
-}
-
-// -XX:OnError=<string>, where <string> can be a list of commands, separated
-// by ';'. "%p" is replaced by current process id (pid); "%%" is replaced by
-// a single "%". Some examples:
-//
-// -XX:OnError="pmap %p"                // show memory map
-// -XX:OnError="gcore %p; dbx - %p"     // dump core and launch debugger
-// -XX:OnError="cat hs_err_pid%p.log | mail my_email@sun.com"
-// -XX:OnError="kill -9 %p"             // ?#!@#
-
 // A simple parser for -XX:OnError, usage:
 //  ptr = OnError;
 //  while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr) != NULL)
@@ -196,7 +93,6 @@
   return buf;
 }
 
-
 static void print_bug_submit_message(outputStream *out, Thread *thread) {
   if (out == NULL) return;
   out->print_raw_cr("# If you would like to submit a bug report, please visit:");
@@ -223,7 +119,6 @@
   coredump_message[sizeof(coredump_message)-1] = 0;
 }
 
-
 // Return a string to describe the error
 char* VMError::error_string(char* buf, int buflen) {
   char signame_buf[64];
@@ -243,9 +138,9 @@
                          p ? p + 1 : _filename, _lineno,
                          os::current_process_id(), os::current_thread_id());
     if (n >= 0 && n < buflen && _message) {
-      if (_detail_msg) {
+      if (strlen(_detail_msg) > 0) {
         jio_snprintf(buf + n, buflen - n, "%s%s: %s",
-                     os::line_separator(), _message, _detail_msg);
+        os::line_separator(), _message, _detail_msg);
       } else {
         jio_snprintf(buf + n, buflen - n, "%sError: %s",
                      os::line_separator(), _message);
@@ -357,7 +252,11 @@
 // thread can report error, so large buffers are statically allocated in data
 // segment.
 
-void VMError::report(outputStream* st) {
+int          VMError::_current_step;
+const char*  VMError::_current_step_info;
+
+void VMError::report(outputStream* st, bool _verbose) {
+
 # define BEGIN if (_current_step == 0) { _current_step = 1;
 # define STEP(n, s) } if (_current_step < n) { _current_step = n; _current_step_info = s;
 # define END }
@@ -384,14 +283,14 @@
   // error handler after a secondary crash works.
   STEP(20, "(test secondary crash 1)")
     if (_verbose && TestCrashInErrorHandler != 0) {
-      st->print_cr("Will crash now (TestCrashInErrorHandler=%d)...",
+      st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
         TestCrashInErrorHandler);
       controlled_crash(TestCrashInErrorHandler);
     }
 
   STEP(30, "(test secondary crash 2)")
     if (_verbose && TestCrashInErrorHandler != 0) {
-      st->print_cr("Will crash now (TestCrashInErrorHandler=%d)...",
+      st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
         TestCrashInErrorHandler);
       controlled_crash(TestCrashInErrorHandler);
     }
@@ -429,15 +328,15 @@
            jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
            st->print("%s", buf);
            st->print(" bytes");
-           if (_message != NULL) {
+           if (strlen(_detail_msg) > 0) {
              st->print(" for ");
-             st->print("%s", _message);
+             st->print("%s", _detail_msg);
            }
            st->cr();
          } else {
-           if (_message != NULL) {
+           if (strlen(_detail_msg) > 0) {
              st->print("# ");
-             st->print_cr("%s", _message);
+             st->print_cr("%s", _detail_msg);
            }
          }
          // In error file give some solutions
@@ -460,7 +359,7 @@
      if (os::exception_name(_id, buf, sizeof(buf))) {
        st->print("%s", buf);
        st->print(" (0x%x)", _id);                // signal number
-       st->print(" at pc=" PTR_FORMAT, _pc);
+       st->print(" at pc=" PTR_FORMAT, p2i(_pc));
      } else {
        if (should_report_bug(_id)) {
          st->print("Internal Error");
@@ -493,12 +392,12 @@
 
      if (should_report_bug(_id)) {  // already printed the message.
        // error message
-       if (_detail_msg) {
+       if (strlen(_detail_msg) > 0) {
          st->print_cr("#  %s: %s", _message ? _message : "Error", _detail_msg);
        } else if (_message) {
          st->print_cr("#  Error: %s", _message);
        }
-    }
+     }
 
   STEP(90, "(printing Java version string)")
 
@@ -511,11 +410,17 @@
                                   JDK_Version::runtime_version() : "";
      st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version);
      // This is the long version with some default settings added
-     st->print_cr("# Java VM: %s (%s, %s%s%s, %s, %s)",
+     st->print_cr("# Java VM: %s (%s, %s%s%s%s%s, %s, %s)",
                    Abstract_VM_Version::vm_name(),
                    Abstract_VM_Version::vm_release(),
                    Abstract_VM_Version::vm_info_string(),
                    TieredCompilation ? ", tiered" : "",
+#if INCLUDE_JVMCI
+                   EnableJVMCI ? ", jvmci" : "",
+                   UseJVMCICompiler ? ", jvmci compiler" : "",
+#else
+                   "", "",
+#endif
                    UseCompressedOops ? ", compressed oops" : "",
                    gc_mode(),
                    Abstract_VM_Version::vm_platform_string()
@@ -595,7 +500,7 @@
      // current thread
      if (_verbose) {
        if (_thread) {
-         st->print("Current thread (" PTR_FORMAT "):  ", _thread);
+         st->print("Current thread (" PTR_FORMAT "):  ", p2i(_thread));
          _thread->print_on_error(st, buf, sizeof(buf));
          st->cr();
        } else {
@@ -634,13 +539,13 @@
        }
 
        address stack_bottom = stack_top - stack_size;
-       st->print("[" PTR_FORMAT "," PTR_FORMAT "]", stack_bottom, stack_top);
+       st->print("[" PTR_FORMAT "," PTR_FORMAT "]", p2i(stack_bottom), p2i(stack_top));
 
        frame fr = _context ? os::fetch_frame_from_context(_context)
                            : os::current_frame();
 
        if (fr.sp()) {
-         st->print(",  sp=" PTR_FORMAT, fr.sp());
+         st->print(",  sp=" PTR_FORMAT, p2i(fr.sp()));
          size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024);
          st->print(",  free space=" SIZE_FORMAT "k", free_stack_size);
        }
@@ -674,7 +579,7 @@
      if (_verbose && _thread && (_thread->is_Named_thread())) {
        JavaThread*  jt = ((NamedThread *)_thread)->processed_thread();
        if (jt != NULL) {
-         st->print_cr("JavaThread " PTR_FORMAT " (nid = " UINTX_FORMAT ") was being processed", jt, jt->osthread()->thread_id());
+         st->print_cr("JavaThread " PTR_FORMAT " (nid = %d) was being processed", p2i(jt), jt->osthread()->thread_id());
          print_stack_trace(st, jt, buf, sizeof(buf), true);
        }
      }
@@ -704,6 +609,31 @@
        st->cr();
      }
 
+  STEP(265, "(printing code blob if possible)")
+
+     if (_verbose && _context) {
+       CodeBlob* cb = CodeCache::find_blob(_pc);
+       if (cb != NULL) {
+         if (Interpreter::contains(_pc)) {
+           // The interpreter CodeBlob is very large so try to print the codelet instead.
+           InterpreterCodelet* codelet = Interpreter::codelet_containing(_pc);
+           if (codelet != NULL) {
+             codelet->print_on(st);
+             Disassembler::decode(codelet->code_begin(), codelet->code_end(), st);
+           }
+         } else {
+           StubCodeDesc* desc = StubCodeDesc::desc_for(_pc);
+           if (desc != NULL) {
+             desc->print_on(st);
+             Disassembler::decode(desc->begin(), desc->end(), st);
+           } else {
+             Disassembler::decode(cb, st);
+             st->cr();
+           }
+         }
+       }
+     }
+
   STEP(270, "(printing VM operation)" )
 
      if (_verbose && _thread && _thread->is_VM_thread()) {
@@ -786,7 +716,7 @@
        Universe::heap()->print_on_error(st);
        st->cr();
 
-       st->print_cr("Polling page: " INTPTR_FORMAT, os::get_polling_page());
+       st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
        st->cr();
      }
 
@@ -896,8 +826,7 @@
 # undef END
 }
 
-VMError* volatile VMError::first_error = NULL;
-volatile jlong VMError::first_error_tid = -1;
+volatile intptr_t VMError::first_error_tid = -1;
 
 // An error could happen before tty is initialized or after it has been
 // destroyed. Here we use a very simple unbuffered fdStream for printing.
@@ -958,7 +887,59 @@
   return fd;
 }
 
-void VMError::report_and_die() {
+int         VMError::_id;
+const char* VMError::_message;
+char        VMError::_detail_msg[1024];
+Thread*     VMError::_thread;
+address     VMError::_pc;
+void*       VMError::_siginfo;
+void*       VMError::_context;
+const char* VMError::_filename;
+int         VMError::_lineno;
+size_t      VMError::_size;
+
+void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo,
+                             void* context, const char* detail_fmt, ...)
+{
+  va_list detail_args;
+  va_start(detail_args, detail_fmt);
+  report_and_die(sig, NULL, detail_fmt, detail_args, thread, pc, siginfo, context, NULL, 0, 0);
+  va_end(detail_args);
+}
+
+void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context)
+{
+  report_and_die(thread, sig, pc, siginfo, context, "%s", "");
+}
+
+void VMError::report_and_die(const char* message, const char* detail_fmt, ...)
+{
+  va_list detail_args;
+  va_start(detail_args, detail_fmt);
+  report_and_die(INTERNAL_ERROR, message, detail_fmt, detail_args, NULL, NULL, NULL, NULL, NULL, 0, 0);
+  va_end(detail_args);
+}
+
+void VMError::report_and_die(const char* message)
+{
+  report_and_die(message, "%s", "");
+}
+
+void VMError::report_and_die(Thread* thread, const char* filename, int lineno, const char* message,
+                             const char* detail_fmt, va_list detail_args)
+{
+  report_and_die(INTERNAL_ERROR, message, detail_fmt, detail_args, thread, NULL, NULL, NULL, filename, lineno, 0);
+}
+
+void VMError::report_and_die(Thread* thread, const char* filename, int lineno, size_t size,
+                             VMErrorType vm_err_type, const char* detail_fmt, va_list detail_args) {
+  report_and_die(vm_err_type, NULL, detail_fmt, detail_args, thread, NULL, NULL, NULL, filename, lineno, size);
+}
+
+void VMError::report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
+                             Thread* thread, address pc, void* siginfo, void* context, const char* filename,
+                             int lineno, size_t size)
+{
   // Don't allocate large buffer on stack
   static char buffer[O_BUFLEN];
 
@@ -974,12 +955,22 @@
   if (SuppressFatalErrorMessage) {
       os::abort(CreateCoredumpOnCrash);
   }
-  jlong mytid = os::current_thread_id();
-  if (first_error == NULL &&
-      Atomic::cmpxchg_ptr(this, &first_error, NULL) == NULL) {
+  intptr_t mytid = os::current_thread_id();
+  if (first_error_tid == -1 &&
+      Atomic::cmpxchg_ptr(mytid, &first_error_tid, -1) == -1) {
+
+    _id = id;
+    _message = message;
+    _thread = thread;
+    _pc = pc;
+    _siginfo = siginfo;
+    _context = context;
+    _filename = filename;
+    _lineno = lineno;
+    _size = size;
+    jio_vsnprintf(_detail_msg, sizeof(_detail_msg), detail_fmt, detail_args);
 
     // first time
-    first_error_tid = mytid;
     set_error_reported();
 
     if (ShowMessageBoxOnError || PauseAtExit) {
@@ -1007,7 +998,7 @@
     if (first_error_tid != mytid) {
       char msgbuf[64];
       jio_snprintf(msgbuf, sizeof(msgbuf),
-                   "[thread " INT64_FORMAT " also had an error]",
+                   "[thread " INTX_FORMAT " also had an error]",
                    mytid);
       out.print_raw_cr(msgbuf);
 
@@ -1022,8 +1013,7 @@
 
       jio_snprintf(buffer, sizeof(buffer),
                    "[error occurred during error reporting %s, id 0x%x]",
-                   first_error ? first_error->_current_step_info : "",
-                   _id);
+                   _current_step_info, _id);
       if (log.is_open()) {
         log.cr();
         log.print_raw_cr(buffer);
@@ -1038,21 +1028,17 @@
 
   // print to screen
   if (!out_done) {
-    first_error->_verbose = false;
-
     staticBufferStream sbs(buffer, sizeof(buffer), &out);
-    first_error->report(&sbs);
+    report(&sbs, false);
 
     out_done = true;
 
-    first_error->_current_step = 0;         // reset current_step
-    first_error->_current_step_info = "";   // reset current_step string
+    _current_step = 0;
+    _current_step_info = "";
   }
 
   // print to error log file
   if (!log_done) {
-    first_error->_verbose = true;
-
     // see if log file is already open
     if (!log.is_open()) {
       // open log file
@@ -1072,12 +1058,12 @@
     }
 
     staticBufferStream sbs(buffer, O_BUFLEN, &log);
-    first_error->report(&sbs);
-    first_error->_current_step = 0;         // reset current_step
-    first_error->_current_step_info = "";   // reset current_step string
+    report(&sbs, true);
+    _current_step = 0;
+    _current_step_info = "";
 
     // Run error reporting to determine whether or not to report the crash.
-    if (!transmit_report_done && should_report_bug(first_error->_id)) {
+    if (!transmit_report_done && should_report_bug(_id)) {
       transmit_report_done = true;
       const int fd2 = ::dup(log.fd());
       FILE* const hs_err = ::fdopen(fd2, "r");
@@ -1149,7 +1135,7 @@
     }
   }
 
-  static bool skip_bug_url = !should_report_bug(first_error->_id);
+  static bool skip_bug_url = !should_report_bug(_id);
   if (!skip_bug_url) {
     skip_bug_url = true;
 
@@ -1162,7 +1148,7 @@
     static bool skip_os_abort = false;
     if (!skip_os_abort) {
       skip_os_abort = true;
-      bool dump_core = should_report_bug(first_error->_id);
+      bool dump_core = should_report_bug(_id);
       os::abort(dump_core && CreateCoredumpOnCrash, _siginfo, _context);
     }
 
@@ -1177,10 +1163,10 @@
  */
 class VM_ReportJavaOutOfMemory : public VM_Operation {
  private:
-  VMError *_err;
+  const char* _message;
  public:
-  VM_ReportJavaOutOfMemory(VMError *err) { _err = err; }
-  VMOp_Type type() const                 { return VMOp_ReportJavaOutOfMemory; }
+  VM_ReportJavaOutOfMemory(const char* message) { _message = message; }
+  VMOp_Type type() const                        { return VMOp_ReportJavaOutOfMemory; }
   void doit();
 };
 
@@ -1189,7 +1175,7 @@
   static char buffer[O_BUFLEN];
 
   tty->print_cr("#");
-  tty->print_cr("# java.lang.OutOfMemoryError: %s", _err->message());
+  tty->print_cr("# java.lang.OutOfMemoryError: %s", _message);
   tty->print_cr("# -XX:OnOutOfMemoryError=\"%s\"", OnOutOfMemoryError);
 
   // make heap parsability
@@ -1212,10 +1198,10 @@
   }
 }
 
-void VMError::report_java_out_of_memory() {
+void VMError::report_java_out_of_memory(const char* message) {
   if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
     MutexLocker ml(Heap_lock);
-    VM_ReportJavaOutOfMemory op(this);
+    VM_ReportJavaOutOfMemory op(message);
     VMThread::execute(&op);
   }
 }
--- a/hotspot/src/share/vm/utilities/vmError.hpp	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.hpp	Thu Oct 22 11:13:08 2015 -0700
@@ -30,39 +30,40 @@
 class Decoder;
 class VM_ReportJavaOutOfMemory;
 
-class VMError : public StackObj {
+class VMError : public AllStatic {
   friend class VM_ReportJavaOutOfMemory;
   friend class Decoder;
 
-  int          _id;          // Solaris/Linux signals: 0 - SIGRTMAX
-                             // Windows exceptions: 0xCxxxxxxx system errors
-                             //                     0x8xxxxxxx system warnings
+  static int         _id;               // Solaris/Linux signals: 0 - SIGRTMAX
+                                        // Windows exceptions: 0xCxxxxxxx system errors
+                                        //                     0x8xxxxxxx system warnings
 
-  const char * _message;
-  const char * _detail_msg;
+  static const char* _message;
+  static char        _detail_msg[1024];
 
-  Thread *     _thread;      // NULL if it's native thread
-
+  static Thread*     _thread;           // NULL if it's native thread
 
   // additional info for crashes
-  address      _pc;          // faulting PC
-  void *       _siginfo;     // ExceptionRecord on Windows,
-                             // siginfo_t on Solaris/Linux
-  void *       _context;     // ContextRecord on Windows,
-                             // ucontext_t on Solaris/Linux
+  static address     _pc;               // faulting PC
+  static void*       _siginfo;          // ExceptionRecord on Windows,
+                                        // siginfo_t on Solaris/Linux
+  static void*       _context;          // ContextRecord on Windows,
+                                        // ucontext_t on Solaris/Linux
 
   // additional info for VM internal errors
-  const char * _filename;
-  int          _lineno;
+  static const char* _filename;
+  static int         _lineno;
+
+  // used by reporting about OOM
+  static size_t      _size;
 
   // used by fatal error handler
-  int          _current_step;
-  const char * _current_step_info;
-  int          _verbose;
-  // First error, and its thread id. We must be able to handle native thread,
+  static int         _current_step;
+  static const char* _current_step_info;
+
+  // Thread id of the first error. We must be able to handle native thread,
   // so use thread id instead of Thread* to identify thread.
-  static VMError* volatile first_error;
-  static volatile jlong    first_error_tid;
+  static volatile intptr_t first_error_tid;
 
   // Core dump status, false if we have been unable to write a core/minidump for some reason
   static bool coredump_status;
@@ -72,18 +73,16 @@
   // no core/minidump has been written to disk
   static char coredump_message[O_BUFLEN];
 
-  // used by reporting about OOM
-  size_t       _size;
 
   // set signal handlers on Solaris/Linux or the default exception filter
   // on Windows, to handle recursive crashes.
-  void reset_signal_handlers();
+  static void reset_signal_handlers();
 
   // handle -XX:+ShowMessageBoxOnError. buf is used to format the message string
-  void show_message_box(char* buf, int buflen);
+  static void show_message_box(char* buf, int buflen);
 
   // generate an error report
-  void report(outputStream* st);
+  static void report(outputStream* st, bool verbose);
 
   // generate a stack trace
   static void print_stack_trace(outputStream* st, JavaThread* jt,
@@ -92,42 +91,44 @@
   static const char* gc_mode();
   static void print_oom_reasons(outputStream* st);
 
-  // accessor
-  const char* message() const    { return _message; }
-  const char* detail_msg() const { return _detail_msg; }
-  bool should_report_bug(unsigned int id) {
+  static bool should_report_bug(unsigned int id) {
     return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR);
   }
 
+  static void report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo,
+                             void* context, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(6, 7);
+  static void report_and_die(const char* message, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(2, 3);
+
   static fdStream out;
   static fdStream log; // error log used by VMError::report_and_die()
 
 public:
 
-  // Constructor for crashes
-  VMError(Thread* thread, unsigned int sig, address pc, void* siginfo,
-          void* context);
-  // Constructor for VM internal errors
-  VMError(Thread* thread, const char* filename, int lineno,
-          const char* message, const char * detail_msg);
-
-  // Constructor for VM OOM errors
-  VMError(Thread* thread, const char* filename, int lineno, size_t size,
-          VMErrorType vm_err_type, const char* message);
-  // Constructor for non-fatal errors
-  VMError(const char* message);
-
   // return a string to describe the error
-  char *error_string(char* buf, int buflen);
+  static char* error_string(char* buf, int buflen);
 
   // Record status of core/minidump
   static void record_coredump_status(const char* message, bool status);
 
   // main error reporting function
-  void report_and_die();
+  static void report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
+                             Thread* thread, address pc, void* siginfo, void* context,
+                             const char* filename, int lineno, size_t size) ATTRIBUTE_PRINTF(3, 0);
+
+  static void report_and_die(Thread* thread, unsigned int sig, address pc,
+                             void* siginfo, void* context);
+
+  static void report_and_die(Thread* thread,const char* filename, int lineno, const char* message,
+                             const char* detail_fmt, va_list detail_args) ATTRIBUTE_PRINTF(5, 0);
+
+  static void report_and_die(Thread* thread, const char* filename, int lineno, size_t size,
+                             VMErrorType vm_err_type, const char* detail_fmt,
+                             va_list detail_args) ATTRIBUTE_PRINTF(6, 0);
+
+  static void report_and_die(const char* message);
 
   // reporting OutOfMemoryError
-  void report_java_out_of_memory();
+  static void report_java_out_of_memory(const char* message);
 
   // returns original flags for signal, if it was resetted, or -1 if
   // signal was not changed by error reporter
@@ -138,11 +139,9 @@
   static address get_resetted_sighandler(int sig);
 
   // check to see if fatal error reporting is in progress
-  static bool fatal_error_in_progress() { return first_error != NULL; }
+  static bool fatal_error_in_progress() { return first_error_tid != -1; }
 
-  static jlong get_first_error_tid() {
-    return first_error_tid;
-  }
+  static intptr_t get_first_error_tid() { return first_error_tid; }
 };
 
 #endif // SHARE_VM_UTILITIES_VMERROR_HPP
--- a/hotspot/test/TEST.groups	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/TEST.groups	Thu Oct 22 11:13:08 2015 -0700
@@ -319,7 +319,7 @@
 
 hotspot_runtime = \
   runtime/ \
- -runtime/6888954/vmerrors.sh \
+ -runtime/ErrorHandling/ErrorHandler.java \
  -runtime/RedefineObject/TestRedefineObject.java \
  -runtime/8003720/Test8003720.java \
  -runtime/Metaspace/FragmentMetaspace.java \
@@ -327,6 +327,7 @@
  -runtime/Thread/TestThreadDumpMonitorContention.java \
  -runtime/SharedArchiveFile/SharedBaseAddress.java \
  -runtime/memory/ReserveMemory.java \
+ -runtime/memory/RunUnitTestsConcurrently.java \
  -runtime/Unsafe/RangeCheck.java \
  -runtime/SharedArchiveFile/CdsSameObjectAlignment.java \
  -runtime/SharedArchiveFile/DefaultUseWithClient.java \
--- a/hotspot/test/compiler/TestMoveStoresOutOfLoopsStoreNoCtrl.java	Thu Oct 22 08:47:43 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2015, 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 8134288
- * @summary Store nodes may not have a control if used to update profiling
- * @run main/othervm -XX:-ProfileInterpreter -XX:-TieredCompilation -XX:-BackgroundCompilation TestMoveStoresOutOfLoopsStoreNoCtrl
- *
- */
-
-public class TestMoveStoresOutOfLoopsStoreNoCtrl {
-
-    static void test(boolean flag) {
-        for (int i = 0; i < 20000; i++) {
-            if (flag) {
-                int j = 0;
-                do {
-                    j++;
-                } while(j < 10);
-            }
-        }
-    }
-
-    static public void main(String[] args) {
-        test(false);
-    }
-
-}
--- a/hotspot/test/compiler/c2/5057225/Test5057225.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/c2/5057225/Test5057225.java	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,11 @@
  * @test
  * @bug 5057225
  * @summary Remove useless I2L conversions
- *
+ * @library /testlibrary
  * @run main/othervm -Xcomp -XX:CompileOnly=Test5057225.doload Test5057225
  */
 
-import java.net.URLClassLoader;
+import jdk.test.lib.Utils;
 
 public class Test5057225 {
     static byte[]  ba = new byte[]  { -1 };
@@ -89,8 +89,9 @@
 
     static void loadAndRunClass(String classname) throws Exception {
         Class cl = Class.forName(classname);
-        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
-        ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+        ClassLoader apploader = cl.getClassLoader();
+        ClassLoader loader
+                = Utils.getTestClassPathURLClassLoader(apploader.getParent());
         Class c = loader.loadClass(classname);
         Runnable r = (Runnable) c.newInstance();
         r.run();
--- a/hotspot/test/compiler/c2/5091921/Test7005594.sh	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/c2/5091921/Test7005594.sh	Thu Oct 22 11:13:08 2015 -0700
@@ -78,7 +78,7 @@
 
 ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7005594.java
 
-${TESTJAVA}/bin/java ${TESTOPTS} -Xmx1600m -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1
+${TESTJAVA}/bin/java ${TESTOPTS} -Xmx1600m -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test -XX:CompileCommand=quiet Test7005594 > test.out 2>&1
 
 result=$?
 
--- a/hotspot/test/compiler/c2/6603011/Test.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/c2/6603011/Test.java	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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,7 +25,7 @@
  * @test
  * @bug 6603011
  * @summary long/int division by constant
- *
+ * @library /testlibrary
  * @run main/othervm -Xcomp -Xbatch -XX:-Inline Test
  */
 
@@ -36,7 +36,7 @@
 //   dividend and divisor combinations are tested
 //
 
-import java.net.*;
+import jdk.test.lib.Utils;
 
 class s {
   static int  divi(int  dividend, int  divisor) { return dividend / divisor; }
@@ -189,10 +189,10 @@
   // This allows the JIT to see q.DIVISOR as a final constant, and change
   // any divisions or mod operations into multiplies.
   public static void test_divisor(int divisor,
-                                  URLClassLoader apploader) throws Exception {
+                                  ClassLoader apploader) throws Exception {
     System.setProperty("divisor", "" + divisor);
-    ClassLoader loader = new URLClassLoader(apploader.getURLs(),
-                                            apploader.getParent());
+    ClassLoader loader
+                = Utils.getTestClassPathURLClassLoader(apploader.getParent());
     Class c = loader.loadClass("Test");
     Runnable r = (Runnable)c.newInstance();
     r.run();
@@ -200,7 +200,7 @@
 
   public static void main(String[] args) throws Exception {
     Class cl = Class.forName("Test");
-    URLClassLoader apploader = (URLClassLoader)cl.getClassLoader();
+    ClassLoader apploader = cl.getClassLoader();
 
 
     // Test every divisor between -100 and 100.
--- a/hotspot/test/compiler/c2/6800154/Test6800154.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/c2/6800154/Test6800154.java	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,11 @@
  * @test
  * @bug 6800154
  * @summary Add comments to long_by_long_mulhi() for better understandability
- *
+ * @library /testlibrary
  * @run main/othervm -Xcomp -XX:CompileOnly=Test6800154.divcomp Test6800154
  */
 
-import java.net.URLClassLoader;
+import jdk.test.lib.Utils;
 
 public class Test6800154 implements Runnable {
     static final long[] DIVIDENDS = {
@@ -78,12 +78,13 @@
     public static void main(String[] args) throws Exception
     {
         Class cl = Class.forName("Test6800154");
-        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
+        ClassLoader apploader = cl.getClassLoader();
 
         // Iterate over all divisors.
         for (int i = 0; i < DIVISORS.length; i++) {
             System.setProperty("divisor", "" + DIVISORS[i]);
-            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+            ClassLoader loader
+                    = Utils.getTestClassPathURLClassLoader(apploader.getParent());
             Class c = loader.loadClass("Test6800154");
             Runnable r = (Runnable) c.newInstance();
             r.run();
--- a/hotspot/test/compiler/c2/6805724/Test6805724.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/c2/6805724/Test6805724.java	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,12 +24,13 @@
 /**
  * @test
  * @bug 6805724
- * @summary ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant.
- *
+ * @summary ModLNode::Ideal() generates functionally incorrect graph
+ *          when divisor is any (2^k-1) constant.
+ * @library /testlibrary
  * @run main/othervm -Xcomp -XX:CompileOnly=Test6805724.fcomp Test6805724
  */
 
-import java.net.URLClassLoader;
+import jdk.test.lib.Utils;
 
 public class Test6805724 implements Runnable {
     // Initialize DIVISOR so that it is final in this class.
@@ -65,13 +66,14 @@
 
     public static void main(String args[]) throws Exception {
         Class cl = Class.forName("Test6805724");
-        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
+        ClassLoader apploader = cl.getClassLoader();
 
         // Iterate over all 2^k-1 divisors.
         for (int k = 1; k < Long.SIZE; k++) {
             long divisor = (1L << k) - 1;
             System.setProperty("divisor", "" + divisor);
-            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+            ClassLoader loader
+                    = Utils.getTestClassPathURLClassLoader(apploader.getParent());
             Class c = loader.loadClass("Test6805724");
             Runnable r = (Runnable) c.newInstance();
             r.run();
--- a/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import compiler.testlibrary.CompilerUtils;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.OutputAnalyzer;
@@ -47,7 +48,7 @@
  * @test SegmentedCodeCacheDtraceTest
  * @bug 8015774
  * @requires os.family=="solaris"
- * @library /testlibrary /compiler/testlibrary /../../test/lib
+ * @library /testlibrary / /../../test/lib
  * @build SegmentedCodeCacheDtraceTestWorker
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *     sun.hotspot.WhiteBox$WhiteBoxPermission
--- a/hotspot/test/compiler/codegen/6823354/Test6823354.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/codegen/6823354/Test6823354.java	Thu Oct 22 11:13:08 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,11 @@
  * @test
  * @bug 6823354
  * @summary These methods can be instrinsified by using bit scan, bit test, and population count instructions.
- *
+ * @library /testlibrary
  * @run main/othervm -Xcomp -XX:CompileOnly=Test6823354.lzcomp,Test6823354.tzcomp,.dolzcomp,.dotzcomp Test6823354
  */
 
-import java.net.URLClassLoader;
+import jdk.test.lib.Utils;
 
 public class Test6823354 {
     // Arrays of corner case values.
@@ -197,8 +197,9 @@
 
     static void loadandrunclass(String classname) throws Exception {
         Class cl = Class.forName(classname);
-        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
-        ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+        ClassLoader apploader = cl.getClassLoader();
+        ClassLoader loader
+                = Utils.getTestClassPathURLClassLoader(apploader.getParent());
         Class c = loader.loadClass(classname);
         Runnable r = (Runnable) c.newInstance();
         r.run();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2015, 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 compiler.compilercontrol.matcher;
+
+import jdk.test.lib.Pair;
+import compiler.compilercontrol.share.method.MethodDescriptor;
+import compiler.compilercontrol.share.method.MethodGenerator;
+import pool.PoolHelper;
+import sun.hotspot.WhiteBox;
+
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/*
+ * @test
+ * @bug 8135068
+ * @summary Tests CompilerCommand's method matcher
+ * @library /testlibrary /../../test/lib /compiler/whitebox ../share /
+ * @build MethodMatcherTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *           -XX:+WhiteBoxAPI compiler.compilercontrol.matcher.MethodMatcherTest
+ */
+public class MethodMatcherTest {
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final PoolHelper POOL = new PoolHelper();
+    private static final List<Pair<Executable, Callable<?>>> METHODS =
+            POOL.getAllMethods();
+    private static final int AMOUNT = Integer.parseInt(System
+            .getProperty("test.amount", "25"));
+
+    public static void main(String[] args) {
+        MethodGenerator gen = new MethodGenerator();
+        List<Pair<Executable, Callable<?>>> testMethods =
+                POOL.getAllMethods(PoolHelper.METHOD_FILTER);
+        for (Pair<Executable, Callable<?>> pair : testMethods) {
+            for (int i = 0; i < AMOUNT; i++) {
+                MethodDescriptor md = gen.generateRandomDescriptor(pair.first);
+                check(md);
+            }
+        }
+    }
+
+    /**
+     * Check method matcher with given test case
+     *
+     * @param methodDescriptor method descriptor to check matcher's pattern
+     */
+    private static void check(MethodDescriptor methodDescriptor) {
+        System.out.println("Test case: " + methodDescriptor.getString());
+        System.out.println("Regex: " + methodDescriptor.getRegexp());
+        Pattern pattern = Pattern.compile(methodDescriptor.getRegexp());
+        boolean isValidDesc = methodDescriptor.isValid();
+        List<MethodDescriptor> failList = new ArrayList<>();
+        // walk through all methods in pool to check match with test pattern
+        for (Pair<Executable, Callable<?>> pair : METHODS) {
+            MethodDescriptor m = MethodGenerator.commandDescriptor(pair.first);
+            Matcher matcher = pattern.matcher(m.getCanonicalString());
+            // get expected result
+            MatcherResult expected;
+            if (isValidDesc) {
+                expected = matcher.matches() ?
+                        MatcherResult.MATCH : MatcherResult.NO_MATCH;
+            } else {
+                expected = MatcherResult.PARSING_FAILURE;
+            }
+            // get MethodMatcher's result
+            MatcherResult matchResult = MatcherResult.fromCode(WB.matchesMethod(
+                    pair.first, methodDescriptor.getString()));
+            // compare
+            if (matchResult != expected) {
+                System.out.printf("- Method: %s%n-- FAILED: result: %s, " +
+                                "but expected: %s%n", m.getCanonicalString(),
+                        matchResult, expected);
+                failList.add(m);
+            }
+        }
+        int size = failList.size();
+        if (size != 0) {
+            System.err.println("FAILED test case: " + methodDescriptor
+                    .getString());
+            if (size == METHODS.size()) {
+                System.err.println("-- All methods failed to match");
+            } else {
+                for (MethodDescriptor md : failList) {
+                    System.err.println("-- FAILED match: " + md.getString());
+                }
+            }
+            throw new AssertionError("FAIL: " + methodDescriptor.getString());
+        }
+        System.out.println("--PASSED");
+    }
+
+    /**
+     * Represents MethodMatcher's matching result
+     */
+    public enum MatcherResult {
+        PARSING_FAILURE(-1, "Parsing failed"),
+        NO_MATCH(0, "No match"),
+        MATCH(1, "Match");
+
+        public final int code;
+        private final String message;
+
+        private MatcherResult(int code, String message) {
+            this.code = code;
+            this.message = message;
+        }
+
+        public static MatcherResult fromCode(int code) {
+            switch (code) {
+                case -1: return PARSING_FAILURE;
+                case  0: return NO_MATCH;
+                case  1: return MATCH;
+                default:
+                    throw new IllegalArgumentException("MATCHER FAILURE:"
+                            + "Wrong code: " + code);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return message;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/method/ClassType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2015, 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 compiler.compilercontrol.share.method;
+
+import java.lang.reflect.Executable;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * Element represents class in method descriptor
+ * that consist from class package and class itself
+ */
+public class ClassType extends MethodElementType {
+    private final String[] packageDirs;
+    private final Class<?> aClass;
+    private boolean setPackage;
+
+    public ClassType(Executable method) {
+        // Use pack/subpack/Class::method separators style
+        super(MethodDescriptor.Separator.SLASH);
+        // Get package
+        aClass = method.getDeclaringClass();
+        Package aPackage = method.getDeclaringClass().getPackage();
+        if (aPackage != null) {
+            // split into directories
+            packageDirs = aPackage.getName().split("\\.");
+        } else {
+            packageDirs = null;
+        }
+        setPackage = true;
+        buildElement(setPackage);
+    }
+
+    @Override
+    public boolean isValid() {
+        if (element.isEmpty()) {
+            return false;
+        }
+        boolean separatorMet = false;
+        char separatorChar = 0;
+        char[] charArray = element.toCharArray();
+        for (int i = 0; i < charArray.length; i++) {
+            char ch = charArray[i];
+            switch (ch) {
+                case '/':
+                case '.':
+                    if (separatorMet) {
+                        if (ch != separatorChar) {
+                            // there are two different separators
+                            return false;
+                        }
+                    } else {
+                        separatorChar = ch;
+                        separatorMet = true;
+                    }
+                    break;
+                case ':':
+                    if (++i != charArray.length) {
+                        if (charArray[i] == ':') {
+                            // :: is invalid separator
+                            separator = MethodDescriptor.Separator.DOUBLECOLON;
+                            return false;
+                        }
+                    }
+                    break;
+                // Invalid separators
+                case ',':
+                case ' ':
+                    return false;
+            }
+        }
+        // set correct separator
+        switch (separatorChar) {
+            case '.':
+                separator = MethodDescriptor.Separator.DOT;
+                break;
+            case '/':
+                separator = MethodDescriptor.Separator.SLASH;
+                break;
+            default:
+                separator = MethodDescriptor.Separator.NONE;
+                break;
+        }
+        return super.isValid();
+    }
+
+    @Override
+    public void setSeparator(MethodDescriptor.Separator separator) {
+        this.separator = separator;
+        buildElement(setPackage);
+    }
+
+    @Override
+    public void setPattern(MethodDescriptor.PatternType patternType) {
+        switch (patternType) {
+            case EXACT:
+                break;
+            case PREFIX:
+                // For prefix pattern use only class name without package
+                buildElement(false);
+                regexp = ".*" + regexp;
+                element = "*" + element;
+                break;
+            case ANY:
+                regexp = ".*";
+                element = "*";
+                break;
+            case SUFFIX:
+                regexp = regexp + ".*";
+                element = element + "*";
+                break;
+            case SUBSTRING:
+                setPattern(MethodDescriptor.PatternType.PREFIX);
+                setPattern(MethodDescriptor.PatternType.SUFFIX);
+                break;
+            default:
+                throw new IllegalArgumentException("ERROR: wrong pattern type "
+                        + patternType);
+        }
+    }
+
+    /**
+     * Builds element string and regexp.
+     *
+     * @param setPackage shows that element should have a package name
+     */
+    private void buildElement(boolean setPackage) {
+        this.setPackage = setPackage;
+        StringBuilder elementBuilder = new StringBuilder();
+        if (packageDirs != null && setPackage) {
+            elementBuilder.append(Arrays.stream(packageDirs)
+                    .collect(Collectors.joining(separator.symbol)));
+            elementBuilder.append(separator.symbol);
+        }
+        String className = aClass.getSimpleName();
+        if (setPackage) {
+            // Add outer classes if any
+            Class<?> enclosingClass = aClass.getEnclosingClass();
+            while (enclosingClass != null) {
+                className = enclosingClass.getSimpleName() + "$" + className;
+                enclosingClass = enclosingClass.getEnclosingClass();
+            }
+        }
+        elementBuilder.append(className);
+        element = elementBuilder.toString();
+        if (separator == MethodDescriptor.Separator.DOT) {
+            // Replace . with / to make regexp look like CommandSignature
+            regexp = element.replace(".", "/");
+        } else {
+            regexp = element;
+        }
+        regexp = regexp.replace("$", "\\$");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/method/MethodDescriptor.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2015, 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 compiler.compilercontrol.share.method;
+
+import jdk.test.lib.Triple;
+
+import java.lang.reflect.Executable;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+
+/**
+ * Method descriptor for Compiler Control commands.
+ * It represents method pattern used for matching in Compiler Control
+ * and CompileCommand option
+ */
+public class MethodDescriptor {
+    public final ClassType aClass;         // Represents class and package
+    public final MethodType aMethod;       // Represents method
+    public final SignatureType aSignature; // Represents signature
+
+    /**
+     * Constructor
+     *
+     * @param method executable to build method descriptor from
+     */
+    public MethodDescriptor(Executable method) {
+        aClass = new ClassType(method);
+        aMethod = new MethodType(method);
+        aSignature = new SignatureType(method);
+    }
+
+    /**
+     * Sets signature separators for all elements
+     */
+    public void setSeparators(
+            Triple<Separator, Separator, Separator> separators) {
+        aClass.setSeparator(separators.getFirst());
+        aMethod.setSeparator(separators.getSecond());
+        aSignature.setSeparator(separators.getThird());
+    }
+
+    /**
+     * Sets custom strings for each element
+     */
+    public void setStrings(Triple<String, String, String> strings) {
+        aClass.setElement(strings.getFirst());
+        aMethod.setElement(strings.getSecond());
+        aSignature.setElement(strings.getThird());
+    }
+
+    /**
+     * Sets patterns for all elements
+     */
+    public void setPatterns(
+            Triple<PatternType, PatternType, PatternType> patterns) {
+        aClass.setPattern(patterns.getFirst());
+        aMethod.setPattern(patterns.getSecond());
+        aSignature.setPattern(patterns.getThird());
+    }
+
+    /**
+     * Separates elements in the MethodDescriptor
+     */
+    public static enum Separator {
+        SLASH("/"),
+        DOT("."),
+        COMMA(","),
+        DOUBLECOLON("::"),
+        SPACE(" "),
+        NONE("");
+
+        public final String symbol;
+
+        Separator(String symbol) {
+            this.symbol = symbol;
+        }
+
+        /**
+         * Validates method descriptor separators
+         *
+         * @param md method descriptor to validate
+         * @return true if descriptor's separators are valid
+         */
+        public static boolean isValid(MethodDescriptor md) {
+            Separator cls = md.getClassSeparator();
+            Separator method = md.getMethodSeparator();
+            Separator sign = md.getSignatureSeparator();
+            if (sign == SPACE || sign == NONE || sign == COMMA) {
+                // if it looks like java/lang/String.indexOf
+                if ((cls == SLASH || cls == NONE)
+                        // allow space and comma instead of dot
+                        && (method == DOT || method == SPACE
+                        || method == COMMA)) {
+                    return true;
+                }
+                // if it looks like java.lang.String::indexOf
+                if ((cls == DOT || cls == NONE) && method == DOUBLECOLON) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Type of the pattern
+     */
+    public static enum PatternType {
+        PREFIX,
+        ANY,
+        SUFFIX,
+        SUBSTRING,
+        EXACT
+    }
+
+    public Separator getClassSeparator() {
+        return aClass.getSeparator();
+    }
+
+    public Separator getMethodSeparator() {
+        return aMethod.getSeparator();
+    }
+
+    public Separator getSignatureSeparator() {
+        return aSignature.getSeparator();
+    }
+
+    /**
+     * Gets regular expression to match methods
+     *
+     * @return string representation of the regular expression
+     */
+    public String getRegexp() {
+        // regexp should have a . as a method separator
+        // and / as a package/class separator
+        return aClass.getRegexp().replaceAll("\\.", "/")
+                .replaceAll("/\\*", ".*")
+                + Pattern.quote(Separator.DOT.symbol)
+                + aMethod.getRegexp() + aSignature.getRegexp();
+    }
+
+    /**
+     * Gets method descriptor string representation.
+     * This string is used as a pattern in CompilerControl and CompileCommand
+     */
+    public String getString() {
+        return aClass.getElement() + getMethodSeparator().symbol
+                + aMethod.getElement() + getSignatureSeparator().symbol
+                + aSignature.getElement();
+    }
+
+    /**
+     * Convert method descriptor to be regexp-compatible
+     *
+     * @return string representation of the method signature
+     */
+    public String getCanonicalString() {
+        return aClass.getElement().replaceAll("\\.", "/") + Separator.DOT.symbol
+                + aMethod.getElement() + aSignature.getElement();
+    }
+
+    /**
+     * Shows if this descriptor is a valid pattern for CompilerControl
+     *
+     * @return true, if descriptor is valid, false otherwise
+     */
+    public boolean isValid() {
+        return aClass.isValid() && aMethod.isValid() && aSignature.isValid()
+                && Separator.isValid(this);
+    }
+
+    /**
+     * Sets custom string from element mutate function
+     * to the appropriate element of method descriptor
+     */
+    public void applyMutates(Triple<Function<String, String>,
+                             Function<String, String>,
+                             Function<String, String>> mutators) {
+        String elementString = aClass.getElement();
+        aClass.setElement(mutators.getFirst().apply(elementString));
+        elementString = aMethod.getElement();
+        aMethod.setElement(mutators.getSecond().apply(elementString));
+        elementString = aSignature.getElement();
+        aSignature.setElement(mutators.getThird().apply(elementString));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/method/MethodElementType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, 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 compiler.compilercontrol.share.method;
+
+import java.util.regex.Pattern;
+
+/**
+ * Class represents an element of the MethodDescriptor
+ * used as pattern for CompilerCommand method strings
+ */
+public abstract class MethodElementType {
+    private static final char[] INVALID_CHARS = { ';', '[', '(', ')', ']',
+            '<', '>'};
+    protected String element;
+    protected String regexp;
+    protected MethodDescriptor.Separator separator;
+
+    /**
+     * Constructor
+     */
+    protected MethodElementType(MethodDescriptor.Separator separator) {
+        this.separator = separator;
+    }
+
+    /**
+     * Gets element's separator
+     *
+     * @return separator instance
+     */
+    public MethodDescriptor.Separator getSeparator() {
+        return separator;
+    }
+
+    /**
+     * Sets separator for this element
+     *
+     * @param separator separator type
+     */
+    public void setSeparator(MethodDescriptor.Separator separator) {
+        this.separator = separator;
+    }
+
+    /**
+     * Gets String representation of the element
+     *
+     * @return element string
+     */
+    public String getElement() {
+        return element;
+    }
+
+    /**
+     * Sets String representation of the element
+     *
+     * @param element custom string to be used as an element
+     */
+    public void setElement(String element) {
+        this.element = element;
+        this.regexp = Pattern.quote(element);
+    }
+
+    /**
+     * Shows that the element is valid according to CompilerControl and JVMS specs
+     *
+     * @return true, if the element is a valid string
+     */
+    public boolean isValid() {
+        for (char ch : INVALID_CHARS) {
+            if (element.indexOf(ch) != -1) {
+                return false;
+            }
+        }
+        // Check for * usage
+        if (element.equals("**")) {
+            return false;
+        }
+        for (int i = 0; i < element.length(); i++) {
+            char c = element.charAt(i);
+            if (c == '*' && i > 0 && i < element.length() - 1) {
+                // Embedded * isn't allowed
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Creates pattern of a given type
+     *
+     * @param patternType type of the pattern
+     */
+    public void setPattern(MethodDescriptor.PatternType patternType) {
+        switch (patternType) {
+            case EXACT:
+                break;
+            case PREFIX:
+                regexp = ".*" + regexp;
+                element = "*" + element;
+                break;
+            case ANY:
+                regexp = ".*";
+                element = "*";
+                break;
+            case SUFFIX:
+                regexp = regexp + ".*";
+                element = element + "*";
+                break;
+            case SUBSTRING:
+                setPattern(MethodDescriptor.PatternType.PREFIX);
+                setPattern(MethodDescriptor.PatternType.SUFFIX);
+                break;
+            default:
+                throw new IllegalArgumentException("ERROR: wrong pattern type"
+                        + patternType);
+        }
+    }
+
+    /**
+     * Gets regular expression of this element
+     *
+     * @return string representation of regexp
+     */
+    public String getRegexp() {
+        return regexp;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/method/MethodGenerator.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015, 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 compiler.compilercontrol.share.method;
+
+import compiler.compilercontrol.share.method.MethodDescriptor.PatternType;
+import compiler.compilercontrol.share.method.MethodDescriptor.Separator;
+import jdk.test.lib.Pair;
+import jdk.test.lib.Triple;
+import jdk.test.lib.Utils;
+import pool.PoolHelper;
+
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.function.Function;
+
+/**
+ * Generates combinations of method descriptors from the pool of methods
+ */
+public class MethodGenerator {
+    private static final List<Pair<Executable, Callable<?>>> METHODS =
+            new PoolHelper().getAllMethods(PoolHelper.METHOD_FILTER);
+    // Different combinations of patterns
+    private static final List<Combination<PatternType>> PATTERNS_LIST;
+    // Different combinations of separators
+    private static final List<Combination<Separator>> SEPARATORS_LIST;
+    // List of functions that modify elements
+    private static final List<Function<String, String>> ELEMENT_MUTATORS;
+
+    static {
+        PATTERNS_LIST =
+                generate(EnumSet.allOf(PatternType.class),
+                        EnumSet.allOf(PatternType.class),
+                        EnumSet.of(PatternType.ANY, PatternType.EXACT));
+        SEPARATORS_LIST =
+                generate(EnumSet.of(Separator.SLASH, Separator.DOT),
+                        EnumSet.complementOf(EnumSet.of(Separator.NONE)),
+                        EnumSet.of(Separator.COMMA, Separator.SPACE,
+                                Separator.NONE));
+        ELEMENT_MUTATORS = generateMutators();
+    }
+
+    // Test method
+    public static void main(String[] args) {
+        MethodGenerator methodGenerator = new MethodGenerator();
+        List<MethodDescriptor> tests = methodGenerator.getTests();
+        tests.forEach(System.out::println);
+    }
+
+    /**
+     * Generates random method descriptor
+     *
+     * @param executable executable used to generate descriptor
+     * @return MethodDescriptor instance
+     */
+    public MethodDescriptor generateRandomDescriptor(Executable executable) {
+        Combination<PatternType> patterns =
+                Utils.getRandomElement(PATTERNS_LIST);
+        Combination<Separator> separators =
+                Utils.getRandomElement(SEPARATORS_LIST);
+        // Create simple mutators for signature generation
+        List<Function<String, String>> signMutators = new ArrayList<>();
+        signMutators.add(input -> input);
+        signMutators.add(input -> "");
+        Combination<Function<String, String>> mutators = new Combination<>(
+                Utils.getRandomElement(ELEMENT_MUTATORS),
+                Utils.getRandomElement(ELEMENT_MUTATORS),
+                // use only this type of mutators
+                Utils.getRandomElement(signMutators));
+        return makeMethodDescriptor(executable, patterns,
+                separators, mutators);
+    }
+
+    /**
+     * Compile command signature that looks like java/lang/String.indexOf
+     * http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABDDFII
+     *
+     * @param executable executable used to generate descriptor
+     * @return MethodDescriptor instance
+     */
+    public static MethodDescriptor commandDescriptor(Executable executable) {
+        MethodDescriptor md = new MethodDescriptor(executable);
+        md.aClass.setSeparator(Separator.SLASH);
+        md.aMethod.setSeparator(Separator.DOT);
+        md.aSignature.setSeparator(Separator.NONE);
+        return md;
+    }
+
+    /**
+     * Compile command signature that looks like java.lang.String::indexOf
+     *
+     * @param executable executable used to generate descriptor
+     * @return MethodDescriptor instance
+     */
+    public static MethodDescriptor logDescriptor(Executable executable) {
+        MethodDescriptor md = new MethodDescriptor(executable);
+        md.aClass.setSeparator(Separator.DOT);
+        md.aMethod.setSeparator(Separator.DOUBLECOLON);
+        md.aSignature.setSeparator(Separator.NONE);
+        return md;
+    }
+
+    /**
+     * Generates a list of method patterns from the pool of methods
+     *
+     * @return a list of test cases
+     */
+    public List<MethodDescriptor> getTests() {
+        List<MethodDescriptor> list = new ArrayList<>();
+        METHODS.forEach(pair -> list.addAll(getTests(pair.first)));
+        return list;
+    }
+
+    /**
+     * Generates all combinations of method descriptors for a given executable
+     *
+     * @param executable executable for which the different combination is built
+     * @return list of method descriptors
+     */
+    public List<MethodDescriptor> getTests(Executable executable) {
+        List<MethodDescriptor> list = new ArrayList<>();
+        for (Combination<PatternType> patterns : PATTERNS_LIST) {
+            for (Combination<Separator> separators : SEPARATORS_LIST) {
+                for (Function<String, String> classGen : ELEMENT_MUTATORS) {
+                    for (Function<String, String> methodGen :
+                            ELEMENT_MUTATORS) {
+                        for (Function<String, String> signatureGen :
+                                ELEMENT_MUTATORS) {
+                            list.add(makeMethodDescriptor(executable,
+                                    patterns, separators,
+                                    new Combination<>(classGen, methodGen,
+                                        signatureGen)));
+                        }
+                    }
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Creates method descriptor from the given executable,
+     * patterns and separators for its elements
+     */
+    private MethodDescriptor makeMethodDescriptor(
+            Executable executable,
+            Combination<PatternType> patterns,
+            Combination<Separator> separators,
+            Combination<Function<String, String>> mutators) {
+        MethodDescriptor methodDescriptor = new MethodDescriptor(executable);
+        methodDescriptor.setSeparators(separators);
+        methodDescriptor.applyMutates(mutators);
+        methodDescriptor.setPatterns(patterns);
+        return methodDescriptor;
+    }
+
+    /**
+     * Creates a list of functions that change given string
+     */
+    private static List<Function<String, String>> generateMutators() {
+        List<Function<String, String>> elements = new ArrayList<>();
+        // Use the input itself
+        elements.add(input -> input);
+        // Use half of the input string
+        elements.add(input -> input.substring(input.length() / 2));
+        // Add nonexistent element
+        elements.add(input -> "nonexistent");
+        // Use left and right angle brackets
+        elements.add(input -> "<" + input + ">");
+        // Embed * inside
+        elements.add(input -> embed(input, "*"));
+        // ** as a whole element
+        elements.add(input -> "**");
+        // Embed JLS-invalid letters
+        elements.add(input -> embed(input, "@%"));
+        elements.add(input -> embed(input, "]"));
+        // Use JLS-invalid letters
+        elements.add(input -> "-");
+        elements.add(input -> "+");
+        elements.add(input -> ")" + input);
+        elements.add(input -> "{" + input + "}");
+        // Add valid Java identifier start char
+        elements.add(input -> "_" + input);
+        elements.add(input -> "$" + input);
+        elements.add(input -> "0" + input);
+        // Unicode characters
+        elements.add(input -> embed(input, "\u0001"));
+        elements.add(input -> embed(input, "\u007F"));
+        // Combining character
+        elements.add(input -> embed(input, "\u0300"));
+        elements.add(input -> embed(input, "\u0306"));
+        // Supplementary character
+        elements.add(input -> new String(Character.toChars(0x1F64C)));
+        return elements;
+    }
+
+    /**
+     * Embeds one string inside another one
+     *
+     * @param target  target source string
+     * @param element string to be embedded into target string
+     * @return result string
+     */
+    private static String embed(String target, String element) {
+        int mid = target.length() / 2;
+        String begin = target.substring(0, mid);
+        String end = target.substring(mid);
+        return begin + element + end;
+    }
+
+    /**
+     * Generates triples from the given enum sets
+     * for each of the method elements
+     *
+     * @param classSet  set of allowed elements for class
+     * @param methodSet set of allowed elements for method
+     * @param signSet   set of allowed elements for signature
+     * @param <E>       type of generated triples
+     * @return list of triples
+     */
+    private static <E extends Enum<E>> List<Combination<E>> generate(
+            EnumSet<E> classSet, EnumSet<E> methodSet, EnumSet<E> signSet) {
+        List<Combination<E>> list = new ArrayList<>();
+        classSet.forEach(clsElement ->
+            methodSet.forEach(methodElement ->
+                signSet.forEach(signElement ->
+                    list.add(new Combination<>(clsElement, methodElement,
+                            signElement))
+                )
+            )
+        );
+        return list;
+    }
+
+    private static class Combination<T> extends Triple<T, T, T> {
+        public Combination(T first, T second, T third) {
+            super(first, second, third);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/method/MethodType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, 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 compiler.compilercontrol.share.method;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+
+/**
+ * Represents a method in CompileControl method signature
+ */
+public class MethodType extends MethodElementType {
+    private static final char[] INVALID_CHARS = { '.', '/' };
+
+    public MethodType(Executable method) {
+        // Use pack/subpack/Class::method separators style
+        super(MethodDescriptor.Separator.DOT);
+        if (method instanceof Constructor) {
+            element = "<init>";
+        } else {
+            element = method.getName();
+        }
+        regexp = element;
+    }
+
+    @Override
+    public boolean isValid() {
+        for (char ch : INVALID_CHARS) {
+            if (element.indexOf(ch) != -1) {
+                return false;
+            }
+        }
+        if (element.isEmpty()) {
+            // Shouldn't be empty
+            return false;
+        }
+        if (element.contains("<") || element.contains(">")) {
+            return element.matches("(\\*)?<(cl)?init>(\\*)?");
+        }
+        return super.isValid();
+    }
+
+    @Override
+    public void setPattern(MethodDescriptor.PatternType patternType) {
+        switch (patternType) {
+            case EXACT:
+                break;
+            case PREFIX:
+                regexp = ".*" + regexp;
+                element = "*" + element;
+                break;
+            case ANY:
+                regexp = "[^(]*";
+                element = "*";
+                break;
+            case SUFFIX:
+                regexp = regexp + "[^(]*";
+                element = element + "*";
+                break;
+            case SUBSTRING:
+                setPattern(MethodDescriptor.PatternType.PREFIX);
+                setPattern(MethodDescriptor.PatternType.SUFFIX);
+                break;
+            default:
+                throw new IllegalArgumentException("ERROR: wrong pattern type "
+                        + patternType);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/method/SignatureType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2015, 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 compiler.compilercontrol.share.method;
+
+import jdk.test.lib.Utils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * This class represents a signature of the method
+ */
+public class SignatureType extends MethodElementType {
+    public SignatureType(Executable method) {
+        super(MethodDescriptor.Separator.NONE);
+        // Get parameters
+        Class<?>[] types = method.getParameterTypes();
+        String[] parameterTypes = new String[types.length];
+        for (int i = 0; i < types.length; i++) {
+            parameterTypes[i] = Utils.toJVMTypeSignature(types[i]);
+        }
+        // Get return value
+        String returnType;
+        if (method instanceof Method) {
+            returnType = Utils.toJVMTypeSignature(((Method) method)
+                    .getReturnType());
+        } else if (method instanceof Constructor) {
+            // Constructor returns void in VM
+            returnType = Utils.toJVMTypeSignature(void.class);
+        } else {
+            throw new Error(String.format("TESTBUG: wrong type of executable "
+                    + "%s of class %s", method, method.getClass()));
+        }
+        // Create signature
+        setElement("(" + String.join("", parameterTypes)+ ")" + returnType);
+        regexp = element;
+        setPattern(MethodDescriptor.PatternType.EXACT);
+        separator = MethodDescriptor.Separator.NONE;
+    }
+
+    @Override
+    public void setElement(String element) {
+        if (element.isEmpty()) {
+            setPattern(MethodDescriptor.PatternType.ANY);
+        } else {
+            super.setElement(element);
+        }
+    }
+
+    @Override
+    public boolean isValid() {
+        if (element.isEmpty()) {
+            return true;
+        }
+        // Allowed primitive types
+        char[] baseTypes = {'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z'};  // sorted
+        // Parsing states
+        boolean isArray = false;
+        boolean isInsideSig = false;
+        boolean isClass = false;
+
+        for (char ch : element.toCharArray()) {
+            if (ch == '(') {
+                if (isInsideSig) {
+                    // Met another ( inside
+                    return false;
+                }
+                isInsideSig = true;
+            } else if (ch == ')') {
+                if (!isInsideSig) {
+                    // met another ) outside
+                    return false;
+                }
+                isInsideSig = false;
+            } else if (ch == 'V') {
+                if (isInsideSig) {
+                    // void type is allowed only as a return value
+                    return false;
+                }
+            } else if (ch == 'L') {
+                // this is a beginning of class/interface
+                isClass = true;
+                // met actual type of array
+                isArray = false;
+            } else if (ch == '[') {
+                isArray = true;
+            } else if (isClass) {
+                if (!Character.isJavaIdentifierPart(ch)) {
+                    if (ch == '/' || ch == '.') {
+                        // separator met
+                    } else if (ch == ';') {
+                        // end of class/interface
+                        isClass = false;
+                    } else {
+                        return false;
+                    }
+                }
+            } else if (Arrays.binarySearch(baseTypes, ch) < 0) {
+                // if it doesn't belong to base types
+                return false;
+            } else {
+                // array of a base type
+                isArray = false;
+            }
+        }
+        return !(isArray || isInsideSig || isClass);
+    }
+
+    @Override
+    public void setPattern(MethodDescriptor.PatternType patternType) {
+        switch (patternType) {
+            case PREFIX:
+            case SUFFIX:
+            case SUBSTRING:
+                // These patterns are not supported in Compiler Control
+                // Just use ANY pattern instead
+            case ANY:
+                regexp = "\\(.*\\).*";
+                element = "";
+                break;
+            case EXACT:
+                break;
+            default:
+                throw new IllegalArgumentException("ERROR: wrong pattern type "
+                        + patternType);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/pool/MethodHolder.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015, 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 pool;
+
+import jdk.test.lib.Pair;
+
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * Represents a holder that contains test methods
+ */
+public abstract class MethodHolder {
+    /**
+     * Helper method to get executable for the specified method
+     *
+     * @param holder class that holds specified method
+     * @param name method name
+     * @param parameterTypes parameter types of the specified method
+     * @return {@link Method} instance
+     */
+    public Method getMethod(MethodHolder holder,
+                             String name,
+                             Class<?>... parameterTypes) {
+        try {
+            return holder.getClass().getDeclaredMethod(name, parameterTypes);
+        } catch (NoSuchMethodException e) {
+            throw new Error("TESTBUG: Can't get method " + name, e);
+        }
+    }
+
+    /**
+     * Gets all test methods
+     *
+     * @return pairs of Executable and appropriate Callable
+     */
+    public List<Pair<Executable, Callable<?>>> getAllMethods() {
+        Class<?> aClass = this.getClass();
+        Object classInstance;
+        try {
+            classInstance = aClass.newInstance();
+        } catch (ReflectiveOperationException e) {
+            throw new Error("TESTBUG: unable to get new instance", e);
+        }
+        List<Pair<Executable, Callable<?>>> pairs = new ArrayList<>();
+        {
+            Method method = getMethod(this, "method", int.class, String[].class,
+                    Integer.class, byte[].class, double[][].class);
+            Pair<Executable, Callable<?>> pair = new Pair<>(method,
+                    () -> {
+                        // Make args
+                        int a = 0;
+                        String[] ss = {"a", "b", "c", "d"};
+                        Integer i = 1;
+                        byte[] bb = {1, 2};
+                        double[][] dd = {
+                                {1.618033, 3.141592},
+                                {2.718281, 0.007874}
+                        };
+                        // Invoke method
+                        method.invoke(classInstance, a, ss, i, bb, dd);
+                        return true;
+                    });
+            pairs.add(pair);
+        }
+        {
+            Method method = getMethod(this, "method");
+            Pair<Executable, Callable<?>> pair = new Pair<>(method,
+                    () -> {
+                        method.invoke(classInstance);
+                        return true;
+                    });
+            pairs.add(pair);
+        }
+        {
+            Method method = getMethod(this, "smethod");
+            Pair<Executable, Callable<?>> pair = new Pair<>(method,
+                    () -> method.invoke(classInstance));
+            pairs.add(pair);
+        }
+        {
+            Method method = getMethod(this, "smethod", int.class, int[].class);
+            Pair<Executable, Callable<?>> pair = new Pair<>(method,
+                    () -> {
+                        int[] array = {1, 2, 3};
+                        return method.invoke(classInstance, 42, array);
+                    });
+            pairs.add(pair);
+        }
+        {
+            Method method = getMethod(this, "smethod", Integer.class);
+            Pair<Executable, Callable<?>> pair = new Pair<>(method,
+                    () -> method.invoke(classInstance, 100));
+            pairs.add(pair);
+        }
+        return pairs;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/pool/PoolHelper.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, 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 pool;
+
+import jdk.test.lib.Pair;
+import pool.MethodHolder;
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * This is a helper class that provides tests with methods
+ */
+public class PoolHelper extends MethodHolder {
+    private static final List<Pair<Executable, Callable<?>>> METHODS;
+
+    /**
+     * Filters only those methods who belong to Klass or its internal class
+     * Internal and named as "method" or is a constructor
+     */
+    public static final Predicate<Executable> METHOD_FILTER = executable -> {
+        String methodName = executable.getName();
+        String className = executable.getDeclaringClass().getName();
+        return className.matches(".*(Klass)(\\$Internal)?") &&
+                (methodName.equals("method") ||
+                        methodName.equals(className)); // if method is <init>
+    };
+
+    static {
+        METHODS = new ArrayList<>();
+        List<MethodHolder> holders = new ArrayList<>();
+        holders.add(new pool.sub.Klass());
+        holders.add(new pool.sub.KlassDup());
+        holders.add(new pool.subpack.Klass());
+        holders.add(new pool.subpack.KlassDup());
+        holders.add(new pool.sub.Klass.Internal());
+        holders.add(new pool.subpack.KlassDup.Internal());
+        for (MethodHolder holder : holders) {
+            METHODS.addAll(holder.getAllMethods());
+        }
+    }
+
+    /**
+     * Gets all methods from the pool using specified filter
+     *
+     * @param filter method filter
+     * @return pairs of Executable and appropriate Callable
+     */
+    public List<Pair<Executable, Callable<?>>> getAllMethods(
+            Predicate<Executable> filter) {
+        return getAllMethods().stream()
+                .filter(pair -> filter.test(pair.first))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Gets all methods from the pool
+     *
+     * @return pairs of Executable and appropriate Callable
+     */
+    @Override
+    public List<Pair<Executable, Callable<?>>> getAllMethods() {
+        return METHODS;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/pool/sub/Klass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, 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 pool.sub;
+
+import jdk.test.lib.Pair;
+import pool.MethodHolder;
+
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * Simple class with methods to test signatures
+ */
+public class Klass extends MethodHolder {
+    public void method(int a, String[] ss, Integer i, byte[] bb, double[][] dd) { }
+
+    public void method() { }
+
+    public static String smethod() {
+        return "ABC";
+    }
+
+    public static String smethod(int iarg, int[] aarg) {
+        return "ABC";
+    }
+
+    public static Integer smethod(Integer arg) {
+        Integer var = 1024;
+        return arg + var;
+    }
+
+    // Internal class and constructor
+    public static class Internal extends MethodHolder {
+        public Internal() { }
+
+        public Double method(Float fl) { return Double.valueOf(fl); }
+
+        public Double methodDup() {
+            return Math.exp(1.0);
+        }
+
+        public static Integer smethod(Integer arg) {
+            Integer var = 1024;
+            return arg + var;
+        }
+
+        @Override
+        public List<Pair<Executable, Callable<?>>> getAllMethods() {
+            List<Pair<Executable, Callable<?>>> pairs = new ArrayList<>();
+            Pair<Executable, Callable<?>> pair = new Pair<>
+                    (getMethod(this, "method", Float.class),
+                            () -> this.method(3.141592f));
+            pairs.add(pair);
+            pair = new Pair<>(getMethod(this, "methodDup"), this::methodDup);
+            pairs.add(pair);
+            pair = new Pair<>(getMethod(this, "smethod", Integer.class),
+                    () -> smethod(1024));
+            pairs.add(pair);
+            try {
+                pair = new Pair<>(this.getClass().getConstructor(),
+                        Internal::new);
+                pairs.add(pair);
+            } catch (NoSuchMethodException e) {
+                throw new Error("TESTBUG: unable to get constructor");
+            }
+            return pairs;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/pool/sub/KlassDup.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 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 pool.sub;
+
+import pool.MethodHolder;
+
+/**
+ * Simple class with methods to test signatures
+ * This class has Dup suffix in the name to test suffix patterns like Klass*.
+ * Such patterns should match both Klass and KlassDup
+ */
+public class KlassDup extends MethodHolder {
+    public void method(int a, String[] ss, Integer i, byte[] bb, double[][] dd) { }
+
+    public void method() { }
+
+    public static String smethod() {
+        return "ABC";
+    }
+
+    public static String smethod(int iarg, int[] aarg) {
+        return "ABC";
+    }
+
+    public static Integer smethod(Integer arg) {
+        Integer var = 1024;
+        return arg + var;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/pool/subpack/Klass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, 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 pool.subpack;
+
+import pool.MethodHolder;
+
+/**
+ * Simple class with methods to test signatures
+ * This is a clone of the pool.sub.Klass, but without inner class
+ * This class has different package name to test prefix patterns like *Klass.
+ * *Klass patern should match both pool.sub.Klass and pool.subpack.Klass
+ */
+public class Klass extends MethodHolder {
+    public void method(int a, String[] ss, Integer i, byte[] bb, double[][] dd) { }
+
+    public void method() { }
+
+    public static String smethod() {
+        return "ABC";
+    }
+
+    public static String smethod(int iarg, int[] aarg) {
+        return "ABC";
+    }
+
+    public static Integer smethod(Integer arg) {
+        Integer var = 1024;
+        return arg + var;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/compilercontrol/share/pool/subpack/KlassDup.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, 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 pool.subpack;
+
+import jdk.test.lib.Pair;
+import pool.MethodHolder;
+
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * This is a clone of the pool.sub.Klass used to test pattern matching
+ * Full class name contains both suffix (Dup) and prefix (pool.subpack)
+ */
+public class KlassDup extends MethodHolder {
+    public void method(int a, String[] ss, Integer i, byte[] bb, double[][] dd) { }
+
+    public void method() { }
+
+    public static String smethod() {
+        return "ABC";
+    }
+
+    public static String smethod(int iarg, int[] aarg) {
+        return "ABC";
+    }
+
+    public static Integer smethod(Integer arg) {
+        Integer var = 1024;
+        return arg + var;
+    }
+
+    // Internal class and constructor
+    public static class Internal extends MethodHolder {
+        public Internal() { }
+
+        public Double method(Float fl) { return Double.valueOf(fl); }
+
+        public Double methodDup() {
+            return Math.exp(1.0);
+        }
+
+        public static Integer smethod(Integer arg) {
+            Integer var = 1024;
+            return arg + var;
+        }
+
+        @Override
+        public List<Pair<Executable, Callable<?>>> getAllMethods() {
+            List<Pair<Executable, Callable<?>>> pairs = new ArrayList<>();
+            Pair<Executable, Callable<?>> pair = new Pair<>
+                    (getMethod(this, "method", Float.class),
+                            () -> this.method(3.141592f));
+            pairs.add(pair);
+            pair = new Pair<>(getMethod(this, "methodDup"), this::methodDup);
+            pairs.add(pair);
+            pair = new Pair<>(getMethod(this, "smethod", Integer.class),
+                    () -> smethod(1024));
+            pairs.add(pair);
+            try {
+                pair = new Pair<>(this.getClass().getConstructor(),
+                        Internal::new);
+                pairs.add(pair);
+            } catch (NoSuchMethodException e) {
+                throw new Error("TESTBUG: unable to get constructor");
+            }
+            return pairs;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *      -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=true
+ *      -XX:+EnableJVMCI
+ *      compiler.jvmci.JVM_GetJVMCIRuntimeTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *      -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=false
+ *      -XX:-EnableJVMCI
+ *      compiler.jvmci.JVM_GetJVMCIRuntimeTest
+
+ */
+
+package compiler.jvmci;
+
+import jdk.vm.ci.runtime.JVMCI;
+import jdk.test.lib.Asserts;
+
+import java.lang.reflect.Method;
+
+public class JVM_GetJVMCIRuntimeTest {
+    private static final boolean IS_POSITIVE = Boolean.getBoolean(
+            "compiler.jvmci.JVM_GetJVMCIRuntimeTest.positive");
+
+    private final Method initializeRuntime;
+
+    public static void main(String[] args) {
+        new JVM_GetJVMCIRuntimeTest().runTest();
+    }
+
+    private void runTest() {
+        Object result;
+        try {
+            result = invoke();
+        } catch (InternalError e) {
+            if (IS_POSITIVE) {
+                throw new AssertionError("unexpected exception", e);
+            }
+            return;
+        }
+        if (!IS_POSITIVE) {
+            throw new AssertionError("didn't get expected exception");
+        }
+        Asserts.assertNotNull(result,
+                "initializeRuntime returned null");
+        Asserts.assertEQ(result, invoke(),
+                "initializeRuntime returns different results");
+
+    }
+    private Object invoke() {
+        Object result;
+        try {
+            result = initializeRuntime.invoke(JVMCI.class);
+        } catch (ReflectiveOperationException e) {
+            throw new Error("can't invoke initializeRuntime", e);
+        }
+        return result;
+    }
+
+    private JVM_GetJVMCIRuntimeTest() {
+        Method method;
+        try {
+            method = JVMCI.class.getDeclaredMethod("initializeRuntime");
+            method.setAccessible(true);
+        } catch (NoSuchMethodException e) {
+            throw new Error("can't find JVMCI::initializeRuntime", e);
+        }
+        initializeRuntime = method;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      compiler.jvmci.SecurityRestrictionsTest
+ *      NO_SEC_MAN
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      compiler.jvmci.SecurityRestrictionsTest
+ *      NO_PERM
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      compiler.jvmci.SecurityRestrictionsTest
+ *      ALL_PERM
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      compiler.jvmci.SecurityRestrictionsTest
+ *      NO_JVMCI_ACCESS_PERM
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *      compiler.jvmci.SecurityRestrictionsTest
+ *      NO_JVMCI
+ */
+
+package compiler.jvmci;
+
+import jdk.vm.ci.hotspot.CompilerToVM;
+import jdk.test.lib.Utils;
+import java.lang.InternalError;
+import java.security.AccessControlException;
+import java.security.Permission;
+import java.util.PropertyPermission;
+import java.util.function.Consumer;
+
+public class SecurityRestrictionsTest {
+
+    public static void main(String[] args) {
+        try {
+            // to init Utils before call SecurityManager
+            Class.forName(Utils.class.getName(), true,
+                    Utils.class.getClassLoader());
+        } catch (ClassNotFoundException e) {
+            throw new Error("[TEST BUG]: jdk.test.lib.Utils not found", e);
+        }
+        try {
+            TestCase mode = TestCase.valueOf(args[0]);
+            mode.run();
+        } catch (IllegalArgumentException e) {
+            throw new Error("[TEST BUG]: Unknown mode " + args[0], e);
+        }
+    }
+
+    private enum TestCase {
+        NO_SEC_MAN,
+        NO_JVMCI {
+            @Override
+            public Class<? extends Throwable> getExpectedException() {
+                return InternalError.class;
+            }
+        },
+        ALL_PERM {
+            @Override
+            public SecurityManager getSecurityManager() {
+                return new SecurityManager() {
+                    @Override
+                    public void checkPermission(Permission perm) {
+                    }
+                };
+            }
+        },
+        NO_PERM {
+            @Override
+            public SecurityManager getSecurityManager() {
+                return new SecurityManager();
+            }
+
+            @Override
+            public Class<? extends Throwable> getExpectedException() {
+                return AccessControlException.class;
+            }
+        },
+        NO_JVMCI_ACCESS_PERM {
+            @Override
+            public SecurityManager getSecurityManager() {
+                return new SecurityManager() {
+                    @Override
+                    public void checkPermission(Permission perm) {
+                        if (isJvmciPermission(perm)) {
+                            super.checkPermission(perm);
+                        }
+                    }
+
+                    @Override
+                    public void checkPropertyAccess(String key) {
+                        if (key.startsWith(JVMCI_PROP_START)) {
+                            super.checkPropertyAccess(key);
+                        }
+                    }
+                };
+            }
+
+            private boolean isJvmciPermission(Permission perm) {
+                String name = perm.getName();
+                boolean isJvmciRuntime = perm instanceof RuntimePermission
+                        && (JVMCI_SERVICES.equals(name)
+                            || name.startsWith(JVMCI_RT_PERM_START));
+                boolean isJvmciProperty = perm instanceof PropertyPermission
+                        && name.startsWith(JVMCI_PROP_START);
+                return isJvmciRuntime || isJvmciProperty;
+            }
+
+            @Override
+            public Class<? extends Throwable> getExpectedException() {
+                return AccessControlException.class;
+            }
+        };
+
+        public void run() {
+            System.setSecurityManager(getSecurityManager());
+            Consumer<Throwable> exceptionCheck = e -> {
+                if (e == null) {
+                    if (getExpectedException() != null) {
+                        String message = name() + ": Didn't get expected exception "
+                                + getExpectedException();
+                        throw new AssertionError(message);
+                    }
+                } else {
+                    String message = name() + ": Got unexpected exception "
+                            + e.getClass().getSimpleName();
+                    if (getExpectedException() == null){
+                        throw new AssertionError(message, e);
+                    }
+
+                    Throwable t = e;
+                    while (t.getCause() != null) {
+                        t = t.getCause();
+                    }
+                    if (!getExpectedException().isAssignableFrom(t.getClass())) {
+                        message += " instead of " + getExpectedException()
+                                .getSimpleName();
+                        throw new AssertionError(message, e);
+                    }
+                }
+            };
+            Utils.runAndCheckException(CompilerToVM::new, exceptionCheck);
+        }
+
+        public SecurityManager getSecurityManager() {
+            return null;
+        }
+
+        public Class<? extends Throwable> getExpectedException() {
+            return null;
+        }
+
+        private static final String JVMCI_RT_PERM_START
+                = "accessClassInPackage.jdk.vm.ci";
+        private static final String JVMCI_SERVICES = "jvmciServices";
+        private static final String JVMCI_PROP_START = "jvmci.";
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/CTVMUtilities.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+
+public class CTVMUtilities {
+    /*
+     * A method to return HotSpotResolvedJavaMethod object using class object
+     * and method as input
+     */
+    public static HotSpotResolvedJavaMethodImpl getResolvedMethod(Class<?> cls,
+            Executable method) {
+        if (!(method instanceof Method || method instanceof Constructor)) {
+            throw new Error("wrong executable type " + method.getClass());
+        }
+        Field slotField;
+        int slot;
+        try {
+            slotField = method.getClass().getDeclaredField("slot");
+            boolean old = slotField.isAccessible();
+            slotField.setAccessible(true);
+            slot = slotField.getInt(method);
+            slotField.setAccessible(old);
+        } catch (ReflectiveOperationException e) {
+            throw new Error("TEST BUG: Can't get slot field", e);
+        }
+        return CompilerToVMHelper.getResolvedJavaMethodAtSlot(cls, slot);
+    }
+
+    public static HotSpotResolvedJavaMethodImpl getResolvedMethod(
+            Executable method) {
+        return getResolvedMethod(method.getDeclaringClass(), method);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/CompilerToVMHelper.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.SpeculationLog;
+
+/*
+ * A simple "proxy" class to get test access to CompilerToVM package-private methods
+ */
+public class CompilerToVMHelper {
+    public static final CompilerToVM CTVM = new CompilerToVM();
+
+    public static byte[] getBytecode(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.getBytecode(method);
+    }
+
+    public static int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.getExceptionTableLength(method);
+    }
+
+    public static long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.getExceptionTableStart(method);
+    }
+
+    public static boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.canInlineMethod(method);
+    }
+
+    public static boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.shouldInlineMethod(method);
+    }
+
+    public static HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(
+            HotSpotResolvedObjectTypeImpl actualHolderType,
+            HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.findUniqueConcreteMethod(actualHolderType, method);
+    }
+
+    public static HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type) {
+        return CTVM.getImplementor(type);
+    }
+
+    public static boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.methodIsIgnoredBySecurityStackWalk(method);
+    }
+
+    public static HotSpotResolvedObjectTypeImpl lookupType(String name,
+            Class<?> accessingClass, boolean resolve) {
+        return CTVM.lookupType(name, accessingClass, resolve);
+    }
+
+    public static Object resolveConstantInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.resolveConstantInPool(constantPool, cpi);
+    }
+
+    public static Object resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.resolvePossiblyCachedConstantInPool(constantPool, cpi);
+    }
+
+    public static int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.lookupNameAndTypeRefIndexInPool(constantPool, cpi);
+    }
+
+    public static String lookupNameInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.lookupNameInPool(constantPool, cpi);
+    }
+
+    public static String lookupSignatureInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.lookupSignatureInPool(constantPool, cpi);
+    }
+
+    public static int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.lookupKlassRefIndexInPool(constantPool, cpi);
+    }
+
+    public static Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.lookupKlassInPool(constantPool, cpi);
+    }
+
+    public static HotSpotResolvedJavaMethodImpl lookupMethodInPool(
+            HotSpotConstantPool constantPool, int cpi, byte opcode) {
+        return CTVM.lookupMethodInPool(constantPool, cpi, opcode);
+    }
+
+    public static void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi) {
+        CTVM.resolveInvokeDynamicInPool(constantPool, cpi);
+    }
+
+    public static void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi) {
+        CTVM.resolveInvokeHandleInPool(constantPool, cpi);
+    }
+
+    public static HotSpotResolvedObjectTypeImpl resolveTypeInPool(
+            HotSpotConstantPool constantPool, int cpi) throws LinkageError {
+        return CTVM.resolveTypeInPool(constantPool, cpi);
+    }
+
+    public static HotSpotResolvedObjectTypeImpl resolveFieldInPool(
+            HotSpotConstantPool constantPool, int cpi, byte opcode, long[] info) {
+        return CTVM.resolveFieldInPool(constantPool, cpi, opcode, info);
+    }
+
+    public static int constantPoolRemapInstructionOperandFromCache(
+            HotSpotConstantPool constantPool, int cpci) {
+        return CTVM.constantPoolRemapInstructionOperandFromCache(constantPool, cpci);
+    }
+
+    public static Object lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi) {
+        return CTVM.lookupAppendixInPool(constantPool, cpi);
+    }
+
+    public static int installCode(TargetDescription target,
+            HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog) {
+        return CTVM.installCode(target, compiledCode, code, speculationLog);
+    }
+
+    public static int getMetadata(TargetDescription target,
+            HotSpotCompiledCode compiledCode, HotSpotMetaData metaData) {
+        return CTVM.getMetadata(target, compiledCode, metaData);
+    }
+
+    public static void notifyCompilationStatistics(int id,
+            HotSpotResolvedJavaMethodImpl method, boolean osr,
+            int processedBytecodes, long time, long timeUnitsPerSecond,
+            InstalledCode installedCode) {
+        CTVM.notifyCompilationStatistics(id, method, osr, processedBytecodes,
+                time, timeUnitsPerSecond, installedCode);
+    }
+
+    public static void resetCompilationStatistics() {
+        CTVM.resetCompilationStatistics();
+    }
+
+    public static long initializeConfiguration() {
+        return CTVM.initializeConfiguration();
+    }
+
+    public static HotSpotResolvedJavaMethodImpl resolveMethod(
+            HotSpotResolvedObjectTypeImpl exactReceiver,
+            HotSpotResolvedJavaMethodImpl method,
+            HotSpotResolvedObjectTypeImpl caller) {
+        return CTVM.resolveMethod(exactReceiver, method, caller);
+    }
+
+    public static HotSpotResolvedJavaMethodImpl getClassInitializer(
+            HotSpotResolvedObjectTypeImpl type) {
+        return CTVM.getClassInitializer(type);
+    }
+
+    public static boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type) {
+        return CTVM.hasFinalizableSubclass(type);
+    }
+
+    public static HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(Class<?> holder,
+            int slot) {
+        return CTVM.getResolvedJavaMethodAtSlot(holder, slot);
+    }
+
+    public static long getMaxCallTargetOffset(long address) {
+        return CTVM.getMaxCallTargetOffset(address);
+    }
+
+    public static String disassembleCodeBlob(long codeBlob) {
+        return CTVM.disassembleCodeBlob(codeBlob);
+    }
+
+    public static StackTraceElement getStackTraceElement(
+            HotSpotResolvedJavaMethodImpl method, int bci) {
+        return CTVM.getStackTraceElement(method, bci);
+    }
+
+    public static Object executeInstalledCode(Object[] args,
+            InstalledCode installedCode) throws InvalidInstalledCodeException {
+        return CTVM.executeInstalledCode(args, installedCode);
+    }
+
+    public static long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.getLineNumberTable(method);
+    }
+
+    public static int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.getLocalVariableTableLength(method);
+    }
+
+    public static long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.getLocalVariableTableStart(method);
+    }
+
+    public static Object readUncompressedOop(long address) {
+        return CTVM.readUncompressedOop(address);
+    }
+
+    public static void doNotInlineOrCompile(HotSpotResolvedJavaMethodImpl method) {
+        CTVM.doNotInlineOrCompile(method);
+    }
+
+    public static void reprofile(HotSpotResolvedJavaMethodImpl method) {
+        CTVM.reprofile(method);
+    }
+
+    public static void invalidateInstalledCode(InstalledCode installedCode) {
+        CTVM.invalidateInstalledCode(installedCode);
+    }
+
+    public static long[] collectCounters() {
+        return CTVM.collectCounters();
+    }
+
+    public static boolean isMature(long metaspaceMethodData) {
+        return CTVM.isMature(metaspaceMethodData);
+    }
+
+    public static int allocateCompileId(HotSpotResolvedJavaMethodImpl method,
+            int entryBCI) {
+        return CTVM.allocateCompileId(method, entryBCI);
+    }
+
+    public static boolean hasCompiledCodeForOSR(
+            HotSpotResolvedJavaMethodImpl method, int entryBCI, int level) {
+        return CTVM.hasCompiledCodeForOSR(method, entryBCI, level);
+    }
+
+    public static String getSymbol(long metaspaceSymbol) {
+        return CTVM.getSymbol(metaspaceSymbol);
+    }
+
+    public static HotSpotStackFrameReference getNextStackFrame(
+            HotSpotStackFrameReference frame,
+            HotSpotResolvedJavaMethodImpl[] methods, int initialSkip) {
+        return CTVM.getNextStackFrame(frame, methods, initialSkip);
+    }
+
+    public static void materializeVirtualObjects(
+            HotSpotStackFrameReference stackFrame, boolean invalidate) {
+        CTVM.materializeVirtualObjects(stackFrame, invalidate);
+    }
+
+    public static int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type,
+            HotSpotResolvedJavaMethodImpl method) {
+        return CTVM.getVtableIndexForInterfaceMethod(type, method);
+    }
+
+    public static boolean shouldDebugNonSafepoints() {
+        return CTVM.shouldDebugNonSafepoints();
+    }
+
+    public static void writeDebugOutput(byte[] bytes, int offset, int length) {
+        CTVM.writeDebugOutput(bytes, offset, length);
+    }
+
+    public static void flushDebugOutput() {
+        CTVM.flushDebugOutput();
+    }
+
+    public static HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base,
+            long displacement) {
+        return CTVM.getResolvedJavaMethod(base, displacement);
+    }
+
+    public static HotSpotConstantPool getConstantPool(Object base, long displacement) {
+        return CTVM.getConstantPool(base, displacement);
+    }
+
+    public static HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base,
+            long displacement, boolean compressed) {
+        return CTVM.getResolvedJavaType(base, displacement, compressed);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/JVMCIHelpers.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common;
+
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import jdk.vm.ci.compiler.Compiler;
+import jdk.vm.ci.compiler.CompilerFactory;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.runtime.JVMCIRuntime;
+
+/*
+ * A stub classes to be able to use jvmci
+ */
+public class JVMCIHelpers {
+
+    public static class EmptyVMEventListener implements HotSpotVMEventListener {
+        // just empty, using default interface methods
+    }
+
+    public static class EmptyHotspotCompiler implements Compiler {
+
+        @Override
+        public void compileMethod(ResolvedJavaMethod method, int entryBCI,
+                long jvmciEnv, int id) {
+            // do nothing
+        }
+    }
+
+    public static class EmptyCompilerFactory implements CompilerFactory {
+
+        @Override
+        public String getCompilerName() {
+            return "EmptyCompiler";
+        }
+
+        @Override
+        public Architecture initializeArchitecture(Architecture arch) {
+            return arch;
+        }
+
+        @Override
+        public Compiler createCompiler(JVMCIRuntime runtime) {
+            return new EmptyHotspotCompiler();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.compiler.Compiler	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.compiler.CompilerFactory	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.HotSpotVMEventListener	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+compiler.jvmci.common.JVMCIHelpers$EmptyVMEventListener
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/AbstractClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public abstract class AbstractClass {
+    public static final long initTime = System.currentTimeMillis();
+    public abstract void abstractMethod();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/AbstractClassExtender.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class AbstractClassExtender extends AbstractClass {
+    @Override
+    public void abstractMethod() {
+        // empty
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/AnotherSingleImplementer.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class AnotherSingleImplementer implements AnotherSingleImplementerInterface {
+
+    @Override
+    public void interfaceMethod() {
+        // empty
+    }
+
+    public void nonInterfaceMethod() {
+        // empty
+    }
+
+    @Override
+    public void finalize() throws Throwable {
+        super.finalize();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/AnotherSingleImplementerInterface.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public interface AnotherSingleImplementerInterface {
+    public static final long initTime = System.currentTimeMillis();
+
+    default void defaultMethod() {
+        // empty
+    }
+
+    void interfaceMethod();
+
+    void finalize() throws Throwable;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/DoNotExtendClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class DoNotExtendClass {
+    // empty
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/DoNotImplementInterface.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public interface DoNotImplementInterface {
+    // empty
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultiSubclassedClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class MultiSubclassedClass {
+    // empty
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultiSubclassedClassSubclass1.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class MultiSubclassedClassSubclass1 extends MultiSubclassedClass {
+    // empty
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultiSubclassedClassSubclass2.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class MultiSubclassedClassSubclass2 extends MultiSubclassedClass {
+    // empty
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultipleAbstractImplementer.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public abstract class MultipleAbstractImplementer
+        implements MultipleImplementersInterface {
+
+    public abstract void abstractMethod();
+
+    @Override
+    public void finalize() throws Throwable {
+        super.finalize();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultipleImplementer1.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class MultipleImplementer1 implements MultipleImplementersInterface {
+
+    @Override
+    public void defaultMethod() {
+        // empty
+    }
+
+    @Override
+    public void testMethod() {
+        // empty
+    }
+    @Override
+    public void finalize() throws Throwable {
+        super.finalize();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultipleImplementer2.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class MultipleImplementer2 implements MultipleImplementersInterface {
+
+    private static int intStaticField = INT_CONSTANT;
+    static long longStaticField = LONG_CONSTANT;
+    static float floatStaticField = FLOAT_CONSTANT;
+    static double doubleStaticField = DOUBLE_CONSTANT;
+    public static String stringStaticField = STRING_CONSTANT;
+    protected static Object objectStaticField = OBJECT_CONSTANT;
+
+    public int intField = INT_CONSTANT;
+    private long longField = LONG_CONSTANT;
+    protected float floatField = FLOAT_CONSTANT;
+    double doubleField = DOUBLE_CONSTANT;
+    String stringField = STRING_CONSTANT;
+    Object objectField = OBJECT_CONSTANT;
+
+    public MultipleImplementer2() {
+        intField = Integer.MAX_VALUE;
+        longField = Long.MAX_VALUE;
+        floatField = Float.MAX_VALUE;
+        doubleField = Double.MAX_VALUE;
+        stringField = "Message";
+        objectField = new Object();
+    }
+
+    @Override
+    public void testMethod() {
+        // empty
+    }
+
+    @Override
+    public void finalize() throws Throwable {
+        super.finalize();
+    }
+
+    public void interfaceMethodReferral2(MultipleImplementersInterface obj) {
+        obj.interfaceMethodReferral(obj);
+    }
+
+    public void lambdaUsingMethod2() {
+        Thread t = new Thread(this::testMethod);
+        t.start();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultipleImplementersInterface.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public interface MultipleImplementersInterface {
+
+    int INT_CONSTANT = Integer.MAX_VALUE;
+    long LONG_CONSTANT = Long.MAX_VALUE;
+    float FLOAT_CONSTANT = Float.MAX_VALUE;
+    double DOUBLE_CONSTANT = Double.MAX_VALUE;
+    String STRING_CONSTANT = "Hello";
+    Object OBJECT_CONSTANT = new Object();
+
+    default void defaultMethod() {
+        // empty
+    }
+
+    void testMethod();
+
+    default void finalize() throws Throwable {
+        // empty
+    }
+
+    default void interfaceMethodReferral(MultipleImplementersInterface obj) {
+        obj.defaultMethod();
+    }
+
+    default void lambdaUsingMethod() {
+        Thread t = new Thread(this::defaultMethod);
+        t.start();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultipleImplementersInterfaceExtender.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public interface MultipleImplementersInterfaceExtender
+        extends MultipleImplementersInterface {
+    // provide default implementation for parent interface
+    @Override
+    default void testMethod() {
+        // empty
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/PackagePrivateClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+class PackagePrivateClass {
+    // empty
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/SimpleClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+// just a most common simple class with method "testMethod" to use anywhere
+public class SimpleClass {
+
+    public void testMethod() {
+        // empty
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/SingleImplementer.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class SingleImplementer implements SingleImplementerInterface {
+    public static final long initTime = System.currentTimeMillis();
+
+    @Override
+    public void interfaceMethod() {
+        // empty
+    }
+
+    public void nonInterfaceMethod() {
+        // empty
+    }
+
+    @Override
+    public void finalize() throws Throwable {
+        super.finalize();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/SingleImplementerInterface.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public interface SingleImplementerInterface {
+    public static final long initTime = System.currentTimeMillis();
+
+    default void defaultMethod() {
+        // empty
+    }
+
+    void interfaceMethod();
+
+    void finalize() throws Throwable;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/SingleSubclass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class SingleSubclass extends SingleSubclassedClass {
+    public void usualMethod() {
+        // empty
+    }
+
+    @Override
+    public void overridenMethod() {
+        // empty
+    }
+
+    private void privateMethod() {
+        // empty
+    }
+
+    public static void staticMethod() {
+        // empty
+    }
+
+    protected void protectedMethod() {
+        // empty
+    }
+
+    void defaultAccessMethod() {
+        // empty
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/SingleSubclassedClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+public class SingleSubclassedClass {
+    public void inheritedMethod() {
+        // empty
+    }
+
+    public void overridenMethod() {
+        //empty
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/TestCase.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.common.testcases;
+
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+
+/**
+ * A test case for tests in compiler.jvmci.compilerToVM package.
+ */
+public class TestCase {
+    private static final Class<?>[] CLASSES = {
+            AbstractClass.class,
+            AbstractClassExtender.class,
+            AnotherSingleImplementer.class,
+            AnotherSingleImplementerInterface.class,
+            DoNotExtendClass.class,
+            DoNotImplementInterface.class,
+            MultipleAbstractImplementer.class,
+            MultipleImplementer1.class,
+            MultipleImplementer2.class,
+            MultipleImplementersInterface.class,
+            MultipleImplementersInterfaceExtender.class,
+            MultiSubclassedClass.class,
+            MultiSubclassedClassSubclass1.class,
+            MultiSubclassedClassSubclass2.class,
+            PackagePrivateClass.class,
+            SimpleClass.class,
+            SingleImplementer.class,
+            SingleImplementerInterface.class,
+            SingleSubclass.class,
+            SingleSubclassedClass.class
+    };
+
+    public static Collection<Class<?>> getAllClasses() {
+        return  Arrays.asList(CLASSES);
+    }
+
+    public static Collection<Executable> getAllExecutables() {
+        Set<Executable> result = new HashSet<>();
+        for (Class<?> aClass : CLASSES) {
+            result.addAll(Arrays.asList(aClass.getMethods()));
+            result.addAll(Arrays.asList(aClass.getConstructors()));
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/AllocateCompileIdTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      -XX:-BackgroundCompilation
+ *      compiler.jvmci.compilerToVM.AllocateCompileIdTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.HashSet;
+
+import compiler.jvmci.common.testcases.TestCase;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Pair;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+import sun.hotspot.code.NMethod;
+
+public class AllocateCompileIdTest {
+
+    private final HashSet<Integer> ids = new HashSet<>();
+
+    public static void main(String[] args) {
+        AllocateCompileIdTest test = new AllocateCompileIdTest();
+        createTestCasesCorrectBci().forEach(test::runSanityCorrectTest);
+        createTestCasesIncorrectBci().forEach(test::runSanityIncorrectTest);
+    }
+
+
+    private static List<CompileCodeTestCase> createTestCasesCorrectBci() {
+        List<CompileCodeTestCase> result = new ArrayList<>();
+        try {
+            Class<?> aClass = DummyClass.class;
+            Method method = aClass.getMethod("withLoop");
+            result.add(new CompileCodeTestCase(method, 17));
+            result.add(new CompileCodeTestCase(method, -1));
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG : " + e, e);
+        }
+        return result;
+    }
+
+
+    private static List<Pair<CompileCodeTestCase, Class<? extends Throwable>>>
+            createTestCasesIncorrectBci() {
+        List<Pair<CompileCodeTestCase, Class<? extends Throwable>>> result
+                = new ArrayList<>();
+
+        try {
+            Class<?> aClass = DummyClass.class;
+            Method method = aClass.getMethod("dummyInstanceFunction");
+            // greater than bytecode.length
+            int[] bcis = new int[] {30, 50, 200};
+            for (int bci : bcis) {
+                result.add(new Pair<>(new CompileCodeTestCase(method, bci),
+                        IllegalArgumentException.class));
+            }
+            bcis = new int[] {-4, -50, -200};
+            for (int bci : bcis) {
+                result.add(new Pair<>(new CompileCodeTestCase(method, bci),
+                        IllegalArgumentException.class));
+            }
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG : " + e.getMessage(), e);
+        }
+        return result;
+    }
+
+    private void runSanityCorrectTest(CompileCodeTestCase testCase) {
+        System.out.println(testCase);
+        Executable aMethod = testCase.executable;
+        int bci = testCase.bci;
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        int wbCompileID = getWBCompileID(testCase);
+        int id = CompilerToVMHelper.allocateCompileId(method, bci);
+        Asserts.assertNE(id, 0, testCase + " : zero compile id");
+
+        if (wbCompileID > 0) {
+            Asserts.assertGT(id, wbCompileID, testCase
+                    + " : allocated 'compile id' not  greater than existed");
+            if (!ids.add(wbCompileID)) {
+                throw new AssertionError(String.format(
+                        "%s : vm compilation allocated existed id -- %d",
+                        testCase, id));
+            }
+        }
+        if (!ids.add(id)) {
+            throw new AssertionError(String.format(
+                    "%s : allocateCompileId returned existed id %d",
+                    testCase, id));
+        }
+    }
+
+    private void runSanityIncorrectTest(
+            Pair<CompileCodeTestCase, Class<? extends Throwable>> testCase) {
+        System.out.println(testCase);
+        Class<? extends Throwable> exception = testCase.second;
+        Executable aMethod = testCase.first.executable;
+        int bci = testCase.first.bci;
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        Utils.runAndCheckException(
+                () -> CompilerToVMHelper.allocateCompileId(method, bci),
+                exception);
+    }
+
+    private int getWBCompileID(CompileCodeTestCase testCase) {
+        NMethod nm = testCase.deoptimizeAndCompile();
+        if (nm == null) {
+            throw new Error("[TEST BUG] cannot compile method " + testCase);
+        }
+        return nm.compile_id;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.CanInlineMethodTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+public class CanInlineMethodTest {
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) {
+        List<Executable> testCases = createTestCases();
+        testCases.forEach(CanInlineMethodTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        boolean canInline = CompilerToVMHelper.canInlineMethod(method);
+        boolean expectedCanInline = !WB.testSetDontInlineMethod(aMethod,
+                true);
+        Asserts.assertEQ(canInline, expectedCanInline, "Unexpected initial " +
+                "value of property 'can inline'");
+
+        canInline = CompilerToVMHelper.canInlineMethod(method);
+        Asserts.assertFalse(canInline, aMethod + "Unexpected value of " +
+                "property 'can inline' after setting 'do not inline' to true");
+        WB.testSetDontInlineMethod(aMethod, false);
+        canInline = CompilerToVMHelper.canInlineMethod(method);
+        Asserts.assertTrue(canInline, "Unexpected value of " +
+                "property 'can inline' after setting 'do not inline' to false");
+    }
+
+    private static List<Executable> createTestCases() {
+        List<Executable> testCases = new ArrayList<>();
+
+        Class<?> aClass = DummyClass.class;
+        testCases.addAll(Arrays.asList(aClass.getDeclaredMethods()));
+        testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors()));
+        return testCases;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/CollectCountersTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib/
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @build compiler.jvmci.compilerToVM.CollectCountersTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI -Xbootclasspath/a:.
+ *     -XX:JVMCICounterSize=0
+ *     -Dcompiler.jvmci.compilerToVM.CollectCountersTest.expected=0
+ *     compiler.jvmci.compilerToVM.CollectCountersTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI -Xbootclasspath/a:.
+ *     -XX:JVMCICounterSize=11
+ *     -Dcompiler.jvmci.compilerToVM.CollectCountersTest.expected=11
+ *     compiler.jvmci.compilerToVM.CollectCountersTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+
+public class CollectCountersTest {
+    private static final int EXPECTED = Integer.getInteger(
+            "compiler.jvmci.compilerToVM.CollectCountersTest.expected");
+    public static void main(String args[]) {
+        new CollectCountersTest().runTest();
+    }
+
+    private void runTest() {
+        long[] counters = CompilerToVMHelper.collectCounters();
+        Asserts.assertNotNull(counters, "Expected not-null counters array");
+        int ctvmData = counters.length;
+        Asserts.assertEQ(EXPECTED, ctvmData, "Unexpected counters amount");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.compilerToVM;
+
+import compiler.testlibrary.CompilerUtils;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+import sun.hotspot.code.NMethod;
+
+import java.lang.reflect.Executable;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A test case for tests which require compiled code.
+ */
+public final class CompileCodeTestCase {
+    public static final Map<Class<?>, Object> RECEIVERS;
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final int COMP_LEVEL;
+    static {
+        int[] levels = CompilerUtils.getAvailableCompilationLevels();
+        if (levels.length == 0) {
+            throw new Error("TESTBUG: no compilers available");
+        }
+        COMP_LEVEL = levels[levels.length - 1];
+    }
+    private static final Class<?>[] CLASSES = {
+            Interface.class,
+            Dummy.class,
+            DummyEx.class};
+
+    public final Executable executable;
+    public final int bci;
+    private final boolean isOsr;
+
+    public CompileCodeTestCase(Executable executable, int bci) {
+        this.executable = executable;
+        this.bci = bci;
+        isOsr = bci >= 0;
+    }
+
+    public NMethod compile() {
+        return compile(COMP_LEVEL);
+    }
+
+    public NMethod compile(int level) {
+        boolean enqueued = WB.enqueueMethodForCompilation(executable,
+                level, bci);
+        if (!enqueued) {
+            throw new Error(String.format(
+                    "%s can't be enqueued for %scompilation on level %d",
+                    executable, bci >= 0 ? "osr-" : "", level));
+        }
+        Utils.waitForCondition(() -> WB.isMethodCompiled(executable, isOsr));
+        return NMethod.get(executable, isOsr);
+    }
+
+    public static List<CompileCodeTestCase> generate(int bci) {
+        ArrayList<CompileCodeTestCase> result = new ArrayList<>();
+        for (Class<?> aClass : CLASSES) {
+            for (Executable m : aClass.getDeclaredConstructors()) {
+                result.add(new CompileCodeTestCase(m, bci));
+            }
+            Arrays.stream(aClass.getDeclaredMethods())
+                    .filter(m -> !Modifier.isAbstract(m.getModifiers()))
+                    .filter(m -> !Modifier.isNative(m.getModifiers()))
+                    .map(m -> new CompileCodeTestCase(m, bci))
+                    .forEach(result::add);
+        }
+        return result;
+    }
+
+    public NMethod toNMethod() {
+        return NMethod.get(executable, isOsr);
+    }
+
+    @Override
+    public String toString() {
+        return "CompileCodeTestCase{" +
+                "executable=" + executable +
+                ", bci=" + bci +
+                '}';
+    }
+
+    public void deoptimize() {
+        WB.deoptimizeMethod(executable, isOsr);
+    }
+
+    public NMethod deoptimizeAndCompile() {
+        deoptimize();
+        return compile();
+    }
+
+    // classes which are used as "input" data in test cases
+    private static interface Interface {
+        Interface interfaceMethod();
+        default Long defaultOverriddenMethod(Interface[] array) {
+            return array == null ? 0L : array.length;
+        }
+        default int defaultMethod(Object o) {
+            return o != null ? o.hashCode() : 0;
+        }
+    }
+
+    private static abstract class Dummy implements Interface {
+        protected Dummy() {
+        }
+
+        private static void staticMethod() {
+        }
+
+        Dummy instanceMethod(int i) {
+            return null;
+        }
+
+        abstract Object abstractMethod(double d);
+
+        @Override
+        public Long defaultOverriddenMethod(Interface[] array) {
+            return 0L;
+        }
+    }
+
+    public static class DummyEx extends Dummy {
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
+
+        public DummyEx() {
+        }
+
+        protected Dummy instanceMethod(int i) {
+            if (i == 0) {
+                return this;
+            }
+            return null;
+        }
+
+        @Override
+        Object abstractMethod(double d) {
+            return this;
+        }
+
+        @Override
+        public Interface interfaceMethod() {
+            return null;
+        }
+    }
+
+    static {
+        Map<Class<?>, Object> map = new HashMap<>();;
+        map.put(CompileCodeTestCase.DummyEx.class,
+                new CompileCodeTestCase.DummyEx());
+        map.put(CompileCodeTestCase.Dummy.class,
+                new CompileCodeTestCase.Dummy() {
+                    @Override
+                    public CompileCodeTestCase.Interface interfaceMethod() {
+                        throw new AbstractMethodError();
+                    }
+
+                    @Override
+                    Object abstractMethod(double d) {
+                        throw new AbstractMethodError();
+                    }
+                });
+        map.put(CompileCodeTestCase.Interface.class,
+                new CompileCodeTestCase.Interface() {
+                    @Override
+                    public CompileCodeTestCase.Interface interfaceMethod() {
+                        throw new AbstractMethodError();
+                    }
+                });
+        RECEIVERS = Collections.unmodifiableMap(map);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.compilerToVM;
+
+import java.util.HashMap;
+import java.util.Map;
+import jdk.vm.ci.hotspot.HotSpotConstantPool;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.internal.misc.SharedSecrets;
+import sun.reflect.ConstantPool;
+
+/**
+ * Common class for jdk.vm.ci.hotspot.CompilerToVM constant pool tests
+ */
+public class ConstantPoolTestCase {
+
+    private final Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests;
+
+    public static interface Validator {
+        void validate(HotSpotConstantPool constantPoolCTVM, ConstantPool constantPoolSS,
+            ConstantPoolTestsHelper.DummyClasses dummyClass, int index);
+    }
+
+    public ConstantPoolTestCase(Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests) {
+        this.typeTests = new HashMap<>();
+        this.typeTests.putAll(typeTests);
+    }
+
+    private void messageOnFail(Throwable t,
+            ConstantPoolTestsHelper.ConstantTypes cpType,
+            ConstantPoolTestsHelper.DummyClasses dummyClass, int index) {
+        ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess().
+                        getConstantPool(dummyClass.klass);
+        String msg = String.format("Test for %s constant pool entry of"
+                        + " type %s",
+                        dummyClass.klass, cpType.name());
+        switch (cpType) {
+            case CONSTANT_CLASS:
+            case CONSTANT_STRING:
+            case CONSTANT_METHODTYPE:
+                String utf8 = constantPoolSS
+                        .getUTF8At((int) dummyClass.cp.get(index).value);
+                msg = String.format("%s (%s) failed with %s", msg, utf8, t);
+                break;
+            case CONSTANT_INTEGER:
+                int intValue = constantPoolSS.getIntAt(index);
+                msg = String.format("%s (%d) failed with %s", msg, intValue, t);
+                break;
+            case CONSTANT_LONG:
+                long longValue = constantPoolSS.getLongAt(index);
+                msg = String.format("%s (%d) failed with %s", msg, longValue, t);
+                break;
+            case CONSTANT_FLOAT:
+                float floatValue = constantPoolSS.getFloatAt(index);
+                msg = String.format("%s (%E) failed with %s", msg, floatValue, t);
+                break;
+            case CONSTANT_DOUBLE:
+                double doubleValue = constantPoolSS.getDoubleAt(index);
+                msg = String.format("%s (%E) failed with %s", msg, doubleValue, t);
+                break;
+            case CONSTANT_UTF8:
+                String utf8Value = constantPoolSS.getUTF8At(index);
+                msg = String.format("%s (%s) failed with %s", msg, utf8Value, t);
+                break;
+            case CONSTANT_INVOKEDYNAMIC:
+                index = ((int[]) dummyClass.cp.get(index).value)[1];
+            case CONSTANT_NAMEANDTYPE:
+                String name = constantPoolSS
+                        .getUTF8At(((int[]) dummyClass.cp.get(index).value)[0]);
+                String type = constantPoolSS
+                        .getUTF8At(((int[]) dummyClass.cp.get(index).value)[1]);
+                msg = String.format("%s (%s:%s) failed with %s",
+                        msg, name, type, t);
+                break;
+            case CONSTANT_METHODHANDLE:
+                index = ((int[]) dummyClass.cp.get(index).value)[1];
+            case CONSTANT_METHODREF:
+            case CONSTANT_INTERFACEMETHODREF:
+            case CONSTANT_FIELDREF:
+                int classIndex = ((int[]) dummyClass.cp.get(index).value)[0];
+                int nameAndTypeIndex = ((int[]) dummyClass.cp.get(index).value)[1];
+                String cName = constantPoolSS
+                        .getUTF8At((int) dummyClass.cp.get(classIndex).value);
+                String mName = constantPoolSS
+                        .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[0]);
+                String mType = constantPoolSS
+                        .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[1]);
+                msg = String.format("%s (%s.%s:%s) failed with %s ",
+                        msg, cName, mName, mType, t);
+                break;
+            default:
+                msg = String.format("Test bug: unknown constant type %s ", cpType);
+        }
+        throw new Error(msg + t.getMessage(), t);
+    }
+
+    public void test() {
+        for (ConstantPoolTestsHelper.DummyClasses dummyClass
+                : ConstantPoolTestsHelper.DummyClasses.values()) {
+            System.out.printf("%nTesting dummy %s%n", dummyClass.klass);
+            HotSpotResolvedObjectTypeImpl holder = HotSpotResolvedObjectTypeImpl
+                    .fromObjectClass(dummyClass.klass);
+            HotSpotConstantPool constantPoolCTVM = holder.getConstantPool();
+            ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess().
+                        getConstantPool(dummyClass.klass);
+            for (Integer i : dummyClass.cp.keySet()) {
+                ConstantPoolTestsHelper.ConstantTypes cpType
+                        = dummyClass.cp.get(i).type;
+                if (!typeTests.keySet().contains(cpType)) {
+                    continue;
+                }
+                try {
+                    typeTests.get(cpType).validate(constantPoolCTVM,
+                            constantPoolSS, dummyClass, i);
+                } catch (Throwable t) {
+                    messageOnFail(t, cpType, dummyClass, i);
+                }
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ConstantPoolTestsHelper.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.MultipleImplementer2;
+import compiler.jvmci.common.testcases.MultipleImplementersInterface;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class contains hard-coded constant pool tables for dummy classes used for
+ * jdk.vm.ci.hotspot.CompilerToVM constant pool methods
+ */
+public class ConstantPoolTestsHelper {
+
+    public enum ConstantTypes {
+        CONSTANT_CLASS,
+        CONSTANT_FIELDREF,
+        CONSTANT_METHODREF,
+        CONSTANT_INTERFACEMETHODREF,
+        CONSTANT_STRING,
+        CONSTANT_INTEGER,
+        CONSTANT_FLOAT,
+        CONSTANT_LONG,
+        CONSTANT_DOUBLE,
+        CONSTANT_NAMEANDTYPE,
+        CONSTANT_UTF8,
+        CONSTANT_METHODHANDLE,
+        CONSTANT_METHODTYPE,
+        CONSTANT_INVOKEDYNAMIC;
+    }
+
+    public enum DummyClasses {
+        DUMMY_CLASS(MultipleImplementer2.class, CP_MAP_FOR_CLASS),
+        DUMMY_INTERFACE(MultipleImplementersInterface.class, CP_MAP_FOR_INTERFACE);
+
+        public final Class<?> klass;
+        public final Map<Integer, ConstantPoolEntry> cp;
+
+        DummyClasses(Class<?> klass, Map<Integer, ConstantPoolEntry> cp) {
+            this.klass = klass;
+            this.cp = cp;
+        }
+    }
+
+    public static class ConstantPoolEntry {
+
+        public final ConstantTypes type;
+        public final Object value;
+
+        public ConstantPoolEntry(ConstantTypes type, Object value) {
+            this.type = type;
+            this.value = value;
+        }
+    }
+
+    private static final Map<Integer, ConstantPoolEntry> CP_MAP_FOR_CLASS
+            = new HashMap<>();
+    static {
+        CP_MAP_FOR_CLASS.put(1, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{22, 68}));
+        CP_MAP_FOR_CLASS.put(2, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 69));
+        CP_MAP_FOR_CLASS.put(3, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTEGER, 2147483647));
+        CP_MAP_FOR_CLASS.put(4, new ConstantPoolEntry(ConstantTypes.CONSTANT_FIELDREF, new int[]{35, 70}));
+        CP_MAP_FOR_CLASS.put(5, new ConstantPoolEntry(ConstantTypes.CONSTANT_LONG, 9223372036854775807L));
+        CP_MAP_FOR_CLASS.put(8, new ConstantPoolEntry(ConstantTypes.CONSTANT_FLOAT, 3.4028235E38F));
+        CP_MAP_FOR_CLASS.put(10, new ConstantPoolEntry(ConstantTypes.CONSTANT_DOUBLE, 1.7976931348623157E308D));
+        CP_MAP_FOR_CLASS.put(13, new ConstantPoolEntry(ConstantTypes.CONSTANT_STRING, 74));
+        CP_MAP_FOR_CLASS.put(22, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 83));
+        CP_MAP_FOR_CLASS.put(23, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{22, 84}));
+        CP_MAP_FOR_CLASS.put(24, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTERFACEMETHODREF, new int[]{2, 85}));
+        CP_MAP_FOR_CLASS.put(26, new ConstantPoolEntry(ConstantTypes.CONSTANT_INVOKEDYNAMIC, new int[]{0, 91}));
+        CP_MAP_FOR_CLASS.put(29, new ConstantPoolEntry(ConstantTypes.CONSTANT_FIELDREF, new int[]{35, 94}));
+        CP_MAP_FOR_CLASS.put(35, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 100));
+        CP_MAP_FOR_CLASS.put(68, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{54, 55}));
+        CP_MAP_FOR_CLASS.put(70, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{48, 37}));
+        CP_MAP_FOR_CLASS.put(84, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{59, 55}));
+        CP_MAP_FOR_CLASS.put(85, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{103, 63}));
+        CP_MAP_FOR_CLASS.put(91, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{106, 107}));
+        CP_MAP_FOR_CLASS.put(94, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{36, 37}));
+        CP_MAP_FOR_CLASS.put(104, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{110, 111}));
+        CP_MAP_FOR_CLASS.put(105, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{35, 112}));
+        CP_MAP_FOR_CLASS.put(110, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 113));
+        CP_MAP_FOR_CLASS.put(111, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{114, 118}));
+        CP_MAP_FOR_CLASS.put(112, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{58, 55}));
+    }
+
+    private static final Map<Integer, ConstantPoolEntry> CP_MAP_FOR_INTERFACE
+            = new HashMap<>();
+    static {
+        CP_MAP_FOR_INTERFACE.put(1, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 48));
+        CP_MAP_FOR_INTERFACE.put(5, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTERFACEMETHODREF, new int[]{13, 52}));
+        CP_MAP_FOR_INTERFACE.put(6, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 53));
+        CP_MAP_FOR_INTERFACE.put(7, new ConstantPoolEntry(ConstantTypes.CONSTANT_INVOKEDYNAMIC, new int[]{0, 58}));
+        CP_MAP_FOR_INTERFACE.put(8, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{6, 59}));
+        CP_MAP_FOR_INTERFACE.put(9, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{6, 60}));
+        CP_MAP_FOR_INTERFACE.put(12, new ConstantPoolEntry(ConstantTypes.CONSTANT_FIELDREF, new int[]{13, 63}));
+        CP_MAP_FOR_INTERFACE.put(13, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 64));
+        CP_MAP_FOR_INTERFACE.put(17, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTEGER, 2147483647));
+        CP_MAP_FOR_INTERFACE.put(20, new ConstantPoolEntry(ConstantTypes.CONSTANT_LONG, 9223372036854775807l));
+        CP_MAP_FOR_INTERFACE.put(24, new ConstantPoolEntry(ConstantTypes.CONSTANT_FLOAT, 3.4028235E38f));
+        CP_MAP_FOR_INTERFACE.put(27, new ConstantPoolEntry(ConstantTypes.CONSTANT_DOUBLE, 1.7976931348623157E308d));
+        CP_MAP_FOR_INTERFACE.put(31, new ConstantPoolEntry(ConstantTypes.CONSTANT_STRING, 65));
+        CP_MAP_FOR_INTERFACE.put(52, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{34, 35}));
+        CP_MAP_FOR_INTERFACE.put(55, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODHANDLE, new int[]{6, 67}));
+        CP_MAP_FOR_INTERFACE.put(56, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODTYPE, 35));
+        CP_MAP_FOR_INTERFACE.put(57, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODHANDLE, new int[]{9, 5}));
+        CP_MAP_FOR_INTERFACE.put(58, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{68, 69}));
+        CP_MAP_FOR_INTERFACE.put(59, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{70, 71}));
+        CP_MAP_FOR_INTERFACE.put(60, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{72, 35}));
+        CP_MAP_FOR_INTERFACE.put(63, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{32, 33}));
+        CP_MAP_FOR_INTERFACE.put(67, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{73, 74}));
+        CP_MAP_FOR_INTERFACE.put(73, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 75));
+        CP_MAP_FOR_INTERFACE.put(74, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{76, 80}));
+        CP_MAP_FOR_INTERFACE.put(77, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 82));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DebugOutputTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run driver compiler.jvmci.compilerToVM.DebugOutputTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.ProcessTools;
+import java.util.Arrays;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.Utils;
+
+public class DebugOutputTest {
+    public static void main(String[] args) {
+        new DebugOutputTest().test();
+    }
+
+    private void test() {
+        for (TestCaseData testCase : TestCaseData.values()) {
+            System.out.println(testCase);
+            OutputAnalyzer oa;
+            try {
+                ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                        /* use test options = */ true,
+                        "-XX:+UnlockExperimentalVMOptions",
+                        "-XX:+EnableJVMCI",
+                        "-Xbootclasspath/a:.",
+                        DebugOutputTest.Worker.class.getName(),
+                        testCase.name());
+               oa = ProcessTools.executeProcess(pb);
+               } catch (Exception e) {
+                e.printStackTrace();
+                throw new Error("Problems running child process", e);
+            }
+            if (testCase.expectedException != null) {
+                oa.shouldHaveExitValue(1);
+                oa.shouldContain(testCase.expectedException.getName());
+            } else {
+                oa.shouldHaveExitValue(0);
+                oa.shouldContain(new String(testCase.getExpected()));
+            }
+        }
+    }
+
+    /**
+     * A list of test cases that are executed in forked VM
+     */
+    private enum TestCaseData {
+        PART_ARRAY(100, 50),
+        FULL_ARRAY(0, 255),
+        EMPTY(0, 0),
+        NEGATIVE_LENGTH(0, Integer.MIN_VALUE,
+                ArrayIndexOutOfBoundsException.class),
+        NEGATIVE_OFFSET(-1, 255,
+                ArrayIndexOutOfBoundsException.class),
+        LEFT_BOUND(Integer.MIN_VALUE, 100,
+                ArrayIndexOutOfBoundsException.class),
+        RIGHT_BOUND(Integer.MAX_VALUE, 100,
+                ArrayIndexOutOfBoundsException.class),
+        BIG_LENGTH(0, Integer.MAX_VALUE,
+                ArrayIndexOutOfBoundsException.class),
+        NULL_POINTER(0, 0,
+                NullPointerException.class),
+        ;
+
+        private static final int SIZE = 255;
+        private static final byte[] DATA = generate();
+        public final int offset;
+        public final int length;
+        public final Class<? extends Throwable> expectedException;
+
+        private TestCaseData(int offset, int length,
+                Class<? extends Throwable> expectedException) {
+            this.offset = offset;
+            this.length = length;
+            this.expectedException = expectedException;
+        }
+
+        private TestCaseData(int offset, int length) {
+            this(offset, length, null);
+        }
+
+        private static byte[] generate() {
+            byte[] byteArray = new byte[SIZE];
+            for (int i = 0; i < SIZE; i++) {
+                byteArray[i] = (byte) (i + 1);
+            }
+            return byteArray;
+        }
+
+        public byte[] getExpected() {
+            if (expectedException != null) {
+                return new byte[0];
+            }
+            return Arrays.copyOfRange(TestCaseData.DATA, offset,
+                    offset + length);
+        }
+
+        @Override
+        public String toString() {
+            return "CASE: " + this.name();
+        }
+
+        public byte[] getData() {
+            if (equals(NULL_POINTER)) {
+                return null;
+            } else {
+                return DATA;
+            }
+        }
+    }
+
+    public static class Worker {
+        public static void main(String[] args) {
+            for (String arg : args) {
+                TestCaseData tcase = TestCaseData.valueOf(arg);
+                CompilerToVMHelper.writeDebugOutput(tcase.getData(),
+                        tcase.offset, tcase.length);
+                CompilerToVMHelper.flushDebugOutput();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @ignore 8139700
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ *        compiler.jvmci.compilerToVM.DisassembleCodeBlobTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.DisassembleCodeBlobTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import sun.hotspot.code.NMethod;
+
+import java.util.List;
+
+public class DisassembleCodeBlobTest {
+
+    public static void main(String[] args) {
+        DisassembleCodeBlobTest test
+                = new DisassembleCodeBlobTest();
+        List<CompileCodeTestCase> testCases
+                = CompileCodeTestCase.generate(/* bci = */ -1);
+        testCases.addAll(CompileCodeTestCase.generate(/* bci = */ 0));
+        testCases.forEach(test::check);
+        test.checkNull();
+    }
+
+    private void checkNull() {
+        String str = CompilerToVMHelper.disassembleCodeBlob(0L);
+        Asserts.assertNull(str, "not null string returned for null pointer");
+    }
+
+    private void check(CompileCodeTestCase testCase) {
+        System.out.println(testCase);
+        // to have a clean state
+        NMethod nMethod = testCase.deoptimizeAndCompile();
+        if (nMethod == null) {
+            throw new Error(testCase + " : method is not compiled");
+        }
+        String str = CompilerToVMHelper.disassembleCodeBlob(nMethod.address);
+        if (str != null) {
+            Asserts.assertGT(str.length(), 0,
+                   testCase +  " : returned string has to be non-zero length");
+        }
+        String str2 = CompilerToVMHelper.disassembleCodeBlob(nMethod.address);
+        Asserts.assertEQ(str, str2,
+                testCase + " : 2nd invocation returned different value");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.DoNotInlineOrCompileTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+public class DoNotInlineOrCompileTest {
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) {
+        List<Executable> testCases = createTestCases();
+        testCases.forEach(DoNotInlineOrCompileTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        boolean canInline = CompilerToVMHelper.canInlineMethod(method);
+        Asserts.assertTrue(canInline, "Unexpected initial " +
+                "value of property 'can inline'");
+        CompilerToVMHelper.doNotInlineOrCompile(method);
+        canInline = CompilerToVMHelper.canInlineMethod(method);
+        Asserts.assertFalse(canInline, aMethod
+                + " : can be inlined even after doNotInlineOrCompile'");
+    }
+
+    private static List<Executable> createTestCases() {
+        List<Executable> testCases = new ArrayList<>();
+
+        Class<?> aClass = DummyClass.class;
+        testCases.addAll(Arrays.asList(aClass.getDeclaredMethods()));
+        testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors()));
+        return testCases;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DummyAbstractClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.compilerToVM;
+
+abstract class DummyAbstractClass implements DummyInterface {
+    public abstract int dummyAbstractFunction();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DummyClass.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.compilerToVM;
+
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+import java.util.Random;
+
+class DummyClass extends DummyAbstractClass {
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    int p1 = 5;
+    int p2 = 6;
+
+    public int dummyInstanceFunction() {
+        String str1 = "123123123";
+        double x = 3.14;
+        int y = Integer.parseInt(str1);
+
+        return y / (int) x;
+    }
+
+    public int dummyEmptyInstanceFunction() {
+        return 42;
+    }
+
+    public static int dummyEmptyStaticFunction() {
+        return -42;
+    }
+
+    @Override
+    public int dummyAbstractFunction() {
+        int z = p1 * p2;
+        return (int) (Math.cos(p2 - p1 + z) * 100);
+    }
+
+    @Override
+    public void dummyFunction() {
+        dummyEmptyInstanceFunction();
+    }
+
+    public void withLoop() {
+        long tier4 = (Long) WB.getVMFlag("Tier4BackEdgeThreshold");
+        for (long i = 0; i < tier4; ++i) {
+            randomProfile();
+        }
+    }
+
+    private double randomProfile() {
+        String str1 = "123123123";
+        double x = 3.14;
+        int y = Integer.parseInt(str1);
+
+        Random rnd = Utils.getRandomInstance();
+        if (rnd.nextDouble() > 0.2) {
+            return y / (int) x;
+        } else {
+            return x / y;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DummyInterface.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.compilerToVM;
+
+interface DummyInterface {
+    void dummyFunction();
+
+    default int dummyDefaultFunction(int x, int y) {
+        int z = x * y;
+        return (int) (Math.cos(x - y + z) * 100);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,176 @@
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Pair;
+import sun.hotspot.code.NMethod;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/*
+ * @test
+ * @bug 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ *        compiler.jvmci.compilerToVM.ExecuteInstalledCodeTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.ExecuteInstalledCodeTest
+ */
+
+public class ExecuteInstalledCodeTest {
+
+
+    public static void main(String[] args) {
+        ExecuteInstalledCodeTest test = new ExecuteInstalledCodeTest();
+        List<CompileCodeTestCase> testCases = new ArrayList<>();
+        testCases.addAll(CompileCodeTestCase.generate(/* bci = */ -1));
+        testCases .stream()
+                // ignore <init> of abstract class -- 8138793
+                .filter(e -> !(e.executable instanceof Constructor
+                        && Modifier.isAbstract(
+                                e.executable.getDeclaringClass()
+                                        .getModifiers())))
+                .forEach(test::checkSanity);
+    }
+
+    private void checkSanity(CompileCodeTestCase testCase) {
+        System.out.println(testCase);
+        // to have a clean state
+        testCase.deoptimize();
+        Pair<Object, ? extends Throwable> reflectionResult;
+        Object[] args = getArguments(testCase.executable);
+        reflectionResult = invoke(testCase, args);
+        NMethod nMethod = testCase.compile();
+        if (nMethod == null) {
+            throw new Error(testCase + " : nmethod is null");
+        }
+        InstalledCode installedCode = new InstalledCode(
+                testCase.executable.getName());
+        installedCode.setAddress(nMethod.address);
+        Object result = null;
+        Throwable expectedException = reflectionResult.second;
+        boolean gotException = true;
+        try {
+            args = addReceiver(testCase, args);
+            result = CompilerToVMHelper.executeInstalledCode(
+                    args, installedCode);
+            if (testCase.executable instanceof Constructor) {
+                // <init> doesn't have return value, it changes receiver
+                result = args[0];
+            }
+            gotException = false;
+        } catch (InvalidInstalledCodeException e) {
+            throw new AssertionError(
+                    testCase + " : unexpected InvalidInstalledCodeException", e);
+        } catch (Throwable t) {
+            if (expectedException == null) {
+                throw new AssertionError(testCase
+                        + " : got unexpected execption : " + t.getMessage(), t);
+            }
+
+            if (expectedException.getClass() != t.getClass()) {
+                System.err.println("exception from CompilerToVM:");
+                t.printStackTrace();
+                System.err.println("exception from reflection:");
+                expectedException.printStackTrace();
+                throw new AssertionError(String.format(
+                        "%s : got unexpected different exceptions : %s != %s",
+                        testCase, expectedException.getClass(), t.getClass()));
+            }
+        }
+
+        Asserts.assertEQ(reflectionResult.first, result, testCase
+                + " : different return value");
+        if (!gotException) {
+            Asserts.assertNull(expectedException, testCase
+                    + " : expected exception hasn't been thrown");
+        }
+    }
+
+    private Object[] addReceiver(CompileCodeTestCase testCase, Object[] args) {
+        if (!Modifier.isStatic(testCase.executable.getModifiers())) {
+            // add instance as 0th arg
+            Object[] newArgs = new Object[args.length + 1];
+            newArgs[0] = getReciever(testCase);
+            System.arraycopy(args, 0, newArgs, 1, args.length);
+            args = newArgs;
+        }
+        return args;
+    }
+
+    private Object getReciever(CompileCodeTestCase testCase) {
+        return CompileCodeTestCase.RECEIVERS.get(
+                testCase.executable.getDeclaringClass());
+    }
+
+    public Pair<Object, ? extends Throwable> invoke(
+            CompileCodeTestCase testCase, Object[] args) {
+        Executable executable = testCase.executable;
+        boolean old = executable.isAccessible();
+        executable.setAccessible(true);
+        try {
+            try {
+                if (executable instanceof Method) {
+                    Method m = (Method) executable;
+                    return new Pair<>(m.invoke(getReciever(testCase), args), null);
+                }
+
+                if (executable instanceof Constructor) {
+                    Constructor c = (Constructor) executable;
+                    return new Pair<>(c.newInstance(args), null);
+                }
+            } catch (InvocationTargetException e) {
+                return new Pair<>(null, e.getCause());
+            } catch (Throwable e) {
+                return new Pair<>(null, e);
+            }
+        } finally {
+            executable.setAccessible(old);
+        }
+        throw new Error(executable + " has unsupported type "
+                + executable.getClass());
+    }
+
+    private Object[] getArguments(Executable method) {
+        Class<?>[] params = method.getParameterTypes();
+        Object[] result = new Object[params.length];
+        int i = 0;
+        for (Class<?> aClass : params) {
+            result[i++] = getArgument(aClass);
+        }
+        return result;
+    }
+    private static Map<Class<?>, Object> DEFAULT_VALUES = new HashMap<>();
+    static {
+        DEFAULT_VALUES.put(boolean.class, false);
+        DEFAULT_VALUES.put(byte.class, (byte) 0);
+        DEFAULT_VALUES.put(short.class, (short) 0);
+        DEFAULT_VALUES.put(char.class, '\0');
+        DEFAULT_VALUES.put(int.class, 0);
+        DEFAULT_VALUES.put(long.class, 0L);
+        DEFAULT_VALUES.put(float.class, 0.0f);
+        DEFAULT_VALUES.put(double.class, 0.0d);
+    }
+    private Object getArgument(Class<?> aClass) {
+        if (aClass.isPrimitive()) {
+            return DEFAULT_VALUES.get(aClass);
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.FindUniqueConcreteMethodTest
+ * @run main ClassFileInstaller
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.FindUniqueConcreteMethodTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.MultipleImplementer1;
+import compiler.jvmci.common.testcases.SingleImplementer;
+import compiler.jvmci.common.testcases.SingleSubclass;
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.SingleImplementerInterface;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+public class FindUniqueConcreteMethodTest {
+    public static void main(String args[]) {
+        FindUniqueConcreteMethodTest test = new FindUniqueConcreteMethodTest();
+        try {
+            for (TestCase tcase : createTestCases()) {
+                test.runTest(tcase);
+            }
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG: can't find method", e);
+        }
+    }
+
+    private static Set<TestCase> createTestCases() {
+        Set<TestCase> result = new HashSet<>();
+        // a public method
+        result.add(new TestCase(true, SingleSubclass.class,
+                SingleSubclass.class, "usualMethod"));
+        // overriden method
+        result.add(new TestCase(true, SingleSubclass.class,
+                SingleSubclass.class, "overridenMethod"));
+        // private method
+        result.add(new TestCase(true, SingleSubclass.class,
+                SingleSubclass.class, "privateMethod"));
+        // protected method
+        result.add(new TestCase(true, SingleSubclass.class,
+                SingleSubclass.class, "protectedMethod"));
+        // default(package-private) method
+        result.add(new TestCase(true, SingleSubclass.class,
+                SingleSubclass.class, "defaultAccessMethod"));
+        // default interface method redefined in implementer
+        result.add(new TestCase(true, MultipleImplementer1.class,
+                MultipleImplementer1.class, "defaultMethod"));
+        // interface method
+        result.add(new TestCase(true, MultipleImplementer1.class,
+                MultipleImplementer1.class, "testMethod"));
+        // default interface method not redefined in implementer
+        result.add(new TestCase(true, SingleImplementer.class,
+                SingleImplementerInterface.class, "defaultMethod"));
+        // static method
+        result.add(new TestCase(false, SingleSubclass.class,
+                SingleSubclass.class, "staticMethod"));
+        return result;
+    }
+
+    private void runTest(TestCase tcase) throws NoSuchMethodException {
+        System.out.println(tcase);
+        Method method = tcase.holder.getDeclaredMethod(tcase.methodName);
+        HotSpotResolvedJavaMethodImpl testMethod = CTVMUtilities
+                .getResolvedMethod(tcase.reciever, method);
+        HotSpotResolvedObjectTypeImpl resolvedType = CompilerToVMHelper
+                .lookupType(Utils.toJVMTypeSignature(tcase.reciever), getClass(),
+                /* resolve = */ true);
+        HotSpotResolvedJavaMethodImpl concreteMethod = CompilerToVMHelper
+                .findUniqueConcreteMethod(resolvedType, testMethod);
+        Asserts.assertEQ(concreteMethod, tcase.isPositive ? testMethod : null,
+                "Unexpected concrete method for " + tcase.methodName);
+    }
+
+    private static class TestCase {
+        public final Class<?> reciever;
+        public final Class<?> holder;
+        public final String methodName;
+        public final boolean isPositive;
+
+        public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder,
+                String methodName) {
+            this.reciever = clazz;
+            this.methodName = methodName;
+            this.isPositive = isPositive;
+            this.holder = holder;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("CASE: reciever=%s, holder=%s, method=%s,"
+                    + " isPositive=%s", reciever.getName(),
+                    holder.getName(), methodName, isPositive);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.GetBytecodeTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.TestCase;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Modifier;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.test.lib.Asserts;
+
+public class GetBytecodeTest {
+
+    public static void main(String[] args) {
+        TestCase.getAllExecutables()
+                .forEach(GetBytecodeTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        byte[] bytecode = CompilerToVMHelper.getBytecode(method);
+
+        int mods = aMethod.getModifiers();
+        boolean shouldHasZeroLength = Modifier.isAbstract(mods)
+                || Modifier.isNative(mods);
+        boolean correctLength = (bytecode.length == 0 && shouldHasZeroLength)
+                || (bytecode.length > 0 && !shouldHasZeroLength);
+
+        Asserts.assertTrue(correctLength, "Bytecode of '" + aMethod + "' has "
+                + bytecode.length + " length");
+
+        if (!shouldHasZeroLength) {
+            Asserts.assertTrue(containsReturn(bytecode), "Bytecode of '"
+                    + aMethod + "' doesn't have any return statement");
+        }
+    }
+
+    private static boolean containsReturn(byte[] bytecode) {
+        for (byte b : bytecode) {
+            //  cast unsigned byte to int
+            int value = (int) b & 0x000000FF;
+            switch (value) {
+                case Opcodes.RET:
+                case Opcodes.ARETURN:
+                case Opcodes.IRETURN:
+                case Opcodes.LRETURN:
+                case Opcodes.FRETURN:
+                case Opcodes.DRETURN:
+                case Opcodes.RETURN:
+                    return true;
+            }
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.GetClassInitializerTest
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetClassInitializerTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.AbstractClass;
+import compiler.jvmci.common.testcases.AbstractClassExtender;
+import compiler.jvmci.common.testcases.DoNotExtendClass;
+import compiler.jvmci.common.testcases.MultipleImplementersInterfaceExtender;
+import compiler.jvmci.common.testcases.SingleImplementer;
+import compiler.jvmci.common.testcases.SingleImplementerInterface;
+import java.util.HashSet;
+import java.util.Set;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+public class GetClassInitializerTest {
+
+    public static void main(String args[]) {
+        GetClassInitializerTest test = new GetClassInitializerTest();
+        for (TestCase tcase : createTestCases()) {
+            test.runTest(tcase);
+        }
+    }
+
+    private static Set<TestCase> createTestCases() {
+        Set<TestCase> result = new HashSet<>();
+        // a simple class with initializer
+        result.add(new TestCase(SingleImplementer.class, true));
+        // an interface with initializer
+        result.add(new TestCase(SingleImplementerInterface.class, true));
+        // an abstract class with initializer
+        result.add(new TestCase(AbstractClass.class, true));
+        // a class without initializer, extending class with initializer
+        result.add(new TestCase(AbstractClassExtender.class, false));
+        // an interface without initializer
+        result.add(new TestCase(MultipleImplementersInterfaceExtender.class, false));
+        // a class without initializer
+        result.add(new TestCase(DoNotExtendClass.class, false));
+        return result;
+    }
+
+    private void runTest(TestCase tcase) {
+        System.out.println(tcase);
+        String className = tcase.holder.getName();
+        HotSpotResolvedObjectTypeImpl resolvedClazz = CompilerToVMHelper
+                .lookupType(Utils.toJVMTypeSignature(tcase.holder),
+                        getClass(), /* resolve = */ true);
+        HotSpotResolvedJavaMethodImpl initializer = CompilerToVMHelper
+                .getClassInitializer(resolvedClazz);
+        if (tcase.isPositive) {
+            Asserts.assertNotNull(initializer, "Couldn't get initializer for "
+                    + className);
+            Asserts.assertEQ(initializer.getName(), "<clinit>",
+                    "Unexpected initializer name for " + className);
+        } else {
+            Asserts.assertNull(initializer, "Unexpected: found initializer for "
+                    + className);
+        }
+    }
+
+    private static class TestCase {
+        public final Class<?> holder;
+        public final boolean isPositive;
+
+        public TestCase(Class<?> clazz, boolean isPositive) {
+            this.holder = clazz;
+            this.isPositive = isPositive;
+        }
+
+        @Override
+        public String toString() {
+            return "CASE: clazz=" + holder.getName()
+                    + ", isPositive=" + isPositive;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ *        compiler.jvmci.compilerToVM.GetConstantPoolTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions
+ *                   -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetConstantPoolTest
+ */
+package compiler.jvmci.compilerToVM;
+
+import java.lang.reflect.Field;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotConstantPool;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.MetaspaceWrapperObject;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+import sun.misc.Unsafe;
+
+/**
+ * Tests for jdk.vm.ci.hotspot.CompilerToVM::getConstantPool method
+ */
+public class GetConstantPoolTest {
+    private static enum TestCase {
+        NULL_BASE {
+            @Override
+            HotSpotConstantPool getConstantPool() {
+                return CompilerToVMHelper.getConstantPool(null,
+                        getPtrToCpAddress());
+            }
+        },
+        JAVA_METHOD_BASE {
+            @Override
+            HotSpotConstantPool getConstantPool() {
+                HotSpotResolvedJavaMethodImpl methodInstance
+                        = CompilerToVMHelper.getResolvedJavaMethodAtSlot(
+                                TEST_CLASS, 0);
+                Field field;
+                try {
+                    field = HotSpotResolvedJavaMethodImpl
+                            .class.getDeclaredField("metaspaceMethod");
+                    field.setAccessible(true);
+                    field.set(methodInstance, getPtrToCpAddress());
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+
+                return CompilerToVMHelper.getConstantPool(methodInstance, 0L);
+            }
+        },
+        CONSTANT_POOL_BASE {
+            @Override
+            HotSpotConstantPool getConstantPool() {
+                HotSpotConstantPool cpInst;
+                try {
+                    cpInst = CompilerToVMHelper.getConstantPool(null,
+                            getPtrToCpAddress());
+                    Field field = HotSpotConstantPool.class
+                            .getDeclaredField("metaspaceConstantPool");
+                    field.setAccessible(true);
+                    field.set(cpInst, getPtrToCpAddress());
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getConstantPool(cpInst, 0L);
+            }
+        },
+        CONSTANT_POOL_BASE_IN_TWO {
+            @Override
+            HotSpotConstantPool getConstantPool() {
+                long ptr = getPtrToCpAddress();
+                HotSpotConstantPool cpInst;
+                try {
+                    cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
+                    Field field = HotSpotConstantPool.class
+                            .getDeclaredField("metaspaceConstantPool");
+                    field.setAccessible(true);
+                    field.set(cpInst, ptr / 2L);
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getConstantPool(cpInst,
+                        ptr - ptr / 2L);
+            }
+        },
+        CONSTANT_POOL_BASE_ZERO {
+            @Override
+            HotSpotConstantPool getConstantPool() {
+                long ptr = getPtrToCpAddress();
+                HotSpotConstantPool cpInst;
+                try {
+                    cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
+                    Field field = HotSpotConstantPool.class
+                            .getDeclaredField("metaspaceConstantPool");
+                    field.setAccessible(true);
+                    field.set(cpInst, 0L);
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getConstantPool(cpInst, ptr);
+            }
+        },
+        OBJECT_TYPE_BASE {
+            @Override
+            HotSpotConstantPool getConstantPool() {
+                HotSpotResolvedObjectTypeImpl type
+                        = HotSpotResolvedObjectTypeImpl.fromObjectClass(
+                                OBJECT_TYPE_BASE.getClass());
+                long ptrToClass = UNSAFE.getKlassPointer(OBJECT_TYPE_BASE);
+                return CompilerToVMHelper.getConstantPool(type,
+                        getPtrToCpAddress() - ptrToClass);
+            }
+        },
+        ;
+        abstract HotSpotConstantPool getConstantPool();
+    }
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+    private static final Class TEST_CLASS = GetConstantPoolTest.class;
+    private static final long CP_ADDRESS
+            = WB.getConstantPool(GetConstantPoolTest.class);
+
+    public void test(TestCase testCase) {
+        System.out.println(testCase.name());
+        HotSpotConstantPool cp = testCase.getConstantPool();
+        String cpStringRep = cp.toString();
+        if (!cpStringRep.contains(HotSpotConstantPool.class.getSimpleName())
+                || !cpStringRep.contains(TEST_CLASS.getName())) {
+            String msg = String.format("%s : "
+                    + " Constant pool is not valid."
+                    + " String representation should contain \"%s\" and \"%s\"",
+                    testCase.name(),
+                    HotSpotConstantPool.class.getSimpleName(),
+                    TEST_CLASS.getName());
+            throw new AssertionError(msg);
+        }
+    }
+
+    public static void main(String[] args) {
+        GetConstantPoolTest test = new GetConstantPoolTest();
+        for (TestCase testCase : TestCase.values()) {
+            test.test(testCase);
+        }
+        testObjectBase();
+        testMetaspaceWrapperBase();
+    }
+
+    private static void testObjectBase() {
+        try {
+            HotSpotConstantPool cp
+                    = CompilerToVMHelper.getConstantPool(new Object(), 0L);
+            throw new AssertionError("Test OBJECT_BASE."
+                + " Expected IllegalArgumentException has not been caught");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+    private static void testMetaspaceWrapperBase() {
+        try {
+            HotSpotConstantPool cp = CompilerToVMHelper.getConstantPool(
+                    new MetaspaceWrapperObject() {
+                        @Override
+                        public long getMetaspacePointer() {
+                            return getPtrToCpAddress();
+                        }
+                    }, 0L);
+            throw new AssertionError("Test METASPACE_WRAPPER_BASE."
+                + " Expected IllegalArgumentException has not been caught");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+
+    private static long getPtrToCpAddress() {
+        Field field;
+        try {
+            field = TEST_CLASS.getDeclaredField("CP_ADDRESS");
+        } catch (NoSuchFieldException nsfe) {
+            throw new Error("TESTBUG : cannot find field \"CP_ADDRESS\" : "
+                    + nsfe.getMessage(), nsfe);
+        }
+        Object base = UNSAFE.staticFieldBase(field);
+        return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.GetExceptionTableTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.io.IOException;
+import java.lang.reflect.Executable;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+
+public class GetExceptionTableTest {
+
+    public static final int TRY_CATCH_COUNT = 3;
+    public static final int TRY_CATCH_FINALLY_COUNT = 8;
+    public static final int TRY_WITH_RESOURCES_COUNT = 6;
+    public static final int EMPTY_COUNT = 0;
+
+    public static void main(String[] args) {
+        Map<Executable, Integer> testCases = createTestCases();
+        testCases.forEach(GetExceptionTableTest::runSanityTest);
+    }
+
+    private static Map<Executable, Integer> createTestCases() {
+        HashMap<Executable, Integer> methods = new HashMap<>();
+        try {
+            Class<?> aClass = GetExceptionTableTest.DummyClass.class;
+            methods.put(aClass.getMethod("tryCatchDummy"), TRY_CATCH_COUNT);
+            methods.put(aClass.getMethod("tryCatchFinallyDummy"),
+                    TRY_CATCH_FINALLY_COUNT);
+            methods.put(aClass.getMethod("tryWithResourcesDummy"),
+                    TRY_WITH_RESOURCES_COUNT);
+            methods.put(aClass.getMethod("emptyFunction"), EMPTY_COUNT);
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG", e);
+        }
+        return methods;
+    }
+
+    private static void runSanityTest(Executable aMethod,
+                                      Integer expectedTableLength) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        int tableLength = CompilerToVMHelper.getExceptionTableLength(method);
+        Asserts.assertEQ(tableLength, expectedTableLength, aMethod
+                + " incorrect exception table length.");
+
+        long tableStart = CompilerToVMHelper.getExceptionTableStart(method);
+        if (tableLength > 0) {
+            Asserts.assertNE(tableStart, 0L, aMethod + " exception table starts "
+                    + "at 0.");
+        }
+    }
+
+    private static class DummyClass {
+        public static void emptyFunction() {}
+        public static void tryCatchDummy() throws Throwable {
+            try {
+                throw new Exception("Dummy exception");
+            } catch (ArithmeticException ex) {
+                throw new IOException(ex.getMessage());
+            } catch (IOException ex) {
+                throw new Exception(ex);
+            } catch (Exception ex) {
+                throw new Exception(ex);
+            }
+        }
+
+        public int tryCatchFinallyDummy() {
+            // 4 times catch/finally = 8 catch-blocks and finally-blocks
+            try {
+                throw new Exception("Dummy exception");
+            } catch (IndexOutOfBoundsException ex) {
+                return 1;
+            } catch (ArithmeticException ex) {
+                return 2;
+            } catch (IOException ex) {
+                return 3;
+            } catch (Exception ex) {
+                return 4;
+            } finally {
+                return 0;
+            }
+        }
+
+        public static int tryWithResourcesDummy() throws Throwable {
+            try (Socket socket = new Socket()) {
+                throw new Exception("Dummy exception");
+            } catch (ArithmeticException ex) {
+                return 1;
+            } catch (IOException ex) {
+                return 2;
+            } catch (Exception ex) {
+                return 3;
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetImplementorTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib/
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.GetImplementorTest
+ * @run main ClassFileInstaller
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetImplementorTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.AbstractClass;
+import compiler.jvmci.common.testcases.AbstractClassExtender;
+import compiler.jvmci.common.testcases.DoNotImplementInterface;
+import compiler.jvmci.common.testcases.DoNotExtendClass;
+import compiler.jvmci.common.testcases.MultipleImplementer1;
+import compiler.jvmci.common.testcases.MultipleImplementer2;
+import compiler.jvmci.common.testcases.MultipleImplementersInterface;
+import compiler.jvmci.common.testcases.SingleImplementer;
+import compiler.jvmci.common.testcases.SingleImplementerInterface;
+import compiler.jvmci.common.testcases.SingleSubclass;
+import compiler.jvmci.common.testcases.SingleSubclassedClass;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+public class GetImplementorTest {
+    public static void main(String args[]) {
+        GetImplementorTest test = new GetImplementorTest();
+        for (TestCase tcase : createTestCases()) {
+            test.runTest(tcase);
+        }
+    }
+
+    private static Set<TestCase> createTestCases() {
+        Set<TestCase> result = new HashSet<>();
+        Stream.of(
+                    SingleSubclass.class,
+                    AbstractClassExtender.class,
+                    MultipleImplementer2.class,
+                    MultipleImplementer1.class,
+                    MultipleImplementersInterface.class,
+                    DoNotImplementInterface.class,
+                    DoNotExtendClass.class,
+                    AbstractClass.class,
+                    SingleSubclassedClass.class)
+                .forEach(Utils::ensureClassIsLoaded);
+        // an interface with single class implementing it
+        result.add(new TestCase(SingleImplementerInterface.class,
+                SingleImplementer.class));
+        /* an interface with multiple implementers. According to getImplementor
+           javadoc, an itself should be returned in case of more than one
+           implementor
+         */
+        result.add(new TestCase(MultipleImplementersInterface.class,
+                MultipleImplementersInterface.class));
+        // an interface with no implementors
+        result.add(new TestCase(DoNotImplementInterface.class, null));
+        // an abstract class with extender class
+        result.add(new TestCase(AbstractClass.class, null));
+        // a simple class, which is not extended
+        result.add(new TestCase(DoNotExtendClass.class, null));
+        // a usual class, which is extended
+        result.add(new TestCase(SingleSubclassedClass.class, null));
+        return result;
+    }
+
+    private void runTest(TestCase tcase) {
+        System.out.println(tcase);
+        HotSpotResolvedObjectTypeImpl resolvedIface = CompilerToVMHelper
+                .lookupType(Utils.toJVMTypeSignature(tcase.anInterface),
+                        getClass(), /* resolve = */ true);
+        HotSpotResolvedObjectTypeImpl resolvedImplementer = CompilerToVMHelper
+                .getImplementor(resolvedIface);
+        HotSpotResolvedObjectTypeImpl resolvedExpected = null;
+        if (tcase.expectedImplementer != null) {
+            resolvedExpected = CompilerToVMHelper.lookupType(Utils
+                    .toJVMTypeSignature(tcase.expectedImplementer),
+                    getClass(), /* resolve = */ true);
+        }
+        Asserts.assertEQ(resolvedImplementer, resolvedExpected,
+                "Unexpected implementer for " + tcase.anInterface.getName());
+    }
+
+    private static class TestCase {
+        public final Class<?> anInterface;
+        public final Class<?> expectedImplementer;
+
+        public TestCase(Class<?> iface, Class<?> expectedImplementer) {
+            this.anInterface = iface;
+            this.expectedImplementer = expectedImplementer;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("CASE: interface=%s, expected=%s",
+                    anInterface.getName(),
+                    expectedImplementer == null
+                            ? null
+                            : expectedImplementer.getName());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.GetLineNumberTableTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.TestCase;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.tree.ClassNode;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class GetLineNumberTableTest {
+    public static void main(String[] args) {
+        TestCase.getAllExecutables()
+                .forEach(GetLineNumberTableTest::runSanityTest);
+    }
+
+    public static void runSanityTest(Executable aMethod) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        long[] lineNumbers = CompilerToVMHelper.getLineNumberTable(method);
+        long[] expectedLineNumbers = getExpectedLineNumbers(aMethod);
+
+        Asserts.assertTrue(Arrays.equals(lineNumbers, expectedLineNumbers),
+                String.format("%s : unequal table values : %n%s%n%s%n",
+                        aMethod,
+                        Arrays.toString(lineNumbers),
+                        Arrays.toString(expectedLineNumbers)));
+    }
+
+    public static long[] getExpectedLineNumbers(Executable aMethod) {
+        try {
+            ClassReader cr = new ClassReader(aMethod.getDeclaringClass()
+                    .getName());
+            ClassNode cn = new ClassNode();
+            cr.accept(cn, ClassReader.EXPAND_FRAMES);
+
+            Map<Label, Integer> lineNumbers = new HashMap<>();
+            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+            ClassVisitor cv = new ClassVisitorForLabels(cw, lineNumbers,
+                    aMethod);
+            cr.accept(cv, ClassReader.EXPAND_FRAMES);
+
+            long[] result = null;
+            if (!lineNumbers.isEmpty()) {
+                Map<Integer, Integer> labels = new TreeMap<>();
+                lineNumbers.forEach((k, v) -> labels.put(k.getOffset(), v));
+
+                result = new long[2 * labels.size()];
+                int i = 0;
+                for (Integer key : labels.keySet()) {
+                    result[i++] = key.longValue();
+                    result[i++] = labels.get(key).longValue();
+                }
+            }
+            // compilerToVM::getLineNumberTable returns null in case empty table
+            return result;
+        } catch (IOException e) {
+            throw new Error("TEST BUG " + e, e);
+        }
+    }
+
+    private static class ClassVisitorForLabels extends ClassVisitor {
+        private final Map<Label, Integer> lineNumbers;
+        private final String targetName;
+        private final String targetDesc;
+
+        public ClassVisitorForLabels(ClassWriter cw, Map<Label, Integer> lines,
+                                     Executable target) {
+            super(Opcodes.ASM5, cw);
+            this.lineNumbers = lines;
+
+            StringBuilder builder = new StringBuilder("(");
+            for (Parameter parameter : target.getParameters()) {
+                builder.append(Utils.toJVMTypeSignature(parameter.getType()));
+            }
+            builder.append(")");
+            if (target instanceof Constructor) {
+                targetName = "<init>";
+                builder.append("V");
+            } else {
+                targetName = target.getName();
+                builder.append(Utils.toJVMTypeSignature(
+                        ((Method) target).getReturnType()));
+            }
+            targetDesc = builder.toString();
+        }
+
+        @Override
+        public final MethodVisitor visitMethod(int access, String name,
+                                               String desc, String signature,
+                                               String[] exceptions) {
+            MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
+                    exceptions);
+            if (targetDesc.equals(desc) && targetName.equals(name)) {
+                return new MethodVisitor(Opcodes.ASM5, mv) {
+                    @Override
+                    public void visitLineNumber(int i, Label label) {
+                        super.visitLineNumber(i, label);
+                        lineNumbers.put(label, i);
+                    }
+                };
+            }
+            return  mv;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @clean compiler.jvmci.compilerToVM.*
+ * @compile -g DummyInterface.java
+ * @compile -g DummyAbstractClass.java
+ * @compile -g DummyClass.java
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.GetLocalVariableTableTest
+ * @clean compiler.jvmci.compilerToVM.*
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+
+import java.lang.reflect.Executable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class GetLocalVariableTableTest {
+
+    public static final int MAIN_LOCALS_COUNT = 0;
+    public static final int INSTANCE_LOCALS_COUNT = 4;
+    public static final int EMPTY_INSTANCE_COUNT = 1;
+    public static final int EMPTY_STATIC_COUNT = 0;
+    public static final int ABSTRACT_INHERIT_LOCALS_COUNT = 2;
+    public static final int DEFAULTFUNC_LOCALS_COUNT = 4;
+
+    public static void main(String[] args) {
+        Map<Executable, Integer> testCases = createTestCases();
+        testCases.forEach(GetLocalVariableTableTest::runSanityTest);
+    }
+
+    private static Map<Executable, Integer> createTestCases() {
+        HashMap<Executable, Integer> methods = new HashMap<>();
+        try {
+            Class<?> aClass;
+
+            aClass = GetLocalVariableTableTest.class;
+            methods.put(aClass.getDeclaredMethod("main", String[].class),
+                    MAIN_LOCALS_COUNT);
+
+            aClass = DummyClass.class;
+            methods.put(aClass.getMethod("dummyInstanceFunction"),
+                    INSTANCE_LOCALS_COUNT);
+            methods.put(aClass.getMethod("dummyEmptyInstanceFunction"),
+                    EMPTY_INSTANCE_COUNT);
+            methods.put(aClass.getMethod("dummyEmptyStaticFunction"),
+                    EMPTY_STATIC_COUNT);
+            methods.put(aClass.getMethod("dummyFunction"),
+                    EMPTY_INSTANCE_COUNT);
+            methods.put(aClass.getMethod("dummyAbstractFunction"),
+                    ABSTRACT_INHERIT_LOCALS_COUNT);
+
+            aClass = DummyInterface.class;
+            methods.put(aClass.getMethod("dummyFunction"), EMPTY_STATIC_COUNT);
+            methods.put(aClass.getMethod("dummyDefaultFunction", int.class,
+                    int.class), DEFAULTFUNC_LOCALS_COUNT);
+
+            aClass = DummyAbstractClass.class;
+            methods.put(aClass.getMethod("dummyAbstractFunction"), 0);
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG", e);
+        }
+        return methods;
+    }
+
+    private static void runSanityTest(Executable aMethod,
+                                      Integer expectedTableLength) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+
+        int tblLength = CompilerToVMHelper.getLocalVariableTableLength(method);
+        Asserts.assertEQ(tblLength, expectedTableLength, aMethod + " : incorrect "
+                + "local variable table length.");
+
+        long tblStart = CompilerToVMHelper.getLocalVariableTableStart(method);
+        if (tblLength > 0) {
+            Asserts.assertNE(tblStart, 0L, aMethod + " : local variable table starts"
+                    + " at 0 with length " + tblLength);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetMaxCallTargetOffsetTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib/
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.GetMaxCallTargetOffsetTest
+ * @run main ClassFileInstaller
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetMaxCallTargetOffsetTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+
+public class GetMaxCallTargetOffsetTest {
+    public static void main(String args[]) {
+        new GetMaxCallTargetOffsetTest().runTest();
+    }
+
+    private void runTest() {
+        long offset1 = CompilerToVMHelper.getMaxCallTargetOffset(0L);
+        Asserts.assertNE(offset1, 0L,
+                "Unexpected maxCallTargetOffset for 0L");
+        long offset2 = CompilerToVMHelper.getMaxCallTargetOffset(100L);
+        Asserts.assertNE(offset2, 0L,
+                "Unexpected maxCallTargetOffset for 100L");
+        long offset3 = CompilerToVMHelper.getMaxCallTargetOffset(1000000L);
+        Asserts.assertNE(offset3, 0L,
+                "Unexpected maxCallTargetOffset for 1000000L");
+        // there can be 2 same offsets, but not 3
+        Asserts.assertFalse(offset1 == offset2 && offset2 == offset3,
+                "All 3 offsets are unexpectedly equal: " + offset1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *      -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetNextStackFrameTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.lang.reflect.Method;
+import jdk.vm.ci.hotspot.CompilerToVM;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotStackFrameReference;
+import jdk.test.lib.Asserts;
+
+public class GetNextStackFrameTest {
+    private static final int RECURSION_AMOUNT = 3;
+    private static final HotSpotResolvedJavaMethodImpl REC_FRAME_METHOD;
+    private static final HotSpotResolvedJavaMethodImpl FRAME1_METHOD;
+    private static final HotSpotResolvedJavaMethodImpl FRAME2_METHOD;
+    private static final HotSpotResolvedJavaMethodImpl FRAME3_METHOD;
+    private static final HotSpotResolvedJavaMethodImpl FRAME4_METHOD;
+    private static final HotSpotResolvedJavaMethodImpl RUN_METHOD;
+
+    static {
+        Method method;
+        try {
+            Class<?> aClass = GetNextStackFrameTest.class;
+            method = aClass.getDeclaredMethod("recursiveFrame", int.class);
+            REC_FRAME_METHOD = CTVMUtilities.getResolvedMethod(method);
+            method = aClass.getDeclaredMethod("frame1");
+            FRAME1_METHOD = CTVMUtilities.getResolvedMethod(method);
+            method = aClass.getDeclaredMethod("frame2");
+            FRAME2_METHOD = CTVMUtilities.getResolvedMethod(method);
+            method = aClass.getDeclaredMethod("frame3");
+            FRAME3_METHOD = CTVMUtilities.getResolvedMethod(method);
+            method = aClass.getDeclaredMethod("frame4");
+            FRAME4_METHOD = CTVMUtilities.getResolvedMethod(method);
+            method = Thread.class.getDeclaredMethod("run");
+            RUN_METHOD = CTVMUtilities.getResolvedMethod(Thread.class, method);
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG: can't find a test method", e);
+        }
+    }
+
+    public static void main(String[] args) {
+        new GetNextStackFrameTest().test();
+    }
+
+    private void test() {
+        // Create new thread to get new clean stack
+        Thread thread = new Thread(() -> recursiveFrame(RECURSION_AMOUNT));
+        thread.start();
+        try {
+            thread.join();
+        } catch (InterruptedException e) {
+            throw new Error("Interrupted while waiting to join", e);
+        }
+    }
+
+    // Helper methods for a longer stack
+    private void recursiveFrame(int recursionAmount) {
+        if (--recursionAmount != 0) {
+            recursiveFrame(recursionAmount);
+        } else {
+            frame1();
+        }
+    }
+
+    private void frame1() {
+        frame2();
+    }
+
+    private void frame2() {
+        frame3();
+    }
+
+    private void frame3() {
+        frame4();
+    }
+
+    private void frame4() {
+        check();
+    }
+
+    private void check() {
+        findFirst();
+        walkThrough();
+        skipAll();
+        findNextSkipped();
+        findYourself();
+    }
+
+    /**
+     * Finds the first topmost frame from the list of methods to search
+     */
+    private void findFirst() {
+        checkNextFrameFor(null /* topmost frame */,
+                new HotSpotResolvedJavaMethodImpl[]
+                        {FRAME2_METHOD, FRAME3_METHOD, FRAME4_METHOD},
+                FRAME4_METHOD, 0);
+    }
+
+    /**
+     * Walks through whole stack and checks that every frame could be found
+     * while going down the stack till the end
+     */
+    private void walkThrough() {
+        // Check that we would get a frame 4 starting from the topmost frame
+        HotSpotStackFrameReference nextStackFrame = checkNextFrameFor(
+                null /* topmost frame */,
+                new HotSpotResolvedJavaMethodImpl[] {FRAME4_METHOD},
+                FRAME4_METHOD, 0);
+        // Check that we would get a frame 3 starting from frame 4 when we try
+        // to search one of the next two frames
+        nextStackFrame = checkNextFrameFor(nextStackFrame,
+                new HotSpotResolvedJavaMethodImpl[] {FRAME3_METHOD,
+                        FRAME2_METHOD},
+                FRAME3_METHOD, 0);
+        // Check that we would get a frame 1
+        nextStackFrame = checkNextFrameFor(nextStackFrame,
+                new HotSpotResolvedJavaMethodImpl[] {FRAME1_METHOD},
+                FRAME1_METHOD, 0);
+        // Check that we would skip (RECURSION_AMOUNT - 1) methods and find a
+        // recursionFrame starting from frame 1
+        nextStackFrame = checkNextFrameFor(nextStackFrame,
+                new HotSpotResolvedJavaMethodImpl[] {REC_FRAME_METHOD},
+                REC_FRAME_METHOD, RECURSION_AMOUNT - 1);
+        // Check that we would get a Thread::run method frame;
+        nextStackFrame = checkNextFrameFor(nextStackFrame,
+                new HotSpotResolvedJavaMethodImpl[] {RUN_METHOD},
+                RUN_METHOD, 0);
+        // Check that there are no more frames after thread's run method
+        nextStackFrame = CompilerToVMHelper.getNextStackFrame(nextStackFrame,
+                null /* any */, 0);
+        Asserts.assertNull(nextStackFrame,
+                "Found stack frame after Thread::run");
+    }
+
+    /**
+     * Skips all frames to get null at the end of the stack
+     */
+    private void skipAll() {
+        // Skip all frames (stack size) + 2 (getNextStackFrame() itself
+        // and from CompilerToVMHelper)
+        int initialSkip = Thread.currentThread().getStackTrace().length + 2;
+        HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper
+                .getNextStackFrame(null /* topmost frame */, null /* any */,
+                        initialSkip);
+        Asserts.assertNull(nextStackFrame, "Unexpected frame");
+    }
+
+    /**
+     * Search for any frame skipping one frame
+     */
+    private void findNextSkipped() {
+        // Get frame 4
+        HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper
+                .getNextStackFrame(null /* topmost frame */,
+                        new HotSpotResolvedJavaMethodImpl[] {FRAME4_METHOD}, 0);
+        // Get frame 2 by skipping one method starting from frame 4
+        checkNextFrameFor(nextStackFrame, null /* any */,
+                FRAME2_METHOD , 1 /* skip one */);
+    }
+
+    /**
+     * Finds test method in the stack
+     */
+    private void findYourself() {
+        Method method;
+        try {
+            method = CompilerToVM.class.getDeclaredMethod("getNextStackFrame",
+                        HotSpotStackFrameReference.class,
+                        HotSpotResolvedJavaMethodImpl[].class, int.class);
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG: can't find getNextStackFrame method");
+        }
+        HotSpotResolvedJavaMethodImpl self
+                = CTVMUtilities.getResolvedMethod(CompilerToVM.class, method);
+        checkNextFrameFor(null /* topmost frame */, null /* any */, self, 0);
+    }
+
+    /**
+     * Searches next frame and checks that it equals to expected
+     *
+     * @param currentFrame  start frame to search from
+     * @param searchMethods a list of methods to search
+     * @param expected      expected frame
+     * @param skip          amount of frames to be skipped
+     * @return frame reference
+     */
+    private HotSpotStackFrameReference checkNextFrameFor(
+            HotSpotStackFrameReference currentFrame,
+            HotSpotResolvedJavaMethodImpl[] searchMethods,
+            HotSpotResolvedJavaMethodImpl expected,
+            int skip) {
+        HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper
+                .getNextStackFrame(currentFrame, searchMethods, skip);
+        Asserts.assertNotNull(nextStackFrame);
+        Asserts.assertTrue(nextStackFrame.isMethod(expected),
+                "Unexpected next frame: " + nextStackFrame
+                        + " from current frame: " + currentFrame);
+        return nextStackFrame;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodAtSlotTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.GetResolvedJavaMethodAtSlotTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import java.util.HashMap;
+import java.util.Map;
+
+public class GetResolvedJavaMethodAtSlotTest {
+
+    private static class A {
+        {
+            System.out.println("Dummy");
+        }
+        public void f1() {}
+        public int f2() { return 0; }
+        public String f3() { return ""; }
+    }
+
+
+    private static class S {
+        static {
+            System.out.println("Dummy static");
+        }
+        public S() {}
+        public void f1() {}
+        public int f2() { return 0; }
+        public String f3() { return ""; }
+    }
+
+    private class B extends A {
+        public void f4() {}
+    }
+
+    private interface I {
+        void f1();
+        int f2();
+        String f3();
+    }
+
+    public static void main(String[] args) {
+        Map<Class<?>, Integer> testCases = getTestCases();
+        testCases.forEach(GetResolvedJavaMethodAtSlotTest::test);
+    }
+
+    private static Map<Class<?>, Integer> getTestCases() {
+        Map<Class<?>, Integer> testCases = new HashMap<>();
+        testCases.put(A.class, 5); // ctor, init, f1, f2, f3
+        testCases.put(S.class, 5); // ctor, cinit, f1, f2, f3
+        testCases.put(I.class, 3); // f1, f2, f3
+        testCases.put(B.class, 2); // ctor, f4
+        return testCases;
+    }
+
+    private static void test(Class<?> aClass, int methodNumber) {
+        testSlotBigger(aClass);
+        testCorrectMethods(aClass, methodNumber);
+    }
+
+    private static void testSlotBigger(Class<?> holder) {
+        HotSpotResolvedJavaMethodImpl method
+                = CompilerToVMHelper.getResolvedJavaMethodAtSlot(holder, 50);
+        Asserts.assertNull(method, "Got method for non existing slot 50 in "
+                + holder);
+    }
+
+    private static void testCorrectMethods(Class<?> holder, int methodsNumber) {
+        for (int i = 0; i < methodsNumber; i++) {
+            HotSpotResolvedJavaMethodImpl method = CompilerToVMHelper
+                    .getResolvedJavaMethodAtSlot(holder, i);
+            Asserts.assertNotNull(method, "Did not got method for slot " + i
+                    + " in class " + holder.getCanonicalName());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.GetResolvedJavaMethodTest
+ * @run main ClassFileInstaller
+ *      sun.hotspot.WhiteBox
+ *      sun.hotspot.WhiteBox$WhiteBoxPermission
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *      -XX:+EnableJVMCI -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *      compiler.jvmci.compilerToVM.GetResolvedJavaMethodTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.MetaspaceWrapperObject;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+import sun.misc.Unsafe;
+
+import java.lang.reflect.Field;
+
+public class GetResolvedJavaMethodTest {
+    private static enum TestCase {
+        NULL_BASE {
+            @Override
+            HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
+                return CompilerToVMHelper.getResolvedJavaMethod(
+                        null, getPtrToMethod());
+            }
+        },
+        JAVA_METHOD_BASE {
+            @Override
+            HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
+                HotSpotResolvedJavaMethodImpl methodInstance
+                        = CompilerToVMHelper.getResolvedJavaMethodAtSlot(
+                       TEST_CLASS, 0);
+                Field field;
+                try {
+                    field = HotSpotResolvedJavaMethodImpl
+                            .class.getDeclaredField("metaspaceMethod");
+                    field.setAccessible(true);
+                    field.set(methodInstance, getPtrToMethod());
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TEST BUG : " + e, e);
+                }
+                return CompilerToVMHelper.getResolvedJavaMethod(
+                        methodInstance, 0L);
+            }
+        },
+        JAVA_METHOD_BASE_IN_TWO {
+            @Override
+            HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
+                long ptr = getPtrToMethod();
+                HotSpotResolvedJavaMethodImpl methodInstance
+                        = CompilerToVMHelper.getResolvedJavaMethodAtSlot(
+                        TEST_CLASS, 0);
+                Field field;
+                try {
+                    field = HotSpotResolvedJavaMethodImpl
+                            .class.getDeclaredField("metaspaceMethod");
+                    field.setAccessible(true);
+                    field.set(methodInstance, ptr / 2L);
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getResolvedJavaMethod(methodInstance,
+                        ptr - ptr / 2L);
+            }
+        },
+        JAVA_METHOD_BASE_ZERO {
+            @Override
+            HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
+                long ptr = getPtrToMethod();
+                HotSpotResolvedJavaMethodImpl methodInstance
+                        = CompilerToVMHelper.getResolvedJavaMethodAtSlot(
+                        TEST_CLASS, 0);
+                Field field;
+                try {
+                    field = HotSpotResolvedJavaMethodImpl
+                            .class.getDeclaredField("metaspaceMethod");
+                    field.setAccessible(true);
+                    field.set(methodInstance, 0L);
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getResolvedJavaMethod(methodInstance,
+                        ptr);
+            }
+        }
+        ;
+        abstract HotSpotResolvedJavaMethodImpl getResolvedJavaMethod();
+    }
+
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final Class<?> TEST_CLASS = GetResolvedJavaMethodTest.class;
+    private static final long PTR;
+    static  {
+        HotSpotResolvedJavaMethodImpl method
+                = CompilerToVMHelper.getResolvedJavaMethodAtSlot(TEST_CLASS, 0);
+        PTR = method.getMetaspacePointer();
+    }
+
+    private static long getPtrToMethod() {
+        Field field;
+        try {
+            field = TEST_CLASS.getDeclaredField("PTR");
+        } catch (NoSuchFieldException e) {
+            throw new Error("TEST BUG : " + e, e);
+        }
+        Object base = UNSAFE.staticFieldBase(field);
+        return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field);
+    }
+
+    public void test(TestCase testCase) {
+        System.out.println(testCase.name());
+        HotSpotResolvedJavaMethodImpl result = testCase.getResolvedJavaMethod();
+        Asserts.assertNotNull(result, testCase + " : got null");
+        Asserts.assertEQ(result.getDeclaringClass().mirror(), TEST_CLASS,
+                testCase + " : returned method has unexpected declaring class");
+    }
+
+    public static void main(String[] args) {
+        GetResolvedJavaMethodTest test = new GetResolvedJavaMethodTest();
+        for (TestCase testCase : TestCase.values()) {
+            test.test(testCase);
+        }
+        testObjectBase();
+        testMetaspaceWrapperBase();
+    }
+
+    private static void testMetaspaceWrapperBase() {
+        try {
+            HotSpotResolvedJavaMethodImpl method
+                    = CompilerToVMHelper.getResolvedJavaMethod(
+                            new MetaspaceWrapperObject() {
+                                @Override
+                                public long getMetaspacePointer() {
+                                    return getPtrToMethod();
+                                }
+                            }, 0L);
+            throw new AssertionError("Test METASPACE_WRAPPER_BASE."
+                    + " Expected IllegalArgumentException has not been caught");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+
+    private static void testObjectBase() {
+        try {
+            HotSpotResolvedJavaMethodImpl method
+                    = CompilerToVMHelper.getResolvedJavaMethod(new Object(), 0L);
+            throw new AssertionError("Test OBJECT_BASE."
+                + " Expected IllegalArgumentException has not been caught");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.GetResolvedJavaTypeTest
+ * @run main ClassFileInstaller
+ *      sun.hotspot.WhiteBox
+ *      sun.hotspot.WhiteBox$WhiteBoxPermission
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *      -XX:+EnableJVMCI -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *      -XX:+UseCompressedOops
+ *      compiler.jvmci.compilerToVM.GetResolvedJavaTypeTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *      -XX:+EnableJVMCI -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *      -XX:-UseCompressedOops
+ *      compiler.jvmci.compilerToVM.GetResolvedJavaTypeTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import java.lang.reflect.Field;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotConstantPool;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.MetaspaceWrapperObject;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+import sun.misc.Unsafe;
+
+public class GetResolvedJavaTypeTest {
+    private static enum TestCase {
+        NULL_BASE {
+            @Override
+            HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+                return CompilerToVMHelper.getResolvedJavaType(
+                        null, getPtrToKlass(), COMPRESSED);
+            }
+        },
+        JAVA_METHOD_BASE {
+            @Override
+            HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+                HotSpotResolvedJavaMethodImpl methodInstance
+                        = CompilerToVMHelper.getResolvedJavaMethodAtSlot(
+                        TEST_CLASS, 0);
+                Field field;
+                try {
+                    field = HotSpotResolvedJavaMethodImpl
+                            .class.getDeclaredField("metaspaceMethod");
+                    field.setAccessible(true);
+                    field.set(methodInstance, getPtrToKlass());
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TEST BUG : " + e, e);
+                }
+
+                return CompilerToVMHelper.getResolvedJavaType(methodInstance,
+                        0L, COMPRESSED);
+            }
+        },
+        CONSTANT_POOL_BASE {
+            @Override
+            HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+                HotSpotConstantPool cpInst;
+                try {
+                    cpInst = CompilerToVMHelper.getConstantPool(null,
+                            getPtrToKlass());
+                    Field field = HotSpotConstantPool.class
+                            .getDeclaredField("metaspaceConstantPool");
+                    field.setAccessible(true);
+                    field.set(cpInst, getPtrToKlass());
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getResolvedJavaType(cpInst,
+                        0L, COMPRESSED);
+            }
+        },
+        CONSTANT_POOL_BASE_IN_TWO {
+            @Override
+            HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+                long ptr = getPtrToKlass();
+                HotSpotConstantPool cpInst = HotSpotResolvedObjectTypeImpl
+                        .fromObjectClass(TEST_CLASS).getConstantPool();
+                try {
+                    Field field = HotSpotConstantPool.class
+                            .getDeclaredField("metaspaceConstantPool");
+                    field.setAccessible(true);
+                    field.set(cpInst, ptr / 2L);
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getResolvedJavaType(cpInst,
+                        ptr - ptr / 2L, COMPRESSED);
+            }
+        },
+        CONSTANT_POOL_BASE_ZERO {
+            @Override
+            HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+                long ptr = getPtrToKlass();
+                HotSpotConstantPool cpInst = HotSpotResolvedObjectTypeImpl
+                        .fromObjectClass(TEST_CLASS).getConstantPool();
+                try {
+                    Field field = HotSpotConstantPool.class
+                            .getDeclaredField("metaspaceConstantPool");
+                    field.setAccessible(true);
+                    field.set(cpInst, 0L);
+                } catch (ReflectiveOperationException e) {
+                    throw new Error("TESTBUG : " + e.getMessage(), e);
+                }
+                return CompilerToVMHelper.getResolvedJavaType(cpInst,
+                        ptr, COMPRESSED);
+            }
+        },
+        OBJECT_TYPE_BASE {
+            @Override
+            HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+                HotSpotResolvedObjectTypeImpl type
+                        = HotSpotResolvedObjectTypeImpl.fromObjectClass(
+                        OBJECT_TYPE_BASE.getClass());
+                long ptrToClass = UNSAFE.getKlassPointer(OBJECT_TYPE_BASE);
+                return CompilerToVMHelper.getResolvedJavaType(type,
+                        getPtrToKlass() - ptrToClass, COMPRESSED);
+            }
+        },
+        ;
+        abstract HotSpotResolvedObjectTypeImpl getResolvedJavaType();
+    }
+
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final long PTR = UNSAFE.getKlassPointer(
+            new GetResolvedJavaTypeTest());
+    private static final Class TEST_CLASS = GetResolvedJavaTypeTest.class;
+    /* a compressed parameter for tested method is set to false because
+       unsafe.getKlassPointer always returns uncompressed pointer */
+    private static final boolean COMPRESSED = false;
+            // = WB.getBooleanVMFlag("UseCompressedClassPointers");
+
+    private static long getPtrToKlass() {
+        Field field;
+        try {
+            field = TEST_CLASS.getDeclaredField("PTR");
+        } catch (NoSuchFieldException e) {
+            throw new Error("TEST BUG : " + e, e);
+        }
+        Object base = UNSAFE.staticFieldBase(field);
+        return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field);
+    }
+
+    public void test(TestCase testCase) {
+        System.out.println(testCase.name());
+        HotSpotResolvedObjectTypeImpl type = testCase.getResolvedJavaType();
+        Asserts.assertEQ(type.mirror(), TEST_CLASS, testCase +
+                        " Unexpected Class returned by getResolvedJavaType");
+    }
+
+    public static void main(String[] args) {
+        GetResolvedJavaTypeTest test = new GetResolvedJavaTypeTest();
+        for (TestCase testCase : TestCase.values()) {
+            test.test(testCase);
+        }
+        testObjectBase();
+        testMetaspaceWrapperBase();
+    }
+
+    private static void testMetaspaceWrapperBase() {
+        try {
+            HotSpotResolvedObjectTypeImpl type
+                    = CompilerToVMHelper.getResolvedJavaType(
+                            new MetaspaceWrapperObject() {
+                                @Override
+                                public long getMetaspacePointer() {
+                                    return getPtrToKlass();
+                                }
+                            }, 0L, COMPRESSED);
+            throw new AssertionError("Test METASPACE_WRAPPER_BASE."
+                    + " Expected IllegalArgumentException has not been caught");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+
+    private static void testObjectBase() {
+        try {
+            HotSpotResolvedObjectTypeImpl type
+                    = CompilerToVMHelper.getResolvedJavaType(new Object(), 0L,
+                            COMPRESSED);
+            throw new AssertionError("Test OBJECT_BASE."
+                + " Expected IllegalArgumentException has not been caught");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -Xbootclasspath/a:. compiler.jvmci.compilerToVM.GetStackTraceElementTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+
+public class GetStackTraceElementTest {
+
+    public static void main(String[] args) {
+        Map<Executable, int[]> testCases = createTestCases();
+        testCases.forEach(GetStackTraceElementTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod, int[] bcis) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        String className = aMethod.getDeclaringClass().getName();
+        int lastDot = className.lastIndexOf('.');
+        int firstDol = className.contains("$")
+                ? className.indexOf('$')
+                : className.length();
+        String fileName = className.substring(lastDot + 1, firstDol) + ".java";
+        for (int bci : bcis) {
+            StackTraceElement ste = CompilerToVMHelper
+                    .getStackTraceElement(method, bci);
+            Asserts.assertNotNull(ste);
+            Asserts.assertEQ(ste.getClassName(), className);
+            Asserts.assertEQ(ste.getFileName(), fileName);
+            Asserts.assertEQ(ste.getMethodName(), aMethod.getName());
+            Asserts.assertEQ(ste.isNativeMethod(), Modifier
+                    .isNative(aMethod.getModifiers()));
+        }
+
+    }
+
+    private static Map<Executable, int[]> createTestCases() {
+        Map<Executable, int[]> testCases = new HashMap<>();
+
+        try {
+            Class<?> aClass = DummyClass.class;
+            Method aMethod = aClass.getDeclaredMethod("dummyInstanceFunction");
+            int[] bci = new int[] {0, 2, 3, 6, 7, 8, 11, 13, 15, 16, 17, 18};
+            testCases.put(aMethod, bci);
+
+            aMethod = aClass.getDeclaredMethod("dummyEmptyFunction");
+            bci = new int[] {0};
+            testCases.put(aMethod, bci);
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG : test method not found", e);
+        }
+        return testCases;
+    }
+
+    private class DummyClass {
+        public int dummyInstanceFunction() {
+            String str1 = "123123123";
+            double x = 3.14;
+            int y = Integer.parseInt(str1);
+
+            return y / (int)x;
+        }
+
+        public void dummyEmptyFunction() {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetSymbolTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.GetSymbolTest
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ *                              compiler.jvmci.common.testcases.SingleImplementer
+ *                              compiler.jvmci.common.testcases.SingleImplementerInterface
+ *                              compiler.jvmci.compilerToVM.GetSymbolTest
+ *                              compiler.jvmci.common.CTVMUtilities
+ *                              jdk.test.lib.Utils
+ *                              jdk.test.lib.Asserts
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -Xbootclasspath/a:. compiler.jvmci.compilerToVM.GetSymbolTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.SingleImplementer;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.test.lib.Utils;
+
+public class GetSymbolTest {
+    private static final int CONSTANT_POOL_UTF8_TAG = 1; // see jvms, section 4.4
+
+    private static final Function<Member[], List<String>> NAMES = members ->
+            Stream.of(members)
+                    .map(Member::getName)
+                    .collect(Collectors.toList());
+
+    public static void main(String[] args) {
+        new GetSymbolTest().test(SingleImplementer.class);
+    }
+
+    private void test(Class<?> aClass) {
+        Utils.ensureClassIsLoaded(aClass);
+        Method method;
+        try {
+            method = aClass.getDeclaredMethod("nonInterfaceMethod");
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG: can't find test method", e);
+        }
+        HotSpotResolvedJavaMethodImpl resolvedMethod
+                = CTVMUtilities.getResolvedMethod(aClass, method);
+        List<String> symbols;
+        try {
+            symbols = getSymbols(resolvedMethod);
+        } catch (ReflectiveOperationException e) {
+            throw new Error("TEST BUG: can't access private members", e);
+        }
+        List<String> classSymbols = new ArrayList<>();
+        classSymbols.addAll(NAMES.apply(aClass.getDeclaredFields()));
+        classSymbols.addAll(NAMES.apply(aClass.getDeclaredMethods()));
+        // Check that all members of test class have symbols from constant pool
+        for (String s : classSymbols) {
+            if (!symbols.contains(s)) {
+                // failed. print all symbols found by getSymbol
+                System.out.println("getSymbol data:");
+                for (String ctvmValue : symbols) {
+                    System.out.println(ctvmValue);
+                }
+                throw new AssertionError("Unable to find symbol " + s
+                        + " using CompilerToVM.getSymbol");
+            }
+        }
+    }
+
+    private List<String> getSymbols(HotSpotResolvedJavaMethodImpl
+            metaspaceMethod) throws ReflectiveOperationException {
+        List<String> symbols = new ArrayList<>();
+        ConstantPool pool = metaspaceMethod.getConstantPool();
+        long length = pool.length();
+        // jvms-4.1: The constant_pool table is indexed from 1 ...
+        for (int i = 1; i < length; i++) {
+            if (getTag(pool, i) == CONSTANT_POOL_UTF8_TAG) {
+                long entryPointer;
+                Method getEntryAt = pool.getClass()
+                        .getDeclaredMethod("getEntryAt", int.class);
+                getEntryAt.setAccessible(true);
+                entryPointer = (Long) getEntryAt.invoke(pool, i);
+                String symbol = CompilerToVMHelper.getSymbol(entryPointer);
+                symbols.add(symbol);
+            }
+        }
+        return symbols;
+    }
+
+    private int getTag(ConstantPool pool, int index)
+            throws ReflectiveOperationException {
+        Object jvmConstant;
+        Method getTag = pool.getClass().getDeclaredMethod("getTagAt",
+                int.class);
+        getTag.setAccessible(true);
+        jvmConstant = getTag.invoke(pool, index);
+        Field tagCode = jvmConstant.getClass().getDeclaredField("tag");
+        tagCode.setAccessible(true);
+        return tagCode.getInt(jvmConstant);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.GetVtableIndexForInterfaceTest
+ * @run main ClassFileInstaller
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetVtableIndexForInterfaceTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.AbstractClass;
+import compiler.jvmci.common.testcases.DoNotExtendClass;
+import compiler.jvmci.common.testcases.MultipleAbstractImplementer;
+import compiler.jvmci.common.testcases.MultipleImplementersInterface;
+import compiler.jvmci.common.testcases.MultipleImplementersInterfaceExtender;
+import compiler.jvmci.common.testcases.SingleImplementer;
+import compiler.jvmci.common.testcases.SingleImplementerInterface;
+import compiler.jvmci.common.testcases.SingleSubclass;
+import compiler.jvmci.common.testcases.SingleSubclassedClass;
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.AnotherSingleImplementer;
+import compiler.jvmci.common.testcases.AnotherSingleImplementerInterface;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+public class GetVtableIndexForInterfaceTest {
+    private static final int INVALID_VTABLE_INDEX = -4; // see method.hpp: VtableIndexFlag
+
+    public static void main(String args[]) {
+        GetVtableIndexForInterfaceTest test
+                = new GetVtableIndexForInterfaceTest();
+        try {
+            for (TestCase tcase : createTestCases()) {
+                test.runTest(tcase);
+            }
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG: can't find requested method", e);
+        }
+    }
+
+    private static Set<TestCase> createTestCases() {
+        Set<TestCase> result = new HashSet<>();
+        Stream.of(
+                    AbstractClass.class,
+                    SingleImplementer.class,
+                    SingleImplementerInterface.class,
+                    MultipleImplementersInterface.class,
+                    MultipleImplementersInterfaceExtender.class,
+                    SingleSubclass.class,
+                    SingleSubclassedClass.class,
+                    DoNotExtendClass.class,
+                    MultipleAbstractImplementer.class
+                )
+                .forEach(Utils::ensureClassIsLoaded);
+        // non iface method
+        result.add(new TestCase(SingleImplementer.class,
+                SingleImplementer.class, "nonInterfaceMethod",
+                false, InternalError.class));
+        // iface method w/o default implementation
+        result.add(new TestCase(SingleImplementer.class,
+                SingleImplementerInterface.class, "interfaceMethod", false));
+        /* another iface which provides default implementation for the
+           original iface*/
+        result.add(new TestCase(MultipleImplementersInterfaceExtender.class,
+                MultipleImplementersInterface.class, "testMethod", false,
+                InternalError.class));
+        // iface method w/ default implementation
+        result.add(new TestCase(SingleImplementer.class,
+                SingleImplementerInterface.class, "defaultMethod", true));
+        // non iface class
+        result.add(new TestCase(SingleSubclass.class,
+                SingleSubclassedClass.class, "inheritedMethod", false,
+                InternalError.class));
+        // class not implementing iface
+        result.add(new TestCase(DoNotExtendClass.class,
+                SingleImplementerInterface.class, "defaultMethod", false));
+        // abstract class which doesn't implement iface
+        result.add(new TestCase(AbstractClass.class,
+                SingleImplementerInterface.class, "defaultMethod", false));
+        // abstract class which implements iface
+        result.add(new TestCase(MultipleAbstractImplementer.class,
+                MultipleImplementersInterface.class, "defaultMethod", true));
+        // class not initialized
+        result.add(new TestCase(AnotherSingleImplementer.class,
+                AnotherSingleImplementerInterface.class, "defaultMethod",
+                false, InternalError.class));
+        return result;
+    }
+
+    private void runTest(TestCase tcase) throws NoSuchMethodException {
+        System.out.println(tcase);
+        Method method = tcase.holder.getDeclaredMethod(tcase.methodName);
+        HotSpotResolvedObjectTypeImpl metaspaceKlass = CompilerToVMHelper
+                .lookupType(Utils.toJVMTypeSignature(tcase.receiver),
+                        getClass(), /* resolve = */ true);
+        HotSpotResolvedJavaMethodImpl metaspaceMethod = CTVMUtilities
+                .getResolvedMethod(tcase.holder, method);
+        int index = 0;
+        try {
+            index = CompilerToVMHelper
+                    .getVtableIndexForInterfaceMethod(metaspaceKlass,
+                            metaspaceMethod);
+        } catch (Throwable t) {
+            if (tcase.isPositive || tcase.expectedException == null) {
+                throw new Error("Caught unexpected exception " + t);
+            }
+            if (!tcase.expectedException.equals(t.getClass())) {
+                throw new Error(String.format("Caught %s while expected %s",
+                        t.getClass().getName(),
+                        tcase.expectedException.getName()));
+            }
+            return;
+        }
+        if (tcase.expectedException != null) {
+            throw new AssertionError("Expected exception wasn't caught: "
+                    + tcase.expectedException.getName());
+        }
+        if (tcase.isPositive) {
+            Asserts.assertNE(index, INVALID_VTABLE_INDEX,
+                    "Unexpected: got invalid index");
+        } else {
+            Asserts.assertEQ(index, INVALID_VTABLE_INDEX,
+                    "Unexpected: got valid index ");
+        }
+    }
+
+    private static class TestCase {
+        public final Class<?> receiver;
+        public final Class<?> holder;
+        public final String methodName;
+        public final boolean isPositive;
+        public final Class<? extends Throwable> expectedException;
+
+        public TestCase(Class<?> receiver, Class<?> holder, String methodName,
+                boolean isPositive,
+                Class<? extends Throwable> expectedException) {
+            this.receiver = receiver;
+            this.holder = holder;
+            this.methodName = methodName;
+            this.isPositive = isPositive;
+            this.expectedException = expectedException;
+        }
+
+        public TestCase(Class<?> receiver, Class<?> holder, String methodName,
+                boolean isPositive) {
+            this(receiver, holder, methodName, isPositive, null);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("CASE: receiver=%s, holder=%s, method=%s,"
+                    + " isPositive=%s%n", receiver.getName(), holder.getName(),
+                    methodName, isPositive);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      -XX:-BackgroundCompilation
+ *      compiler.jvmci.compilerToVM.HasCompiledCodeForOSRTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import compiler.testlibrary.CompilerUtils;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+import sun.hotspot.code.NMethod;
+
+public class HasCompiledCodeForOSRTest {
+    public static void main(String[] args) {
+        List<CompileCodeTestCase>testCases = createTestCases();
+        testCases.forEach(HasCompiledCodeForOSRTest::runSanityTest);
+    }
+
+    public static List<CompileCodeTestCase> createTestCases() {
+        List<CompileCodeTestCase> testCases = new ArrayList<>();
+
+        try {
+            Class<?> aClass = DummyClass.class;
+            testCases.add(new CompileCodeTestCase(
+                    aClass.getMethod("withLoop"), 17));
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG : " + e.getMessage(), e);
+        }
+        return testCases;
+    }
+
+    private static void runSanityTest(CompileCodeTestCase testCase) {
+        System.out.println(testCase);
+        Executable aMethod = testCase.executable;
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        testCase.deoptimize();
+        int[] levels = CompilerUtils.getAvailableCompilationLevels();
+        // not compiled
+        for (int level : levels) {
+            boolean isCompiled = CompilerToVMHelper.hasCompiledCodeForOSR(
+                    method, testCase.bci, level);
+            Asserts.assertFalse(isCompiled, String.format(
+                    "%s : unexpected return value for non-compiled method at "
+                            + "level %d", testCase, level));
+        }
+        NMethod nm = testCase.compile();
+        if (nm == null) {
+            throw new Error(String.format(
+                    "TEST BUG : %s : cannot compile method", testCase));
+        }
+
+        boolean isCompiled;
+        int level = nm.comp_level;
+        for (int i : levels) {
+            isCompiled = CompilerToVMHelper.hasCompiledCodeForOSR(
+                    method, testCase.bci, i);
+            Asserts.assertEQ(isCompiled, level == i, String.format(
+                    "%s : unexpected return value for compiled method at "
+                            + "level %d", testCase, i));
+        }
+
+        for (int i : new int[] {-1, +1}) {
+            int bci = testCase.bci + i;
+            isCompiled = CompilerToVMHelper.hasCompiledCodeForOSR(
+                    method, bci, level);
+            Asserts.assertFalse(isCompiled, String.format(
+                    "%s : unexpected return value for compiled method at "
+                            + "level %d with bci = %d ",
+                    testCase, level, bci));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.HasFinalizableSubclassTest
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.HasFinalizableSubclassTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.AbstractClass;
+import compiler.jvmci.common.testcases.AbstractClassExtender;
+import compiler.jvmci.common.testcases.DoNotImplementInterface;
+import compiler.jvmci.common.testcases.MultipleImplementer1;
+import compiler.jvmci.common.testcases.MultipleImplementersInterface;
+import compiler.jvmci.common.testcases.SingleImplementerInterface;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+public class HasFinalizableSubclassTest {
+    public static void main(String args[]) {
+        HasFinalizableSubclassTest test = new HasFinalizableSubclassTest();
+        for (TestCase tcase : createTestCases()) {
+            test.runTest(tcase);
+        }
+    }
+
+    private static Set<TestCase> createTestCases() {
+        Stream.of(
+                    AbstractClassExtender.class,
+                    SingleImplementerInterface.class,
+                    MultipleImplementersInterface.class,
+                    MultipleImplementer1.class,
+                    DoNotImplementInterface.class)
+                .forEach(Utils::ensureClassIsLoaded);
+        Set<TestCase> result = new HashSet<>();
+        // iface with finalize method
+        result.add(new TestCase(SingleImplementerInterface.class, false));
+        // iface with default finalize method
+        result.add(new TestCase(MultipleImplementersInterface.class, false));
+        // class which implements iface w/ default finalize method
+        result.add(new TestCase(MultipleImplementer1.class, true));
+        // abstract class with finalizeable subclass
+        result.add(new TestCase(AbstractClass.class, true));
+        // non-implemented iface
+        result.add(new TestCase(DoNotImplementInterface.class, false));
+        return result;
+    }
+
+    private void runTest(TestCase tcase) {
+        System.out.println(tcase);
+        HotSpotResolvedObjectTypeImpl metaspaceKlass = CompilerToVMHelper
+                .lookupType(Utils.toJVMTypeSignature(tcase.aClass),
+                        getClass(), /* resolve = */ true);
+        Asserts.assertEQ(tcase.expected,
+                CompilerToVMHelper.hasFinalizableSubclass(metaspaceKlass),
+                        "Unexpected finalizableSubclass state for "
+                                + tcase.aClass.getName());
+    }
+
+    private static class TestCase {
+        public final Class<?> aClass;
+        public final boolean expected;
+
+        public TestCase(Class<?> clazz, boolean expected) {
+            this.aClass = clazz;
+            this.expected = expected;
+        }
+        @Override
+        public String toString() {
+            return "CASE: class= " + aClass.getName() + ", expected=" + expected;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/InitializeConfigurationTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.InitializeConfigurationTest
+ * @run main ClassFileInstaller
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:.
+ *     -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     compiler.jvmci.compilerToVM.InitializeConfigurationTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.function.Consumer;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import sun.misc.Unsafe;
+
+public class InitializeConfigurationTest {
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+
+    public static void main(String args[]) {
+        new InitializeConfigurationTest().runTest(generateTestCases());
+    }
+
+    private static List<TestCase> generateTestCases() {
+        List<TestCase> result = new ArrayList<>();
+        result.add(new TestCase("CodeCache", "_high_bound", "address",
+                InitializeConfigurationTest::verifyLongIsNotZero));
+        result.add(new TestCase("StubRoutines", "_jint_arraycopy", "address",
+                InitializeConfigurationTest::verifyLongIsNotZero));
+        return result;
+    }
+
+    private static void verifyLongIsNotZero(Object o) {
+        Asserts.assertNotNull(o, "Got null value");
+        Asserts.assertEQ(o.getClass(), Long.class, "Unexpected value type");
+        Asserts.assertNE(o, 0L, "Got null address");
+    }
+
+    private void runTest(List<TestCase> tcases) {
+        VMStructDataReader reader = new VMStructDataReader(
+                CompilerToVMHelper.initializeConfiguration());
+        while (reader.hasNext()) {
+            VMFieldData data = reader.next();
+            for (TestCase tcase : tcases) {
+                tcase.check(data);
+            }
+        }
+        // now check if all passed
+        for (TestCase tcase: tcases) {
+            Asserts.assertTrue(tcase.isFound(), "Case failed: " + tcase);
+        }
+    }
+
+    private static class VMStructDataReader implements Iterator<VMFieldData> {
+        // see jvmciCompilerToVM:105 static uintptr_t ciHotSpotVMData[28];
+        private static final int HOTSPOT_VM_DATA_INDEX_COUNT = 28;
+        private final long addresses[];
+        private final long vmStructsBase;
+        private final long entityNameFieldOffset;
+        private final long nameFieldOffset;
+        private final long typeStringFieldOffset;
+        private final long addressOffset;
+        private final long entrySize;
+        private long nextElementAddress;
+        private VMFieldData nextElement;
+
+        public VMStructDataReader(long gHotSpotVMData) {
+            Asserts.assertNE(gHotSpotVMData, 0L, "Got null base address");
+            addresses = new long[HOTSPOT_VM_DATA_INDEX_COUNT];
+            for (int i = 0; i < HOTSPOT_VM_DATA_INDEX_COUNT; i++) {
+                addresses[i] = UNSAFE.getAddress(
+                        gHotSpotVMData + Unsafe.ADDRESS_SIZE * i);
+            }
+            vmStructsBase = addresses[0];
+            entityNameFieldOffset = addresses[1];
+            nameFieldOffset = addresses[2];
+            typeStringFieldOffset = addresses[3];
+            addressOffset = addresses[6];
+            entrySize = addresses[7];
+            nextElementAddress = vmStructsBase;
+            nextElement = read();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return nextElement != null;
+        }
+
+        @Override
+        public VMFieldData next() {
+            if (nextElement == null) {
+                throw new NoSuchElementException("Next element is null");
+            }
+            VMFieldData toReturn = nextElement;
+            nextElementAddress += entrySize;
+            nextElement = read();
+            return toReturn;
+        }
+
+        private VMFieldData read() {
+            String entityFieldName = readCString(
+                    UNSAFE.getAddress(nextElementAddress + nameFieldOffset));
+            if (entityFieldName == null) {
+                return null;
+            }
+            String fieldType = readCString(UNSAFE.getAddress(
+                    nextElementAddress + typeStringFieldOffset));
+            String entityName = readCString(UNSAFE.getAddress(
+                    nextElementAddress + entityNameFieldOffset));
+            Object value;
+            if ("address".equals(fieldType)) {
+                long address = UNSAFE.getAddress(
+                        nextElementAddress + addressOffset);
+                value = address;
+            } else {
+                // non-address cases are not supported
+                value = null;
+            }
+            return new VMFieldData(entityName, entityFieldName, fieldType,
+                    value);
+        }
+
+        private static String readCString(long address) {
+            if (address == 0) {
+                return null;
+            }
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0;; i++) {
+                char c = (char) UNSAFE.getByte(address + i);
+                if (c == 0) {
+                    break;
+                }
+                sb.append(c);
+            }
+            return sb.toString();
+        }
+    }
+
+    private static class VMFieldData {
+        public final String entityFieldName;
+        public final String entityName;
+        public final String fieldType;
+        public final Object value;
+
+        private VMFieldData(String entityName, String entityFieldName,
+                String fieldType, Object value) {
+            this.entityName = entityName;
+            this.entityFieldName = entityFieldName;
+            this.fieldType = fieldType;
+            this.value = value;
+        }
+    }
+
+    private static class TestCase {
+        public final String entityName;
+        public final String fieldType;
+        public final String entityFieldName;
+        public final Consumer consumer;
+        private boolean found;
+
+        public TestCase(String entityName, String entityFieldName,
+                String fieldType, Consumer predicate) {
+            Objects.requireNonNull(entityName, "Got null entityName");
+            Objects.requireNonNull(entityFieldName, "Got null entityFieldName");
+            Objects.requireNonNull(fieldType, "Got null type");
+            if (!"address".equals(fieldType)) {
+                throw new Error("TESTBUG: unsupported testcase with fieldType="
+                        + fieldType);
+            }
+            this.entityName = entityName;
+            this.fieldType = fieldType;
+            this.entityFieldName = entityFieldName;
+            this.consumer = predicate;
+            this.found = false;
+        }
+
+        public void check(VMFieldData data) {
+            if (entityFieldName.equals(data.entityFieldName)
+                    && entityName.equals(data.entityName)
+                    && fieldType.equals(data.fieldType)) {
+                Asserts.assertFalse(found, "Found 2 entries of " + this);
+                found = true;
+                consumer.accept(data.value);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "CASE: entityName=" + entityName + " entityFieldName="
+                    + entityFieldName + " fieldType=" + fieldType;
+        }
+
+        public boolean isFound() {
+            return found;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @ignore 8139700
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ *        compiler.jvmci.compilerToVM.InvalidateInstalledCodeTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.InvalidateInstalledCodeTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import sun.hotspot.code.NMethod;
+
+import java.util.List;
+
+public class InvalidateInstalledCodeTest {
+    public static void main(String[] args) {
+        InvalidateInstalledCodeTest test
+                = new InvalidateInstalledCodeTest();
+        List<CompileCodeTestCase> testCases
+                = CompileCodeTestCase.generate(/* bci = */ 0);
+        testCases.addAll(CompileCodeTestCase.generate(/* bci = */ -1));
+        testCases.forEach(test::check);
+        test.checkNull();
+    }
+
+    private void checkNull() {
+        InstalledCode installedCode = new InstalledCode("<null>");
+        installedCode.setAddress(0);
+        CompilerToVMHelper.invalidateInstalledCode(installedCode);
+    }
+
+    private void check(CompileCodeTestCase testCase) {
+        System.out.println(testCase);
+        // to have a clean state
+        NMethod beforeInvalidation = testCase.deoptimizeAndCompile();
+        if (beforeInvalidation == null) {
+            throw new Error("method is not compiled, testCase " + testCase);
+        }
+
+        // run twice to verify how it works if method is already invalidated
+        for (int i = 0; i < 2; ++i) {
+            InstalledCode installedCode = new InstalledCode(
+                    testCase.executable.getName());
+            installedCode.setAddress(beforeInvalidation.address);
+
+            CompilerToVMHelper.invalidateInstalledCode(installedCode);
+            NMethod afterInvalidation = testCase.toNMethod();
+            if (afterInvalidation != null) {
+                System.err.println("before: " + beforeInvalidation);
+                System.err.println("after: " + afterInvalidation);
+                throw new AssertionError(testCase
+                        + " : method hasn't been invalidated, i = " + i);
+            }
+            Asserts.assertFalse(installedCode.isValid(), testCase
+                            + " : code is valid after invalidation, i = " + i);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/IsMatureTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox IsMatureTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *     -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     compiler.jvmci.compilerToVM.IsMatureTest
+ */
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.SimpleClass;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+import java.lang.reflect.Executable;
+
+public class IsMatureTest {
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) throws Exception {
+        new IsMatureTest().test();
+    }
+
+    public void test() throws Exception {
+        SimpleClass sclass = new SimpleClass();
+        Executable method = SimpleClass.class.getDeclaredMethod("testMethod");
+        long metaspaceMethodData = WB.getMethodData(method);
+        Asserts.assertEQ(metaspaceMethodData, 0L, "MDO should be null for "
+                 + "never invoked method");
+        boolean isMature = CompilerToVMHelper.isMature(metaspaceMethodData);
+        Asserts.assertFalse(isMature, "null MDO can't be mature");
+        for (int i = 0; i < 1000; i++) {
+            sclass.testMethod();
+        }
+        // warmed up, mdo should be ready for now
+        metaspaceMethodData = WB.getMethodData(method);
+        Asserts.assertNE(metaspaceMethodData, 0L,
+                "MDO should be available after 1000 calls");
+        for (int i = 0; i < 100_000; i++) {
+            sclass.testMethod();
+        }
+        isMature = CompilerToVMHelper.isMature(metaspaceMethodData);
+        Asserts.assertTrue(isMature,
+                "a 100_000 times invoked method should be mature");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *      -Dcompiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives.positive=true
+ *      -XX:+EnableJVMCI
+ *      compiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *      -Dcompiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives.positive=false
+ *      -XX:-EnableJVMCI
+ *      compiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives
+
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVM;
+import jdk.vm.ci.runtime.JVMCI;
+import jdk.test.lib.Asserts;
+
+import java.lang.reflect.Method;
+
+public class JVM_RegisterJVMCINatives {
+    private static final boolean IS_POSITIVE = Boolean.getBoolean(
+            "compiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives.positive");
+
+    private final Method registerNatives;
+
+    public static void main(String[] args) {
+        new JVM_RegisterJVMCINatives().runTest();
+    }
+
+    private void runTest() {
+        Object result;
+        try {
+            result = invoke();
+        } catch (InternalError e) {
+            if (IS_POSITIVE) {
+                throw new AssertionError("unexpected exception", e);
+            }
+            return;
+        }
+        if (!IS_POSITIVE) {
+            throw new AssertionError("didn't get expected exception");
+        }
+        Asserts.assertNull(result,
+                "registerNatives()V returned non-null");
+        Asserts.assertEQ(result, invoke(),
+                "registerNatives returns different results");
+
+    }
+    private Object invoke() {
+        Object result;
+        try {
+            result = registerNatives.invoke(JVMCI.class);
+        } catch (ReflectiveOperationException e) {
+            throw new Error("can't invoke registerNatives", e);
+        }
+        return result;
+    }
+
+    private JVM_RegisterJVMCINatives() {
+        Method method;
+        try {
+            method = CompilerToVM.class.getDeclaredMethod("registerNatives");
+            method.setAccessible(true);
+        } catch (NoSuchMethodException e) {
+            throw new Error("can't find CompilerToVM::registerNatives", e);
+        }
+        registerNatives = method;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @summary Testing compiler.jvmci.CompilerToVM.lookupKlassInPool method
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.common.testcases.MultipleImplementersInterface
+ *        compiler.jvmci.common.testcases.MultipleImplementer2
+ *        compiler.jvmci.compilerToVM.ConstantPoolTestsHelper
+ *        compiler.jvmci.compilerToVM.ConstantPoolTestCase
+ *        compiler.jvmci.compilerToVM.LookupKlassInPoolTest
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *                   -XX:+EnableJVMCI compiler.jvmci.compilerToVM.LookupKlassInPoolTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import java.util.HashMap;
+import java.util.Map;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotConstantPool;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import sun.reflect.ConstantPool;
+
+/**
+ * Test for {@code compiler.jvmci.CompilerToVM.lookupKlassInPool} method
+ */
+public class LookupKlassInPoolTest {
+
+    public static void main(String[] args)  {
+        Map<ConstantPoolTestsHelper.ConstantTypes,
+                ConstantPoolTestCase.Validator> typeTests = new HashMap<>(1);
+        typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_CLASS,
+                LookupKlassInPoolTest::validate);
+        ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests);
+        testCase.test();
+    }
+
+    public static void validate(HotSpotConstantPool constantPoolCTVM,
+            ConstantPool constantPoolSS,
+            ConstantPoolTestsHelper.DummyClasses dummyClass, int i) {
+        Object classToVerify = CompilerToVMHelper
+                .lookupKlassInPool(constantPoolCTVM, i);
+        if (!(classToVerify instanceof HotSpotResolvedObjectTypeImpl)
+                && !(classToVerify instanceof String)) {
+            String msg = String.format("Output of method"
+                    + " CTVM.lookupKlassInPool is neither"
+                    + " a HotSpotResolvedObjectTypeImpl, nor a String");
+            throw new AssertionError(msg);
+        }
+        int classNameIndex = (int) dummyClass.cp.get(i).value;
+        String classNameToRefer
+                = constantPoolSS.getUTF8At(classNameIndex);
+        String outputToVerify = classToVerify.toString();
+        if (!outputToVerify.contains(classNameToRefer)) {
+            String msg = String.format("Wrong class accessed by constant"
+                    + " pool index %d: %s, but should be %s",
+                    i, outputToVerify, classNameToRefer);
+            throw new AssertionError(msg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupTypeTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.LookupTypeTest
+ * @run main ClassFileInstaller
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.LookupTypeTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.DoNotExtendClass;
+import compiler.jvmci.common.testcases.MultiSubclassedClass;
+import compiler.jvmci.common.testcases.SingleSubclass;
+import java.util.HashSet;
+import java.util.Set;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+public class LookupTypeTest {
+    public static void main(String args[]) {
+        LookupTypeTest test = new LookupTypeTest();
+        for (TestCase tcase : createTestCases()) {
+            test.runTest(tcase);
+        }
+    }
+
+    private static Set<TestCase> createTestCases() {
+        Set<TestCase> result = new HashSet<>();
+        // a primitive class
+        result.add(new TestCase(Utils.toJVMTypeSignature(int.class),
+                LookupTypeTest.class, true, false, InternalError.class));
+        // lookup not existing class
+        result.add(new TestCase("Lsome_not_existing;", LookupTypeTest.class,
+                true, false, ClassNotFoundException.class));
+        // lookup invalid classname
+        result.add(new TestCase("L!@#$%^&**()[]{}?;", LookupTypeTest.class,
+                true, false, ClassNotFoundException.class));
+        // lookup package private class
+        result.add(new TestCase(
+                "Lcompiler/jvmci/compilerToVM/testcases/PackagePrivateClass;",
+                LookupTypeTest.class, true, false,
+                ClassNotFoundException.class));
+        // lookup usual class with resolve=true
+        result.add(new TestCase(Utils.toJVMTypeSignature(SingleSubclass.class),
+                LookupTypeTest.class, true, true));
+        // lookup usual class with resolve=false
+        result.add(new TestCase(
+                Utils.toJVMTypeSignature(DoNotExtendClass.class),
+                LookupTypeTest.class, false, true));
+        // lookup usual class with null accessor
+        result.add(new TestCase(
+                Utils.toJVMTypeSignature(MultiSubclassedClass.class), null,
+                false, false, NullPointerException.class));
+        return result;
+    }
+
+    private void runTest(TestCase tcase) {
+        System.out.println(tcase);
+        HotSpotResolvedObjectTypeImpl metaspaceKlass;
+        try {
+            metaspaceKlass = CompilerToVMHelper.lookupType(tcase.className,
+                    tcase.accessing, tcase.resolve);
+        } catch (Throwable t) {
+            Asserts.assertNotNull(tcase.expectedException,
+                    "Assumed no exception, but got " + t);
+            Asserts.assertFalse(tcase.isPositive,
+                    "Got unexpected exception " + t);
+            Asserts.assertEQ(t.getClass(), tcase.expectedException,
+                    "Unexpected exception");
+            // passed
+            return;
+        }
+        if (tcase.expectedException != null) {
+            throw new AssertionError("Expected exception was not thrown: "
+                    + tcase.expectedException.getName());
+        }
+        if (tcase.isPositive) {
+            Asserts.assertNotNull(metaspaceKlass,
+                    "Unexpected null metaspace klass");
+            Asserts.assertEQ(metaspaceKlass.getName(), tcase.className,
+                    "Got unexpected resolved class name");
+        } else {
+            Asserts.assertNull(metaspaceKlass, "Unexpected metaspace klass");
+        }
+    }
+
+    private static class TestCase {
+        public final String className;
+        public final Class<?> accessing;
+        public final boolean resolve;
+        public final boolean isPositive;
+        public final Class<? extends Throwable> expectedException;
+
+        public TestCase(String className, Class<?> accessing, boolean resolve,
+                boolean isPositive,
+                Class<? extends Throwable> expectedException) {
+            this.className = className;
+            this.accessing = accessing;
+            this.resolve = resolve;
+            this.isPositive = isPositive;
+            this.expectedException = expectedException;
+        }
+
+        public TestCase(String className, Class<?> accessing, boolean resolve,
+                boolean isPositive) {
+            this.className = className;
+            this.accessing = accessing;
+            this.resolve = resolve;
+            this.isPositive = isPositive;
+            this.expectedException = null;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("CASE: class=%s, accessing=%s,"
+                + " resolve=%s, positive=%s, expectedException=%s", className,
+                accessing, resolve, isPositive, expectedException);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @ignore 8139703
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox MaterializeVirtualObjectTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *     -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -XX:CompileCommand=exclude,*::check -XX:+DoEscapeAnalysis -Xbatch
+ *     -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=false
+ *     compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *     -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -XX:CompileCommand=exclude,*::check -XX:+DoEscapeAnalysis -Xbatch
+ *     -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=true
+ *     compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.testlibrary.CompilerUtils;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+import java.lang.reflect.Method;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotStackFrameReference;
+
+public class MaterializeVirtualObjectTest {
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final Method METHOD;
+    private static final HotSpotResolvedJavaMethodImpl RESOLVED_METHOD;
+    private static final boolean INVALIDATE = Boolean.getBoolean(
+            "compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate");
+
+    static {
+        try {
+            METHOD = MaterializeVirtualObjectTest.class.getDeclaredMethod(
+                    "testFrame", String.class, boolean.class);
+        } catch (NoSuchMethodException e) {
+            throw new Error("Can't get executable for test method", e);
+        }
+        RESOLVED_METHOD = CTVMUtilities.getResolvedMethod(METHOD);
+    }
+
+    public static void main(String[] args) {
+        int levels[] = CompilerUtils.getAvailableCompilationLevels();
+        // we need compilation level 4 to use EscapeAnalysis
+        if (levels.length < 1 || levels[levels.length - 1] != 4) {
+            System.out.println("INFO: Test needs compilation level 4 to"
+                    + " be available. Skipping.");
+        } else {
+            new MaterializeVirtualObjectTest().test();
+        }
+    }
+
+    private static String getName() {
+        return "CASE: invalidate=" + INVALIDATE;
+    }
+
+    private void test() {
+        System.out.println(getName());
+        Asserts.assertFalse(WB.isMethodCompiled(METHOD), getName()
+                + " : method unexpectedly compiled");
+        /* need to call testFrame at least once to be able to compile it, so
+           calling with materialize=false, because testFrame is not compiled */
+        testFrame("someString", /* materialize= */ false);
+        WB.enqueueMethodForCompilation(METHOD, 4);
+        Asserts.assertTrue(WB.isMethodCompiled(METHOD), getName()
+                + "Method unexpectedly not compiled");
+        // calling with materialize=true to materialize compiled testFrame
+        testFrame("someString", /* materialize= */ true);
+    }
+
+    private void testFrame(String str, boolean materialize) {
+        Helper helper = new Helper(str);
+        check(materialize);
+        Asserts.assertTrue((helper.string != null) && (this != null)
+                && (helper != null), getName() + " : some locals are null");
+    }
+
+    private void check(boolean materialize) {
+        // Materialize virtual objects on last invocation
+        if (materialize) {
+            HotSpotStackFrameReference hsFrame = CompilerToVMHelper
+                    .getNextStackFrame(/* topmost frame */ null,
+                            new HotSpotResolvedJavaMethodImpl[]{
+                                RESOLVED_METHOD}, /* don't skip any */ 0);
+            Asserts.assertNotNull(hsFrame, getName() + " : got null frame");
+            Asserts.assertTrue(WB.isMethodCompiled(METHOD), getName()
+                    + "Test method should be compiled");
+            Asserts.assertTrue(hsFrame.hasVirtualObjects(), getName()
+                    + ": has no virtual object before materialization");
+            CompilerToVMHelper.materializeVirtualObjects(hsFrame, INVALIDATE);
+            Asserts.assertFalse(hsFrame.hasVirtualObjects(), getName()
+                    + " : has virtual object after materialization");
+            Asserts.assertEQ(WB.isMethodCompiled(METHOD), !INVALIDATE, getName()
+                    + " : unexpected compiled status");
+        }
+    }
+
+    private class Helper {
+        public String string;
+
+        public Helper(String s) {
+            this.string = s;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.MethodIsIgnoredBySecurityStackWalkTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.lang.reflect.Method;
+import java.lang.reflect.Executable;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+
+public class MethodIsIgnoredBySecurityStackWalkTest {
+
+    public static void main(String[] args) {
+        Map<Executable, Boolean> testCases = createTestCases();
+        testCases.forEach(
+                MethodIsIgnoredBySecurityStackWalkTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod, Boolean expected) {
+        HotSpotResolvedJavaMethodImpl method
+                = CTVMUtilities.getResolvedMethod(aMethod);
+        boolean isIgnored = CompilerToVMHelper
+                .methodIsIgnoredBySecurityStackWalk(method);
+        String msg = String.format("%s is%s ignored but must%s", aMethod,
+                isIgnored ? "" : " not",
+                expected ? "" : " not");
+        Asserts.assertEQ(isIgnored, expected, msg);
+    }
+
+    private static Map<Executable, Boolean> createTestCases() {
+        Map<Executable, Boolean> testCases = new HashMap<>();
+
+        try {
+            Class<?> aClass = Method.class;
+            testCases.put(aClass.getMethod("invoke", Object.class,
+                    Object[].class), true);
+
+            aClass = Class.forName("sun.reflect.NativeMethodAccessorImpl");
+            testCases.put(aClass.getMethod("invoke", Object.class,
+                    Object[].class), true);
+            testCases.put(aClass.getDeclaredMethod("invoke0", Method.class,
+                    Object.class, Object[].class), true);
+
+            aClass = MethodIsIgnoredBySecurityStackWalkTest.class;
+            for (Executable method : aClass.getMethods()) {
+                testCases.put(method, false);
+            }
+            for (Executable method : aClass.getDeclaredMethods()) {
+                testCases.put(method, false);
+            }
+            for (Executable method : aClass.getConstructors()) {
+                testCases.put(method, false);
+            }
+        } catch (NoSuchMethodException | ClassNotFoundException e) {
+            throw new Error("TEST BUG " + e.getMessage(), e);
+        }
+        return testCases;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ReadUncompressedOopTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib/
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.ReadUncompressedOopTest
+ * @run main ClassFileInstaller
+ *     sun.hotspot.WhiteBox
+ *     sun.hotspot.WhiteBox$WhiteBoxPermission
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:.
+ *     -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:-UseCompressedOops
+ *     compiler.jvmci.compilerToVM.ReadUncompressedOopTest
+ * @run main/othervm -Xbootclasspath/a:.
+ *     -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:+UseCompressedOops
+ *     compiler.jvmci.compilerToVM.ReadUncompressedOopTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+import sun.misc.Unsafe;
+
+import java.lang.reflect.Field;
+
+public class ReadUncompressedOopTest {
+
+    public static void main(String args[])  {
+        new ReadUncompressedOopTest().runTest();
+    }
+
+    private void runTest()  {
+        long ptr = getPtr();
+        System.out.printf("calling readUncompressedOop(0x%x)%n", ptr);
+        Asserts.assertEQ(getClass(),
+                CompilerToVMHelper.readUncompressedOop(ptr),
+                String.format("unexpected class returned for 0x%x", ptr));
+    }
+
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final Class<?> CLASS = ReadUncompressedOopTest.class;
+    private static final long PTR = WB.getObjectAddress(CLASS);
+
+    private static long getPtr() {
+        Field field;
+        try {
+            field = CLASS.getDeclaredField("PTR");
+        } catch (NoSuchFieldException nsfe) {
+            throw new Error("TESTBUG : " + nsfe, nsfe);
+        }
+        Object base = UNSAFE.staticFieldBase(field);
+        return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller
+ *      sun.hotspot.WhiteBox
+ *      sun.hotspot.WhiteBox$WhiteBoxPermission
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      -Xmixed
+ *      compiler.jvmci.compilerToVM.ReprofileTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.meta.ProfilingInfo;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+public class ReprofileTest {
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) {
+        List<Method> testCases = createTestCases();
+        testCases.forEach(ReprofileTest::runSanityTest);
+    }
+
+    private static List<Method> createTestCases() {
+        List<Method> testCases = new ArrayList<>();
+        try {
+
+            Class<?> aClass = DummyClass.class;
+            testCases.add(aClass.getMethod("withLoop"));
+
+            aClass = DummyClass.class;
+            testCases.add(aClass.getDeclaredMethod("dummyFunction"));
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG " + e.getMessage(), e);
+        }
+        return testCases;
+    }
+
+    private static void runSanityTest(Method aMethod) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        ProfilingInfo startProfile = method.getProfilingInfo();
+        Asserts.assertFalse(startProfile.isMature(), aMethod
+                + " : profiling info is mature in the begging");
+
+        long compileThreshold = (Long) WB.getVMFlag("CompileThreshold");
+        // make interpreter to profile this method
+        try {
+            Object obj = aMethod.getDeclaringClass().newInstance();
+            for (long i = 0; i < compileThreshold; i++) {
+                aMethod.invoke(obj);
+            }
+        } catch (ReflectiveOperationException e) {
+            throw new Error("TEST BUG : " + e.getMessage(), e);
+        }
+        ProfilingInfo compProfile = method.getProfilingInfo();
+
+        Asserts.assertNE(startProfile.toString(), compProfile.toString(),
+                String.format("%s : profiling info wasn't changed after "
+                                + "%d invocations",
+                        aMethod, compileThreshold));
+        Asserts.assertTrue(compProfile.isMature(),
+                String.format("%s is not mature after %d invocations",
+                        aMethod, compileThreshold));
+
+        CompilerToVMHelper.reprofile(method);
+        ProfilingInfo reprofiledProfile = method.getProfilingInfo();
+
+        Asserts.assertNE(startProfile.toString(), reprofiledProfile.toString(),
+                aMethod + " : profiling info wasn't changed after reprofiling");
+        Asserts.assertNE(compProfile.toString(), reprofiledProfile.toString(),
+                aMethod + " : profiling info didn't change after reprofile");
+        Asserts.assertFalse(reprofiledProfile.isMature(), aMethod
+                + " : profiling info is mature after reprofiling");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.ResolveConstantInPoolTest
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:.
+ *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *                   compiler.jvmci.compilerToVM.ResolveConstantInPoolTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotConstantPool;
+import jdk.test.lib.Asserts;
+import sun.reflect.ConstantPool;
+
+/**
+ * Test for {@code compiler.jvmci.CompilerToVM.resolveConstantInPool} method
+ */
+public class ResolveConstantInPoolTest {
+
+    public static void main(String[] args) throws Exception {
+        Map<ConstantPoolTestsHelper.ConstantTypes,
+                ConstantPoolTestCase.Validator> typeTests = new HashMap<>(2);
+        typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_METHODHANDLE,
+                ResolveConstantInPoolTest::validateMethodHandle);
+        typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_METHODTYPE,
+                ResolveConstantInPoolTest::validateMethodType);
+        ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests);
+        testCase.test();
+    }
+
+    private static void validateMethodHandle(HotSpotConstantPool constantPoolCTVM,
+            ConstantPool constantPoolSS,
+            ConstantPoolTestsHelper.DummyClasses dummyClass, int index) {
+        Object constantInPool = CompilerToVMHelper
+                .resolveConstantInPool(constantPoolCTVM, index);
+        if (!(constantInPool instanceof MethodHandle)) {
+            String msg = String.format(
+                    "Wrong constant pool entry accessed by index"
+                            + " %d: %s, but should be subclass of %s",
+                    index + 1, constantInPool.getClass(),
+                    MethodHandle.class.getName());
+            throw new AssertionError(msg);
+        }
+    }
+
+    private static void validateMethodType(HotSpotConstantPool constantPoolCTVM,
+            ConstantPool constantPoolSS,
+            ConstantPoolTestsHelper.DummyClasses dummyClass, int index) {
+        Object constantInPool = CompilerToVMHelper
+                .resolveConstantInPool(constantPoolCTVM, index);
+        Class mtToVerify = constantInPool.getClass();
+        Class mtToRefer = MethodType.class;
+        String msg = String.format("Wrong %s accessed by constant pool index"
+                            + " %d: %s, but should be %s", "method type class",
+                            index, mtToVerify, mtToRefer);
+        Asserts.assertEQ(mtToRefer, mtToVerify, msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.ResolveMethodTest
+ * @run main ClassFileInstaller
+ *      jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *     -XX:+EnableJVMCI compiler.jvmci.compilerToVM.ResolveMethodTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.testcases.AbstractClass;
+import compiler.jvmci.common.testcases.AbstractClassExtender;
+import compiler.jvmci.common.testcases.MultipleImplementer1;
+import compiler.jvmci.common.testcases.MultipleImplementer2;
+import compiler.jvmci.common.testcases.MultipleImplementersInterface;
+import compiler.jvmci.common.testcases.SingleImplementer;
+import compiler.jvmci.common.testcases.SingleImplementerInterface;
+import compiler.jvmci.common.testcases.SingleSubclass;
+import compiler.jvmci.common.testcases.SingleSubclassedClass;
+import compiler.jvmci.common.CTVMUtilities;
+import java.util.HashSet;
+import java.util.Set;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import sun.misc.Unsafe;
+
+public class ResolveMethodTest {
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+
+    public static void main(String args[]) {
+        ResolveMethodTest test = new ResolveMethodTest();
+        // positive cases
+        try {
+            for (TestCase tcase: createTestCases()) {
+                test.runTest(tcase);
+            }
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG: can't find requested method", e);
+        }
+    }
+
+    private static Set<TestCase> createTestCases() {
+        Set<TestCase> result = new HashSet<>();
+        // a usual class public method
+        result.add(new TestCase(SingleSubclass.class, SingleSubclass.class,
+                "usualMethod", ResolveMethodTest.class, true));
+        // an array method
+        result.add(new TestCase(int[].class, Object.class, "toString",
+                ResolveMethodTest.class, true));
+        // a method from base class, which was overriden in tested one
+        result.add(new TestCase(SingleSubclass.class, SingleSubclass.class,
+                "overridenMethod", ResolveMethodTest.class, true));
+        // a method from base class, which was not overriden in tested one
+        result.add(new TestCase(SingleSubclass.class,
+                SingleSubclassedClass.class, "inheritedMethod",
+                ResolveMethodTest.class, true));
+        /* a method from base class, which was overriden in tested one with
+           base class as holder */
+        result.add(new TestCase(SingleSubclass.class,
+                SingleSubclassedClass.class, "overridenMethod",
+                ResolveMethodTest.class, true));
+        // an interface method
+        result.add(new TestCase(SingleImplementer.class,
+                SingleImplementerInterface.class, "interfaceMethod",
+                ResolveMethodTest.class, true));
+        // an interface default method overriden in implementer
+        result.add(new TestCase(MultipleImplementer1.class,
+                MultipleImplementersInterface.class, "defaultMethod",
+                ResolveMethodTest.class, true));
+        // an interface default method not overriden in implementer
+        result.add(new TestCase(MultipleImplementer2.class,
+                MultipleImplementersInterface.class, "defaultMethod",
+                ResolveMethodTest.class, true));
+        // an abstract method
+        result.add(new TestCase(AbstractClassExtender.class, AbstractClass.class,
+                "abstractMethod", ResolveMethodTest.class, true));
+        // private method with right accessor
+        result.add(new TestCase(SingleSubclass.class, SingleSubclass.class,
+                "privateMethod", SingleSubclass.class, true));
+        // package-private method with right accessor
+        result.add(new TestCase(SingleSubclass.class, SingleSubclass.class,
+                "defaultAccessMethod", SingleSubclass.class, true));
+
+        // negative cases
+
+        // private method of another class
+        result.add(new TestCase(SingleSubclass.class, SingleSubclass.class,
+                "privateMethod", ResolveMethodTest.class, false));
+        // package-private method from another package
+        result.add(new TestCase(SingleSubclass.class, SingleSubclass.class,
+                "defaultAccessMethod", ResolveMethodTest.class, false));
+        return result;
+    }
+
+    private void runTest(TestCase tcase) throws NoSuchMethodException {
+        System.out.println(tcase);
+        HotSpotResolvedJavaMethodImpl metaspaceMethod = CTVMUtilities
+                .getResolvedMethod(tcase.holder,
+                        tcase.holder.getDeclaredMethod(tcase.methodName));
+        HotSpotResolvedObjectTypeImpl holderMetaspace = CompilerToVMHelper
+                .lookupType(Utils.toJVMTypeSignature(tcase.holder),
+                        getClass(), /* resolve = */ true);
+        HotSpotResolvedObjectTypeImpl callerMetaspace = CompilerToVMHelper
+                .lookupType(Utils.toJVMTypeSignature(tcase.caller),
+                        getClass(), /* resolve = */ true);
+        HotSpotResolvedJavaMethodImpl resolvedMetaspaceMethod
+                = CompilerToVMHelper.resolveMethod(holderMetaspace,
+                        metaspaceMethod, callerMetaspace);
+        if (tcase.isPositive) {
+            Asserts.assertNotNull(resolvedMetaspaceMethod,
+                    "Unexpected null resolved method value for "
+                            + tcase.methodName);
+            Asserts.assertEQ(metaspaceMethod.getName(), tcase.methodName,
+                    "Reflection and c2vm method names doesn't match");
+        } else {
+            Asserts.assertNull(resolvedMetaspaceMethod,
+                    "Method unexpectedly resolved");
+        }
+    }
+
+    private static class TestCase {
+        public final Class<?> receiver;
+        public final Class<?> holder;
+        public final Class<?> caller;
+        public final String methodName;
+        public final boolean isPositive;
+
+        public TestCase(Class<?> recv, Class<?> holder, String methodName,
+                Class<?> caller, boolean isPositive) {
+            this.receiver = recv;
+            this.holder = holder;
+            this.caller = caller;
+            this.methodName = methodName;
+            this.isPositive = isPositive;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("CASE: receiver=%s, holder=%s, method=%s,"
+                + "caller=%s, isPositive=%s%n", receiver.getName(),
+                holder.getName(), methodName, caller.getName(), isPositive);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @summary Testing compiler.jvmci.CompilerToVM.resolveTypeInPool method
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.common.testcases.MultipleImplementersInterface
+ *        compiler.jvmci.common.testcases.MultipleImplementer2
+ *        compiler.jvmci.compilerToVM.ConstantPoolTestsHelper
+ *        compiler.jvmci.compilerToVM.ConstantPoolTestCase
+ *        compiler.jvmci.compilerToVM.ResolveTypeInPoolTest
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
+ *                   -XX:+EnableJVMCI compiler.jvmci.compilerToVM.ResolveTypeInPoolTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import java.util.HashMap;
+import java.util.Map;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotConstantPool;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import sun.reflect.ConstantPool;
+
+/**
+ * Test for {@code compiler.jvmci.CompilerToVM.resolveTypeInPool} method
+ */
+public class ResolveTypeInPoolTest {
+
+    public static void main(String[] args) throws Exception {
+        Map<ConstantPoolTestsHelper.ConstantTypes,
+                ConstantPoolTestCase.Validator> typeTests = new HashMap<>(1);
+        typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_CLASS,
+                ResolveTypeInPoolTest::validate);
+        ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests);
+        testCase.test();
+    }
+
+    public static void validate(HotSpotConstantPool constantPoolCTVM,
+            ConstantPool constantPoolSS,
+            ConstantPoolTestsHelper.DummyClasses dummyClass, int i) {
+        HotSpotResolvedObjectTypeImpl typeToVerify = CompilerToVMHelper
+                .resolveTypeInPool(constantPoolCTVM, i);
+        int classNameIndex = (int) dummyClass.cp.get(i).value;
+        String classNameToRefer = constantPoolSS.getUTF8At(classNameIndex);
+        String outputToVerify = typeToVerify.toString();
+        if (!outputToVerify.contains(classNameToRefer)) {
+            String msg = String.format("Wrong class accessed by constant"
+                    + " pool index %d: %s, but should be %s",
+                    i, outputToVerify, classNameToRefer);
+            throw new AssertionError(msg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ShouldDebugNonSafepointsTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary /../../test/lib/
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.compilerToVM.ShouldDebugNonSafepointsTest
+ * @run main ClassFileInstaller
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm
+ *     -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Xbootclasspath/a:.
+ *     -XX:+UnlockDiagnosticVMOptions
+ *     -XX:+DebugNonSafepoints
+ *     -Dcompiler.jvmci.compilerToVM.ShouldDebugNonSafepointsTest.expected=true
+ *     compiler.jvmci.compilerToVM.ShouldDebugNonSafepointsTest
+ * @run main/othervm
+ *     -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Xbootclasspath/a:.
+ *     -XX:+UnlockDiagnosticVMOptions
+ *     -XX:-DebugNonSafepoints
+ *     -Dcompiler.jvmci.compilerToVM.ShouldDebugNonSafepointsTest.expected=false
+ *     compiler.jvmci.compilerToVM.ShouldDebugNonSafepointsTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.test.lib.Asserts;
+
+public class ShouldDebugNonSafepointsTest {
+    private static final boolean EXPECTED = Boolean.getBoolean("compiler"
+            + ".jvmci.compilerToVM.ShouldDebugNonSafepointsTest.expected");
+
+    public static void main(String args[]) {
+        new ShouldDebugNonSafepointsTest().runTest();
+    }
+
+    private void runTest() {
+        Asserts.assertEQ(CompilerToVMHelper.shouldDebugNonSafepoints(),
+                EXPECTED, "Unexpected shouldDebugnonSafepoints value");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /../../test/lib /
+ * @compile ../common/CompilerToVMHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *                              jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      compiler.jvmci.compilerToVM.ShouldInlineMethodTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+public class ShouldInlineMethodTest {
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) {
+        List<Executable> testCases = createTestCases();
+        testCases.forEach(ShouldInlineMethodTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod) {
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        boolean shouldInline = CompilerToVMHelper.shouldInlineMethod(method);
+        boolean expectedShouldInline = WB.testSetForceInlineMethod(aMethod,
+                true);
+        Asserts.assertEQ(shouldInline, expectedShouldInline,
+                "Unexpected value of property 'should inline'");
+
+        shouldInline = CompilerToVMHelper.shouldInlineMethod(method);
+        Asserts.assertTrue(shouldInline, "Unexpected value of property "
+                + "'should inline' after setting 'force inline' to true");
+        WB.testSetForceInlineMethod(aMethod, false);
+        shouldInline = CompilerToVMHelper.shouldInlineMethod(method);
+        Asserts.assertFalse(shouldInline, "Unexpected value of property "
+                + "'should inline' after setting 'force inline' to false");
+    }
+
+    private static List<Executable> createTestCases() {
+        List<Executable> testCases = new ArrayList<>();
+
+        Class<?> aClass = DummyClass.class;
+        testCases.addAll(Arrays.asList(aClass.getDeclaredMethods()));
+        testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors()));
+        return testCases;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciCompleteInitializationTest.config	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+compiler.jvmci.events.JvmciCompleteInitializationTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciCompleteInitializationTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary
+ * @build compiler.jvmci.common.JVMCIHelpers
+ *     compiler.jvmci.events.JvmciCompleteInitializationTest
+ * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
+ * @run main jdk.test.lib.FileInstaller ./JvmciCompleteInitializationTest.config
+ *     ./META-INF/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
+ * @run main ClassFileInstaller
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
+ *     compiler.jvmci.events.JvmciCompleteInitializationTest
+ *     jdk.test.lib.Asserts
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *     -Xbootclasspath/a:.
+ *     -XX:+EnableJVMCI
+ *     -Dcompiler.jvmci.events.JvmciCompleteInitializationTest.positive=true
+ *     compiler.jvmci.events.JvmciCompleteInitializationTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ *     -Xbootclasspath/a:.
+ *     -XX:-EnableJVMCI
+ *     -Dcompiler.jvmci.events.JvmciCompleteInitializationTest.positive=false
+ *     compiler.jvmci.events.JvmciCompleteInitializationTest
+ */
+
+package compiler.jvmci.events;
+
+import jdk.test.lib.Asserts;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+
+public class JvmciCompleteInitializationTest implements HotSpotVMEventListener {
+    private static final boolean IS_POSITIVE = Boolean.getBoolean(
+            "compiler.jvmci.events.JvmciCompleteInitializationTest.positive");
+    private static volatile int completeInitializationCount = 0;
+    private static volatile String errorMessage = "";
+
+    public static void main(String args[]) {
+        if (completeInitializationCount != 0) {
+            throw new Error("Unexpected completeInitialization events"
+                    + " count at start");
+        }
+        initializeRuntime();
+        int expectedEventCount = IS_POSITIVE ? 1 : 0;
+        Asserts.assertEQ(completeInitializationCount, expectedEventCount,
+                "Unexpected completeInitialization events count"
+                        + " after JVMCI init");
+        initializeRuntime();
+        Asserts.assertEQ(completeInitializationCount, expectedEventCount,
+                "Unexpected completeInitialization events count"
+                        + " after 2nd JVMCI init");
+        Asserts.assertTrue(errorMessage.isEmpty(), errorMessage);
+    }
+
+    private static void initializeRuntime() {
+        Error t = null;
+        try {
+            /* in case JVMCI disabled, an InternalError on initialization
+               and NoClassDefFound on 2nd try */
+            HotSpotJVMCIRuntime.runtime();
+        } catch (Error e) {
+            t = e;
+        }
+        if (IS_POSITIVE) {
+            Asserts.assertNull(t, "Caught unexpected exception");
+        } else {
+            Asserts.assertNotNull(t, "Got no expected error");
+        }
+    }
+
+    @Override
+    public void completeInitialization(HotSpotJVMCIRuntime
+            hotSpotJVMCIRuntime) {
+        completeInitializationCount++;
+        if (hotSpotJVMCIRuntime == null) {
+            errorMessage += " HotSpotJVMCIRuntime is null.";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciCreateMetaAccessContextTest.config	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+compiler.jvmci.events.JvmciCreateMetaAccessContextTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciCreateMetaAccessContextTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary
+ * @compile ./MetaAccessWrapper.java
+ * @build compiler.jvmci.common.JVMCIHelpers
+ *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
+ * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
+ * @run main jdk.test.lib.FileInstaller
+ *     ./JvmciCreateMetaAccessContextTest.config
+ *     ./META-INF/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
+ * @run main ClassFileInstaller
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
+ *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
+ *     jdk.vm.ci.hotspot.MetaAccessWrapper
+ *     jdk.test.lib.Asserts
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -Xbootclasspath/a:.
+ *     -Dcompiler.jvmci.events.JvmciCreateMetaAccessContextTest.providenull=true
+ *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -Xbootclasspath/a:.
+ *     -Dcompiler.jvmci.events.JvmciCreateMetaAccessContextTest.providenull=false
+ *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
+ */
+
+package compiler.jvmci.events;
+
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.MetaAccessWrapper;
+import jdk.vm.ci.meta.JVMCIMetaAccessContext;
+import jdk.test.lib.Asserts;
+
+public class JvmciCreateMetaAccessContextTest
+        implements HotSpotVMEventListener {
+    private static final boolean PROVIDE_NULL_CONTEXT = Boolean.getBoolean(
+            "compiler.jvmci.events.JvmciCreateMetaAccessContextTest"
+                    + ".providenull");
+    private static volatile int createMetaAccessContextCount = 0;
+    private static volatile String errorMessage = "";
+
+    public static void main(String args[]) {
+        if (createMetaAccessContextCount != 0) {
+            throw new Error("Unexpected createMetaAccessContextevents count"
+                    + " at test start");
+        }
+        JVMCIMetaAccessContext context;
+        context = HotSpotJVMCIRuntime.runtime().getMetaAccessContext();
+        Asserts.assertNotNull(context,
+                "JVMCIMetaAccessContext is null after 1st request");
+        Asserts.assertEQ(createMetaAccessContextCount, 1,
+                "Unexpected createMetaAccessContext events count after 1st"
+                        + " JVMCI runtime request");
+        context = HotSpotJVMCIRuntime.runtime().getMetaAccessContext();
+        Asserts.assertNotNull(context,
+                "JVMCIMetaAccessContext is null after 2nd request");
+        Asserts.assertEQ(createMetaAccessContextCount, 1,
+                "Unexpected createMetaAccessContext events count after 2nd"
+                        + " JVMCI runtime request");
+        Asserts.assertTrue(errorMessage.isEmpty(), errorMessage);
+        if (PROVIDE_NULL_CONTEXT) {
+            Asserts.assertFalse(context instanceof MetaAccessWrapper,
+                    "Got unexpected context: " + context.getClass());
+        } else {
+            Asserts.assertTrue(context instanceof MetaAccessWrapper,
+                    "Got unexpected context: " + context.getClass());
+        }
+    }
+
+    @Override
+    public JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime
+            hotSpotJVMCIRuntime) {
+        createMetaAccessContextCount++;
+        if (hotSpotJVMCIRuntime == null) {
+            errorMessage += " HotSpotJVMCIRuntime is null.";
+        }
+        if (PROVIDE_NULL_CONTEXT) {
+            return null;
+        }
+        return new MetaAccessWrapper();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.config	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+compiler.jvmci.events.JvmciNotifyInstallEventTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library / /testlibrary
+ * @compile ../common/CompilerToVMHelper.java
+ * @build compiler.jvmci.common.JVMCIHelpers
+ *     compiler.jvmci.events.JvmciNotifyInstallEventTest
+ * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
+ * @run main jdk.test.lib.FileInstaller ./JvmciNotifyInstallEventTest.config
+ *     ./META-INF/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
+ * @run main ClassFileInstaller
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
+ *     compiler.jvmci.events.JvmciNotifyInstallEventTest
+ *     compiler.jvmci.common.CTVMUtilities
+ *     compiler.jvmci.common.testcases.SimpleClass
+ *     jdk.vm.ci.hotspot.CompilerToVMHelper
+ *     jdk.test.lib.Asserts
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *     -Djvmci.compiler=EmptyCompiler -Xbootclasspath/a:. -Xmixed
+ *     -XX:+UseJVMCICompiler -XX:-BootstrapJVMCI
+ *     -Dcompiler.jvmci.events.JvmciNotifyInstallEventTest.noevent=false
+ *     compiler.jvmci.events.JvmciNotifyInstallEventTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-EnableJVMCI
+ *     -Djvmci.compiler=EmptyCompiler -Xbootclasspath/a:. -Xmixed
+ *     -Dcompiler.jvmci.events.JvmciNotifyInstallEventTest.noevent=true
+ *     compiler.jvmci.events.JvmciNotifyInstallEventTest
+ */
+
+package compiler.jvmci.events;
+
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.SimpleClass;
+import jdk.test.lib.Asserts;
+import java.lang.reflect.Method;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+
+public class JvmciNotifyInstallEventTest implements HotSpotVMEventListener {
+    private static final String METHOD_NAME = "testMethod";
+    private static final boolean IS_POSITIVE = !Boolean.getBoolean(
+            "compiler.jvmci.events.JvmciNotifyInstallEventTest.noevent");
+    private static volatile int gotInstallNotification = 0;
+
+    public static void main(String args[]) {
+        new JvmciNotifyInstallEventTest().runTest();
+    }
+
+    private void runTest() {
+        if (gotInstallNotification != 0) {
+            throw new Error("Got install notification before test actions");
+        }
+        HotSpotCodeCacheProvider codeCache = null;
+        try {
+            codeCache = (HotSpotCodeCacheProvider) HotSpotJVMCIRuntime.runtime()
+                    .getHostJVMCIBackend().getCodeCache();
+        } catch (InternalError ie) {
+            if (IS_POSITIVE) {
+                throw new AssertionError(
+                        "Got unexpected InternalError trying to get code cache",
+                        ie);
+            }
+            // passed
+            return;
+        }
+        Asserts.assertTrue(IS_POSITIVE,
+                    "Haven't caught InternalError in negative case");
+        Method testMethod;
+        try {
+            testMethod = SimpleClass.class.getDeclaredMethod(METHOD_NAME);
+        } catch (NoSuchMethodException e) {
+            throw new Error("TEST BUG: Can't find " + METHOD_NAME, e);
+        }
+        HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+                .getResolvedMethod(SimpleClass.class, testMethod);
+        CompilationResult compResult = new CompilationResult(METHOD_NAME);
+        // to pass sanity check of default -1
+        compResult.setTotalFrameSize(0);
+        codeCache.installMethod(method, compResult, /* jvmciEnv = */ 0L,
+                /* isDefault = */ false);
+        Asserts.assertEQ(gotInstallNotification, 1,
+                "Got unexpected event count after 1st install attempt");
+        // since "empty" compilation result is ok, a second attempt should be ok
+        codeCache.installMethod(method, compResult, /* jvmciEnv = */ 0L,
+                /* isDefault = */ false);
+        Asserts.assertEQ(gotInstallNotification, 2,
+                "Got unexpected event count after 2nd install attempt");
+    }
+
+    @Override
+    public void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider,
+            InstalledCode installedCode, CompilationResult compResult) {
+        gotInstallNotification++;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventListener.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, 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 compiler.jvmci.events;
+
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+
+public class JvmciShutdownEventListener implements HotSpotVMEventListener {
+    public static final String MESSAGE = "Shutdown notified";
+    public static final String GOT_INTERNAL_ERROR = "Got internal error";
+
+    public static void main(String args[]) {
+        try {
+            HotSpotJVMCIRuntime.runtime(); // let's trigger that lazy jvmci init
+        } catch (InternalError e) {
+            System.out.println(GOT_INTERNAL_ERROR);
+        }
+    }
+
+    @Override
+    public void notifyShutdown() {
+        System.out.println(MESSAGE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.config	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+compiler.jvmci.events.JvmciShutdownEventListener
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /testlibrary /
+ * @build compiler.jvmci.common.JVMCIHelpers
+ *        compiler.jvmci.events.JvmciShutdownEventListener
+ *        compiler.jvmci.events.JvmciShutdownEventTest
+ * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
+ * @run main jdk.test.lib.FileInstaller ./JvmciShutdownEventTest.config
+ *     ./META-INF/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
+ * @run main ClassFileInstaller
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
+ *     compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
+ *     compiler.jvmci.events.JvmciShutdownEventListener
+ * @run driver
+ *     compiler.jvmci.events.JvmciShutdownEventTest
+ */
+
+package compiler.jvmci.events;
+
+import jdk.test.lib.ExitCode;
+import jdk.test.lib.cli.CommandLineOptionTest;
+
+public class JvmciShutdownEventTest {
+    private final static String[] MESSAGE = new String[]{
+        JvmciShutdownEventListener.MESSAGE
+    };
+
+    private final static String[] ERROR_MESSAGE = new String[]{
+        JvmciShutdownEventListener.GOT_INTERNAL_ERROR
+    };
+
+    public static void main(String args[]) throws Throwable {
+        boolean addTestVMOptions = true;
+        CommandLineOptionTest.verifyJVMStartup(MESSAGE, ERROR_MESSAGE,
+                "Unexpected exit code with +EnableJVMCI",
+                "Unexpected output with +EnableJVMCI", ExitCode.OK,
+                addTestVMOptions, "-XX:+UnlockExperimentalVMOptions",
+                "-XX:+EnableJVMCI", "-Xbootclasspath/a:.",
+                JvmciShutdownEventListener.class.getName()
+        );
+
+        CommandLineOptionTest.verifyJVMStartup(ERROR_MESSAGE, MESSAGE,
+                "Unexpected exit code with -EnableJVMCI",
+                "Unexpected output with -EnableJVMCI", ExitCode.OK,
+                addTestVMOptions, "-XX:+UnlockExperimentalVMOptions",
+                "-XX:-EnableJVMCI", "-Xbootclasspath/a:.",
+                JvmciShutdownEventListener.class.getName()
+        );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/events/MetaAccessWrapper.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.JVMCIMetaAccessContext;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+/*
+ * A JVMCIMetaAccessContext wrapper class to mark context
+ * being provided/returned
+ */
+public class MetaAccessWrapper implements JVMCIMetaAccessContext {
+    private static final HotSpotJVMCIMetaAccessContext CONTEXT
+            = new HotSpotJVMCIMetaAccessContext();
+    @Override
+    public ResolvedJavaType fromClass(Class<?> clazz) {
+        return CONTEXT.fromClass(clazz);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/NestedBooleanOptionValueTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2013, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @run junit jdk.vm.ci.options.test.NestedBooleanOptionValueTest
+ */
+
+package jdk.vm.ci.options.test;
+
+import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.*;
+import static org.junit.Assert.*;
+import jdk.vm.ci.options.*;
+import jdk.vm.ci.options.OptionValue.*;
+
+import org.junit.*;
+
+public class NestedBooleanOptionValueTest {
+
+    public static class Options {
+        public static final OptionValue<Boolean> Master0 = new OptionValue<>(true);
+        public static final OptionValue<Boolean> NestedOption0 = new NestedBooleanOptionValue(Master0, true);
+        public static final OptionValue<Boolean> Master1 = new OptionValue<>(true);
+        public static final OptionValue<Boolean> NestedOption1 = new NestedBooleanOptionValue(Master1, true);
+        public static final OptionValue<Boolean> Master2 = new OptionValue<>(true);
+        public static final OptionValue<Boolean> NestedOption2 = new NestedBooleanOptionValue(Master2, false);
+    }
+
+    static final OptionDescriptor master0 = OptionDescriptor.create("Master0", Boolean.class, "", Options.class, "Master0", Master0);
+    static final OptionDescriptor nestedOption0 = OptionDescriptor.create("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0);
+    static final OptionDescriptor master1 = OptionDescriptor.create("Master1", Boolean.class, "", Options.class, "Master1", Master1);
+    static final OptionDescriptor nestedOption1 = OptionDescriptor.create("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1);
+    static final OptionDescriptor master2 = OptionDescriptor.create("Master2", Boolean.class, "", Options.class, "Master2", Master2);
+    static final OptionDescriptor nestedOption2 = OptionDescriptor.create("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2);
+
+    @SuppressWarnings("try")
+    @Test
+    public void runOverrides() {
+        assertTrue(Master0.getValue());
+        assertTrue(NestedOption0.getValue());
+        try (OverrideScope s1 = OptionValue.override(Master0, false)) {
+            assertFalse(Master0.getValue());
+            assertFalse(NestedOption0.getValue());
+            try (OverrideScope s2 = OptionValue.override(NestedOption0, false)) {
+                assertFalse(NestedOption0.getValue());
+            }
+            try (OverrideScope s2 = OptionValue.override(NestedOption0, true)) {
+                assertTrue(NestedOption0.getValue());
+            }
+        }
+        assertTrue(Master0.getValue());
+        try (OverrideScope s1 = OptionValue.override(NestedOption0, false)) {
+            assertFalse(NestedOption0.getValue());
+        }
+        try (OverrideScope s1 = OptionValue.override(NestedOption0, true)) {
+            assertTrue(NestedOption0.getValue());
+        }
+    }
+
+    @Test
+    public void runDefaultTrue() {
+        Master1.setValue(true);
+        assertTrue(Master1.getValue());
+        assertTrue(NestedOption1.getValue());
+        // nested value unset
+        Master1.setValue(false);
+        assertFalse(Master1.getValue());
+        assertFalse(NestedOption1.getValue());
+        // set false
+        Master1.setValue(false);
+        NestedOption1.setValue(false);
+        assertFalse(Master1.getValue());
+        assertFalse(NestedOption1.getValue());
+        Master1.setValue(true);
+        assertTrue(Master1.getValue());
+        assertFalse(NestedOption1.getValue());
+        // set true
+        Master1.setValue(false);
+        NestedOption1.setValue(true);
+        assertFalse(Master1.getValue());
+        assertTrue(NestedOption1.getValue());
+        Master1.setValue(true);
+        assertTrue(Master1.getValue());
+        assertTrue(NestedOption1.getValue());
+    }
+
+    @Test
+    public void runDefaultFalse() {
+        Master2.setValue(true);
+        assertTrue(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        // nested value unset
+        Master2.setValue(false);
+        assertFalse(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        // set false
+        Master2.setValue(false);
+        NestedOption2.setValue(false);
+        assertFalse(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        Master2.setValue(true);
+        assertTrue(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        // set true
+        Master2.setValue(false);
+        NestedOption2.setValue(true);
+        assertFalse(Master2.getValue());
+        assertTrue(NestedOption2.getValue());
+        Master2.setValue(true);
+        assertTrue(Master2.getValue());
+        assertTrue(NestedOption2.getValue());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/TestOptionValue.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2013, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @run junit jdk.vm.ci.options.test.TestOptionValue
+ */
+
+package jdk.vm.ci.options.test;
+
+import static jdk.vm.ci.options.test.TestOptionValue.Options.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import jdk.vm.ci.options.*;
+import jdk.vm.ci.options.OptionValue.*;
+
+import org.junit.*;
+
+@SuppressWarnings("try")
+public class TestOptionValue {
+
+    public static class Options {
+        public static final OptionValue<Boolean> Stable = new StableOptionValue<>(true);
+        public static final OptionValue<String> Mutable = new OptionValue<>("original");
+        public static final OptionValue<String> SecondMutable = new OptionValue<>("second");
+    }
+
+    static final OptionDescriptor stable = OptionDescriptor.create("Stable", Boolean.class, "", Options.class, "Stable", Stable);
+    static final OptionDescriptor mutable = OptionDescriptor.create("Mutable", String.class, "", Options.class, "Mutable", Mutable);
+    static final OptionDescriptor secondMutable = OptionDescriptor.create("SecondMutable", String.class, "", Options.class, "SecondMutable", SecondMutable);
+
+    @Test
+    public void testMutable() {
+        assertEquals("original", Mutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) {
+            assertEquals("override1", Mutable.getValue());
+            try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) {
+                assertEquals("override2", Mutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+            try (OverrideScope s3 = OptionValue.override(Mutable, "override3")) {
+                assertEquals("override3", Mutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+        }
+        assertEquals("original", Mutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "original")) {
+            assertEquals("original", Mutable.getValue());
+        }
+    }
+
+    @Test
+    public void testMultiple() {
+        assertEquals("original", Mutable.getValue());
+        assertEquals("second", SecondMutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "override1", SecondMutable, "secondOverride1")) {
+            assertEquals("override1", Mutable.getValue());
+            assertEquals("secondOverride1", SecondMutable.getValue());
+            try (OverrideScope s2 = OptionValue.override(Mutable, "override2", SecondMutable, "secondOverride2")) {
+                assertEquals("override2", Mutable.getValue());
+                assertEquals("secondOverride2", SecondMutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+            assertEquals("secondOverride1", SecondMutable.getValue());
+            try (OverrideScope s3 = OptionValue.override(Mutable, "override3", SecondMutable, "secondOverride3")) {
+                assertEquals("override3", Mutable.getValue());
+                assertEquals("secondOverride3", SecondMutable.getValue());
+            }
+            assertEquals("override1", Mutable.getValue());
+            assertEquals("secondOverride1", SecondMutable.getValue());
+        }
+        assertEquals("original", Mutable.getValue());
+        assertEquals("second", SecondMutable.getValue());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "original", SecondMutable, "second")) {
+            assertEquals("original", Mutable.getValue());
+            assertEquals("second", SecondMutable.getValue());
+        }
+    }
+
+    @Test
+    public void testStable() {
+        assertTrue(Stable.getValue());
+        try (OverrideScope s = OptionValue.override(Stable, false)) {
+            fail("cannot override stable option");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void toStringTest() {
+        assertEquals("jdk.vm.ci.options.test.TestOptionValue$Options.Mutable=original", Mutable.toString());
+        try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) {
+            assertEquals("jdk.vm.ci.options.test.TestOptionValue$Options.Mutable=override1", Mutable.toString());
+            try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) {
+                assertEquals("jdk.vm.ci.options.test.TestOptionValue$Options.Mutable=override2", Mutable.toString());
+            }
+        }
+    }
+
+    @Test
+    public void getValuesTest() {
+        assertEquals(Arrays.asList("original"), Mutable.getValues(null));
+        assertEquals(Arrays.asList(true), Stable.getValues(null));
+        try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) {
+            assertEquals(Arrays.asList("override1", "original"), Mutable.getValues(null));
+            try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) {
+                assertEquals(Arrays.asList("override2", "override1", "original"), Mutable.getValues(null));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile ConstantTest.java FieldUniverse.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ConstantTest
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+public class ConstantTest extends FieldUniverse {
+
+    @Test
+    public void testNegativeZero() {
+        Assert.assertTrue("Constant for 0.0f must be different from -0.0f", JavaConstant.FLOAT_0 != JavaConstant.forFloat(-0.0F));
+        Assert.assertTrue("Constant for 0.0d must be different from -0.0d", JavaConstant.DOUBLE_0 != JavaConstant.forDouble(-0.0d));
+    }
+
+    @Test
+    public void testNullIsNull() {
+        Assert.assertTrue(JavaConstant.NULL_POINTER.isNull());
+    }
+
+    @Test
+    public void testOne() {
+        for (JavaKind kind : JavaKind.values()) {
+            if (kind.isNumericInteger() || kind.isNumericFloat()) {
+                Assert.assertTrue(JavaConstant.one(kind).getJavaKind() == kind);
+            }
+        }
+        Assert.assertEquals(1, JavaConstant.one(JavaKind.Int).asInt());
+        Assert.assertEquals(1L, JavaConstant.one(JavaKind.Long).asLong());
+        Assert.assertEquals(1, JavaConstant.one(JavaKind.Byte).asInt());
+        Assert.assertEquals(1, JavaConstant.one(JavaKind.Short).asInt());
+        Assert.assertEquals(1, JavaConstant.one(JavaKind.Char).asInt());
+        Assert.assertTrue(1F == JavaConstant.one(JavaKind.Float).asFloat());
+        Assert.assertTrue(1D == JavaConstant.one(JavaKind.Double).asDouble());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testIllegalOne() {
+        JavaConstant.one(JavaKind.Illegal);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testVoidOne() {
+        JavaConstant.one(JavaKind.Void);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/FieldUniverse.java	Thu Oct 22 11:13:08 2015 -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.
+ */
+package jdk.vm.ci.runtime.test;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Context for field related tests.
+ */
+public class FieldUniverse extends TypeUniverse {
+
+    public static final Map<Field, ResolvedJavaField> fields = new HashMap<>();
+
+    {
+        for (Class<?> c : classes) {
+            for (Field f : c.getDeclaredFields()) {
+                ResolvedJavaField field = metaAccess.lookupJavaField(f);
+                fields.put(f, field);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/MethodUniverse.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,49 @@
+/*
+ * 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 jdk.vm.ci.runtime.test;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+/**
+ * Context for method related tests.
+ */
+public class MethodUniverse extends TypeUniverse {
+
+    public static final Map<Method, ResolvedJavaMethod> methods = new HashMap<>();
+    public static final Map<Constructor<?>, ResolvedJavaMethod> constructors = new HashMap<>();
+
+    {
+        for (Class<?> c : classes) {
+            for (Method m : c.getDeclaredMethods()) {
+                ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
+                methods.put(m, method);
+            }
+            for (Constructor<?> m : c.getDeclaredConstructors()) {
+                constructors.put(m, metaAccess.lookupJavaMethod(m));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/NameAndSignature.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+package jdk.vm.ci.runtime.test;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+
+class NameAndSignature {
+
+    public static final MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+
+    final String name;
+    final Class<?> returnType;
+    final Class<?>[] parameterTypes;
+
+    public NameAndSignature(Method m) {
+        this.name = m.getName();
+        this.returnType = m.getReturnType();
+        this.parameterTypes = m.getParameterTypes();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof NameAndSignature) {
+            NameAndSignature s = (NameAndSignature) obj;
+            return s.returnType == returnType && name.equals(s.name) && Arrays.equals(s.parameterTypes, parameterTypes);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(name + "(");
+        String sep = "";
+        for (Class<?> p : parameterTypes) {
+            sb.append(sep);
+            sep = ", ";
+            sb.append(p.getName());
+        }
+        return sb.append(')').append(returnType.getName()).toString();
+    }
+
+    public boolean signatureEquals(ResolvedJavaMethod m) {
+        Signature s = m.getSignature();
+        ResolvedJavaType declaringClass = m.getDeclaringClass();
+        if (!s.getReturnType(declaringClass).resolve(declaringClass).equals(metaAccess.lookupJavaType(returnType))) {
+            return false;
+        }
+        if (s.getParameterCount(false) != parameterTypes.length) {
+            return false;
+        }
+        for (int i = 0; i < parameterTypes.length; i++) {
+            if (!s.getParameterType(i, declaringClass).resolve(declaringClass).equals(metaAccess.lookupJavaType(parameterTypes[i]))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2011, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile RedefineClassTest.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.RedefineClassTest
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assume.*;
+
+import java.io.*;
+import java.lang.instrument.*;
+import java.lang.management.*;
+import java.lang.reflect.*;
+import java.nio.file.*;
+import java.security.*;
+import java.util.*;
+import java.util.jar.*;
+
+import javax.tools.*;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+/**
+ * Tests that {@link ResolvedJavaMethod}s are safe in the context of class redefinition being used
+ * to redefine the method to which they refer.
+ */
+public class RedefineClassTest extends TypeUniverse {
+
+    static class Foo {
+        public static Object getName() {
+            return "foo";
+        }
+    }
+
+    @Test
+    public void test() throws Throwable {
+
+        Method fooMethod = Foo.class.getDeclaredMethod("getName");
+
+        ResolvedJavaMethod foo1 = metaAccess.lookupJavaMethod(fooMethod);
+        ResolvedJavaMethod foo2 = metaAccess.lookupJavaMethod(fooMethod);
+
+        String foo1Code = Arrays.toString(foo1.getCode());
+        String foo2Code = Arrays.toString(foo2.getCode());
+
+        Assert.assertEquals("foo", Foo.getName());
+
+        redefineFoo();
+        System.gc();
+
+        // Make sure the transformation happened
+        Assert.assertEquals("bar", Foo.getName());
+
+        Assert.assertEquals(foo1Code, Arrays.toString(foo1.getCode()));
+        Assert.assertEquals(foo2Code, Arrays.toString(foo1.getCode()));
+    }
+
+    /**
+     * Adds the class file bytes for a given class to a JAR stream.
+     */
+    static void add(JarOutputStream jar, Class<?> c) throws IOException {
+        String name = c.getName();
+        String classAsPath = name.replace('.', '/') + ".class";
+        jar.putNextEntry(new JarEntry(classAsPath));
+
+        InputStream stream = c.getClassLoader().getResourceAsStream(classAsPath);
+
+        int nRead;
+        byte[] buf = new byte[1024];
+        while ((nRead = stream.read(buf, 0, buf.length)) != -1) {
+            jar.write(buf, 0, nRead);
+        }
+
+        jar.closeEntry();
+    }
+
+    protected void redefineFoo() throws Exception {
+        Manifest manifest = new Manifest();
+        manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+        Attributes mainAttrs = manifest.getMainAttributes();
+        mainAttrs.putValue("Agent-Class", FooAgent.class.getName());
+        mainAttrs.putValue("Can-Redefine-Classes", "true");
+        mainAttrs.putValue("Can-Retransform-Classes", "true");
+
+        Path jar = Files.createTempFile("myagent", ".jar");
+        try {
+            JarOutputStream jarStream = new JarOutputStream(new FileOutputStream(jar.toFile()), manifest);
+            add(jarStream, FooAgent.class);
+            add(jarStream, FooTransformer.class);
+            jarStream.close();
+
+            loadAgent(jar);
+        } finally {
+            Files.deleteIfExists(jar);
+        }
+    }
+
+    public static void loadAgent(Path agent) throws Exception {
+        String vmName = ManagementFactory.getRuntimeMXBean().getName();
+        int p = vmName.indexOf('@');
+        assumeTrue(p != -1);
+        String pid = vmName.substring(0, p);
+        ClassLoader cl = ToolProvider.getSystemToolClassLoader();
+        Class<?> c = Class.forName("com.sun.tools.attach.VirtualMachine", true, cl);
+        Method attach = c.getDeclaredMethod("attach", String.class);
+        Method loadAgent = c.getDeclaredMethod("loadAgent", String.class, String.class);
+        Method detach = c.getDeclaredMethod("detach");
+        Object vm = attach.invoke(null, pid);
+        loadAgent.invoke(vm, agent.toString(), "");
+        detach.invoke(vm);
+    }
+
+    public static class FooAgent {
+
+        public static void agentmain(@SuppressWarnings("unused") String args, Instrumentation inst) throws Exception {
+            if (inst.isRedefineClassesSupported() && inst.isRetransformClassesSupported()) {
+                inst.addTransformer(new FooTransformer(), true);
+                Class<?>[] allClasses = inst.getAllLoadedClasses();
+                for (int i = 0; i < allClasses.length; i++) {
+                    Class<?> c = allClasses[i];
+                    if (c == Foo.class) {
+                        inst.retransformClasses(new Class<?>[]{c});
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * This transformer replaces the first instance of the constant "foo" in the class file for
+     * {@link Foo} with "bar".
+     */
+    static class FooTransformer implements ClassFileTransformer {
+
+        @Override
+        public byte[] transform(ClassLoader cl, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
+            if (Foo.class.equals(classBeingRedefined)) {
+                String cf = new String(classfileBuffer);
+                int i = cf.indexOf("foo");
+                Assert.assertTrue("cannot find \"foo\" constant in " + Foo.class.getSimpleName() + "'s class file", i > 0);
+                classfileBuffer[i] = 'b';
+                classfileBuffer[i + 1] = 'a';
+                classfileBuffer[i + 2] = 'r';
+            }
+            return classfileBuffer;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2014, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveConcreteMethodTest
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assert.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+
+import org.junit.*;
+
+public class ResolvedJavaTypeResolveConcreteMethodTest {
+    public final MetaAccessProvider metaAccess;
+
+    public ResolvedJavaTypeResolveConcreteMethodTest() {
+        metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+    }
+
+    protected abstract static class A {
+        @SuppressWarnings("unused")
+        private void priv() {
+        }
+
+        public void v1() {
+        }
+
+        public void v2() {
+        }
+
+        public abstract void abs();
+    }
+
+    protected static class B extends A implements I {
+        public void i() {
+        }
+
+        @Override
+        public void v2() {
+        }
+
+        @Override
+        public void abs() {
+
+        }
+    }
+
+    protected static class C extends B {
+        public void d() {
+        }
+    }
+
+    protected abstract static class D extends A {
+
+    }
+
+    protected static class E extends D {
+        @Override
+        public void abs() {
+        }
+    }
+
+    protected interface I {
+        void i();
+
+        default void d() {
+        }
+    }
+
+    @Test
+    public void testDefaultMethod() {
+        ResolvedJavaType i = getType(I.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaMethod di = getMethod(i, "d");
+        ResolvedJavaMethod dc = getMethod(c, "d");
+
+        assertEquals(di, i.resolveConcreteMethod(di, c));
+        assertEquals(di, b.resolveConcreteMethod(di, c));
+        assertEquals(dc, c.resolveConcreteMethod(di, c));
+    }
+
+    @Test
+    public void testPrivateMethod() {
+        ResolvedJavaType a = getType(A.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaMethod priv = getMethod(a, "priv");
+
+        assertNull(a.resolveConcreteMethod(priv, c));
+        assertNull(b.resolveConcreteMethod(priv, c));
+    }
+
+    @Test
+    public void testAbstractMethod() {
+        ResolvedJavaType a = getType(A.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaType d = getType(D.class);
+        ResolvedJavaType e = getType(E.class);
+        ResolvedJavaMethod absa = getMethod(a, "abs");
+        ResolvedJavaMethod absb = getMethod(b, "abs");
+        ResolvedJavaMethod abse = getMethod(e, "abs");
+
+        assertNull(a.resolveConcreteMethod(absa, c));
+        assertNull(d.resolveConcreteMethod(absa, c));
+
+        assertEquals(absb, b.resolveConcreteMethod(absa, c));
+        assertEquals(absb, b.resolveConcreteMethod(absb, c));
+        assertEquals(absb, c.resolveConcreteMethod(absa, c));
+        assertEquals(absb, c.resolveConcreteMethod(absb, c));
+        assertEquals(abse, e.resolveConcreteMethod(absa, c));
+        assertNull(e.resolveConcreteMethod(absb, c));
+        assertEquals(abse, e.resolveConcreteMethod(abse, c));
+    }
+
+    @Test
+    public void testVirtualMethod() {
+        ResolvedJavaType a = getType(A.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaMethod v1a = getMethod(a, "v1");
+        ResolvedJavaMethod v2a = getMethod(a, "v2");
+        ResolvedJavaMethod v2b = getMethod(b, "v2");
+
+        assertEquals(v1a, a.resolveConcreteMethod(v1a, c));
+        assertEquals(v1a, b.resolveConcreteMethod(v1a, c));
+        assertEquals(v1a, c.resolveConcreteMethod(v1a, c));
+        assertEquals(v2a, a.resolveConcreteMethod(v2a, c));
+        assertEquals(v2b, b.resolveConcreteMethod(v2a, c));
+        assertEquals(v2b, b.resolveConcreteMethod(v2b, c));
+        assertEquals(v2b, c.resolveConcreteMethod(v2a, c));
+        assertEquals(v2b, c.resolveConcreteMethod(v2b, c));
+
+    }
+
+    static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) {
+        for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
+            if (method.getName().equals(methodName)) {
+                return method;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
+
+    protected ResolvedJavaType getType(Class<?> clazz) {
+        ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
+        type.initialize();
+        return type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2014, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveMethodTest
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assert.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+
+import org.junit.*;
+
+public class ResolvedJavaTypeResolveMethodTest {
+    public final MetaAccessProvider metaAccess;
+
+    public ResolvedJavaTypeResolveMethodTest() {
+        metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+    }
+
+    protected abstract static class A {
+        @SuppressWarnings("unused")
+        private void priv() {
+        }
+
+        public void v1() {
+        }
+
+        public void v2() {
+        }
+
+        public abstract void abs();
+    }
+
+    protected static class B extends A implements I {
+        public void i() {
+        }
+
+        @Override
+        public void v2() {
+        }
+
+        @Override
+        public void abs() {
+
+        }
+    }
+
+    protected static class C extends B {
+        public void d() {
+        }
+    }
+
+    protected abstract static class D extends A {
+
+    }
+
+    protected static class E extends D {
+        @Override
+        public void abs() {
+        }
+    }
+
+    protected interface I {
+        void i();
+
+        default void d() {
+        }
+    }
+
+    @Test
+    public void testDefaultMethod() {
+        ResolvedJavaType i = getType(I.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaMethod di = getMethod(i, "d");
+        ResolvedJavaMethod dc = getMethod(c, "d");
+
+        assertEquals(di, i.resolveMethod(di, c));
+        assertEquals(di, b.resolveMethod(di, c));
+        assertEquals(dc, c.resolveMethod(di, c));
+    }
+
+    @Test
+    public void testPrivateMethod() {
+        ResolvedJavaType a = getType(A.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaMethod priv = getMethod(a, "priv");
+
+        assertNull(a.resolveMethod(priv, c));
+        assertNull(b.resolveMethod(priv, c));
+    }
+
+    @Test
+    public void testAbstractMethod() {
+        ResolvedJavaType a = getType(A.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaType d = getType(D.class);
+        ResolvedJavaType e = getType(E.class);
+        ResolvedJavaMethod absa = getMethod(a, "abs");
+        ResolvedJavaMethod absb = getMethod(b, "abs");
+        ResolvedJavaMethod abse = getMethod(e, "abs");
+
+        assertEquals(absa, a.resolveMethod(absa, c));
+        assertEquals(absa, d.resolveMethod(absa, c));
+
+        assertEquals(absb, b.resolveMethod(absa, c));
+        assertEquals(absb, b.resolveMethod(absb, c));
+        assertEquals(absb, c.resolveMethod(absa, c));
+        assertEquals(absb, c.resolveMethod(absb, c));
+        assertEquals(abse, e.resolveMethod(absa, c));
+        assertNull(e.resolveMethod(absb, c));
+        assertEquals(abse, e.resolveMethod(abse, c));
+    }
+
+    @Test
+    public void testVirtualMethod() {
+        ResolvedJavaType a = getType(A.class);
+        ResolvedJavaType b = getType(B.class);
+        ResolvedJavaType c = getType(C.class);
+        ResolvedJavaMethod v1a = getMethod(a, "v1");
+        ResolvedJavaMethod v2a = getMethod(a, "v2");
+        ResolvedJavaMethod v2b = getMethod(b, "v2");
+
+        assertEquals(v1a, a.resolveMethod(v1a, c));
+        assertEquals(v1a, b.resolveMethod(v1a, c));
+        assertEquals(v1a, c.resolveMethod(v1a, c));
+        assertEquals(v2a, a.resolveMethod(v2a, c));
+        assertEquals(v2b, b.resolveMethod(v2a, c));
+        assertEquals(v2b, b.resolveMethod(v2b, c));
+        assertEquals(v2b, c.resolveMethod(v2a, c));
+        assertEquals(v2b, c.resolveMethod(v2b, c));
+
+    }
+
+    static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) {
+        for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
+            if (method.getName().equals(methodName)) {
+                return method;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
+
+    protected ResolvedJavaType getType(Class<?> clazz) {
+        ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
+        type.initialize();
+        return type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestConstantReflectionProvider.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestConstantReflectionProvider
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+/**
+ * Tests for {@link ConstantReflectionProvider}. It assumes an implementation of the interface that
+ * actually returns non-null results for access operations that are possible, i.e., the tests will
+ * fail for an implementation that spuriously returns null (which is allowed by the specification).
+ */
+public class TestConstantReflectionProvider extends TypeUniverse {
+
+    @Test
+    public void constantEqualsTest() {
+        for (ConstantValue c1 : constants()) {
+            for (ConstantValue c2 : constants()) {
+                // test symmetry
+                assertEquals(constantReflection.constantEquals(c1.value, c2.value), constantReflection.constantEquals(c2.value, c1.value));
+                if (c1.value.getJavaKind() != JavaKind.Object && c2.value.getJavaKind() != JavaKind.Object) {
+                    assertEquals(c1.value.equals(c2.value), constantReflection.constantEquals(c2.value, c1.value));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void readArrayLengthTest() {
+        for (ConstantValue cv : constants()) {
+            JavaConstant c = cv.value;
+            Integer actual = constantReflection.readArrayLength(c);
+            if (c.getJavaKind() != JavaKind.Object || c.isNull() || !cv.boxed.getClass().isArray()) {
+                assertNull(actual);
+            } else {
+                assertNotNull(actual);
+                int actualInt = actual;
+                assertEquals(Array.getLength(cv.boxed), actualInt);
+            }
+        }
+    }
+
+    static class PrimitiveConstants {
+        static final long LONG_CONST = 42;
+        static final int INT_CONST = 66;
+        static final byte BYTE_CONST = 123;
+        static final boolean BOOL_CONST = true;
+    }
+
+    static class BoxedConstants {
+        static final Long LONG_CONST = 42L;
+        static final Integer INT_CONST = 66;
+        static final Byte BYTE_CONST = 123;
+        static final Boolean BOOL_CONST = true;
+    }
+
+    @Test
+    public void boxTest() {
+        for (ConstantValue cv : constants()) {
+            JavaConstant c = cv.value;
+            JavaConstant boxed = constantReflection.boxPrimitive(c);
+            if (boxed != null && c.getJavaKind().isPrimitive()) {
+                assertTrue(boxed.getJavaKind().isObject());
+                assertFalse(boxed.isNull());
+            }
+        }
+
+        List<ConstantValue> primitiveConstants = readConstants(PrimitiveConstants.class);
+        List<ConstantValue> boxedConstants = readConstants(BoxedConstants.class);
+        for (int i = 0; i < primitiveConstants.size(); i++) {
+            ConstantValue prim = primitiveConstants.get(i);
+            ConstantValue box = boxedConstants.get(i);
+            assertEquals(box.value, constantReflection.boxPrimitive(prim.value));
+        }
+
+        assertNull(constantReflection.boxPrimitive(JavaConstant.NULL_POINTER));
+    }
+
+    @Test
+    public void unboxTest() {
+        for (ConstantValue cv : constants()) {
+            JavaConstant c = cv.value;
+            JavaConstant unboxed = c.isNull() ? null : constantReflection.unboxPrimitive(c);
+            if (unboxed != null) {
+                assertFalse(unboxed.getJavaKind().isObject());
+            }
+        }
+        List<ConstantValue> primitiveConstants = readConstants(PrimitiveConstants.class);
+        List<ConstantValue> boxedConstants = readConstants(BoxedConstants.class);
+        for (int i = 0; i < primitiveConstants.size(); i++) {
+            ConstantValue prim = primitiveConstants.get(i);
+            ConstantValue box = boxedConstants.get(i);
+            assert prim.getSimpleName().equals(box.getSimpleName());
+            assertEquals(prim.value, constantReflection.unboxPrimitive(box.value));
+        }
+
+        assertNull(constantReflection.unboxPrimitive(JavaConstant.NULL_POINTER));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestJavaField.java FieldUniverse.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestJavaField
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+/**
+ * Tests for {@link JavaField}.
+ */
+public class TestJavaField extends FieldUniverse {
+
+    @Test
+    public void getNameTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            String expected = e.getKey().getName();
+            String actual = e.getValue().getName();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getTypeTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            // Must resolve types first as a resolved types != unresolved types
+            ResolvedJavaField rf = e.getValue();
+            JavaType expected = metaAccess.lookupJavaType(e.getKey().getType()).resolve(rf.getDeclaringClass());
+            JavaType actual = rf.getType().resolve(rf.getDeclaringClass());
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getJavaKindTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            JavaKind expected = metaAccess.lookupJavaType(e.getKey().getType()).getJavaKind();
+            JavaKind actual = e.getValue().getJavaKind();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getDeclaringClassTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            Class<?> expected = e.getKey().getDeclaringClass();
+            ResolvedJavaType actual = e.getValue().getDeclaringClass();
+            assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestJavaMethod.java MethodUniverse.java TypeUniverse.java TestMetaAccessProvider.java NameAndSignature.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestJavaMethod
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+/**
+ * Tests for {@link JavaMethod}.
+ */
+public class TestJavaMethod extends MethodUniverse {
+
+    @Test
+    public void getNameTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            String expected = e.getKey().getName();
+            String actual = e.getValue().getName();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getDeclaringClassTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            Class<?> expected = e.getKey().getDeclaringClass();
+            ResolvedJavaType actual = e.getValue().getDeclaringClass();
+            assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
+        }
+    }
+
+    @Test
+    public void getSignatureTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            assertTrue(new NameAndSignature(e.getKey()).signatureEquals(e.getValue()));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestJavaType.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestJavaType
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import jdk.vm.ci.meta.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+/**
+ * Tests for {@link JavaType}.
+ */
+public class TestJavaType extends TypeUniverse {
+
+    public TestJavaType() {
+    }
+
+    @Test
+    public void getJavaKindTest() {
+        for (Class<?> c : classes) {
+            JavaType type = metaAccess.lookupJavaType(c);
+            JavaKind expected = JavaKind.fromJavaClass(c);
+            JavaKind actual = type.getJavaKind();
+            assertEquals(expected, actual);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestMetaAccessProvider.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestMetaAccessProvider
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static jdk.vm.ci.meta.MetaUtil.*;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+/**
+ * Tests for {@link MetaAccessProvider}.
+ */
+public class TestMetaAccessProvider extends TypeUniverse {
+
+    @Test
+    public void lookupJavaTypeTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            assertNotNull(c.toString(), type);
+            assertEquals(c.toString(), type.getName(), toInternalName(c.getName()));
+            assertEquals(c.toString(), type.getName(), toInternalName(type.toJavaName()));
+            assertEquals(c.toString(), c.getName(), type.toClassName());
+            if (!type.isArray()) {
+                assertEquals(c.toString(), c.getName(), type.toJavaName());
+            }
+        }
+    }
+
+    @Test
+    public void lookupJavaMethodTest() {
+        for (Class<?> c : classes) {
+            for (Method reflect : c.getDeclaredMethods()) {
+                ResolvedJavaMethod method = metaAccess.lookupJavaMethod(reflect);
+                assertNotNull(method);
+                assertTrue(method.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass())));
+            }
+        }
+    }
+
+    @Test
+    public void lookupJavaFieldTest() {
+        for (Class<?> c : classes) {
+            for (Field reflect : c.getDeclaredFields()) {
+                ResolvedJavaField field = metaAccess.lookupJavaField(reflect);
+                assertNotNull(field);
+                assertTrue(field.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass())));
+            }
+        }
+    }
+
+    @Test
+    public void lookupJavaTypeConstantTest() {
+        for (ConstantValue cv : constants()) {
+            JavaConstant c = cv.value;
+            if (c.getJavaKind() == JavaKind.Object && !c.isNull()) {
+                Object o = cv.boxed;
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
+                assertNotNull(type);
+                assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass())));
+            } else {
+                assertEquals(metaAccess.lookupJavaType(c), null);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestResolvedJavaField.java FieldUniverse.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestResolvedJavaField
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assert.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+/**
+ * Tests for {@link ResolvedJavaField}.
+ */
+public class TestResolvedJavaField extends FieldUniverse {
+
+    public TestResolvedJavaField() {
+    }
+
+    @Test
+    public void getModifiersTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            int expected = e.getKey().getModifiers();
+            int actual = e.getValue().getModifiers();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void isSyntheticTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            boolean expected = e.getKey().isSynthetic();
+            boolean actual = e.getValue().isSynthetic();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getAnnotationsTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            Annotation[] expected = e.getKey().getAnnotations();
+            Annotation[] actual = e.getValue().getAnnotations();
+            assertArrayEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getAnnotationTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            for (Annotation expected : e.getKey().getAnnotations()) {
+                if (expected != null) {
+                    Annotation actual = e.getValue().getAnnotation(expected.annotationType());
+                    assertEquals(expected, actual);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void getLocationIdentityTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            LocationIdentity identity = e.getValue().getLocationIdentity();
+            assertTrue(identity != null);
+        }
+    }
+
+    static class ReadConstantValueTestConstants {
+        String stringField = "field";
+        final String constantStringField = "constantField";
+
+        static final Object CONST1 = new ReadConstantValueTestConstants();
+        static final Object CONST2 = null;
+        static final Object CONST3 = new String();
+    }
+
+    @Test
+    public void readConstantValueTest() throws NoSuchFieldException {
+        ResolvedJavaField field = metaAccess.lookupJavaField(ReadConstantValueTestConstants.class.getDeclaredField("stringField"));
+        List<ConstantValue> receiverConstants = readConstants(ReadConstantValueTestConstants.class);
+        for (ConstantValue receiver : receiverConstants) {
+            JavaConstant value = constantReflection.readConstantFieldValue(field, receiver.value);
+            assertNull(value);
+        }
+
+        ResolvedJavaField constField = metaAccess.lookupJavaField(ReadConstantValueTestConstants.class.getDeclaredField("constantStringField"));
+        for (ConstantValue receiver : receiverConstants) {
+            JavaConstant value = constantReflection.readConstantFieldValue(constField, receiver.value);
+            if (value != null) {
+                Object expected = "constantField";
+                String actual = ((ReadConstantValueTestConstants) receiver.boxed).constantStringField;
+                assertTrue(actual + " != " + expected, actual == expected);
+            }
+        }
+    }
+
+    private Method findTestMethod(Method apiMethod) {
+        String testName = apiMethod.getName() + "Test";
+        for (Method m : getClass().getDeclaredMethods()) {
+            if (m.getName().equals(testName) && m.getAnnotation(Test.class) != null) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    // @formatter:off
+    private static final String[] untestedApiMethods = {
+        "getDeclaringClass",
+        "isInternal",
+        "isFinal"
+    };
+    // @formatter:on
+
+    /**
+     * Ensures that any new methods added to {@link ResolvedJavaMethod} either have a test written
+     * for them or are added to {@link #untestedApiMethods}.
+     */
+    @Test
+    public void testCoverage() {
+        Set<String> known = new HashSet<>(Arrays.asList(untestedApiMethods));
+        for (Method m : ResolvedJavaField.class.getDeclaredMethods()) {
+            if (m.isSynthetic()) {
+                continue;
+            }
+            if (findTestMethod(m) == null) {
+                assertTrue("test missing for " + m, known.contains(m.getName()));
+            } else {
+                assertFalse("test should be removed from untestedApiMethods" + m, known.contains(m.getName()));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestResolvedJavaMethod.java MethodUniverse.java TypeUniverse.java TestMetaAccessProvider.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestResolvedJavaMethod
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static org.junit.Assert.*;
+
+import java.lang.annotation.*;
+import java.lang.invoke.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import jdk.vm.ci.meta.*;
+
+import org.junit.*;
+
+/**
+ * Tests for {@link ResolvedJavaMethod}.
+ */
+public class TestResolvedJavaMethod extends MethodUniverse {
+
+    public TestResolvedJavaMethod() {
+    }
+
+    /**
+     * @see ResolvedJavaMethod#getCode()
+     */
+    @Test
+    public void getCodeTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            byte[] code = m.getCode();
+            if (code == null) {
+                assertTrue(m.getCodeSize() == 0);
+            } else {
+                if (m.isAbstract()) {
+                    assertTrue(code.length == 0);
+                } else if (!m.isNative()) {
+                    assertTrue(code.length > 0);
+                }
+            }
+        }
+    }
+
+    /**
+     * @see ResolvedJavaMethod#getCodeSize()
+     */
+    @Test
+    public void getCodeSizeTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            int codeSize = m.getCodeSize();
+            if (m.isAbstract()) {
+                assertTrue(codeSize == 0);
+            } else if (!m.isNative()) {
+                assertTrue(codeSize > 0);
+            }
+        }
+    }
+
+    @Test
+    public void getModifiersTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            int expected = e.getKey().getModifiers();
+            int actual = m.getModifiers();
+            assertEquals(String.format("%s: 0x%x != 0x%x", m, expected, actual), expected, actual);
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            int expected = e.getKey().getModifiers();
+            int actual = m.getModifiers();
+            assertEquals(String.format("%s: 0x%x != 0x%x", m, expected, actual), expected, actual);
+        }
+    }
+
+    /**
+     * @see ResolvedJavaMethod#isClassInitializer()
+     */
+    @Test
+    public void isClassInitializerTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            // Class initializers are hidden from reflection
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isClassInitializer());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isClassInitializer());
+        }
+    }
+
+    @Test
+    public void isConstructorTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isConstructor());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertTrue(m.isConstructor());
+        }
+    }
+
+    @Test
+    public void isSyntheticTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
+        }
+    }
+
+    @Test
+    public void isBridgeTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isBridge(), m.isBridge());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(false, m.isBridge());
+        }
+    }
+
+    @Test
+    public void isVarArgsTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isVarArgs(), m.isVarArgs());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isVarArgs(), m.isVarArgs());
+        }
+    }
+
+    @Test
+    public void isSynchronizedTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized());
+        }
+    }
+
+    @Test
+    public void canBeStaticallyBoundTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey()));
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey()));
+        }
+    }
+
+    private static boolean canBeStaticallyBound(Member method) {
+        int modifiers = method.getModifiers();
+        return (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers) || Modifier.isFinal(method.getDeclaringClass().getModifiers())) &&
+                        !Modifier.isAbstract(modifiers);
+    }
+
+    private static String methodWithExceptionHandlers(String p1, Object o2) {
+        try {
+            return p1.substring(100) + o2.toString();
+        } catch (IndexOutOfBoundsException e) {
+            e.printStackTrace();
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+        } catch (RuntimeException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Test
+    public void getExceptionHandlersTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithExceptionHandlers", String.class, Object.class));
+        ExceptionHandler[] handlers = method.getExceptionHandlers();
+        assertNotNull(handlers);
+        assertEquals(handlers.length, 3);
+        handlers[0].getCatchType().equals(metaAccess.lookupJavaType(IndexOutOfBoundsException.class));
+        handlers[1].getCatchType().equals(metaAccess.lookupJavaType(NullPointerException.class));
+        handlers[2].getCatchType().equals(metaAccess.lookupJavaType(RuntimeException.class));
+    }
+
+    private static String nullPointerExceptionOnFirstLine(Object o, String ignored) {
+        return o.toString() + ignored;
+    }
+
+    @Test
+    public void asStackTraceElementTest() throws NoSuchMethodException {
+        try {
+            nullPointerExceptionOnFirstLine(null, "ignored");
+            Assert.fail("should not reach here");
+        } catch (NullPointerException e) {
+            StackTraceElement expected = e.getStackTrace()[0];
+            ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
+            StackTraceElement actual = method.asStackTraceElement(0);
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getConstantPoolTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            ConstantPool cp = m.getConstantPool();
+            assertTrue(cp.length() > 0);
+        }
+    }
+
+    @Test(timeout = 1000L)
+    public void getAnnotationTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationTest"));
+        Test annotation = method.getAnnotation(Test.class);
+        assertNotNull(annotation);
+        assertEquals(1000L, annotation.timeout());
+    }
+
+    @Test(timeout = 1000L)
+    public void getAnnotationsTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationsTest"));
+        Annotation[] annotations = method.getAnnotations();
+        assertNotNull(annotations);
+        assertEquals(1, annotations.length);
+        assertEquals(1000L, ((Test) annotations[0]).timeout());
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    @interface NonNull {
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    @interface Special {
+    }
+
+    private static native void methodWithAnnotatedParameters(@NonNull HashMap<String, String> p1, @Special @NonNull Class<? extends Annotation> p2);
+
+    @Test
+    public void getParameterAnnotationsTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        Annotation[][] annotations = method.getParameterAnnotations();
+        assertEquals(2, annotations.length);
+        assertEquals(1, annotations[0].length);
+        assertEquals(NonNull.class, annotations[0][0].annotationType());
+        assertEquals(2, annotations[1].length);
+        assertEquals(Special.class, annotations[1][0].annotationType());
+        assertEquals(NonNull.class, annotations[1][1].annotationType());
+    }
+
+    @Test
+    public void getGenericParameterTypesTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        Type[] genericParameterTypes = method.getGenericParameterTypes();
+        assertEquals(2, genericParameterTypes.length);
+        assertEquals("java.util.HashMap<java.lang.String, java.lang.String>", genericParameterTypes[0].toString());
+        assertEquals("java.lang.Class<? extends java.lang.annotation.Annotation>", genericParameterTypes[1].toString());
+    }
+
+    @Test
+    public void getMaxLocalsTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        ResolvedJavaMethod method2 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
+        assertEquals(0, method1.getMaxLocals());
+        assertEquals(2, method2.getMaxLocals());
+
+    }
+
+    @Test
+    public void getMaxStackSizeTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        ResolvedJavaMethod method2 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
+        assertEquals(0, method1.getMaxStackSize());
+        // some versions of javac produce bytecode with a stacksize of 2 for this method
+        // JSR 292 also sometimes need one more stack slot
+        int method2StackSize = method2.getMaxStackSize();
+        assertTrue(2 <= method2StackSize && method2StackSize <= 4);
+    }
+
+    @Test
+    public void isDefaultTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isDefault(), m.isDefault());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isDefault());
+        }
+    }
+
+    @Test
+    public void hasReceiverTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertTrue(m.hasReceiver() != Modifier.isStatic(e.getKey().getModifiers()));
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertTrue(m.hasReceiver());
+        }
+    }
+
+    @Test
+    public void hasBytecodesTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertTrue(m.hasBytecodes() == (m.isConcrete() && !m.isNative()));
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertTrue(m.hasBytecodes());
+        }
+    }
+
+    @Test
+    public void isJavaLangObjectInitTest() throws NoSuchMethodException {
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(Object.class.getConstructor());
+        assertTrue(method.isJavaLangObjectInit());
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isJavaLangObjectInit());
+        }
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            Constructor<?> key = e.getKey();
+            if (key.getDeclaringClass() == Object.class && key.getParameters().length == 0) {
+                assertTrue(m.isJavaLangObjectInit());
+            } else {
+                assertFalse(m.isJavaLangObjectInit());
+            }
+        }
+    }
+
+    @Test
+    public void isSignaturePolymorphicTest() {
+        ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class);
+        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeExact", metaAccess));
+        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invoke", metaAccess));
+        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeBasic", metaAccess));
+        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToVirtual", metaAccess));
+        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToStatic", metaAccess));
+        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToSpecial", metaAccess));
+        assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToInterface", metaAccess));
+        assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "type", metaAccess));
+        assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(metaAccess.lookupJavaType(Object.class), "toString", metaAccess));
+    }
+
+    private Method findTestMethod(Method apiMethod) {
+        String testName = apiMethod.getName() + "Test";
+        for (Method m : getClass().getDeclaredMethods()) {
+            if (m.getName().equals(testName) && m.getAnnotation(Test.class) != null) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    // @formatter:off
+    private static final String[] untestedApiMethods = {
+        "invoke",
+        "newInstance",
+        "getDeclaringClass",
+        "getEncoding",
+        "getProfilingInfo",
+        "reprofile",
+        "getCompilerStorage",
+        "canBeInlined",
+        "shouldBeInlined",
+        "getLineNumberTable",
+        "getLocalVariableTable",
+        "isInVirtualMethodTable",
+        "toParameterTypes",
+        "getParameterAnnotation",
+        "getSpeculationLog",
+        "isFinal",
+        "$jacocoInit"
+    };
+    // @formatter:on
+
+    /**
+     * Ensures that any new methods added to {@link ResolvedJavaMethod} either have a test written
+     * for them or are added to {@link #untestedApiMethods}.
+     */
+    @Test
+    public void testCoverage() {
+        Set<String> known = new HashSet<>(Arrays.asList(untestedApiMethods));
+        for (Method m : ResolvedJavaMethod.class.getDeclaredMethods()) {
+            if (Modifier.isStatic(m.getModifiers())) {
+                continue;
+            }
+            if (findTestMethod(m) == null) {
+                assertTrue("test missing for " + m, known.contains(m.getName()));
+            } else {
+                assertFalse("test should be removed from untestedApiMethods" + m, known.contains(m.getName()));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,947 @@
+/*
+ * Copyright (c) 2012, 2015, 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
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @compile TestResolvedJavaType.java TypeUniverse.java TestMetaAccessProvider.java NameAndSignature.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestResolvedJavaType
+ */
+
+package jdk.vm.ci.runtime.test;
+
+import static java.lang.reflect.Modifier.*;
+import static org.junit.Assert.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+
+import jdk.vm.ci.common.*;
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Assumptions.*;
+
+import org.junit.*;
+
+import sun.reflect.ConstantPool;
+
+/**
+ * Tests for {@link ResolvedJavaType}.
+ */
+public class TestResolvedJavaType extends TypeUniverse {
+
+    public TestResolvedJavaType() {
+    }
+
+    @Test
+    public void findInstanceFieldWithOffsetTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            Set<Field> reflectionFields = getInstanceFields(c, true);
+            for (Field f : reflectionFields) {
+                ResolvedJavaField rf = lookupField(type.getInstanceFields(true), f);
+                assertNotNull(rf);
+                long offset = isStatic(f.getModifiers()) ? unsafe.staticFieldOffset(f) : unsafe.objectFieldOffset(f);
+                ResolvedJavaField result = type.findInstanceFieldWithOffset(offset, rf.getJavaKind());
+                assertNotNull(result);
+                assertTrue(fieldsEqual(f, result));
+            }
+        }
+    }
+
+    @Test
+    public void isInterfaceTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            boolean expected = c.isInterface();
+            boolean actual = type.isInterface();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void isInstanceClassTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            boolean expected = !c.isArray() && !c.isPrimitive() && !c.isInterface();
+            boolean actual = type.isInstanceClass();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void isArrayTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            boolean expected = c.isArray();
+            boolean actual = type.isArray();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getModifiersTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            int expected = c.getModifiers() & ModifiersProvider.jvmClassModifiers();
+            int actual = type.getModifiers() & ModifiersProvider.jvmClassModifiers();
+            Class<?> elementalType = c;
+            while (elementalType.isArray()) {
+                elementalType = elementalType.getComponentType();
+            }
+            if (elementalType.isMemberClass()) {
+                // member class get their modifiers from the inner-class attribute in the JVM and
+                // from the classfile header in jvmci
+                expected &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
+                actual &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
+            }
+            assertEquals(String.format("%s: 0x%x != 0x%x", type, expected, actual), expected, actual);
+        }
+    }
+
+    @Test
+    public void isAssignableFromTest() {
+        Class<?>[] all = classes.toArray(new Class<?>[classes.size()]);
+        for (int i = 0; i < all.length; i++) {
+            Class<?> c1 = all[i];
+            for (int j = i; j < all.length; j++) {
+                Class<?> c2 = all[j];
+                ResolvedJavaType t1 = metaAccess.lookupJavaType(c1);
+                ResolvedJavaType t2 = metaAccess.lookupJavaType(c2);
+                boolean expected = c1.isAssignableFrom(c2);
+                boolean actual = t1.isAssignableFrom(t2);
+                assertEquals(expected, actual);
+                if (expected && t1 != t2) {
+                    assertFalse(t2.isAssignableFrom(t1));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void isInstanceTest() {
+        for (ConstantValue cv : constants()) {
+            JavaConstant c = cv.value;
+            if (c.getJavaKind() == JavaKind.Object && !c.isNull()) {
+                ResolvedJavaType cType = metaAccess.lookupJavaType(c);
+                for (ResolvedJavaType t : javaTypes) {
+                    if (t.isAssignableFrom(cType)) {
+                        assertTrue(t.isInstance(c));
+                    } else {
+                        assertFalse(t.isInstance(c));
+                    }
+                }
+            }
+        }
+    }
+
+    private static Class<?> asExactClass(Class<?> c) {
+        if (c.isArray()) {
+            if (asExactClass(c.getComponentType()) != null) {
+                return c;
+            }
+        } else {
+            if (c.isPrimitive() || Modifier.isFinal(c.getModifiers())) {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    @Test
+    public void asExactTypeTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            ResolvedJavaType exactType = type.asExactType();
+            Class<?> expected = asExactClass(c);
+            if (expected == null) {
+                assertTrue("exact(" + c.getName() + ") != null", exactType == null);
+            } else {
+                assertNotNull(exactType);
+                assertTrue(exactType.equals(metaAccess.lookupJavaType(expected)));
+            }
+        }
+    }
+
+    @Test
+    public void getSuperclassTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            Class<?> expected = c.getSuperclass();
+            ResolvedJavaType actual = type.getSuperclass();
+            if (expected == null) {
+                assertTrue(actual == null);
+            } else {
+                assertNotNull(actual);
+                assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
+            }
+        }
+    }
+
+    @Test
+    public void getInterfacesTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            Class<?>[] expected = c.getInterfaces();
+            ResolvedJavaType[] actual = type.getInterfaces();
+            assertEquals(expected.length, actual.length);
+            for (int i = 0; i < expected.length; i++) {
+                assertTrue(actual[i].equals(metaAccess.lookupJavaType(expected[i])));
+            }
+        }
+    }
+
+    public Class<?> getSupertype(Class<?> c) {
+        assert !c.isPrimitive();
+        if (c.isArray()) {
+            Class<?> componentType = c.getComponentType();
+            if (componentType.isPrimitive() || componentType == Object.class) {
+                return Object.class;
+            }
+            return getArrayClass(getSupertype(componentType));
+        }
+        if (c.isInterface()) {
+            return Object.class;
+        }
+        return c.getSuperclass();
+    }
+
+    public Class<?> findLeastCommonAncestor(Class<?> c1Initial, Class<?> c2Initial) {
+        if (c1Initial.isPrimitive() || c2Initial.isPrimitive()) {
+            return null;
+        } else {
+            Class<?> c1 = c1Initial;
+            Class<?> c2 = c2Initial;
+            while (true) {
+                if (c1.isAssignableFrom(c2)) {
+                    return c1;
+                }
+                if (c2.isAssignableFrom(c1)) {
+                    return c2;
+                }
+                c1 = getSupertype(c1);
+                c2 = getSupertype(c2);
+            }
+        }
+    }
+
+    @Test
+    public void findLeastCommonAncestorTest() {
+        Class<?>[] all = classes.toArray(new Class<?>[classes.size()]);
+        for (int i = 0; i < all.length; i++) {
+            Class<?> c1 = all[i];
+            for (int j = i; j < all.length; j++) {
+                Class<?> c2 = all[j];
+                ResolvedJavaType t1 = metaAccess.lookupJavaType(c1);
+                ResolvedJavaType t2 = metaAccess.lookupJavaType(c2);
+                Class<?> expected = findLeastCommonAncestor(c1, c2);
+                ResolvedJavaType actual = t1.findLeastCommonAncestor(t2);
+                if (expected == null) {
+                    assertTrue(actual == null);
+                } else {
+                    assertNotNull(actual);
+                    assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
+                }
+            }
+        }
+    }
+
+    private static class Base {
+    }
+
+    abstract static class Abstract1 extends Base {
+    }
+
+    interface Interface1 {
+    }
+
+    static class Concrete1 extends Abstract1 {
+    }
+
+    static class Concrete2 extends Abstract1 implements Interface1 {
+    }
+
+    static class Concrete3 extends Concrete2 {
+    }
+
+    static final class Final1 extends Abstract1 {
+    }
+
+    abstract static class Abstract4 extends Concrete3 {
+    }
+
+    void checkConcreteSubtype(ResolvedJavaType type, ResolvedJavaType expected) {
+        AssumptionResult<ResolvedJavaType> leafConcreteSubtype = type.findLeafConcreteSubtype();
+        if (leafConcreteSubtype == null) {
+            // findLeafConcreteSubtype() is conservative
+        } else {
+            if (expected == null) {
+                assertNull(leafConcreteSubtype);
+            } else {
+                assertTrue(leafConcreteSubtype.getResult().equals(expected));
+            }
+        }
+
+        if (!type.isArray()) {
+            ResolvedJavaType arrayType = type.getArrayClass();
+            AssumptionResult<ResolvedJavaType> arraySubtype = arrayType.findLeafConcreteSubtype();
+            if (arraySubtype != null) {
+                assertEquals(arraySubtype.getResult(), arrayType);
+            } else {
+                // findLeafConcreteSubtype() method is conservative
+            }
+        }
+    }
+
+    @Test
+    public void findLeafConcreteSubtypeTest() {
+        ResolvedJavaType base = metaAccess.lookupJavaType(Base.class);
+        checkConcreteSubtype(base, base);
+
+        ResolvedJavaType a1 = metaAccess.lookupJavaType(Abstract1.class);
+        ResolvedJavaType c1 = metaAccess.lookupJavaType(Concrete1.class);
+
+        checkConcreteSubtype(base, null);
+        checkConcreteSubtype(a1, c1);
+        checkConcreteSubtype(c1, c1);
+
+        ResolvedJavaType i1 = metaAccess.lookupJavaType(Interface1.class);
+        ResolvedJavaType c2 = metaAccess.lookupJavaType(Concrete2.class);
+
+        checkConcreteSubtype(base, null);
+        checkConcreteSubtype(a1, null);
+        checkConcreteSubtype(c1, c1);
+        checkConcreteSubtype(i1, c2);
+        checkConcreteSubtype(c2, c2);
+
+        ResolvedJavaType c3 = metaAccess.lookupJavaType(Concrete3.class);
+        checkConcreteSubtype(c2, null);
+        checkConcreteSubtype(c3, c3);
+
+        ResolvedJavaType a4 = metaAccess.lookupJavaType(Abstract4.class);
+        checkConcreteSubtype(c3, null);
+        checkConcreteSubtype(a4, null);
+
+        ResolvedJavaType a1a = metaAccess.lookupJavaType(Abstract1[].class);
+        checkConcreteSubtype(a1a, null);
+        ResolvedJavaType c1a = metaAccess.lookupJavaType(Concrete1[].class);
+        checkConcreteSubtype(c1a, null);
+        ResolvedJavaType f1a = metaAccess.lookupJavaType(Final1[].class);
+        checkConcreteSubtype(f1a, f1a);
+
+        ResolvedJavaType obja = metaAccess.lookupJavaType(Object[].class);
+        checkConcreteSubtype(obja, null);
+
+        ResolvedJavaType inta = metaAccess.lookupJavaType(int[].class);
+        checkConcreteSubtype(inta, inta);
+    }
+
+    interface NoImplementor {
+    }
+
+    interface SingleImplementorInterface {
+    }
+
+    static class SingleConcreteImplementor implements SingleImplementorInterface {
+    }
+
+    interface SingleAbstractImplementorInterface {
+    }
+
+    abstract static class SingleAbstractImplementor implements SingleAbstractImplementorInterface {
+    }
+
+    interface MultiImplementorInterface {
+    }
+
+    static class ConcreteImplementor1 implements MultiImplementorInterface {
+    }
+
+    static class ConcreteImplementor2 implements MultiImplementorInterface {
+    }
+
+    interface MultipleAbstractImplementorInterface {
+    }
+
+    abstract static class MultiAbstractImplementor1 implements MultipleAbstractImplementorInterface {
+    }
+
+    abstract static class MultiAbstractImplementor2 implements MultipleAbstractImplementorInterface {
+    }
+
+    interface SingleAbstractImplementorInterface2 {
+    }
+
+    interface ExtendedSingleImplementorInterface {
+    }
+
+    abstract static class SingleAbstractImplementor2 implements SingleAbstractImplementorInterface2 {
+    }
+
+    static class ConcreteTransitiveImplementor1 extends SingleAbstractImplementor2 implements ExtendedSingleImplementorInterface {
+    }
+
+    static class ConcreteTransitiveImplementor2 extends SingleAbstractImplementor2 implements ExtendedSingleImplementorInterface {
+    }
+
+    @Test
+    public void getSingleImplementorTest() {
+        ResolvedJavaType iNi = metaAccess.lookupJavaType(NoImplementor.class);
+        assertNull(iNi.getSingleImplementor());
+
+        ResolvedJavaType iSi = metaAccess.lookupJavaType(SingleImplementorInterface.class);
+        ResolvedJavaType cSi = metaAccess.lookupJavaType(SingleConcreteImplementor.class);
+        assertEquals(cSi, iSi.getSingleImplementor());
+
+        ResolvedJavaType iSai = metaAccess.lookupJavaType(SingleAbstractImplementorInterface.class);
+        ResolvedJavaType aSai = metaAccess.lookupJavaType(SingleAbstractImplementor.class);
+        assertEquals(aSai, iSai.getSingleImplementor());
+
+        ResolvedJavaType iMi = metaAccess.lookupJavaType(MultiImplementorInterface.class);
+        metaAccess.lookupJavaType(ConcreteImplementor1.class);
+        metaAccess.lookupJavaType(ConcreteImplementor2.class);
+        assertEquals(iMi, iMi.getSingleImplementor());
+
+        ResolvedJavaType iMai = metaAccess.lookupJavaType(MultipleAbstractImplementorInterface.class);
+        metaAccess.lookupJavaType(MultiAbstractImplementor1.class);
+        metaAccess.lookupJavaType(MultiAbstractImplementor2.class);
+        assertEquals(iMai, iMai.getSingleImplementor());
+
+        ResolvedJavaType iSai2 = metaAccess.lookupJavaType(SingleAbstractImplementorInterface2.class);
+        ResolvedJavaType aSai2 = metaAccess.lookupJavaType(SingleAbstractImplementor2.class);
+        metaAccess.lookupJavaType(ConcreteTransitiveImplementor1.class);
+        metaAccess.lookupJavaType(ConcreteTransitiveImplementor2.class);
+        assertEquals(aSai2, iSai2.getSingleImplementor());
+    }
+
+    @Test(expected = JVMCIError.class)
+    public void getSingleImplementorTestClassReceiver() {
+        ResolvedJavaType base = metaAccess.lookupJavaType(Base.class);
+        base.getSingleImplementor();
+    }
+
+    @Test(expected = JVMCIError.class)
+    public void getSingleImplementorTestPrimitiveReceiver() {
+        ResolvedJavaType primitive = metaAccess.lookupJavaType(int.class);
+        primitive.getSingleImplementor();
+    }
+
+    @Test
+    public void getComponentTypeTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            Class<?> expected = c.getComponentType();
+            ResolvedJavaType actual = type.getComponentType();
+            if (expected == null) {
+                assertNull(actual);
+            } else {
+                assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
+            }
+        }
+    }
+
+    @Test
+    public void getArrayClassTest() {
+        for (Class<?> c : classes) {
+            if (c != void.class) {
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
+                Class<?> expected = getArrayClass(c);
+                ResolvedJavaType actual = type.getArrayClass();
+                assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
+            }
+        }
+    }
+
+    static class Declarations {
+
+        final Method implementation;
+        final Set<Method> declarations;
+
+        public Declarations(Method impl) {
+            this.implementation = impl;
+            declarations = new HashSet<>();
+        }
+    }
+
+    /**
+     * See <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4.5">Method
+     * overriding</a>.
+     */
+    static boolean isOverriderOf(Method impl, Method m) {
+        if (!isPrivate(m.getModifiers()) && !isFinal(m.getModifiers())) {
+            if (m.getName().equals(impl.getName())) {
+                if (m.getReturnType() == impl.getReturnType()) {
+                    if (Arrays.equals(m.getParameterTypes(), impl.getParameterTypes())) {
+                        if (isPublic(m.getModifiers()) || isProtected(m.getModifiers())) {
+                            // m is public or protected
+                            return isPublic(impl.getModifiers()) || isProtected(impl.getModifiers());
+                        } else {
+                            // m is package-private
+                            return impl.getDeclaringClass().getPackage() == m.getDeclaringClass().getPackage();
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    static final Map<Class<?>, VTable> vtables = new HashMap<>();
+
+    static class VTable {
+
+        final Map<NameAndSignature, Method> methods = new HashMap<>();
+    }
+
+    static synchronized VTable getVTable(Class<?> c) {
+        VTable vtable = vtables.get(c);
+        if (vtable == null) {
+            vtable = new VTable();
+            if (c != Object.class) {
+                VTable superVtable = getVTable(c.getSuperclass());
+                vtable.methods.putAll(superVtable.methods);
+            }
+            for (Method m : c.getDeclaredMethods()) {
+                if (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers())) {
+                    if (isAbstract(m.getModifiers())) {
+                        // A subclass makes a concrete method in a superclass abstract
+                        vtable.methods.remove(new NameAndSignature(m));
+                    } else {
+                        vtable.methods.put(new NameAndSignature(m), m);
+                    }
+                }
+            }
+            vtables.put(c, vtable);
+        }
+        return vtable;
+    }
+
+    static Set<Method> findDeclarations(Method impl, Class<?> c) {
+        Set<Method> declarations = new HashSet<>();
+        NameAndSignature implSig = new NameAndSignature(impl);
+        if (c != null) {
+            for (Method m : c.getDeclaredMethods()) {
+                if (new NameAndSignature(m).equals(implSig)) {
+                    declarations.add(m);
+                    break;
+                }
+            }
+            if (!c.isInterface()) {
+                declarations.addAll(findDeclarations(impl, c.getSuperclass()));
+            }
+            for (Class<?> i : c.getInterfaces()) {
+                declarations.addAll(findDeclarations(impl, i));
+            }
+        }
+        return declarations;
+    }
+
+    private static void checkResolveMethod(ResolvedJavaType type, ResolvedJavaType context, ResolvedJavaMethod decl, ResolvedJavaMethod expected) {
+        ResolvedJavaMethod impl = type.resolveConcreteMethod(decl, context);
+        assertEquals(expected, impl);
+    }
+
+    @Test
+    public void resolveMethodTest() {
+        ResolvedJavaType context = metaAccess.lookupJavaType(TestResolvedJavaType.class);
+        for (Class<?> c : classes) {
+            if (c.isInterface() || c.isPrimitive()) {
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
+                for (Method m : c.getDeclaredMethods()) {
+                    if (JAVA_VERSION <= 1.7D || (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers()))) {
+                        ResolvedJavaMethod resolved = metaAccess.lookupJavaMethod(m);
+                        ResolvedJavaMethod impl = type.resolveMethod(resolved, context);
+                        ResolvedJavaMethod expected = resolved.isDefault() || resolved.isAbstract() ? resolved : null;
+                        assertEquals(m.toString(), expected, impl);
+                    } else {
+                        // As of JDK 8, interfaces can have static and private methods
+                    }
+                }
+            } else {
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
+                VTable vtable = getVTable(c);
+                for (Method impl : vtable.methods.values()) {
+                    Set<Method> decls = findDeclarations(impl, c);
+                    for (Method decl : decls) {
+                        ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl);
+                        if (m.isPublic()) {
+                            ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl);
+                            checkResolveMethod(type, context, m, i);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void resolveConcreteMethodTest() {
+        ResolvedJavaType context = metaAccess.lookupJavaType(TestResolvedJavaType.class);
+        for (Class<?> c : classes) {
+            if (c.isInterface() || c.isPrimitive()) {
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
+                for (Method m : c.getDeclaredMethods()) {
+                    if (JAVA_VERSION <= 1.7D || (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers()))) {
+                        ResolvedJavaMethod resolved = metaAccess.lookupJavaMethod(m);
+                        ResolvedJavaMethod impl = type.resolveConcreteMethod(resolved, context);
+                        ResolvedJavaMethod expected = resolved.isDefault() ? resolved : null;
+                        assertEquals(m.toString(), expected, impl);
+                    } else {
+                        // As of JDK 8, interfaces can have static and private methods
+                    }
+                }
+            } else {
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
+                VTable vtable = getVTable(c);
+                for (Method impl : vtable.methods.values()) {
+                    Set<Method> decls = findDeclarations(impl, c);
+                    for (Method decl : decls) {
+                        ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl);
+                        if (m.isPublic()) {
+                            ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl);
+                            checkResolveMethod(type, context, m, i);
+                        }
+                    }
+                }
+                for (Method m : c.getDeclaredMethods()) {
+                    ResolvedJavaMethod impl = type.resolveConcreteMethod(metaAccess.lookupJavaMethod(m), context);
+                    ResolvedJavaMethod expected = isAbstract(m.getModifiers()) ? null : impl;
+                    assertEquals(type + " " + m.toString(), expected, impl);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void findUniqueConcreteMethodTest() throws NoSuchMethodException {
+        ResolvedJavaMethod thisMethod = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("findUniqueConcreteMethodTest"));
+        ResolvedJavaMethod ucm = metaAccess.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod).getResult();
+        assertEquals(thisMethod, ucm);
+    }
+
+    public static Set<Field> getInstanceFields(Class<?> c, boolean includeSuperclasses) {
+        if (c.isArray() || c.isPrimitive() || c.isInterface()) {
+            return Collections.emptySet();
+        }
+        Set<Field> result = new HashSet<>();
+        for (Field f : c.getDeclaredFields()) {
+            if (!Modifier.isStatic(f.getModifiers())) {
+                result.add(f);
+            }
+        }
+        if (includeSuperclasses && c != Object.class) {
+            result.addAll(getInstanceFields(c.getSuperclass(), true));
+        }
+        return result;
+    }
+
+    public static Set<Field> getStaticFields(Class<?> c) {
+        Set<Field> result = new HashSet<>();
+        for (Field f : c.getDeclaredFields()) {
+            if (Modifier.isStatic(f.getModifiers())) {
+                result.add(f);
+            }
+        }
+        return result;
+    }
+
+    public boolean fieldsEqual(Field f, ResolvedJavaField rjf) {
+        return rjf.getDeclaringClass().equals(metaAccess.lookupJavaType(f.getDeclaringClass())) && rjf.getName().equals(f.getName()) &&
+                        rjf.getType().resolve(rjf.getDeclaringClass()).equals(metaAccess.lookupJavaType(f.getType()));
+    }
+
+    public ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) {
+        for (ResolvedJavaField rf : fields) {
+            if (fieldsEqual(key, rf)) {
+                return rf;
+            }
+        }
+        return null;
+    }
+
+    public Field lookupField(Set<Field> fields, ResolvedJavaField key) {
+        for (Field f : fields) {
+            if (fieldsEqual(f, key)) {
+                return f;
+            }
+        }
+        return null;
+    }
+
+    private static boolean isHiddenFromReflection(ResolvedJavaField f) {
+        if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) {
+            return true;
+        }
+        if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) {
+            return true;
+        }
+        if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Class.class)) && f.getName().equals("classLoader")) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void getInstanceFieldsTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            for (boolean includeSuperclasses : new boolean[]{true, false}) {
+                Set<Field> expected = getInstanceFields(c, includeSuperclasses);
+                ResolvedJavaField[] actual = type.getInstanceFields(includeSuperclasses);
+                for (Field f : expected) {
+                    assertNotNull(lookupField(actual, f));
+                }
+                for (ResolvedJavaField rf : actual) {
+                    if (!isHiddenFromReflection(rf)) {
+                        assertEquals(rf.toString(), lookupField(expected, rf) != null, !rf.isInternal());
+                    }
+                }
+
+                // Test stability of getInstanceFields
+                ResolvedJavaField[] actual2 = type.getInstanceFields(includeSuperclasses);
+                assertArrayEquals(actual, actual2);
+            }
+        }
+    }
+
+    @Test
+    public void getStaticFieldsTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            Set<Field> expected = getStaticFields(c);
+            ResolvedJavaField[] actual = type.getStaticFields();
+            for (Field f : expected) {
+                assertNotNull(lookupField(actual, f));
+            }
+            for (ResolvedJavaField rf : actual) {
+                if (!isHiddenFromReflection(rf)) {
+                    assertEquals(lookupField(expected, rf) != null, !rf.isInternal());
+                }
+            }
+
+            // Test stability of getStaticFields
+            ResolvedJavaField[] actual2 = type.getStaticFields();
+            assertArrayEquals(actual, actual2);
+        }
+    }
+
+    @Test
+    public void getDeclaredMethodsTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            Method[] raw = c.getDeclaredMethods();
+            Set<ResolvedJavaMethod> expected = new HashSet<>();
+            for (Method m : raw) {
+                ResolvedJavaMethod resolvedMethod = metaAccess.lookupJavaMethod(m);
+                assertNotNull(resolvedMethod);
+                expected.add(resolvedMethod);
+            }
+            Set<ResolvedJavaMethod> actual = new HashSet<>(Arrays.asList(type.getDeclaredMethods()));
+            assertEquals(expected, actual);
+        }
+    }
+
+    static class A {
+        static String name = "foo";
+    }
+
+    static class B extends A {
+    }
+
+    static class C {
+    }
+
+    static class D {
+        void foo() {
+            // use of assertions causes the class to have a <clinit>
+            assert getClass() != null;
+        }
+    }
+
+    static class SubD extends D {
+
+    }
+
+    @Test
+    public void getClassInitializerTest() {
+        assertNotNull(metaAccess.lookupJavaType(A.class).getClassInitializer());
+        assertNotNull(metaAccess.lookupJavaType(D.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(B.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(C.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(int.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(void.class).getClassInitializer());
+    }
+
+    @Test
+    public void getAnnotationsTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            assertArrayEquals(c.getAnnotations(), type.getAnnotations());
+        }
+    }
+
+    @Test
+    public void getAnnotationTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            for (Annotation a : c.getAnnotations()) {
+                assertEquals(a, type.getAnnotation(a.annotationType()));
+            }
+        }
+    }
+
+    @Test
+    public void memberClassesTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            assertEquals(c.isLocalClass(), type.isLocal());
+            assertEquals(c.isMemberClass(), type.isMember());
+            Class<?> enclc = c.getEnclosingClass();
+            ResolvedJavaType enclt = type.getEnclosingType();
+            assertFalse(enclc == null ^ enclt == null);
+            if (enclc != null) {
+                assertEquals(enclt, metaAccess.lookupJavaType(enclc));
+            }
+        }
+    }
+
+    @Test
+    public void classFilePathTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            URL path = type.getClassFilePath();
+            if (type.isPrimitive() || type.isArray()) {
+                assertEquals(null, path);
+            } else {
+                assertNotNull(path);
+                String pathString = path.getPath();
+                if (type.isLocal() || type.isMember()) {
+                    assertTrue(pathString.indexOf('$') > 0);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void isTrustedInterfaceTypeTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            if (TrustedInterface.class.isAssignableFrom(c)) {
+                assertTrue(type.isTrustedInterfaceType());
+            }
+        }
+    }
+
+    @Test
+    public void isLeafTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            ResolvedJavaType arrayType = c != void.class ? metaAccess.lookupJavaType(getArrayClass(c)) : null;
+            if (c.isPrimitive()) {
+                assertTrue(type.isLeaf());
+                assertTrue(arrayType == null || arrayType.isLeaf());
+            } else {
+                assertTrue(c.toString(), type.isLeaf() == arrayType.isLeaf());
+                if (!c.isArray()) {
+                    assertTrue(c.toString(), type.isLeaf() == Modifier.isFinal(c.getModifiers()));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void findMethodTest() {
+        try {
+            ResolvedJavaMethod findFoo = metaAccess.lookupJavaType(D.class).findMethod("foo", metaAccess.parseMethodDescriptor("()V"));
+            ResolvedJavaMethod expectedFoo = metaAccess.lookupJavaMethod(D.class.getDeclaredMethod("foo"));
+            assertEquals(expectedFoo, findFoo);
+
+            ResolvedJavaMethod wrongReturnTypeFoo = metaAccess.lookupJavaType(D.class).findMethod("foo", metaAccess.parseMethodDescriptor("()I"));
+            assertNull(wrongReturnTypeFoo);
+
+            ResolvedJavaMethod wrongArgumentsFoo = metaAccess.lookupJavaType(D.class).findMethod("foo", metaAccess.parseMethodDescriptor("(I)V"));
+            assertNull(wrongArgumentsFoo);
+
+            ResolvedJavaMethod wrongNameFoo = metaAccess.lookupJavaType(D.class).findMethod("bar", metaAccess.parseMethodDescriptor("()V"));
+            assertNull(wrongNameFoo);
+
+            ResolvedJavaMethod wrongClassFoo = metaAccess.lookupJavaType(SubD.class).findMethod("foo", metaAccess.parseMethodDescriptor("()V"));
+            assertNull(wrongClassFoo);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private Method findTestMethod(Method apiMethod) {
+        String testName = apiMethod.getName() + "Test";
+        for (Method m : getClass().getDeclaredMethods()) {
+            if (m.getName().equals(testName) && m.getAnnotation(Test.class) != null) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    // @formatter:off
+    private static final String[] untestedApiMethods = {
+        "initialize",
+        "isPrimitive",
+        "newArray",
+        "getDeclaredConstructors",
+        "isInitialized",
+        "isLinked",
+        "getJavaClass",
+        "getObjectHub",
+        "hasFinalizableSubclass",
+        "hasFinalizer",
+        "getSourceFileName",
+        "getClassFilePath",
+        "isLocal",
+        "isJavaLangObject",
+        "isMember",
+        "getElementalType",
+        "getEnclosingType",
+        "$jacocoInit",
+        "isCpiSet",
+        "getCorrespondingCpi",
+        "setCorrespondingCpi"
+    };
+    // @formatter:on
+
+    /**
+     * Ensures that any new methods added to {@link ResolvedJavaMethod} either have a test written
+     * for them or are added to {@link #untestedApiMethods}.
+     */
+    @Test
+    public void testCoverage() {
+        Set<String> known = new HashSet<>(Arrays.asList(untestedApiMethods));
+        for (Method m : ResolvedJavaType.class.getDeclaredMethods()) {
+            if (findTestMethod(m) == null) {
+                assertTrue("test missing for " + m, known.contains(m.getName()));
+            } else {
+                assertFalse("test should be removed from untestedApiMethods" + m, known.contains(m.getName()));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2013, 2014, 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 jdk.vm.ci.runtime.test;
+
+import static java.lang.reflect.Modifier.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Queue;
+import java.util.stream.*;
+
+import jdk.vm.ci.meta.*;
+import jdk.vm.ci.runtime.*;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+//JaCoCo Exclude
+
+/**
+ * Context for type related tests.
+ */
+public class TypeUniverse {
+
+    public static final Unsafe unsafe;
+    public static final double JAVA_VERSION = Double.valueOf(System.getProperty("java.specification.version"));
+
+    public static final MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+    public static final ConstantReflectionProvider constantReflection = JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection();
+    public static final Collection<Class<?>> classes = new HashSet<>();
+    public static final Set<ResolvedJavaType> javaTypes;
+    public static final Map<Class<?>, Class<?>> arrayClasses = new HashMap<>();
+
+    private static List<ConstantValue> constants;
+
+    public class InnerClass {
+
+    }
+
+    public static class InnerStaticClass {
+
+    }
+
+    public static final class InnerStaticFinalClass {
+
+    }
+
+    private class PrivateInnerClass {
+
+    }
+
+    protected class ProtectedInnerClass {
+
+    }
+
+    static {
+        Unsafe theUnsafe = null;
+        try {
+            theUnsafe = Unsafe.getUnsafe();
+        } catch (Exception e) {
+            try {
+                Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+                theUnsafeField.setAccessible(true);
+                theUnsafe = (Unsafe) theUnsafeField.get(null);
+            } catch (Exception e1) {
+                throw (InternalError) new InternalError("unable to initialize unsafe").initCause(e1);
+            }
+        }
+        unsafe = theUnsafe;
+
+        Class<?>[] initialClasses = {void.class, boolean.class, byte.class, short.class, char.class, int.class, float.class, long.class, double.class, Object.class, Class.class, boolean[].class,
+                        byte[].class, short[].class, char[].class, int[].class, float[].class, long[].class, double[].class, Object[].class, Class[].class, List[].class, boolean[][].class,
+                        byte[][].class, short[][].class, char[][].class, int[][].class, float[][].class, long[][].class, double[][].class, Object[][].class, Class[][].class, List[][].class,
+                        ClassLoader.class, String.class, Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class,
+                        HashMap.class, LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class, TrustedInterface.class, InnerClass.class,
+                        InnerStaticClass.class, InnerStaticFinalClass.class, PrivateInnerClass.class, ProtectedInnerClass.class};
+        for (Class<?> c : initialClasses) {
+            addClass(c);
+        }
+
+        javaTypes = Collections.unmodifiableSet(classes.stream().map(c -> metaAccess.lookupJavaType(c)).collect(Collectors.toSet()));
+    }
+
+    static class ConstantsUniverse {
+        static final Object[] ARRAYS = classes.stream().map(c -> c != void.class && !c.isArray() ? Array.newInstance(c, 42) : null).filter(o -> o != null).collect(Collectors.toList()).toArray();
+        static final Object CONST1 = new ArrayList<>();
+        static final Object CONST2 = new ArrayList<>();
+        static final Object CONST3 = new IdentityHashMap<>();
+        static final Object CONST4 = new LinkedHashMap<>();
+        static final Object CONST5 = new TreeMap<>();
+        static final Object CONST6 = new ArrayDeque<>();
+        static final Object CONST7 = new LinkedList<>();
+        static final Object CONST8 = "a string";
+        static final Object CONST9 = 42;
+        static final Object CONST10 = String.class;
+        static final Object CONST11 = String[].class;
+    }
+
+    public static List<ConstantValue> constants() {
+        if (constants == null) {
+            List<ConstantValue> res = readConstants(JavaConstant.class);
+            res.addAll(readConstants(ConstantsUniverse.class));
+            constants = res;
+        }
+        return constants;
+    }
+
+    public static class ConstantValue {
+        public final String name;
+        public final JavaConstant value;
+        public final Object boxed;
+
+        public ConstantValue(String name, JavaConstant value, Object boxed) {
+            this.name = name;
+            this.value = value;
+            this.boxed = boxed;
+        }
+
+        @Override
+        public String toString() {
+            return name + "=" + value;
+        }
+
+        public String getSimpleName() {
+            return name.substring(name.lastIndexOf('.') + 1);
+        }
+    }
+
+    /**
+     * Reads the value of all {@code static final} fields from a given class into an array of
+     * {@link ConstantValue}s.
+     */
+    public static List<ConstantValue> readConstants(Class<?> fromClass) {
+        try {
+            List<ConstantValue> res = new ArrayList<>();
+            for (Field field : fromClass.getDeclaredFields()) {
+                if (isStatic(field.getModifiers()) && isFinal(field.getModifiers())) {
+                    JavaField javaField = metaAccess.lookupJavaField(field);
+                    Object boxed = field.get(null);
+                    if (boxed instanceof JavaConstant) {
+                        res.add(new ConstantValue(javaField.format("%H.%n"), (JavaConstant) boxed, boxed));
+                    } else {
+                        JavaConstant value = constantReflection.readConstantFieldValue(javaField, null);
+                        if (value != null) {
+                            res.add(new ConstantValue(javaField.format("%H.%n"), value, boxed));
+                            if (boxed instanceof Object[]) {
+                                Object[] arr = (Object[]) boxed;
+                                for (int i = 0; i < arr.length; i++) {
+                                    JavaConstant element = constantReflection.readArrayElement(value, i);
+                                    if (element != null) {
+                                        res.add(new ConstantValue(javaField.format("%H.%n[" + i + "]"), element, arr[i]));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            return res;
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    public synchronized Class<?> getArrayClass(Class<?> componentType) {
+        Class<?> arrayClass = arrayClasses.get(componentType);
+        if (arrayClass == null) {
+            arrayClass = Array.newInstance(componentType, 0).getClass();
+            arrayClasses.put(componentType, arrayClass);
+        }
+        return arrayClass;
+    }
+
+    public static int dimensions(Class<?> c) {
+        if (c.getComponentType() != null) {
+            return 1 + dimensions(c.getComponentType());
+        }
+        return 0;
+    }
+
+    private static void addClass(Class<?> c) {
+        if (classes.add(c)) {
+            if (c.getSuperclass() != null) {
+                addClass(c.getSuperclass());
+            }
+            for (Class<?> sc : c.getInterfaces()) {
+                addClass(sc);
+            }
+            for (Class<?> dc : c.getDeclaredClasses()) {
+                addClass(dc);
+            }
+            for (Method m : c.getDeclaredMethods()) {
+                addClass(m.getReturnType());
+                for (Class<?> p : m.getParameterTypes()) {
+                    addClass(p);
+                }
+            }
+
+            if (c != void.class && dimensions(c) < 2) {
+                Class<?> arrayClass = Array.newInstance(c, 0).getClass();
+                arrayClasses.put(c, arrayClass);
+                addClass(arrayClass);
+            }
+        }
+    }
+}
--- a/hotspot/test/compiler/loopopts/TestMoveStoresOutOfLoops.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/loopopts/TestMoveStoresOutOfLoops.java	Thu Oct 22 11:13:08 2015 -0700
@@ -25,8 +25,8 @@
 /**
  * @test
  * @bug 8080289
- * @summary Sink stores out of loops if possible
- * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:+PrintCompilation -XX:CompileCommand=dontinline,TestMoveStoresOutOfLoops::test*  TestMoveStoresOutOfLoops
+ * @summary Move stores out of loops if possible
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestMoveStoresOutOfLoops::test*  TestMoveStoresOutOfLoops
  *
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/loopopts/TestMoveStoresOutOfLoopsStoreNoCtrl.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, 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 8134288
+ * @summary Store nodes may not have a control if used to update profiling
+ * @run main/othervm -XX:-ProfileInterpreter -XX:-TieredCompilation -XX:-BackgroundCompilation TestMoveStoresOutOfLoopsStoreNoCtrl
+ *
+ */
+
+public class TestMoveStoresOutOfLoopsStoreNoCtrl {
+
+    static void test(boolean flag) {
+        for (int i = 0; i < 20000; i++) {
+            if (flag) {
+                int j = 0;
+                do {
+                    j++;
+                } while(j < 10);
+            }
+        }
+    }
+
+    static public void main(String[] args) {
+        test(false);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/loopopts/superword/SumRedAbsNeg_Double.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 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 8138583
+ * @summary Add C2 AArch64 Superword support for scalar sum reduction optimizations : double abs & neg test
+ * @requires os.arch=="aarch64"
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=4 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=4 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=8 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=8 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=16 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=16 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Double
+ */
+
+public class SumRedAbsNeg_Double
+{
+  public static void main(String[] args) throws Exception {
+    double[] a = new double[256*1024];
+    double[] b = new double[256*1024];
+    double[] c = new double[256*1024];
+    double[] d = new double[256*1024];
+    sumReductionInit(a,b,c);
+    double total = 0;
+    double valid = 3.6028590866691944E19;
+
+    for(int j = 0; j < 2000; j++) {
+      total = sumReductionImplement(a,b,c,d,total);
+    }
+
+    if(total == valid) {
+      System.out.println("Success");
+    } else {
+      System.out.println("Invalid sum of elements variable in total: " + total);
+      System.out.println("Expected value = " + valid);
+      throw new Exception("Failed");
+    }
+  }
+
+  public static void sumReductionInit(
+    double[] a,
+    double[] b,
+    double[] c)
+  {
+    for(int j = 0; j < 1; j++)
+    {
+      for(int i = 0; i < a.length; i++)
+      {
+        a[i] = i * 1 + j;
+        b[i] = i * 1 - j;
+        c[i] = i + j;
+      }
+    }
+  }
+
+  public static double sumReductionImplement(
+    double[] a,
+    double[] b,
+    double[] c,
+    double[] d,
+    double total)
+  {
+    for(int i = 0; i < a.length; i++)
+    {
+      d[i] = Math.abs(-a[i] * -b[i]) + Math.abs(-a[i] * -c[i]) + Math.abs(-b[i] * -c[i]);
+      total += d[i];
+    }
+    return total;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/loopopts/superword/SumRedAbsNeg_Float.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 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 8138583
+ * @summary Add C2 AArch64 Superword support for scalar sum reduction optimizations : float abs & neg test
+ * @requires os.arch=="aarch64"
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=4 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=4 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=8 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=8 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=16 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=16 -XX:CompileThresholdScaling=0.1 SumRedAbsNeg_Float
+ */
+
+public class SumRedAbsNeg_Float
+{
+  public static void main(String[] args) throws Exception {
+    float[] a = new float[256*1024];
+    float[] b = new float[256*1024];
+    float[] c = new float[256*1024];
+    float[] d = new float[256*1024];
+    sumReductionInit(a,b,c);
+    float total = 0;
+    float valid = (float)4.611686E18;
+
+    for(int j = 0; j < 2000; j++) {
+      total = sumReductionImplement(a,b,c,d,total);
+    }
+
+    if(total == valid) {
+      System.out.println("Success");
+    } else {
+      System.out.println("Invalid sum of elements variable in total: " + total);
+      System.out.println("Expected value = " + valid);
+      throw new Exception("Failed");
+    }
+  }
+
+  public static void sumReductionInit(
+    float[] a,
+    float[] b,
+    float[] c)
+  {
+    for(int j = 0; j < 1; j++)
+    {
+      for(int i = 0; i < a.length; i++)
+      {
+        a[i] = i * 1 + j;
+        b[i] = i * 1 - j;
+        c[i] = i + j;
+      }
+    }
+  }
+
+  public static float sumReductionImplement(
+    float[] a,
+    float[] b,
+    float[] c,
+    float[] d,
+    float total)
+  {
+    for(int i = 0; i < a.length; i++)
+    {
+      d[i] = Math.abs(-a[i] * -b[i]) + Math.abs(-a[i] * -c[i]) + Math.abs(-b[i] * -c[i]);
+      total += d[i];
+    }
+    return total;
+  }
+
+}
--- a/hotspot/test/compiler/loopopts/superword/SumRedSqrt_Double.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/loopopts/superword/SumRedSqrt_Double.java	Thu Oct 22 11:13:08 2015 -0700
@@ -24,7 +24,9 @@
 
 /**
 * @test
+* @bug 8135028
 * @summary Add C2 x86 Superword support for scalar sum reduction optimizations : double sqrt test
+* @requires os.arch=="x86" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64"
 *
 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
--- a/hotspot/test/compiler/oracle/CheckCompileCommandOption.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/oracle/CheckCompileCommandOption.java	Thu Oct 22 11:13:08 2015 -0700
@@ -66,7 +66,6 @@
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
-            "CompileCommand: option com/oracle/Test.test bool MyBoolOption4 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
@@ -74,7 +73,6 @@
             "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption9 = true",
             "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption10 = true",
             "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption11 = true",
-            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption12 = true",
             "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption13 = true",
             "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption14 = true",
             "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption15 = true",
@@ -96,7 +94,6 @@
             "-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1",
             "-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption2",
             "-XX:CompileCommand=option,com.oracle.Test::test,MyBoolOption3",
-            "-XX:CompileCommand=option,com/oracle/Test::test,MyBoolOption4",
             "-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6",
             "-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8",
             "-version"
@@ -108,7 +105,6 @@
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
-            "CompileCommand: option com/oracle/Test.test bool MyBoolOption4 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
             "CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
@@ -198,7 +194,7 @@
             out.shouldContain(expected_output);
         }
 
-        out.shouldNotContain("CompileCommand: An error occured during parsing");
+        out.shouldNotContain("CompileCommand: An error occurred during parsing");
         out.shouldHaveExitValue(0);
     }
 
@@ -209,7 +205,7 @@
         pb = ProcessTools.createJavaProcessBuilder(arguments);
         out = new OutputAnalyzer(pb.start());
 
-        out.shouldContain("CompileCommand: An error occured during parsing");
+        out.shouldContain("CompileCommand: An error occurred during parsing");
         out.shouldHaveExitValue(0);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/oracle/MethodMatcherTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2015, 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 MethodMatcherTest
+ * @library /testlibrary /../../test/lib
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MethodMatcherTest
+ * @summary Testing of compiler/MethodMatcher
+ * @bug 8135068
+ */
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+import sun.hotspot.WhiteBox;
+
+public class MethodMatcherTest {
+
+    /** Instance of WhiteBox */
+    protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+    Method helper;
+    Method getDate;
+    Method inner;
+    Method toString;
+
+    static final int MATCH = 1;
+    static final int NO_MATCH = 0;
+    static final int PARSING_FAILURE = -1;
+
+    public MethodMatcherTest() {
+    }
+
+    public void test() throws Exception {
+        // instantiate before calling getMethod on innerHelper
+        TestCases testCases = new TestCases();
+
+        helper = getMethod(MethodMatcherTest.class, "helper");
+        getDate = getMethod(java.util.Date.class, "getDate");
+        inner = getMethod(TestCases.class, "innerHelper");
+        toString = getMethod(String.class, "toString");
+
+        testCases.add(helper, "pool/sub/Klass.method(I[Ljava/lang/String;Ljava/lang/Integer;[B[[D)V", NO_MATCH);
+
+        // These should be improved to parsing failed in the future
+        testCases.add(helper, "*Klass*,*$method*::", NO_MATCH);
+        testCases.add(helper, "*Klass *+*", NO_MATCH);
+        testCases.add(helper, "*Klass*::*method*", NO_MATCH);
+
+        testCases.add(helper, "*,**", PARSING_FAILURE);
+        testCases.add(helper, "*,*(I[Ljava/lang/String;Lj]ava/lang/Integer;[B[[D)V", PARSING_FAILURE);
+        testCases.add(helper, "*,*)method*.", PARSING_FAILURE);
+        testCases.add(helper, "{pool.subpack.Klass}* *", PARSING_FAILURE);
+        testCases.add(helper, "*Klass met]hod/", PARSING_FAILURE);
+        testCases.add(helper, "pool::su@%b::Klass* *)method.", PARSING_FAILURE);
+        testCases.add(helper, "0pool/sub/Klass,*{method}*.(I[Ljava/lang/String;Lj]ava/lang/Integer;[B[[D)V", PARSING_FAILURE);
+        testCases.add(helper, "*Klass nonexistent::)(I[Ljava/lang/String;Ljava/lang/Integer;[B[[D)V", PARSING_FAILURE);
+        testCases.add(helper, "pool,su]b,Klass*,*)method*/", PARSING_FAILURE);
+        testCases.add(helper, "_pool,sub,Klass*,met@%hod,(0)V", PARSING_FAILURE);
+
+        testCases.add(helper, "*.*", MATCH);
+        testCases.add(helper, "MethodMatcherTest.*", MATCH);
+        testCases.add(helper, "MethodMatcherTest.helper", MATCH);
+        testCases.add(helper, "MethodMatcherTest.helper()", MATCH);
+        testCases.add(helper, "MethodMatcherTest.helper()V", MATCH);
+        testCases.add(helper, "MethodMatcherTest.helper()V;", NO_MATCH);
+        testCases.add(helper, "MethodMatcherTest.helper()I", NO_MATCH);
+        testCases.add(helper, "MethodMatcherTest.helperX", NO_MATCH);
+        testCases.add(helper, "MethodMatcherTestX.helper;", NO_MATCH);
+        testCases.add(helper, "abc.*", NO_MATCH);
+        testCases.add(helper, "*.abc", NO_MATCH);
+
+        testCases.add(getDate, "*.*", MATCH);
+        testCases.add(getDate, "*.getDate", MATCH);
+        testCases.add(getDate, "java/util/Date.getDate", MATCH);
+        testCases.add(getDate, "java/util/Date.*", MATCH);
+
+        testCases.add(inner, "*.*", MATCH);
+        testCases.add(inner, "MethodMatcherTest$TestCases.innerHelper", MATCH);
+        testCases.add(inner, "MethodMatcherTest*.innerHelper", MATCH);
+        testCases.add(inner, "MethodMatcherTest$*.innerHelper", MATCH);
+        testCases.add(inner, "*$TestCases.innerHelper", MATCH);
+        testCases.add(inner, "*TestCases.innerHelper", MATCH);
+        testCases.add(inner, "TestCases.innerHelper", NO_MATCH);
+        testCases.add(inner, "MethodMatcherTest.innerHelper", NO_MATCH);
+
+        testCases.add(toString, "*.*", MATCH);
+        testCases.add(toString, "java/lang/String.toString", MATCH);
+        testCases.add(toString, "java.lang.String::toString", MATCH);
+
+        testCases.add(toString, "java/lang/String::toString", PARSING_FAILURE);
+        testCases.add(toString, "java.lang/String::toString", PARSING_FAILURE);
+        testCases.add(toString, "java.lang/String.toString", PARSING_FAILURE);
+        testCases.add(toString, "java::lang::String::toString", PARSING_FAILURE);
+
+        testCases.add(toString, "java/lang/String.toString(*)", PARSING_FAILURE);
+        testCases.add(toString, "java/lang/String.toString(L*", PARSING_FAILURE);
+        testCases.add(toString, "java/lang/String.toString*(lsd)l", NO_MATCH);
+        testCases.add(toString, "java/lang/String.toString(lsd)l", NO_MATCH);
+        testCases.add(toString, "java/lang/String.toString (", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()L", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()Lj", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()Ls", NO_MATCH);
+        testCases.add(toString, "java/lang/String.toString*(", MATCH);
+        testCases.add(toString, "java/lang/String.toString* (", MATCH);
+        testCases.add(toString, "java/lang/String.toString*(;", NO_MATCH);
+        testCases.add(toString, "java/lang/String.toString*();sf", NO_MATCH);
+        testCases.add(toString, "java/lang/String.toString*()Ljava/lang/String;", MATCH);
+        testCases.add(toString, "java/lang/String.toString()Ljava/lang/String;", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()Ljava/lang/String;", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()Ljava/lang/String", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()L", MATCH);
+        testCases.add(toString, "java/lang/String.toString ()I;", NO_MATCH);
+
+        testCases.add(toString, "*Internal.*", NO_MATCH);
+        testCases.add(toString, "*Internal.**", PARSING_FAILURE);
+        testCases.add(toString, "*Internal.***", PARSING_FAILURE);
+        testCases.add(toString, "*Internal.*a**", PARSING_FAILURE);
+        testCases.add(toString, "*Internal.**a*", PARSING_FAILURE);
+
+        testCases.add(toString, "java.lang.String::<init>(Ljava/lang/String;)V", NO_MATCH);
+        testCases.add(toString, "java.lang.String::<clinit>(Ljava/lang/String;)V", NO_MATCH);
+        testCases.add(toString, "java.lang.String::<init(Ljava/lang/String;)V", PARSING_FAILURE);
+        testCases.add(toString, "java.lang.String::init>(Ljava/lang/String;)V", PARSING_FAILURE);
+
+        testCases.add(toString, "java/lang/String.toString()Ljava/lang/String;", MATCH);
+        testCases.add(toString, "java/lang/Str<ing.toString()Ljava/lang/String;", PARSING_FAILURE);
+        testCases.add(toString, "java/lang/Str>ing.toString()Ljava/lang/String;", PARSING_FAILURE);
+        testCases.add(toString, "java/lang/<init>.toString()Ljava/lang/String;", PARSING_FAILURE);
+        testCases.add(toString, "java/lang/<clinit>.toString()Ljava/lang/String;", PARSING_FAILURE);
+
+        int failures = 0;
+        for (TestCase t : testCases) {
+            System.out.println("Test case: " + t.pattern);
+            if (!t.test()) {
+                failures++;
+                System.out.println(" * FAILED");
+            }
+        }
+        if (failures != 0) {
+            throw new Exception("There where " + failures + " failures in this test");
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        MethodMatcherTest test = new MethodMatcherTest();
+        test.test();
+    }
+
+    public void helper() {
+
+    }
+
+    private static Method getMethod(Class klass, String name, Class<?>... parameterTypes) {
+        try {
+            return klass.getDeclaredMethod(name, parameterTypes);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new RuntimeException("exception on getting method Helper." + name, e);
+        }
+    }
+
+    class TestCase {
+        String pattern;
+        Method testTarget;
+        int expectedResult;
+
+        public TestCase(Method testTarget, String pattern, int expectedResult) {
+            this.testTarget = testTarget;
+            this.pattern = pattern;
+            this.expectedResult = expectedResult;
+        }
+
+        public String resultAsStr(int errorCode) {
+            switch (errorCode) {
+            case PARSING_FAILURE:
+                return "Parsing failed";
+            case NO_MATCH:
+                return "No match";
+            case MATCH:
+                return "Match";
+            default:
+                return "Unknown error";
+            }
+        }
+
+        boolean test() {
+            int result = WHITE_BOX.matchesMethod(testTarget, pattern);
+            if (result != expectedResult) {
+                System.out
+                        .println("FAIL Wrong result, Got: " + resultAsStr(result) + "\n TestCase: " + this.toString());
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            return "Method: '" + testTarget.toString() + "' Pattern: '" + pattern + "' Expected: "
+                    + resultAsStr(expectedResult);
+        }
+
+        public void innerHelper() {
+        }
+    }
+
+    class TestCases extends ArrayList<TestCase> {
+        private static final long serialVersionUID = 1L;
+
+        public boolean add(Method testTarget, String pattern, int expectedResult) {
+            return super.add(new TestCase(testTarget, pattern, expectedResult));
+        }
+
+        public void innerHelper() {
+        }
+    }
+}
--- a/hotspot/test/compiler/oracle/TestCompileCommand.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/oracle/TestCompileCommand.java	Thu Oct 22 11:13:08 2015 -0700
@@ -40,7 +40,7 @@
 
     private static final String[][] ARGUMENTS = {
         {
-            "-XX:CompileCommand=print,*01234567890123456789012345678901234567890123456789,*0123456789012345678901234567890123456789",
+            "-XX:CompileCommand=print,*01234567890123456789012345678901234567890123456789.*0123456789012345678901234567890123456789",
             "-version"
         }
     };
--- a/hotspot/test/compiler/oracle/command1.txt	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/oracle/command1.txt	Thu Oct 22 11:13:08 2015 -0700
@@ -1,12 +1,10 @@
 option,com/oracle/Test.test,MyBoolOption1
 option,com/oracle/Test,test,MyBoolOption2
 option,com.oracle.Test::test,MyBoolOption3
-option,com/oracle/Test::test,MyBoolOption4
 option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6
 option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8
 option,com/oracle/Test.test(I),MyBoolOption9
 option,com/oracle/Test,test,(I),MyBoolOption10
 option,com.oracle.Test::test(I),MyBoolOption11
-option,com/oracle/Test::test(I),MyBoolOption12
 option,com/oracle/Test.test(I),MyBoolOption13,MyBoolOption14
 option,com/oracle/Test,test(I),MyBoolOption15,MyBoolOption16
--- a/hotspot/test/compiler/startup/SmallCodeCacheStartup.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java	Thu Oct 22 11:13:08 2015 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @ignore 8134286
  * @bug 8023014
  * @summary Test ensures that there is no crash if there is not enough ReservedCodeCacheSize
  *          to initialize all compiler threads. The option -Xcomp gives the VM more time to
--- a/hotspot/test/compiler/testlibrary/CompilerUtils.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/compiler/testlibrary/CompilerUtils.java	Thu Oct 22 11:13:08 2015 -0700
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package compiler.testlibrary;
+
 import jdk.test.lib.Asserts;
 import jdk.test.lib.Platform;
 import java.util.stream.IntStream;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestG1ConcMarkStepDurationMillis.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2015, 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 TestG1ConcMarkStepDurationMillis
+ * @key gc
+ * @requires vm.gc=="null" | vm.gc=="G1"
+ * @summary Tests argument processing for double type flag, G1ConcMarkStepDurationMillis
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ */
+
+import jdk.test.lib.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class TestG1ConcMarkStepDurationMillis {
+
+  static final int PASS                = 0;
+  static final int FAIL_IMPROPER_VALUE = 1;
+  static final int FAIL_OUT_RANGE      = 2;
+
+  static final String DOUBLE_1       = "1.0";
+  static final String DOUBLE_MAX     = "1.79e+308";
+
+  static final String DOUBLE_NEG_EXP = "1.0e-30";
+  static final String NEG_DOUBLE_1   = "-1.0";
+
+  static final String DOUBLE_INF     = "1.79e+309";
+  static final String NEG_DOUBLE_INF = "-1.79e+309";
+  static final String DOUBLE_NAN     = "abe+309";
+  static final String WRONG_DOUBLE_1 = "1.79e+308e";
+  static final String WRONG_DOUBLE_2 = "1.79ee+308";
+
+  public static void main(String args[]) throws Exception {
+    // Pass cases
+    runG1ConcMarkStepDurationMillisTest(DOUBLE_1,       PASS);
+    runG1ConcMarkStepDurationMillisTest(DOUBLE_MAX,     PASS);
+
+    // Fail cases: out of range
+    runG1ConcMarkStepDurationMillisTest(DOUBLE_NEG_EXP, FAIL_OUT_RANGE);
+    runG1ConcMarkStepDurationMillisTest(NEG_DOUBLE_1,   FAIL_OUT_RANGE);
+
+    // Fail cases: not double
+    runG1ConcMarkStepDurationMillisTest(DOUBLE_INF,     FAIL_IMPROPER_VALUE);
+    runG1ConcMarkStepDurationMillisTest(NEG_DOUBLE_INF, FAIL_IMPROPER_VALUE);
+    runG1ConcMarkStepDurationMillisTest(DOUBLE_NAN,     FAIL_IMPROPER_VALUE);
+    runG1ConcMarkStepDurationMillisTest(WRONG_DOUBLE_1, FAIL_IMPROPER_VALUE);
+    runG1ConcMarkStepDurationMillisTest(WRONG_DOUBLE_2, FAIL_IMPROPER_VALUE);
+  }
+
+  private static void runG1ConcMarkStepDurationMillisTest(String expectedValue, int expectedResult) throws Exception {
+    List<String> vmOpts = new ArrayList<>();
+
+    Collections.addAll(vmOpts, "-XX:+UseG1GC", "-XX:G1ConcMarkStepDurationMillis="+expectedValue, "-XX:+PrintFlagsFinal", "-version");
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    output.shouldHaveExitValue(expectedResult == PASS ? 0 : 1);
+    String stdout = output.getStdout();
+    if (expectedResult == PASS) {
+      checkG1ConcMarkStepDurationMillisConsistency(stdout, expectedValue);
+    } else if (expectedResult == FAIL_IMPROPER_VALUE) {
+      output.shouldContain("Improperly specified VM option");
+    } else if (expectedResult == FAIL_OUT_RANGE) {
+      output.shouldContain("outside the allowed range");
+    }
+  }
+
+  private static void checkG1ConcMarkStepDurationMillisConsistency(String output, String expectedValue) {
+    double actualValue = getDoubleValue("G1ConcMarkStepDurationMillis", output);
+
+    if (Double.parseDouble(expectedValue) != actualValue) {
+      throw new RuntimeException(
+            "Actual G1ConcMarkStepDurationMillis(" + Double.toString(actualValue)
+            + ") is not equal to expected value(" + expectedValue + ")");
+    }
+  }
+
+  public static double getDoubleValue(String flag, String where) {
+    Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
+    if (!m.find()) {
+      throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+    }
+    String match = m.group();
+    return Double.parseDouble(match.substring(match.lastIndexOf(" ") + 1, match.length()));
+  }
+}
--- a/hotspot/test/gc/arguments/TestG1HeapRegionSize.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/gc/arguments/TestG1HeapRegionSize.java	Thu Oct 22 11:13:08 2015 -0700
@@ -25,42 +25,59 @@
  * @test TestG1HeapRegionSize
  * @key gc
  * @bug 8021879
+ * @requires vm.gc=="null" | vm.gc=="G1"
  * @summary Verify that the flag G1HeapRegionSize is updated properly
  * @modules java.management/sun.management
- * @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576
- * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152
- * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152
- * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432
+ * @library /testlibrary
+ * @run main TestG1HeapRegionSize
  */
 
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.VMOption;
-import java.lang.management.ManagementFactory;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import jdk.test.lib.*;
 
 public class TestG1HeapRegionSize {
 
-  public static void main(String[] args) {
-    HotSpotDiagnosticMXBean diagnostic =
-        ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
+  private static void checkG1HeapRegionSize(String[] flags, int expectedValue, int exitValue) throws Exception {
+    ArrayList<String> flagList = new ArrayList<String>();
+    flagList.addAll(Arrays.asList(flags));
+    flagList.add("-XX:+UseG1GC");
+    flagList.add("-XX:+PrintFlagsFinal");
+    flagList.add("-version");
 
-    String expectedValue = getExpectedValue(args);
-    VMOption option = diagnostic.getVMOption("UseG1GC");
-    if (option.getValue().equals("false")) {
-      System.out.println("Skipping this test. It is only a G1 test.");
-      return;
-    }
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flagList.toArray(new String[0]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldHaveExitValue(exitValue);
 
-    option = diagnostic.getVMOption("G1HeapRegionSize");
-    if (!expectedValue.equals(option.getValue())) {
-      throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + option.getValue());
+    if (exitValue == 0) {
+      String stdout = output.getStdout();
+      int flagValue = getFlagValue("G1HeapRegionSize", stdout);
+      if (flagValue != expectedValue) {
+        throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + flagValue);
+      }
     }
   }
 
-  private static String getExpectedValue(String[] args) {
-    if (args.length != 1) {
-      throw new RuntimeException("Wrong number of arguments. Expected 1 but got " + args.length);
+  private static int getFlagValue(String flag, String where) {
+    Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
+    if (!m.find()) {
+      throw new RuntimeException("Could not find value for flag " + flag + " in output string");
     }
-    return args[0];
+    String match = m.group();
+    return Integer.parseInt(match.substring(match.lastIndexOf(" ") + 1, match.length()));
   }
 
+  public static void main(String args[]) throws Exception {
+    final int M = 1024 * 1024;
+
+    checkG1HeapRegionSize(new String[] { "-Xmx64m"   /* default is 1m */        },  1*M, 0);
+    checkG1HeapRegionSize(new String[] { "-Xmx64m",  "-XX:G1HeapRegionSize=2m"  },  2*M, 0);
+    checkG1HeapRegionSize(new String[] { "-Xmx64m",  "-XX:G1HeapRegionSize=3m"  },  2*M, 0);
+    checkG1HeapRegionSize(new String[] { "-Xmx256m", "-XX:G1HeapRegionSize=32m" }, 32*M, 0);
+    checkG1HeapRegionSize(new String[] { "-Xmx256m", "-XX:G1HeapRegionSize=64m" }, 32*M, 1);
+  }
 }
--- a/hotspot/test/gc/arguments/TestHeapFreeRatio.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/gc/arguments/TestHeapFreeRatio.java	Thu Oct 22 11:13:08 2015 -0700
@@ -72,7 +72,7 @@
       output.shouldHaveExitValue(1);
       break;
     case COMBINATION_INVALID:
-      output.shouldContain("must be greater than or equal to MinHeapFreeRatio");
+      output.shouldContain("must be less than or equal to MaxHeapFreeRatio");
       output.shouldContain("Error");
       output.shouldHaveExitValue(1);
       break;
--- a/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java	Thu Oct 22 11:13:08 2015 -0700
@@ -25,6 +25,7 @@
  * @test TestInitialTenuringThreshold
  * @key gc
  * @bug 8014765
+ * @requires vm.gc=="Parallel"
  * @summary Tests argument processing for initial tenuring threshold
  * @library /testlibrary
  * @modules java.base/sun.misc
@@ -39,6 +40,7 @@
 
   public static void runWithThresholds(int initial, int max, boolean shouldfail) throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      "-XX:+UseParallelGC",
       "-XX:InitialTenuringThreshold=" + String.valueOf(initial),
       "-XX:MaxTenuringThreshold=" + String.valueOf(max),
       "-version"
--- a/hotspot/test/gc/arguments/TestObjectTenuringFlags.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/gc/arguments/TestObjectTenuringFlags.java	Thu Oct 22 11:13:08 2015 -0700
@@ -25,6 +25,7 @@
  * @test TestObjectTenuringFlags
  * @key gc
  * @bug 6521376
+ * @requires vm.gc=="Parallel"
  * @summary Tests argument processing for NeverTenure, AlwaysTenure,
  * and MaxTenuringThreshold
  * @library /testlibrary
@@ -157,7 +158,7 @@
     if (tenuringFlags.length > 0) {
       Collections.addAll(vmOpts, tenuringFlags);
     }
-    Collections.addAll(vmOpts, "-XX:+PrintFlagsFinal", "-version");
+    Collections.addAll(vmOpts, "-XX:+UseParallelGC", "-XX:+PrintFlagsFinal", "-version");
 
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/mixedgc/TestLogging.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2015, 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 TestLogging
+ * @summary Check that a mixed GC is reflected in the gc logs
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @library /testlibrary /../../test/lib
+ * @ignore 8138607
+ * @modules java.management
+ * @build sun.hotspot.WhiteBox gc.g1.mixedgc.TestLogging
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver gc.g1.mixedgc.TestLogging
+ */
+
+package gc.g1.mixedgc;
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+
+/**
+ * Test spawns MixedGCProvoker in a separate VM and expects to find a message
+ * telling that a mixed gc has happened
+ */
+public class TestLogging {
+    private static final String[] COMMON_OPTIONS = new String[]{
+            "-Xbootclasspath/a:.", "-XX:+UseG1GC",
+            "-XX:+UnlockExperimentalVMOptions",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+WhiteBoxAPI",
+            "-XX:SurvivorRatio=1", // Survivor-to-eden ratio is 1:1
+            "-Xms10M", "-Xmx10M",
+            "-XX:MaxTenuringThreshold=1", // promote objects after first gc
+            "-XX:InitiatingHeapOccupancyPercent=0", // marking cycle happens
+            // each time
+            "-XX:G1MixedGCCountTarget=4",
+            "-XX:MaxGCPauseMillis=30000", // to have enough time
+            "-XX:G1HeapRegionSize=1m", "-XX:G1HeapWastePercent=0",
+            "-XX:G1MixedGCLiveThresholdPercent=100"};
+
+    public static final int ALLOCATION_SIZE = 20000;
+    public static final int ALLOCATION_COUNT = 15;
+
+    public static void main(String args[]) throws Exception {
+        // Test turns logging on by giving -XX:+PrintGC flag
+        test("-XX:+PrintGC");
+        // Test turns logging on by giving -XX:+PrintGCDetails
+        test("-XX:+PrintGCDetails");
+    }
+
+    private static void test(String vmFlag) throws Exception {
+        System.out.println(String.format("%s: running with %s flag", TestLogging.class.getSimpleName(), vmFlag));
+        OutputAnalyzer output = spawnMixedGCProvoker(vmFlag);
+        System.out.println(output.getStdout());
+        output.shouldHaveExitValue(0);
+        output.shouldContain("GC pause (G1 Evacuation Pause) (mixed)");
+    }
+
+    /**
+     * Method spawns MixedGCProvoker with addition flags set
+     *
+     * @parameter extraFlags -flags to be added to the common options set
+     */
+    private static OutputAnalyzer spawnMixedGCProvoker(String... extraFlags)
+            throws Exception {
+        List<String> testOpts = new ArrayList<>();
+        Collections.addAll(testOpts, COMMON_OPTIONS);
+        Collections.addAll(testOpts, extraFlags);
+        testOpts.add(MixedGCProvoker.class.getName());
+        System.out.println(testOpts);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false,
+                testOpts.toArray(new String[testOpts.size()]));
+        return new OutputAnalyzer(pb.start());
+    }
+}
+
+/**
+ * Utility class to guarantee a mixed GC. The class allocates several arrays and
+ * promotes them to the oldgen. After that it tries to provoke mixed GC by
+ * allocating new objects.
+ *
+ * The necessary condition for guaranteed mixed GC is running MixedGCProvoker is
+ * running in VM with the following flags: -XX:MaxTenuringThreshold=1, -Xms10M,
+ * -Xmx10M, -XX:G1MixedGCLiveThresholdPercent=100, -XX:G1HeapWastePercent=0,
+ * -XX:G1HeapRegionSize=1m
+ */
+class MixedGCProvoker {
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final List<byte[]> liveOldObjects = new ArrayList<>();
+    private static final List<byte[]> newObjects = new ArrayList<>();
+
+    private static void allocateOldObjects() throws Exception {
+        List<byte[]> deadOldObjects = new ArrayList<>();
+        // Allocates buffer and promotes it to the old gen. Mix live and dead old
+        // objects
+        for (int i = 0; i < TestLogging.ALLOCATION_COUNT; ++i) {
+            liveOldObjects.add(new byte[TestLogging.ALLOCATION_SIZE * 10]);
+            deadOldObjects.add(new byte[TestLogging.ALLOCATION_SIZE * 10]);
+        }
+
+        // need only 2 promotions to promote objects to the old gen
+        WB.youngGC();
+        WB.youngGC();
+        // check it is promoted & keep alive
+        Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects),
+                "List of the objects is suppose to be in OldGen");
+        Asserts.assertTrue(WB.isObjectInOldGen(deadOldObjects),
+                "List of the objects is suppose to be in OldGen");
+    }
+
+
+    /**
+     * Waits until Concurent Mark Cycle finishes
+     * @param wb  Whitebox instance
+     * @param sleepTime sleep time
+     */
+    public static void waitTillCMCFinished(WhiteBox wb, int sleepTime) {
+        while (wb.g1InConcurrentMark()) {
+            if (sleepTime > -1) {
+                try {
+                    Thread.sleep(sleepTime);
+                } catch (InterruptedException e) {
+                    System.out.println("Got InterruptedException while waiting for ConcMarkCycle to finish");
+                }
+            }
+        }
+    }
+
+
+
+    public static void main(String args[]) throws Exception {
+        // allocate old objects
+        allocateOldObjects();
+        waitTillCMCFinished(WB, 0);
+        WB.g1StartConcMarkCycle();
+        waitTillCMCFinished(WB, 0);
+
+        WB.youngGC();
+        System.out.println("Allocating new objects to provoke mixed GC");
+        // allocate more objects to provoke GC
+        for (int i = 0; i < (TestLogging.ALLOCATION_COUNT * 20); i++) {
+            newObjects.add(new byte[TestLogging.ALLOCATION_SIZE]);
+        }
+        // check that liveOldObjects still alive
+        Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects),
+                "List of the objects is suppose to be in OldGen");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/logging/TestPrintReferences.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 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 TestPrintReferences
+ * @bug 8136991
+ * @summary Validate the reference processing logging
+ * @key gc
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ */
+
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.OutputAnalyzer;
+
+public class TestPrintReferences {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb_enabled =
+      ProcessTools.createJavaProcessBuilder("-XX:+PrintGCDetails", "-XX:+PrintReferenceGC", "-Xmx10M", GCTest.class.getName());
+    OutputAnalyzer output = new OutputAnalyzer(pb_enabled.start());
+
+    String countRegex = "[0-9]+ refs";
+    String timeRegex = "[0-9]+[.,][0-9]+ secs";
+
+    output.shouldMatch(
+      "#[0-9]+: \\[SoftReference, " + countRegex + ", " + timeRegex + "\\]" +
+      "#[0-9]+: \\[WeakReference, " + countRegex + ", " + timeRegex + "\\]" +
+      "#[0-9]+: \\[FinalReference, " + countRegex + ", " + timeRegex + "\\]" +
+      "#[0-9]+: \\[PhantomReference, " + countRegex + ", " + timeRegex + "\\]" +
+      "#[0-9]+: \\[JNI Weak Reference, (" + countRegex + ", )?" + timeRegex + "\\]");
+
+    output.shouldHaveExitValue(0);
+  }
+
+  static class GCTest {
+    public static void main(String [] args) {
+      System.gc();
+    }
+  }
+}
--- a/hotspot/test/runtime/6888954/vmerrors.sh	Thu Oct 22 08:47:43 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-# Copyright (c) 2013, 2015, 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 6888954
-# @bug 8015884
-# @summary exercise HotSpot error handling code
-# @author John Coomes
-# @run shell vmerrors.sh
-
-# Repeatedly invoke java with a command-line option that causes HotSpot to
-# produce an error report and terminate just after initialization.  Each
-# invocation is identified by a small integer, <n>, which provokes a different
-# error (assertion failure, guarantee failure, fatal error, etc.).  The output
-# from stdout/stderr is written to <n>.out and the hs_err_pidXXX.log file is
-# renamed to <n>.log.
-#
-# The automated checking done by this script is minimal.  When updating the
-# fatal error handler it is more useful to run it manually or to use the -retain
-# option with the jtreg so that test directories are not removed automatically.
-# To run stand-alone:
-#
-# TESTJAVA=/java/home/dir
-# TESTVMOPTS=...
-# export TESTJAVA TESTVMOPTS
-# sh test/runtime/6888954/vmerrors.sh
-
-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
-
-ulimit -c 0 # no core files
-
-i=1
-rc=0
-
-assert_re='(assert|guarantee)[(](str|num).*failed: *'
-# for bad_data_ptr_re:
-# EXCEPTION_ACCESS_VIOLATION - Win-*
-# SIGILL - MacOS X
-# SIGSEGV - Linux-*, Solaris SPARC-*, Solaris X86-*
-#
-bad_data_ptr_re='(SIGILL|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc='
-#
-# for bad_func_ptr_re:
-# EXCEPTION_ACCESS_VIOLATION - Win-*
-# SIGBUS - Solaris SPARC-64
-# SIGSEGV - Linux-*, Solaris SPARC-32, Solaris X86-*
-# SIGILL - Aix
-#
-# Note: would like to use "pc=0x00*0f," in the pattern, but Solaris SPARC-*
-# gets its signal at a PC in test_error_handler().
-#
-bad_func_ptr_re='(SIGBUS|SIGSEGV|SIGILL|EXCEPTION_ACCESS_VIOLATION).* at pc='
-guarantee_re='guarantee[(](str|num).*failed: *'
-fatal_re='fatal error: *'
-tail_1='.*expected null'
-tail_2='.*num='
-
-for re in                                                 \
-    "${assert_re}${tail_1}"    "${assert_re}${tail_2}"    \
-    "${guarantee_re}${tail_1}" "${guarantee_re}${tail_2}" \
-    "${fatal_re}${tail_1}"     "${fatal_re}${tail_2}"     \
-    "${fatal_re}.*truncated"   "ChunkPool::allocate"      \
-    "ShouldNotCall"            "ShouldNotReachHere"       \
-    "Unimplemented"            "$bad_data_ptr_re"         \
-    "$bad_func_ptr_re"
-
-do
-    i2=$i
-    [ $i -lt 10 ] && i2=0$i
-
-    "$TESTJAVA/bin/java" $TESTOPTS -XX:+IgnoreUnrecognizedVMOptions \
-        -XX:-TransmitErrorReport -XX:-CreateMinidumpOnCrash \
-        -XX:ErrorHandlerTest=${i} -version > ${i2}.out 2>&1
-
-    # If ErrorHandlerTest is ignored (product build), stop.
-    #
-    # Using the built-in variable $! to get the pid does not work reliably on
-    # windows; use a wildcard instead.
-    mv hs_err_pid*.log ${i2}.log || exit $rc
-
-    for f in ${i2}.log ${i2}.out
-    do
-        egrep -- "$re" $f > $$
-        if [ $? -ne 0 ]
-        then
-            echo "ErrorHandlerTest=$i failed ($f)"
-            rc=1
-        fi
-    done
-    rm -f $$
-
-    i=`expr $i + 1`
-done
-
-exit $rc
--- a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java	Thu Oct 22 11:13:08 2015 -0700
@@ -46,7 +46,7 @@
         pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("CompileCommand: unrecognized command");
-        output.shouldContain("aaa  aaa");
+        output.shouldContain("aaa, aaa");
 
         // Skip on debug builds since we'll always read the file there
         if (!Platform.isDebugBuild()) {
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Thu Oct 22 11:13:08 2015 -0700
@@ -51,6 +51,32 @@
          */
         allOptionsAsMap.remove("CICompilerCount");
 
+        /*
+         * Exclude below options as their maximum value would consume too much memory
+         * and would affect other tests that run in parallel.
+         */
+        allOptionsAsMap.remove("G1ConcRefinementThreads");
+        allOptionsAsMap.remove("G1RSetRegionEntries");
+        allOptionsAsMap.remove("G1RSetSparseRegionEntries");
+
+        /*
+         * Remove parameters controlling the code cache. As these
+         * parameters have implications on the physical memory
+         * reserved by the VM, setting them to large values may hang
+         * the system and/or may cause concurrently executed tests to
+         * fail. These parameters are rigorously checked when the code
+         * cache is initialized (see
+         * hotspot/src/shared/vm/code/codeCache.cpp), therefore
+         * omitting testing for them does not pose a problem.
+         */
+        allOptionsAsMap.remove("InitialCodeCacheSize");
+        allOptionsAsMap.remove("CodeCacheMinimumUseSpace");
+        allOptionsAsMap.remove("ReservedCodeCacheSize");
+        allOptionsAsMap.remove("NonProfiledCodeHeapSize");
+        allOptionsAsMap.remove("ProfiledCodeHeapSize");
+        allOptionsAsMap.remove("NonNMethodCodeHeapSize");
+        allOptionsAsMap.remove("CodeCacheExpansionSize");
+
         allOptions = new ArrayList<>(allOptionsAsMap.values());
 
         Asserts.assertGT(allOptions.size(), 0, "Options with ranges not found!");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/TestVMOptionsFile.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2015, 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 8061999
+ * @summary Test "-XX:VMOptionsFile" VM option
+ * @library /testlibrary
+ * @modules jdk.management
+ * @run main TestVMOptionsFile
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.Path;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.nio.file.attribute.AclEntry;
+import java.nio.file.attribute.AclEntryPermission;
+import java.nio.file.attribute.AclEntryType;
+import java.nio.file.attribute.AclFileAttributeView;
+import java.nio.file.attribute.UserPrincipal;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.DynamicVMOption;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+
+public class TestVMOptionsFile {
+
+    /* Various valid VM Option files */
+    private static final String VM_OPTION_FILE_EMPTY = "optionfile_empty";
+    private static final String VM_OPTION_FILE_TABS_AND_SPACES = "optionfile_only_tabsandspaces";
+    private static final String VM_OPTION_FILE_1 = "optionfile_1";
+    private static final String VM_OPTION_FILE_2 = "optionFILE_2";
+    private static final String VM_OPTION_FILE_3 = "optionfile_3";
+    private static final String VM_OPTION_FILE_QUOTE = "optionfile_quote";
+    private static final String VM_OPTION_FILE_BIG = "optionfile_big";
+    private static final int REPEAT_COUNT = 512;
+    /* Name of the file with flags for VM_OPTION_FILE_2 Option file */
+    private static final String FLAGS_FILE = "flags_file";
+    /* VM Option file with a lot of options with quote on separate lines */
+    private static final String VM_OPTION_FILE_LOT_OF_OPTIONS_QUOTE = "optionfile_lot_of_options_quote";
+    /* Number of properties defined in VM_OPTION_FILE_LOT_OF_OPTIONS_QUOTE */
+    private static final int NUM_OF_PROP_IN_FILE_LOT_OF_OPTIONS_QUOTE = 70;
+    /* VM Option file with long property */
+    private static final String VM_OPTION_FILE_WITH_LONG_PROPERTY = "optionfile_long_property";
+    private static final String LONG_PROPERTY_NAME = "veryl'" + String.format("%1536s", "").replace(' ', 'o') + "ng'name";
+    private static final String LONG_PROPERTY_VALUE = String.format("%2096s", "").replaceAll("    ", "long");
+    /* 2 VM Option files with unmatched quotes */
+    private static final String VM_OPTION_FILE_UNMATCHED_QUOTE_1 = "optionfile_unmatched_quote_1";
+    private static final String VM_OPTION_FILE_UNMATCHED_QUOTE_2 = "optionfile_unmatched_quote_2";
+    /* VM Option file with bad option in it */
+    private static final String VM_OPTION_FILE_WITH_BAD_OPTION = "optionfile_bad_option";
+    /* VM Option file with "-XX:VMOptionsFile=" option in it */
+    private static final String VM_OPTION_FILE_WITH_VM_OPTION_FILE = "optionfile_with_optionfile";
+    /* VM Option file with "-XX:VMOptionsFile=" option in it, where file is the same option file */
+    private static final String VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE = "optionfile_with_same_optionfile";
+    /* VM Option file without read permissions(not accessible) */
+    private static final String VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS = "optionfile_wo_read_perm";
+    /* VM Option file which does not exist */
+    private static final String NOT_EXISTING_FILE = "not_exist_junk2123";
+
+    /* JAVA_TOOL_OPTIONS environment variable */
+    private static final String JAVA_TOOL_OPTIONS = "JAVA_TOOL_OPTIONS";
+    /* _JAVA_OPTIONS environment variable */
+    private static final String JAVA_OPTIONS = "_JAVA_OPTIONS";
+
+    /* Exit code for JVM, zero - for success, non-zero for failure */
+    private static final int JVM_SUCCESS = 0;
+    private static final int JVM_FAIL_WITH_EXIT_CODE_1 = 1;
+
+    /* Current working directory */
+    private static final String CURRENT_DIR = System.getProperty("user.dir");
+
+    /* Source directory */
+    private static final String SOURCE_DIR = System.getProperty("test.src", ".");
+
+    /* VM Options which are passed to the JVM */
+    private static final List<String> VMParams = new ArrayList<>();
+    /* Argument passed to the PrintPropertyAndOptions.main */
+    private static final Set<String> appParams = new LinkedHashSet<>();
+
+    private static OutputAnalyzer output;
+
+    private static final String PRINT_PROPERTY_FORMAT = "Property %s=%s";
+    private static final String PRINT_VM_OPTION_FORMAT = "Virtual Machine option %s=%s";
+
+    /*
+     * Get absoulte path to file from folder with sources
+     */
+    private static String getAbsolutePathFromSource(String fileName) {
+        return SOURCE_DIR + File.separator + fileName;
+    }
+
+    /*
+     * Make file non-readable by modifying its permissions.
+     * If file supports "posix" attributes, then modify it.
+     * Otherwise check for "acl" attributes.
+     */
+    private static void makeFileNonReadable(String file) throws IOException {
+        Path filePath = Paths.get(file);
+        Set<String> supportedAttr = filePath.getFileSystem().supportedFileAttributeViews();
+
+        if (supportedAttr.contains("posix")) {
+            Files.setPosixFilePermissions(filePath, PosixFilePermissions.fromString("-w--w----"));
+        } else if (supportedAttr.contains("acl")) {
+            UserPrincipal fileOwner = Files.getOwner(filePath);
+
+            AclFileAttributeView view = Files.getFileAttributeView(filePath, AclFileAttributeView.class);
+
+            AclEntry entry = AclEntry.newBuilder()
+                    .setType(AclEntryType.DENY)
+                    .setPrincipal(fileOwner)
+                    .setPermissions(AclEntryPermission.READ_DATA)
+                    .build();
+
+            List<AclEntry> acl = view.getAcl();
+            acl.add(0, entry);
+            view.setAcl(acl);
+        }
+    }
+
+    private static void copyFromSource(String fileName) throws IOException {
+        Files.copy(Paths.get(getAbsolutePathFromSource(fileName)),
+                Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    private static void createOptionFiles() throws IOException {
+        FileWriter fw = new FileWriter(VM_OPTION_FILE_WITH_VM_OPTION_FILE);
+
+        /* Create VM option file with following parameters "-XX:VMOptionFile=<absolute_path_to_the_VM_option_file> */
+        fw.write("-XX:VMOptionsFile=" + getAbsolutePathFromSource(VM_OPTION_FILE_1));
+        fw.close();
+
+        /* Create VM option file with following parameters "-XX:MinHeapFreeRatio=12 -XX:VMOptionFile=<absolute_path_to_the_same_VM_option_file> */
+        fw = new FileWriter(VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE);
+        fw.write("-XX:MinHeapFreeRatio=12 -XX:VMOptionsFile=" + (new File(VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE)).getCanonicalPath());
+        fw.close();
+
+        /* Create VM option file with long property */
+        fw = new FileWriter(VM_OPTION_FILE_WITH_LONG_PROPERTY);
+        fw.write("-D" + LONG_PROPERTY_NAME + "=" + LONG_PROPERTY_VALUE);
+        fw.close();
+
+        /* Create big VM option file */
+        fw = new FileWriter(VM_OPTION_FILE_BIG);
+        fw.write("-XX:MinHeapFreeRatio=17\n");
+        for (int i = 0; i < REPEAT_COUNT; i++) {
+            if (i == REPEAT_COUNT / 2) {
+                fw.write("-XX:+PrintVMOptions ");
+            }
+            fw.write("-Dmy.property=value" + (i + 1) + "\n");
+        }
+        fw.write("-XX:MaxHeapFreeRatio=85\n");
+        fw.close();
+
+        /* Copy valid VM option file and change its permission to make it not accessible */
+        Files.copy(Paths.get(getAbsolutePathFromSource(VM_OPTION_FILE_1)),
+                Paths.get(VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS),
+                StandardCopyOption.REPLACE_EXISTING);
+
+        makeFileNonReadable(VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS);
+
+        /* Copy valid VM option file to perform test with relative path */
+        copyFromSource(VM_OPTION_FILE_2);
+
+        /* Copy flags file to the current working folder */
+        copyFromSource(FLAGS_FILE);
+
+        /* Create a new empty file */
+        new File(VM_OPTION_FILE_EMPTY).createNewFile();
+    }
+
+    /*
+     * Add parameters to the VM Parameters list
+     */
+    private static void addVMParam(String... params) {
+        VMParams.addAll(Arrays.asList(params));
+    }
+
+    /*
+     * Add VM option name to the application arguments list
+     */
+    private static void addVMOptionsToCheck(String... params) {
+        for (String param : params) {
+            appParams.add("vmoption=" + param);
+        }
+    }
+
+    /*
+     * Add property to the VM Params list and to the application arguments list
+     */
+    private static void addProperty(String propertyName, String propertyValue) {
+        addVMParam("-D" + propertyName + "=" + propertyValue);
+    }
+
+    /*
+     * Add "-XX:VMOptionsfile" parameter to the VM Params list
+     */
+    private static void addVMOptionsFile(String fileName) {
+        addVMParam("-XX:VMOptionsFile=" + fileName);
+    }
+
+    private static void outputShouldContain(String expectedString) {
+        output.shouldContain(expectedString);
+    }
+
+    private static void outputShouldNotContain(String expectedString) {
+        output.shouldNotContain(expectedString);
+    }
+
+    private static ProcessBuilder createProcessBuilder() throws Exception {
+        ProcessBuilder pb;
+        List<String> runJava = new ArrayList<>();
+
+        runJava.addAll(VMParams);
+        runJava.add(PrintPropertyAndOptions.class.getName());
+        runJava.addAll(appParams);
+
+        pb = ProcessTools.createJavaProcessBuilder(runJava.toArray(new String[0]));
+
+        VMParams.clear();
+        appParams.clear();
+
+        return pb;
+    }
+
+    private static void runJavaCheckExitValue(ProcessBuilder pb, int expectedExitValue) throws Exception {
+        output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(expectedExitValue);
+    }
+
+    private static void runJavaCheckExitValue(int expectedExitValue) throws Exception {
+        runJavaCheckExitValue(createProcessBuilder(), expectedExitValue);
+    }
+
+    /*
+     * Update environment variable in passed ProcessBuilder object to the passed value
+     */
+    private static void updateEnvironment(ProcessBuilder pb, String name, String value) {
+        pb.environment().put(name, value);
+    }
+
+    /*
+     * Check property value by examining output
+     */
+    private static void checkProperty(String property, String expectedValue) {
+        outputShouldContain(String.format(PRINT_PROPERTY_FORMAT, property, expectedValue));
+    }
+
+    /*
+     * Check VM Option value by examining output
+     */
+    private static void checkVMOption(String vmOption, String expectedValue) {
+        outputShouldContain(String.format(PRINT_VM_OPTION_FORMAT, vmOption, expectedValue));
+    }
+
+    private static void testVMOptions() throws Exception {
+        /* Check that empty VM Option file is accepted without errors */
+        addVMOptionsFile(VM_OPTION_FILE_EMPTY);
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+
+        /* Check that VM Option file with tabs and spaces is accepted without errors */
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_TABS_AND_SPACES));
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+
+        /* Check that parameters are gotten from first VM Option file. Pass absolute path to the VM Option file */
+        addVMParam("-showversion");
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_1));
+        addVMOptionsToCheck("SurvivorRatio", "MinHeapFreeRatio");
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+        outputShouldContain("interpreted mode");
+        checkProperty("optfile_1", "option_file_1");
+        checkVMOption("SurvivorRatio", "16");
+        checkVMOption("MinHeapFreeRatio", "22");
+
+        /*
+         * Check that parameters are gotten from second VM Option file which also contains flags file.
+         * Flags file and option file contains NewRatio, but since options from VM Option file
+         * are processed later NewRatio should be set to value from VM Option file
+         * Pass relative path to the VM Option file in form "vmoptionfile"
+         */
+        addVMOptionsFile(VM_OPTION_FILE_2);
+        addVMOptionsToCheck("UseGCOverheadLimit", "NewRatio", "MinHeapFreeRatio", "MaxFDLimit", "AlwaysPreTouch");
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+        checkProperty("javax.net.ssl.keyStorePassword", "someVALUE123+");
+        checkVMOption("UseGCOverheadLimit", "true");
+        checkVMOption("NewRatio", "4");
+        checkVMOption("MinHeapFreeRatio", "3");
+        checkVMOption("MaxFDLimit", "true");
+        checkVMOption("AlwaysPreTouch", "false");
+
+        /* Check that parameters are gotten from third VM Option file which contains a mix of the options */
+        addVMParam("-showversion");
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_3));
+        addVMOptionsToCheck("UseGCOverheadLimit", "NewRatio");
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+        outputShouldContain("interpreted mode");
+        checkProperty("other.secret.data", "qwerty");
+        checkProperty("property", "second");
+        checkVMOption("UseGCOverheadLimit", "false");
+        checkVMOption("NewRatio", "16");
+
+        /* Check that quotes are processed normally in VM Option file */
+        addVMParam("-showversion");
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_QUOTE));
+        addVMOptionsToCheck("ErrorFile");
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+
+        outputShouldContain("interpreted mode");
+        checkProperty("my.quote.single", "Property in single quote. Here a double qoute\" Add some slashes \\/");
+        checkProperty("my.quote.double", "Double qoute. Include single '.");
+        checkProperty("javax.net.ssl.trustStorePassword", "data @+NEW");
+        checkVMOption("ErrorFile", "./my error file");
+
+        /*
+         * Verify that VM Option file accepts a file with 70 properties and with two options on separate
+         * lines and properties that use quotes a lot.
+         */
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_LOT_OF_OPTIONS_QUOTE));
+        addVMOptionsToCheck("MinHeapFreeRatio", "MaxHeapFreeRatio");
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+
+        for (int i = 1; i <= NUM_OF_PROP_IN_FILE_LOT_OF_OPTIONS_QUOTE; i++) {
+            checkProperty(String.format("prop%02d", i), String.format("%02d", i));
+        }
+        checkVMOption("MinHeapFreeRatio", "7");
+        checkVMOption("MaxHeapFreeRatio", "96");
+
+        /*
+         * Verify that VM Option file accepts a file with very long property.
+         */
+        addVMOptionsFile(VM_OPTION_FILE_WITH_LONG_PROPERTY);
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+
+        checkProperty(LONG_PROPERTY_NAME.replaceAll("'", ""), LONG_PROPERTY_VALUE);
+
+        /*
+         * Verify that VM Option file accepts a big VM Option file
+         */
+        addVMOptionsFile(VM_OPTION_FILE_BIG);
+        addVMOptionsToCheck("MinHeapFreeRatio");
+        addVMOptionsToCheck("MaxHeapFreeRatio");
+
+        runJavaCheckExitValue(JVM_SUCCESS);
+
+        outputShouldContain("VM option '+PrintVMOptions'");
+        checkProperty("my.property", "value" + REPEAT_COUNT);
+        checkVMOption("MinHeapFreeRatio", "17");
+        checkVMOption("MaxHeapFreeRatio", "85");
+    }
+
+    private static ProcessBuilder prepareTestCase(int testCase) throws Exception {
+        ProcessBuilder pb;
+
+        Asserts.assertTrue(0 < testCase && testCase < 6, "testCase should be from 1 to 5");
+
+        addVMParam("-showversion");
+        addVMOptionsToCheck("MinHeapFreeRatio", "SurvivorRatio", "NewRatio");
+
+        if (testCase < 5) {
+            addVMParam("-XX:Flags=flags_file", "-XX:-PrintVMOptions");
+            addProperty("shared.property", "command_line_before");
+            addProperty("clb", "unique_command_line_before");
+            addVMParam("-XX:MinHeapFreeRatio=7");
+        }
+
+        if (testCase < 4) {
+            addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_1));
+        }
+
+        if (testCase < 3) {
+            addVMParam("-XX:MinHeapFreeRatio=9", "-XX:-PrintVMOptions");
+            addProperty("shared.property", "command_line_after");
+            addProperty("cla", "unique_command_line_after");
+        }
+
+        /* Create ProcessBuilder after all setup is done to update environment variables */
+        pb = createProcessBuilder();
+
+        if (testCase < 2) {
+            updateEnvironment(pb, JAVA_OPTIONS, "-Dshared.property=somevalue -Djo=unique_java_options "
+                    + "-XX:MinHeapFreeRatio=18 -Dshared.property=java_options -XX:MinHeapFreeRatio=11 -XX:+PrintVMOptions");
+        }
+
+        if (testCase < 6) {
+            updateEnvironment(pb, JAVA_TOOL_OPTIONS, "-Dshared.property=qwerty -Djto=unique_java_tool_options "
+                    + "-XX:MinHeapFreeRatio=15 -Dshared.property=java_tool_options -XX:MinHeapFreeRatio=6 -XX:+PrintVMOptions");
+        }
+
+        return pb;
+    }
+
+    private static void testVMOptionsLastArgumentsWins() throws Exception {
+        ProcessBuilder pb;
+
+        /*
+         * "shared.property" property and "MinHeapFreeRatio" XX VM Option are defined
+         * in flags file, JAVA_TOOL_OPTIONS and _JAVA_OPTIONS environment variables,
+         * on command line before VM Option file, on command line after VM Option file
+         * and also in VM Option file. Verify that last argument wins. Also check
+         * unique properties and VM Options.
+         * Here is the order of options processing and last argument wins:
+         *    1) Flags file
+         *    2) JAVA_TOOL_OPTIONS environment variables
+         *    3) Pseudo command line from launcher
+         *    4) _JAVA_OPTIONS
+         * In every category arguments processed from left to right and from up to down
+         * and the last processed arguments wins, i.e. if argument is defined several
+         * times the value of argument will be equal to the last processed argument.
+         *
+         * "shared.property" property and "MinHeapFreeRatio" should be equal to the
+         * value from _JAVA_OPTIONS environment variable
+         */
+        pb = prepareTestCase(1);
+
+        runJavaCheckExitValue(pb, JVM_SUCCESS);
+
+        outputShouldContain("interpreted mode");
+        outputShouldContain("VM option '+PrintVMOptions'");
+        checkProperty("shared.property", "java_options");
+        checkVMOption("MinHeapFreeRatio", "11");
+        /* Each category defines its own properties */
+        checkProperty("jto", "unique_java_tool_options");
+        checkProperty("jo", "unique_java_options");
+        checkProperty("clb", "unique_command_line_before");
+        checkProperty("optfile_1", "option_file_1");
+        checkProperty("cla", "unique_command_line_after");
+        /* SurvivorRatio defined only in VM Option file */
+        checkVMOption("SurvivorRatio", "16");
+        /* NewRatio defined only in flags file */
+        checkVMOption("NewRatio", "5");
+
+        /*
+         * The same as previous but without _JAVA_OPTIONS environment variable.
+         * "shared.property" property and "MinHeapFreeRatio" should be equal to the
+         * value from pseudo command line after VM Option file
+         */
+        pb = prepareTestCase(2);
+
+        runJavaCheckExitValue(pb, JVM_SUCCESS);
+
+        outputShouldContain("interpreted mode");
+        checkProperty("shared.property", "command_line_after");
+        checkVMOption("MinHeapFreeRatio", "9");
+
+        /*
+         * The same as previous but without arguments in pseudo command line after
+         * VM Option file.
+         * "shared.property" property and "MinHeapFreeRatio" should be equal to the
+         * value from VM Option file.
+         */
+        pb = prepareTestCase(3);
+
+        runJavaCheckExitValue(pb, JVM_SUCCESS);
+
+        outputShouldContain("interpreted mode");
+        outputShouldContain("VM option '+PrintVMOptions'");
+        checkProperty("shared.property", "vmoptfile");
+        checkVMOption("MinHeapFreeRatio", "22");
+
+        /*
+         * The same as previous but without arguments in VM Option file.
+         * "shared.property" property and "MinHeapFreeRatio" should be equal to the
+         * value from pseudo command line.
+         */
+        pb = prepareTestCase(4);
+
+        runJavaCheckExitValue(pb, JVM_SUCCESS);
+
+        outputShouldNotContain("VM option '+PrintVMOptions'");
+        checkProperty("shared.property", "command_line_before");
+        checkVMOption("MinHeapFreeRatio", "7");
+
+        /*
+         * The same as previous but without arguments from pseudo command line.
+         * "shared.property" property and "MinHeapFreeRatio" should be equal to the
+         * value from JAVA_TOOL_OPTIONS environment variable.
+         */
+        pb = prepareTestCase(5);
+
+        runJavaCheckExitValue(pb, JVM_SUCCESS);
+
+        outputShouldContain("VM option '+PrintVMOptions'");
+        checkProperty("shared.property", "java_tool_options");
+        checkVMOption("MinHeapFreeRatio", "6");
+    }
+
+    private static void testVMOptionsInvalid() throws Exception {
+        ProcessBuilder pb;
+
+        /* Pass directory instead of file */
+        addVMOptionsFile(CURRENT_DIR);
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+
+        /* Pass not existing file */
+        addVMOptionsFile(getAbsolutePathFromSource(NOT_EXISTING_FILE));
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("Could not open options file");
+
+        /* Pass VM option file with bad option */
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_WITH_BAD_OPTION));
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("Unrecognized VM option");
+
+        /* Pass VM option file with same VM option file option in it */
+        addVMOptionsFile(VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE);
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("VM options file is only supported on the command line");
+
+        /* Pass VM option file with VM option file option in it */
+        addVMOptionsFile(VM_OPTION_FILE_WITH_VM_OPTION_FILE);
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("VM options file is only supported on the command line");
+
+        /* Pass VM option file which is not accessible (without read permissions) */
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS));
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("Could not open options file");
+
+        /* Pass two VM option files */
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_1));
+        addVMOptionsFile(VM_OPTION_FILE_2);
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("Only one VM Options file is supported on the command line");
+
+        /* Pass empty option file i.e. pass "-XX:VMOptionsFile=" */
+        addVMOptionsFile("");
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("Could not open options file");
+
+        /* Pass VM option file with unmatched single quote */
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_UNMATCHED_QUOTE_1));
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("Unmatched quote in");
+
+        /* Pass VM option file with unmatched double quote in X option */
+        addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_UNMATCHED_QUOTE_2));
+
+        runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("Unmatched quote in");
+    }
+
+    public static void main(String[] args) throws Exception {
+        /*
+         * Preparation before actual testing - create two VM Option files
+         * which contains VM Option file in it and copy other files to the
+         * current working folder
+         */
+        createOptionFiles();
+
+        testVMOptions(); /* Test VM Option file general functionality */
+        testVMOptionsLastArgumentsWins(); /* Verify that last argument wins */
+        testVMOptionsInvalid(); /* Test invalid VM Option file functionality */
+
+    }
+
+    public static class PrintPropertyAndOptions {
+
+        public static void main(String[] arguments) {
+            String vmOption;
+            Properties properties = System.getProperties();
+
+            for (String propertyName : properties.stringPropertyNames()) {
+                System.out.println(String.format(PRINT_PROPERTY_FORMAT, propertyName, System.getProperty(propertyName, "NOT DEFINED")));
+            }
+
+            for (String arg : arguments) {
+                if (arg.startsWith("vmoption=")) {
+                    vmOption = arg.substring(9);
+                    System.out.println(String.format(PRINT_VM_OPTION_FORMAT, vmOption, new DynamicVMOption(vmOption).getValue()));
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/flags_file	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,5 @@
++MaxFDLimit
+-AlwaysPreTouch
+MinHeapFreeRatio=3
+MaxHeapFreeRatio=89
+NewRatio=5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionFILE_2	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,4 @@
+-XX:+UseGCOverheadLimit
+-XX:Flags=flags_file
+-Djavax.net.ssl.keyStorePassword=someVALUE123+
+-XX:NewRatio=4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_1	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+-Dshared.property=othervalue -XX:MinHeapFreeRatio=13 -Doptfile_1=option_file_1 -Xint -XX:SurvivorRatio=16 -Xminf0.22 -Dshared.property=vmoptfile -XX:+PrintVMOptions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_3	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,8 @@
+-Xcomp -Dproperty=first
+
+    -Xint
+-XX:+UseGCOverheadLimit
+
+  	-XX:NewRatio=4	-XX:-UseGCOverheadLimit	-Dproperty=second
+
+-Dother.secret.data=qwerty -XX:NewRatio=16
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_bad_option	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+-Dmy.property=user1 -XX:bad_option -Xint 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_lot_of_options_quote	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,72 @@
+-Dprop01='01'
+-Dprop02='02'
+-Dprop03='03'
+-Dprop04='04'
+-Dprop05='05'
+-D"pr"op06='06'
+-Dprop07='07'
+-Dprop08='08'
+-Dprop09="09"
+-Dprop"10=10"
+-Dprop11='11'
+'-Dprop12=12'
+-Dprop13='13'
+-Dprop14='14'
+-Dprop15='15'
+-Dprop16='16'
+-Dprop17='17'
+-Dprop18='18'
+-Dprop19='19'
+-Dprop20='20'
+-Dprop21='21'
+-Dprop22='22'
+-Dprop23='23'
+-Dpr'o'p24='24'
+-Dprop25='25'
+-Dprop26='26'
+-Dprop27='27'
+-Dprop28='28'
+-XX:MinHeapFreeRatio=7
+-D"prop29=29"
+-Dprop30='30'
+-Dprop31='31'
+-Dprop32="32"
+-Dprop33='33'
+-Dprop34='34'
+-Dprop35='35'
+'-Dpr'op36='36'
+-Dprop37='37'
+-Dprop38='38'
+-Dprop39='39'
+-Dprop40='40'
+-Dprop41='41'
+-Dprop42='42'
+-Dprop43='43'
+-Dprop44='44'
+-Dprop45='45'
+-D"prop46="'46'
+-Dprop47='47'
+-Dprop48='48'
+-Dprop49='49' 	-XX:MaxHeapFreeRatio=96
+"-"Dprop50='50'
+-Dprop51='51'
+-Dprop52='52'
+-Dprop53='53'
+-Dprop54='54'
+-Dprop55='55'
+-Dprop56='56'
+-Dprop57='57'
+-"D"prop58='58'
+-Dprop59='59'
+'-Dprop60=''60'
+-Dprop61='61'
+-Dprop62='62'
+-Dprop63='63'
+-Dprop64=64
+-Dprop65=65
+-Dprop66=66
+-Dprop67=67
+-Dprop68=68
+-Dprop69=69
+-Dprop70=70
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_only_tabsandspaces	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,4 @@
+          	               	          	
+         	
+	
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_quote	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+'-Dmy.quote.single'='Property in single quote. Here a double qoute" Add some slashes \/' -D"my.quote.double"="Double qoute. Include single '." -'Xi'n"t" -X"X:ErrorFile"=./my' error file' -Djavax.net.ssl.trustStorePassword='data @+NEW'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_unmatched_quote_1	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+-Dmy.quote.single='Unmatched single quote with embedded double " quote
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/optionfile_unmatched_quote_2	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,1 @@
+-"Xloggc:Unmatched quote in X option 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ErrorHandling/ErrorHandler.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, 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 6888954
+ * @bug 8015884
+ * @summary Exercise HotSpot error handling code by invoking java with
+ *          -XX:ErrorHandlerTest option to cause an error report. Check the results.
+ * @library /testlibrary
+ * @run driver ErrorHandler
+ */
+
+import jdk.test.lib.*;
+
+public class ErrorHandler {
+
+    public static OutputAnalyzer runTest(int testcase) throws Exception {
+        return new OutputAnalyzer(
+            ProcessTools.createJavaProcessBuilder(
+            "-XX:-TransmitErrorReport", "-XX:-CreateCoredumpOnCrash", "-XX:ErrorHandlerTest=" + testcase)
+            .start());
+    }
+
+    public static void main(String[] args) throws Exception {
+        // Test is only applicable for debug builds
+        if (!Platform.isDebugBuild()) {
+            return;
+        }
+        // Keep this in sync with hotspot/src/share/vm/utilities/debug.cpp
+        int i = 1;
+        String[] strings = {
+            "assert(str == NULL) failed: expected null",
+            "assert(num == 1023 && *str == 'X') failed: num=",
+            "guarantee(str == NULL) failed: expected null",
+            "guarantee(num == 1023 && *str == 'X') failed: num=",
+            "fatal error: expected null",
+            "fatal error: num=",
+            "fatal error: this message should be truncated during formatting",
+            "ChunkPool::allocate",
+            "Error: ShouldNotCall()",
+            "Error: ShouldNotReachHere()",
+            "Error: Unimplemented()"
+        };
+
+        String[] patterns = {
+            "(SIGILL|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc=",
+            "(SIGBUS|SIGSEGV|SIGILL|EXCEPTION_ACCESS_VIOLATION).* at pc="
+        };
+
+        for (String s : strings) {
+            runTest(i++).shouldContain(s);
+        }
+
+        for (String p : patterns) {
+            runTest(i++).shouldMatch(p);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/logging/TestBasicLogOutput.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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 TestBasicLogOutput
+ * @summary Ensure logging can be enabled and successfully prints to stdout.
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.OutputAnalyzer;
+
+public class TestBasicLogOutput {
+
+    public static void main(String[] args) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:all=trace", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldMatch("\\[logging *\\]"); // expected tag(s)
+        output.shouldContain("Log configuration fully initialized."); // expected message
+        output.shouldHaveExitValue(0);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/sa/DeadlockDetectionTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2015, 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.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.apps.LingeredAppWithDeadlock;
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.Platform;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+
+/*
+ * @test
+ * @summary Test deadlock detection
+ * @library /../../test/lib/share/classes
+ * @library /testlibrary
+ * @modules java.management
+ * @build jdk.test.lib.*
+ * @build jdk.test.lib.apps.*
+ * @build DeadlockDetectionTest
+ * @run main DeadlockDetectionTest
+ */
+
+public class DeadlockDetectionTest {
+
+    private static LingeredAppWithDeadlock theApp = null;
+    private static ProcessBuilder processBuilder = new ProcessBuilder();
+
+    private static OutputAnalyzer jstack(String... toolArgs) throws Exception {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addToolArg("jstack");
+        if (toolArgs != null) {
+            for (String toolArg : toolArgs) {
+                launcher.addToolArg(toolArg);
+            }
+        }
+
+        processBuilder.command(launcher.getCommand());
+        System.out.println(processBuilder.command().stream().collect(Collectors.joining(" ")));
+        OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
+        System.out.println(output.getOutput());
+
+        return output;
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Starting DeadlockDetectionTest");
+
+        if (!Platform.shouldSAAttach()) {
+            // Silently skip the test if we don't have enough permissions to attach
+            // Not all conditions checked by function is relevant to SA but it's worth
+            // to check
+            System.err.println("Error! Insufficient permissions to attach.");
+            return;
+        }
+
+
+        if (!LingeredApp.isLastModifiedWorking()) {
+            // Exact behaviour of the test depends on operating system and the test nature,
+            // so just print the warning and continue
+            System.err.println("Warning! Last modified time doesn't work.");
+        }
+
+        try {
+            List<String> vmArgs = new ArrayList<String>();
+            vmArgs.add("-XX:+UsePerfData");
+            vmArgs.addAll(Utils.getVmOptions());
+
+            theApp = new LingeredAppWithDeadlock();
+            LingeredApp.startApp(vmArgs, theApp);
+            OutputAnalyzer output = jstack("--pid", Long.toString(theApp.getPid()));
+            System.out.println(output.getOutput());
+
+            if (output.getExitValue() == 3) {
+                System.out.println("Test can't run for some reason. Skipping");
+            }
+            else {
+                output.shouldHaveExitValue(0);
+                output.shouldContain("Found a total of 1 deadlock.");
+            }
+
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
+    }
+}
--- a/hotspot/test/test_env.sh	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/test_env.sh	Thu Oct 22 11:13:08 2015 -0700
@@ -111,7 +111,8 @@
   exit 1
 fi
 
-${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -Xinternalversion > vm_version.out 2>&1
+${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -Xinternalversion | sed -e 's/[(][^)]*[)]//g' -e 's/ by "[^"]*"//g' > vm_version.out 2>&1
+echo "INT_VERSION=`cat vm_version.out 2>&1`"
 
 VM_TYPE="unknown"
 grep "Server" vm_version.out > ${NULL}
--- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Thu Oct 22 11:13:08 2015 -0700
@@ -24,7 +24,7 @@
 package sun.hotspot.tools.ctw;
 
 import sun.hotspot.WhiteBox;
-import sun.misc.SharedSecrets;
+import jdk.internal.misc.SharedSecrets;
 import sun.reflect.ConstantPool;
 
 import java.lang.reflect.Executable;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jdk/test/lib/FileInstaller.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, 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 jdk.test.lib;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
+
+/**
+ * Copy a resource: file or directory recursively, using relative path(src and dst)
+ * which are applied to test source directory(src) and current directory(dst)
+ */
+public class FileInstaller {
+    /**
+     * @param args source and destination
+     * @throws IOException if an I/O error occurs
+     */
+    public static void main(String[] args) throws IOException {
+        if (args.length != 2) {
+            throw new IllegalArgumentException("Unexpected number of arguments for file copy");
+        }
+        Path src = Paths.get(Utils.TEST_SRC, args[0]);
+        Path dst = Paths.get(args[1]);
+        if (src.toFile().exists()) {
+            if (src.toFile().isDirectory()) {
+                Files.walkFileTree(src, new CopyFileVisitor(src, dst));
+            } else {
+                Path dstDir = dst.getParent();
+                if (!dstDir.toFile().exists()) {
+                    Files.createDirectories(dstDir);
+                }
+                Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
+            }
+        } else {
+            throw new IOException("Can't find source " + src);
+        }
+    }
+
+    private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
+        private final Path copyFrom;
+        private final Path copyTo;
+
+        public CopyFileVisitor(Path copyFrom, Path copyTo) {
+            this.copyFrom = copyFrom;
+            this.copyTo = copyTo;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(Path file,
+                BasicFileAttributes attrs) throws IOException {
+            Path relativePath = file.relativize(copyFrom);
+            Path destination = copyTo.resolve(relativePath);
+            if (!destination.toFile().exists()) {
+                Files.createDirectories(destination);
+            }
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(Path file,
+                BasicFileAttributes attrs) throws IOException {
+            if (!file.toFile().isFile()) {
+                return FileVisitResult.CONTINUE;
+            }
+            Path relativePath = copyFrom.relativize(file);
+            Path destination = copyTo.resolve(relativePath);
+            Files.copy(file, destination, StandardCopyOption.COPY_ATTRIBUTES);
+            return FileVisitResult.CONTINUE;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jdk/test/lib/Pair.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 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 jdk.test.lib;
+
+import java.util.Objects;
+
+/**
+ * Pair - a two element tuple
+ *
+ * @param <F> first type
+ * @param <S> second type
+ */
+public class Pair<F, S> {
+    public final F first;
+    public final S second;
+
+    public Pair(F first, S second) {
+        this.first = first;
+        this.second = second;
+    }
+
+    @Override
+    public String toString() {
+        return "(" + first + ":" + second + ")";
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof Pair<?, ?>) {
+            Pair<?, ?> otherPair = (Pair<?, ?>) other;
+            return Objects.equals(first, otherPair.first) &&
+                    Objects.equals(second, otherPair.second);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        if (first == null) {
+            return (second == null) ? 0 : second.hashCode();
+        } else if (second == null) {
+            return first.hashCode();
+        } else {
+            return first.hashCode() * 17 + second.hashCode();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jdk/test/lib/Triple.java	Thu Oct 22 11:13:08 2015 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015, 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 jdk.test.lib;
+
+import java.util.Objects;
+
+/**
+ * Triple - a three element tuple
+ *
+ * @param <F> first element type
+ * @param <S> second element type
+ * @param <T> third element type
+ */
+public class Triple<F, S, T> {
+    private final Pair<F, Pair<S, T>> container;
+
+    /**
+     * Constructor
+     *
+     * @param first  first element of the triple
+     * @param second second element of the triple
+     * @param third  third element of the triple
+     */
+    public Triple(F first, S second, T third) {
+        container = new Pair<>(first, new Pair<>(second, third));
+    }
+
+    /**
+     * Gets first element of the triple
+     */
+    public F getFirst() {
+        return container.first;
+    }
+
+    /**
+     * Gets second element of the triple
+     */
+    public S getSecond() {
+        return container.second.first;
+    }
+
+    /**
+     * Gets third element of the triple
+     */
+    public T getThird() {
+        return container.second.second;
+    }
+
+    @Override
+    public int hashCode() {
+        return container.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Triple<?, ?, ?>) {
+            Triple<?, ?, ?> objTriple = (Triple<?, ?, ?>) obj;
+            return Objects.equals(container.first, objTriple.container.first)
+                    && Objects.equals(container.second,
+                    objTriple.container.second);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "(" + getFirst() + " : " + getSecond() + " : " + getThird() + ")";
+    }
+}
--- a/hotspot/test/testlibrary/jdk/test/lib/Utils.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/testlibrary/jdk/test/lib/Utils.java	Thu Oct 22 11:13:08 2015 -0700
@@ -23,25 +23,31 @@
 
 package jdk.test.lib;
 
+import java.io.File;
 import static jdk.test.lib.Asserts.assertTrue;
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.net.InetAddress;
+import java.net.MalformedURLException;
 import java.net.ServerSocket;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.net.UnknownHostException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
 import java.util.function.BooleanSupplier;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import java.util.stream.Collectors;
 import sun.misc.Unsafe;
 
 /**
@@ -50,6 +56,11 @@
 public final class Utils {
 
     /**
+     * Returns the value of 'test.class.path' system property.
+     */
+    public static final String TEST_CLASS_PATH = System.getProperty("test.class.path", ".");
+
+    /**
      * Returns the sequence used by operating system to separate lines.
      */
     public static final String NEW_LINE = System.getProperty("line.separator");
@@ -64,6 +75,11 @@
      */
     public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
 
+    /**
+     * Returns the value of 'test.src' system property.
+     */
+    public static final String TEST_SRC = System.getProperty("test.src", "").trim();
+
     private static Unsafe unsafe = null;
 
     /**
@@ -374,6 +390,28 @@
     }
 
     /**
+     * Returns random element of non empty collection
+     *
+     * @param <T> a type of collection element
+     * @param collection collection of elements
+     * @return random element of collection
+     * @throws IllegalArgumentException if collection is empty
+     */
+    public static <T> T getRandomElement(Collection<T> collection)
+            throws IllegalArgumentException {
+        if (collection.isEmpty()) {
+            throw new IllegalArgumentException("Empty collection");
+        }
+        Random random = getRandomInstance();
+        int elementIndex = 1 + random.nextInt(collection.size() - 1);
+        Iterator<T> iterator = collection.iterator();
+        while (--elementIndex != 0) {
+            iterator.next();
+        }
+        return iterator.next();
+    }
+
+    /**
      * Wait for condition to be true
      *
      * @param condition, a condition to wait for
@@ -430,26 +468,114 @@
     }
 
     /**
+     * Ensures a requested class is loaded
+     * @param aClass class to load
+     */
+    public static void ensureClassIsLoaded(Class<?> aClass) {
+        if (aClass == null) {
+            throw new Error("Requested null class");
+        }
+        try {
+            Class.forName(aClass.getName(), /* initialize = */ true,
+                    ClassLoader.getSystemClassLoader());
+        } catch (ClassNotFoundException e) {
+            throw new Error("Class not found", e);
+        }
+    }
+    /**
+     * @param parent a class loader to be the parent for the returned one
+     * @return an UrlClassLoader with urls made of the 'test.class.path' jtreg
+     *         property and with the given parent
+     */
+    public static URLClassLoader getTestClassPathURLClassLoader(ClassLoader parent) {
+        URL[] urls = Arrays.stream(TEST_CLASS_PATH.split(File.pathSeparator))
+                .map(Paths::get)
+                .map(Path::toUri)
+                .map(x -> {
+                    try {
+                        return x.toURL();
+                    } catch (MalformedURLException ex) {
+                        throw new Error("Test issue. JTREG property"
+                                + " 'test.class.path'"
+                                + " is not defined correctly", ex);
+                    }
+                }).toArray(URL[]::new);
+        return new URLClassLoader(urls, parent);
+    }
+
+    /**
      * Runs runnable and checks that it throws expected exception. If exceptionException is null it means
      * that we expect no exception to be thrown.
      * @param runnable what we run
      * @param expectedException expected exception
      */
     public static void runAndCheckException(Runnable runnable, Class<? extends Throwable> expectedException) {
+        runAndCheckException(runnable, t -> {
+            if (t == null) {
+                if (expectedException != null) {
+                    throw new AssertionError("Didn't get expected exception " + expectedException.getSimpleName());
+                }
+            } else {
+                String message = "Got unexpected exception " + t.getClass().getSimpleName();
+                if (expectedException == null) {
+                    throw new AssertionError(message, t);
+                } else if (!expectedException.isAssignableFrom(t.getClass())) {
+                    message += " instead of " + expectedException.getSimpleName();
+                    throw new AssertionError(message, t);
+                }
+            }
+        });
+    }
+
+    /**
+     * Runs runnable and makes some checks to ensure that it throws expected exception.
+     * @param runnable what we run
+     * @param checkException a consumer which checks that we got expected exception and raises a new exception otherwise
+     */
+    public static void runAndCheckException(Runnable runnable, Consumer<Throwable> checkException) {
         try {
             runnable.run();
-            if (expectedException != null) {
-                throw new AssertionError("Didn't get expected exception " + expectedException.getSimpleName());
-            }
+            checkException.accept(null);
         } catch (Throwable t) {
-            if (expectedException == null) {
-                throw new AssertionError("Got unexpected exception ", t);
-            }
-            if (!expectedException.isAssignableFrom(t.getClass())) {
-                throw new AssertionError(String.format("Got unexpected exception %s instead of %s",
-                        t.getClass().getSimpleName(), expectedException.getSimpleName()), t);
-            }
+            checkException.accept(t);
         }
     }
 
+    /**
+     * Converts to VM type signature
+     *
+     * @param type Java type to convert
+     * @return string representation of VM type
+     */
+    public static String toJVMTypeSignature(Class<?> type) {
+        if (type.isPrimitive()) {
+            if (type == boolean.class) {
+                return "Z";
+            } else if (type == byte.class) {
+                return "B";
+            } else if (type == char.class) {
+                return "C";
+            } else if (type == double.class) {
+                return "D";
+            } else if (type == float.class) {
+                return "F";
+            } else if (type == int.class) {
+                return "I";
+            } else if (type == long.class) {
+                return "J";
+            } else if (type == short.class) {
+                return "S";
+            } else if (type == void.class) {
+                return "V";
+            } else {
+                throw new Error("Unsupported type: " + type);
+            }
+        }
+        String result = type.getName().replaceAll("\\.", "/");
+        if (!type.isArray()) {
+            return "L" + result + ";";
+        }
+        return result;
+    }
 }
+
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -36,9 +36,7 @@
 
 public class DoubleTest {
     private static final String FLAG_NAME = "CompileThresholdScaling";
-    private static final Double[] TESTS = {0d, -0d, -1d, 1d,
-            Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN,
-            Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
+    private static final Double[] TESTS = {0d, -0d, 1d, Double.MAX_VALUE};
 
     public static void main(String[] args) throws Exception {
         VmFlagTest.runTest(FLAG_NAME, TESTS,
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java	Thu Oct 22 08:47:43 2015 -0700
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java	Thu Oct 22 11:13:08 2015 -0700
@@ -29,7 +29,7 @@
  * @build IntxTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IntxTest
+ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-ProfileInterpreter IntxTest
  * @summary testing of WB::set/getIntxVMFlag()
  * @author igor.ignatyev@oracle.com
  */
@@ -37,8 +37,7 @@
 public class IntxTest {
     private static final String FLAG_NAME = "OnStackReplacePercentage";
     private static final String FLAG_DEBUG_NAME = "InlineFrequencyCount";
-    private static final Long[] TESTS = {0L, 100L, -1L,
-            (long) Integer.MAX_VALUE, (long) Integer.MIN_VALUE};
+    private static final Long[] TESTS = {0L, 100L, (long) Integer.MAX_VALUE};
 
     public static void main(String[] args) throws Exception {
         VmFlagTest.runTest(FLAG_NAME, TESTS,