Merge
authoramurillo
Thu, 09 Jul 2015 22:46:16 -0700
changeset 31636 75c6dcc9351d
parent 31564 9b3a9d72f07b (current diff)
parent 31635 6bf7a358ca17 (diff)
child 31637 d5811f0c68dc
child 31771 c9f593020799
child 31778 7c57068badaa
Merge
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -48,8 +48,13 @@
     Type type = db.lookupType("CodeCache");
 
     // Get array of CodeHeaps
+    // Note: CodeHeap may be subclassed with optional private heap mechanisms.
+    Type codeHeapType = db.lookupType("CodeHeap");
+    VirtualBaseConstructor heapConstructor =
+        new VirtualBaseConstructor(db, codeHeapType, "sun.jvm.hotspot.memory", CodeHeap.class);
+
     AddressField heapsField = type.getAddressField("_heaps");
-    heapArray = GrowableArray.create(heapsField.getValue(), new StaticBaseConstructor<CodeHeap>(CodeHeap.class));
+    heapArray = GrowableArray.create(heapsField.getValue(), heapConstructor);
 
     scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
 
@@ -180,31 +185,9 @@
 
   public void iterate(CodeCacheVisitor visitor) {
     visitor.prologue(lowBound(), highBound());
-    CodeBlob lastBlob = null;
-
     for (int i = 0; i < heapArray.length(); ++i) {
       CodeHeap current_heap = heapArray.at(i);
-      Address ptr = current_heap.begin();
-      while (ptr != null && ptr.lessThan(current_heap.end())) {
-        try {
-          // Use findStart to get a pointer inside blob other findBlob asserts
-          CodeBlob blob = findBlobUnsafe(current_heap.findStart(ptr));
-          if (blob != null) {
-            visitor.visit(blob);
-            if (blob == lastBlob) {
-              throw new InternalError("saw same blob twice");
-            }
-            lastBlob = blob;
-          }
-        } catch (RuntimeException e) {
-          e.printStackTrace();
-        }
-        Address next = current_heap.nextBlock(ptr);
-        if (next != null && next.lessThan(ptr)) {
-          throw new InternalError("pointer moved backwards");
-        }
-        ptr = next;
-      }
+      current_heap.iterate(visitor, this);
     }
     visitor.epilogue();
   }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CodeHeap.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CodeHeap.java	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,6 +25,7 @@
 package sun.jvm.hotspot.memory;
 
 import java.util.*;
+import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
@@ -90,7 +91,7 @@
     return h.getAllocatedSpace();
   }
 
-  public Address nextBlock(Address ptr) {
+  private Address nextBlock(Address ptr) {
     Address base = blockBase(ptr);
     if (base == null) {
       return null;
@@ -99,6 +100,31 @@
     return base.addOffsetTo(block.getLength() * (1 << getLog2SegmentSize()));
   }
 
+  public void iterate(CodeCacheVisitor visitor, CodeCache cache) {
+    CodeBlob lastBlob = null;
+    Address ptr = begin();
+    while (ptr != null && ptr.lessThan(end())) {
+      try {
+        // Use findStart to get a pointer inside blob other findBlob asserts
+        CodeBlob blob = cache.createCodeBlobWrapper(findStart(ptr));
+        if (blob != null) {
+          visitor.visit(blob);
+          if (blob == lastBlob) {
+            throw new InternalError("saw same blob twice");
+          }
+          lastBlob = blob;
+        }
+      } catch (RuntimeException e) {
+        e.printStackTrace();
+      }
+      Address next = nextBlock(ptr);
+      if (next != null && next.lessThan(ptr)) {
+        throw new InternalError("pointer moved backwards");
+      }
+      ptr = next;
+    }
+  }
+
   //--------------------------------------------------------------------------------
   // Internals only below this point
   //
--- a/hotspot/make/aix/makefiles/mapfile-vers-debug	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/aix/makefiles/mapfile-vers-debug	Thu Jul 09 22:46:16 2015 -0700
@@ -141,6 +141,18 @@
                 JVM_Halt;
                 JVM_HoldsLock;
                 JVM_IHashCode;
+                JVM_ImageAttributeOffsets;
+                JVM_ImageAttributeOffsetsLength;
+                JVM_ImageClose;
+                JVM_ImageFindAttributes;
+                JVM_ImageGetAttributes;
+                JVM_ImageGetAttributesCount;
+                JVM_ImageGetDataAddress;
+                JVM_ImageGetIndexAddress;
+                JVM_ImageGetStringBytes;
+                JVM_ImageOpen;
+                JVM_ImageRead;
+                JVM_ImageReadCompressed;
                 JVM_InitAgentProperties;
                 JVM_InitProperties;
                 JVM_InternString;
--- a/hotspot/make/aix/makefiles/mapfile-vers-product	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/aix/makefiles/mapfile-vers-product	Thu Jul 09 22:46:16 2015 -0700
@@ -139,6 +139,18 @@
                 JVM_Halt;
                 JVM_HoldsLock;
                 JVM_IHashCode;
+                JVM_ImageAttributeOffsets;
+                JVM_ImageAttributeOffsetsLength;
+                JVM_ImageClose;
+                JVM_ImageFindAttributes;
+                JVM_ImageGetAttributes;
+                JVM_ImageGetAttributesCount;
+                JVM_ImageGetDataAddress;
+                JVM_ImageGetIndexAddress;
+                JVM_ImageGetStringBytes;
+                JVM_ImageOpen;
+                JVM_ImageRead;
+                JVM_ImageReadCompressed;
                 JVM_InitAgentProperties;
                 JVM_InitProperties;
                 JVM_InternString;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug	Thu Jul 09 22:46:16 2015 -0700
@@ -139,6 +139,18 @@
                 _JVM_Halt
                 _JVM_HoldsLock
                 _JVM_IHashCode
+                _JVM_ImageAttributeOffsets
+                _JVM_ImageAttributeOffsetsLength
+                _JVM_ImageClose
+                _JVM_ImageFindAttributes
+                _JVM_ImageGetAttributes
+                _JVM_ImageGetAttributesCount
+                _JVM_ImageGetDataAddress
+                _JVM_ImageGetIndexAddress
+                _JVM_ImageGetStringBytes
+                _JVM_ImageOpen
+                _JVM_ImageRead
+                _JVM_ImageReadCompressed
                 _JVM_InitAgentProperties
                 _JVM_InitProperties
                 _JVM_InternString
@@ -188,7 +200,7 @@
                 _JVM_Yield
                 _JVM_handle_bsd_signal
 
-                # miscellaneous functions
+				# miscellaneous functions
                 _jio_fprintf
                 _jio_printf
                 _jio_snprintf
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product	Thu Jul 09 22:46:16 2015 -0700
@@ -139,6 +139,18 @@
                 _JVM_Halt
                 _JVM_HoldsLock
                 _JVM_IHashCode
+                _JVM_ImageAttributeOffsets
+                _JVM_ImageAttributeOffsetsLength
+                _JVM_ImageClose
+                _JVM_ImageFindAttributes
+                _JVM_ImageGetAttributes
+                _JVM_ImageGetAttributesCount
+                _JVM_ImageGetDataAddress
+                _JVM_ImageGetIndexAddress
+                _JVM_ImageGetStringBytes
+                _JVM_ImageOpen
+                _JVM_ImageRead
+                _JVM_ImageReadCompressed
                 _JVM_InitAgentProperties
                 _JVM_InitProperties
                 _JVM_InternString
--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug	Thu Jul 09 22:46:16 2015 -0700
@@ -141,6 +141,18 @@
                 JVM_Halt;
                 JVM_HoldsLock;
                 JVM_IHashCode;
+                JVM_ImageAttributeOffsets;
+                JVM_ImageAttributeOffsetsLength;
+                JVM_ImageClose;
+                JVM_ImageFindAttributes;
+                JVM_ImageGetAttributes;
+                JVM_ImageGetAttributesCount;
+                JVM_ImageGetDataAddress;
+                JVM_ImageGetIndexAddress;
+                JVM_ImageGetStringBytes;
+                JVM_ImageOpen;
+                JVM_ImageRead;
+                JVM_ImageReadCompressed;
                 JVM_InitAgentProperties;
                 JVM_InitProperties;
                 JVM_InternString;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product	Thu Jul 09 22:46:16 2015 -0700
@@ -141,6 +141,18 @@
                 JVM_Halt;
                 JVM_HoldsLock;
                 JVM_IHashCode;
+                JVM_ImageAttributeOffsets;
+                JVM_ImageAttributeOffsetsLength;
+                JVM_ImageClose;
+                JVM_ImageFindAttributes;
+                JVM_ImageGetAttributes;
+                JVM_ImageGetAttributesCount;
+                JVM_ImageGetDataAddress;
+                JVM_ImageGetIndexAddress;
+                JVM_ImageGetStringBytes;
+                JVM_ImageOpen;
+                JVM_ImageRead;
+                JVM_ImageReadCompressed;
                 JVM_InitAgentProperties;
                 JVM_InitProperties;
                 JVM_InternString;
--- a/hotspot/make/linux/makefiles/buildtree.make	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/linux/makefiles/buildtree.make	Thu Jul 09 22:46:16 2015 -0700
@@ -118,7 +118,8 @@
 	$(PLATFORM_DIR)/generated/dependencies \
 	$(PLATFORM_DIR)/generated/adfiles \
 	$(PLATFORM_DIR)/generated/jvmtifiles \
-	$(PLATFORM_DIR)/generated/tracefiles
+	$(PLATFORM_DIR)/generated/tracefiles \
+	$(PLATFORM_DIR)/generated/extensions
 
 TARGETS      = debug fastdebug optimized product
 SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug	Thu Jul 09 22:46:16 2015 -0700
@@ -141,6 +141,18 @@
                 JVM_Halt;
                 JVM_HoldsLock;
                 JVM_IHashCode;
+                JVM_ImageAttributeOffsets;
+                JVM_ImageAttributeOffsetsLength;
+                JVM_ImageClose;
+                JVM_ImageFindAttributes;
+                JVM_ImageGetAttributes;
+                JVM_ImageGetAttributesCount;
+                JVM_ImageGetDataAddress;
+                JVM_ImageGetIndexAddress;
+                JVM_ImageGetStringBytes;
+                JVM_ImageOpen;
+                JVM_ImageRead;
+                JVM_ImageReadCompressed;
                 JVM_InitAgentProperties;
                 JVM_InitProperties;
                 JVM_InternString;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product	Thu Jul 09 22:46:16 2015 -0700
@@ -141,6 +141,18 @@
                 JVM_Halt;
                 JVM_HoldsLock;
                 JVM_IHashCode;
+                JVM_ImageAttributeOffsets;
+                JVM_ImageAttributeOffsetsLength;
+                JVM_ImageClose;
+                JVM_ImageFindAttributes;
+                JVM_ImageGetAttributes;
+                JVM_ImageGetAttributesCount;
+                JVM_ImageGetDataAddress;
+                JVM_ImageGetIndexAddress;
+                JVM_ImageGetStringBytes;
+                JVM_ImageOpen;
+                JVM_ImageRead;
+                JVM_ImageReadCompressed;
                 JVM_InitAgentProperties;
                 JVM_InitProperties;
                 JVM_InternString;
--- a/hotspot/make/linux/makefiles/rules.make	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/linux/makefiles/rules.make	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
 CC_COMPILE       = $(CC) $(CXXFLAGS) $(CFLAGS)
 CXX_COMPILE      = $(CXX) $(CXXFLAGS) $(CFLAGS)
 
-AS.S            = $(AS) $(ASFLAGS)
+AS.S             = $(AS) $(ASFLAGS)
 
 COMPILE.CC       = $(CC_COMPILE) -c
 GENASM.CC        = $(CC_COMPILE) -S
@@ -170,6 +170,12 @@
 	$(QUIETLY) $(REMOVE_TARGET)
 	$(QUIETLY) $(AS.S) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)
 
+# gcc applies preprocessing if the file extension is .S instead of .s
+%.o: %.S
+	@echo $(LOG_INFO) Preprocessing and assembling $<
+	$(QUIETLY) $(REMOVE_TARGET)
+	$(QUIETLY) $(AS.S) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE) 
+
 %.s: %.cpp
 	@echo $(LOG_INFO) Generating assembly for $<
 	$(QUIETLY) $(GENASM.CXX) -o $@ $<
--- a/hotspot/make/linux/makefiles/vm.make	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/linux/makefiles/vm.make	Thu Jul 09 22:46:16 2015 -0700
@@ -54,7 +54,7 @@
 # Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
 # The adfiles directory contains ad_<arch>.[ch]pp.
 # The jvmtifiles directory contains jvmti*.[ch]pp
-Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
+Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles $(GENERATED)/extensions
 VPATH += $(Src_Dirs_V:%=%:)
 
 # set INCLUDES for C preprocessor.
@@ -161,6 +161,8 @@
   fi)
 endif
 
+CORE_PATHS+=$(GENERATED)/extensions
+
 COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
 COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
 
@@ -207,6 +209,8 @@
 Src_Files_EXCLUDE += \*x86_32\*
 endif
 
+Src_Files_BASE += \*.c \*.cpp \*.s 
+
 # Alternate vm.make
 # This has to be included here to allow changes to the source
 # directories and excluded files before they are expanded
@@ -216,13 +220,13 @@
 # Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
 define findsrc
 	$(notdir $(shell find $(1)/. ! -name . -prune \
-		-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
+		-a \( -name DUMMY $(addprefix -o -name ,$(Src_Files_BASE)) \) \
 		-a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
 endef
 
 Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e)))
 
-Obj_Files = $(sort $(addsuffix .o,$(basename $(Src_Files))))
+Obj_Files = $(sort $(addsuffix .o,$(basename $(Src_Files))) $(EXTENDED_JVM_OBJ_FILES))
 
 JVM_OBJ_FILES = $(Obj_Files)
 
@@ -244,10 +248,16 @@
 VMDEF_PAT := ^gHotSpotVM|$(VMDEF_PAT)
 VMDEF_PAT := ^UseSharedSpaces$$|$(VMDEF_PAT)
 VMDEF_PAT := ^_ZN9Arguments17SharedArchivePathE$$|$(VMDEF_PAT)
+ifneq ($(VMDEF_PAT_EXT),)
+  VMDEF_PAT := $(VMDEF_PAT_EXT)|$(VMDEF_PAT)
+endif        
 
-vm.def: $(Res_Files) $(Obj_Files)
+vm.def: $(Res_Files) $(Obj_Files) $(VM_DEF_EXT)
 	$(QUIETLY) $(NM) --defined-only $(Obj_Files) | sort -k3 -u | \
 	awk '$$3 ~ /$(VMDEF_PAT)/ { print "\t" $$3 ";" }' > $@
+ifneq ($(VM_DEF_EXT),)
+	cat $(VM_DEF_EXT) >> $@
+endif        
 
 mapfile_ext:
 	rm -f $@
--- a/hotspot/make/solaris/makefiles/mapfile-vers	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/solaris/makefiles/mapfile-vers	Thu Jul 09 22:46:16 2015 -0700
@@ -141,6 +141,18 @@
                 JVM_Halt;
                 JVM_HoldsLock;
                 JVM_IHashCode;
+                JVM_ImageAttributeOffsets;
+                JVM_ImageAttributeOffsetsLength;
+                JVM_ImageClose;
+                JVM_ImageFindAttributes;
+                JVM_ImageGetAttributes;
+                JVM_ImageGetAttributesCount;
+                JVM_ImageGetDataAddress;
+                JVM_ImageGetIndexAddress;
+                JVM_ImageGetStringBytes;
+                JVM_ImageOpen;
+                JVM_ImageRead;
+                JVM_ImageReadCompressed;
                 JVM_InitAgentProperties;
                 JVM_InitProperties;
                 JVM_InternString;
--- a/hotspot/make/solaris/makefiles/vm.make	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/make/solaris/makefiles/vm.make	Thu Jul 09 22:46:16 2015 -0700
@@ -143,7 +143,7 @@
 LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
 endif # sparcWorks
 
-LIBS += -lkstat
+LIBS += -lkstat -lrt
 
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
--- a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -2270,17 +2270,21 @@
   }
 
   // CRC32 instructions
-#define INSN(NAME, sf, sz)                                                \
+#define INSN(NAME, c, sf, sz)                                             \
   void NAME(Register Rd, Register Rn, Register Rm) {                      \
     starti;                                                               \
-    f(sf, 31), f(0b0011010110, 30, 21), f(0b0100, 15, 12), f(sz, 11, 10); \
-    rf(Rm, 16), rf(Rn, 5), rf(Rd, 0);                                     \
+    f(sf, 31), f(0b0011010110, 30, 21), f(0b010, 15, 13), f(c, 12);       \
+    f(sz, 11, 10), rf(Rm, 16), rf(Rn, 5), rf(Rd, 0);                      \
   }
 
-  INSN(crc32b, 0, 0b00);
-  INSN(crc32h, 0, 0b01);
-  INSN(crc32w, 0, 0b10);
-  INSN(crc32x, 1, 0b11);
+  INSN(crc32b,  0, 0, 0b00);
+  INSN(crc32h,  0, 0, 0b01);
+  INSN(crc32w,  0, 0, 0b10);
+  INSN(crc32x,  0, 1, 0b11);
+  INSN(crc32cb, 1, 0, 0b00);
+  INSN(crc32ch, 1, 0, 0b01);
+  INSN(crc32cw, 1, 0, 0b10);
+  INSN(crc32cx, 1, 1, 0b11);
 
 #undef INSN
 
--- a/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,6 @@
 
 const int StackAlignmentInBytes  = 16;
 
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = true;
-
 #define SUPPORTS_NATIVE_CX8
 
 // The maximum B/BL offset range on AArch64 is 128MB.
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -2914,6 +2914,65 @@
     ornw(crc, zr, crc);
 }
 
+/**
+ * @param crc   register containing existing CRC (32-bit)
+ * @param buf   register pointing to input byte buffer (byte*)
+ * @param len   register containing number of bytes
+ * @param table register that will contain address of CRC table
+ * @param tmp   scratch register
+ */
+void MacroAssembler::kernel_crc32c(Register crc, Register buf, Register len,
+        Register table0, Register table1, Register table2, Register table3,
+        Register tmp, Register tmp2, Register tmp3) {
+  Label L_exit;
+  Label CRC_by64_loop, CRC_by4_loop, CRC_by1_loop;
+
+    subs(len, len, 64);
+    br(Assembler::GE, CRC_by64_loop);
+    adds(len, len, 64-4);
+    br(Assembler::GE, CRC_by4_loop);
+    adds(len, len, 4);
+    br(Assembler::GT, CRC_by1_loop);
+    b(L_exit);
+
+  BIND(CRC_by4_loop);
+    ldrw(tmp, Address(post(buf, 4)));
+    subs(len, len, 4);
+    crc32cw(crc, crc, tmp);
+    br(Assembler::GE, CRC_by4_loop);
+    adds(len, len, 4);
+    br(Assembler::LE, L_exit);
+  BIND(CRC_by1_loop);
+    ldrb(tmp, Address(post(buf, 1)));
+    subs(len, len, 1);
+    crc32cb(crc, crc, tmp);
+    br(Assembler::GT, CRC_by1_loop);
+    b(L_exit);
+
+    align(CodeEntryAlignment);
+  BIND(CRC_by64_loop);
+    subs(len, len, 64);
+    ldp(tmp, tmp3, Address(post(buf, 16)));
+    crc32cx(crc, crc, tmp);
+    crc32cx(crc, crc, tmp3);
+    ldp(tmp, tmp3, Address(post(buf, 16)));
+    crc32cx(crc, crc, tmp);
+    crc32cx(crc, crc, tmp3);
+    ldp(tmp, tmp3, Address(post(buf, 16)));
+    crc32cx(crc, crc, tmp);
+    crc32cx(crc, crc, tmp3);
+    ldp(tmp, tmp3, Address(post(buf, 16)));
+    crc32cx(crc, crc, tmp);
+    crc32cx(crc, crc, tmp3);
+    br(Assembler::GE, CRC_by64_loop);
+    adds(len, len, 64-4);
+    br(Assembler::GE, CRC_by4_loop);
+    adds(len, len, 4);
+    br(Assembler::GT, CRC_by1_loop);
+  BIND(L_exit);
+    return;
+}
+
 SkipIfEqual::SkipIfEqual(
     MacroAssembler* masm, const bool* flag_addr, bool value) {
   _masm = masm;
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -967,6 +967,10 @@
   void kernel_crc32(Register crc, Register buf, Register len,
         Register table0, Register table1, Register table2, Register table3,
         Register tmp, Register tmp2, Register tmp3);
+  // CRC32 code for java.util.zip.CRC32C::updateBytes() instrinsic.
+  void kernel_crc32c(Register crc, Register buf, Register len,
+        Register table0, Register table1, Register table2, Register table3,
+        Register tmp, Register tmp2, Register tmp3);
 
 #undef VIRTUAL
 
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -2359,6 +2359,47 @@
   /**
    *  Arguments:
    *
+   * Inputs:
+   *   c_rarg0   - int crc
+   *   c_rarg1   - byte* buf
+   *   c_rarg2   - int length
+   *   c_rarg3   - int* table
+   *
+   * Ouput:
+   *       rax   - int crc result
+   */
+  address generate_updateBytesCRC32C() {
+    assert(UseCRC32CIntrinsics, "what are we doing here?");
+
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C");
+
+    address start = __ pc();
+
+    const Register crc   = c_rarg0;  // crc
+    const Register buf   = c_rarg1;  // source java byte array address
+    const Register len   = c_rarg2;  // length
+    const Register table0 = c_rarg3; // crc_table address
+    const Register table1 = c_rarg4;
+    const Register table2 = c_rarg5;
+    const Register table3 = c_rarg6;
+    const Register tmp3 = c_rarg7;
+
+    BLOCK_COMMENT("Entry:");
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+    __ kernel_crc32c(crc, buf, len,
+              table0, table1, table2, table3, rscratch1, rscratch2, tmp3);
+
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(lr);
+
+    return start;
+  }
+
+  /**
+   *  Arguments:
+   *
    *  Input:
    *    c_rarg0   - x address
    *    c_rarg1   - x length
@@ -2579,6 +2620,10 @@
       StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true,  "sha256_implCompressMB");
     }
 
+    if (UseCRC32CIntrinsics) {
+      StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
+    }
+
     // Safefetch stubs.
     generate_safefetch("SafeFetch32", sizeof(int),     &StubRoutines::_safefetch32_entry,
                                                        &StubRoutines::_safefetch32_fault_pc,
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -199,9 +199,12 @@
     UseCRC32Intrinsics = true;
   }
 
-  if (UseCRC32CIntrinsics) {
-    if (!FLAG_IS_DEFAULT(UseCRC32CIntrinsics))
-      warning("CRC32C intrinsics are not available on this CPU");
+  if (auxv & HWCAP_CRC32) {
+    if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
+      FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
+    }
+  } else if (UseCRC32CIntrinsics) {
+    warning("CRC32C is not available on the CPU");
     FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
   }
 
@@ -214,34 +217,31 @@
     FLAG_SET_DEFAULT(UseSHA, false);
   }
 
-  if (!UseSHA) {
+  if (UseSHA && (auxv & HWCAP_SHA1)) {
+    if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
+      FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
+    }
+  } else if (UseSHA1Intrinsics) {
+    warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
-    FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
-    FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
-  } else {
-    if (auxv & HWCAP_SHA1) {
-      if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
-        FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
-      }
-    } else if (UseSHA1Intrinsics) {
-      warning("SHA1 instruction is not available on this CPU.");
-      FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+  }
+
+  if (UseSHA && (auxv & HWCAP_SHA2)) {
+    if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
+      FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
     }
-    if (auxv & HWCAP_SHA2) {
-      if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
-        FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
-      }
-    } else if (UseSHA256Intrinsics) {
-      warning("SHA256 instruction (for SHA-224 and SHA-256) is not available on this CPU.");
-      FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
-    }
-    if (UseSHA512Intrinsics) {
-      warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU.");
-      FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
-    }
-    if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
-      FLAG_SET_DEFAULT(UseSHA, false);
-    }
+  } else if (UseSHA256Intrinsics) {
+    warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
+    FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+  }
+
+  if (UseSHA512Intrinsics) {
+    warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
+    FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+  }
+
+  if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
+    FLAG_SET_DEFAULT(UseSHA, false);
   }
 
   // This machine allows unaligned memory accesses
--- a/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -105,7 +105,7 @@
   __ flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
                   vtable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
@@ -184,7 +184,7 @@
   __ flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
                   itable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
--- a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. All rights reserved.
  * 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,12 +31,6 @@
 
 const int StackAlignmentInBytes = 16;
 
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = true;
-
 #define SUPPORTS_NATIVE_CX8
 
 // The PPC CPUs are NOT multiple-copy-atomic.
--- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -465,7 +465,7 @@
   bool has_mh = (strstr(adaptername, "/static") == NULL &&
                  strstr(adaptername, "linkTo") == NULL);    // static linkers don't have MH
   const char* mh_reg_name = has_mh ? "R23_method_handle" : "G23";
-  tty->print_cr("MH %s %s="INTPTR_FORMAT " sp=" INTPTR_FORMAT,
+  tty->print_cr("MH %s %s=" INTPTR_FORMAT " sp=" INTPTR_FORMAT,
                 adaptername, mh_reg_name, p2i(mh), p2i(entry_sp));
 
   if (Verbose) {
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -731,23 +731,8 @@
     case T_SHORT:
     case T_INT:
       // We must cast ints to longs and use full 64 bit stack slots
-      // here. We do the cast in GraphKit::gen_stub() and just guard
-      // here against loosing that change.
-      assert(CCallingConventionRequiresIntsAsLongs,
-             "argument of type int should be promoted to type long");
-      guarantee(i > 0 && sig_bt[i-1] == T_LONG,
-                "argument of type (bt) should have been promoted to type (T_LONG,bt) for bt in "
-                "{T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
-      // Do not count halves.
-      regs[i].set_bad();
-      --arg;
-      break;
+      // here.  Thus fall through, handle as long.
     case T_LONG:
-      guarantee(sig_bt[i+1] == T_VOID    ||
-                sig_bt[i+1] == T_BOOLEAN || sig_bt[i+1] == T_CHAR  ||
-                sig_bt[i+1] == T_BYTE    || sig_bt[i+1] == T_SHORT ||
-                sig_bt[i+1] == T_INT,
-                "expecting type (T_LONG,half) or type (T_LONG,bt) with bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
     case T_OBJECT:
     case T_ARRAY:
     case T_ADDRESS:
@@ -1273,7 +1258,7 @@
 static void int_move(MacroAssembler*masm,
                      VMRegPair src, VMRegPair dst,
                      Register r_caller_sp, Register r_temp) {
-  assert(src.first()->is_valid() && src.second() == src.first()->next(), "incoming must be long-int");
+  assert(src.first()->is_valid(), "incoming must be int");
   assert(dst.first()->is_valid() && dst.second() == dst.first()->next(), "outgoing must be long");
 
   if (src.first()->is_stack()) {
@@ -1762,13 +1747,6 @@
   // the jni function will expect them. To figure out where they go
   // we convert the java signature to a C signature by inserting
   // the hidden arguments as arg[0] and possibly arg[1] (static method)
-  //
-  // Additionally, on ppc64 we must convert integers to longs in the C
-  // signature. We do this in advance in order to have no trouble with
-  // indexes into the bt-arrays.
-  // So convert the signature and registers now, and adjust the total number
-  // of in-arguments accordingly.
-  int i2l_argcnt = convert_ints_to_longints_argcnt(total_in_args, in_sig_bt); // PPC64: pass ints as longs.
 
   // Calculate the total number of C arguments and create arrays for the
   // signature and the outgoing registers.
@@ -1776,7 +1754,7 @@
   // some floating-point arguments must be passed in registers _and_
   // in stack locations.
   bool method_is_static = method->is_static();
-  int  total_c_args     = i2l_argcnt;
+  int  total_c_args     = total_in_args;
 
   if (!is_critical_native) {
     int n_hidden_args = method_is_static ? 2 : 1;
@@ -1785,7 +1763,7 @@
     // No JNIEnv*, no this*, but unpacked arrays (base+length).
     for (int i = 0; i < total_in_args; i++) {
       if (in_sig_bt[i] == T_ARRAY) {
-        total_c_args += 2; // PPC64: T_LONG, T_INT, T_ADDRESS (see convert_ints_to_longints and c_calling_convention)
+        total_c_args++;
       }
     }
   }
@@ -1803,8 +1781,6 @@
 
   int argc = 0;
   if (!is_critical_native) {
-    convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
-
     out_sig_bt[argc++] = T_ADDRESS;
     if (method->is_static()) {
       out_sig_bt[argc++] = T_OBJECT;
@@ -1815,7 +1791,7 @@
     }
   } else {
     Thread* THREAD = Thread::current();
-    in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
+    in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
     SignatureStream ss(method->signature());
     int o = 0;
     for (int i = 0; i < total_in_args ; i++, o++) {
@@ -1839,28 +1815,16 @@
         }
       } else {
         in_elem_bt[o] = T_VOID;
-        switch(in_sig_bt[i]) { // PPC64: pass ints as longs.
-          case T_BOOLEAN:
-          case T_CHAR:
-          case T_BYTE:
-          case T_SHORT:
-          case T_INT: in_elem_bt[++o] = T_VOID; break;
-          default: break;
-        }
       }
       if (in_sig_bt[i] != T_VOID) {
         assert(in_sig_bt[i] == ss.type(), "must match");
         ss.next();
       }
     }
-    assert(i2l_argcnt==o, "must match");
-
-    convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
 
     for (int i = 0; i < total_in_args ; i++ ) {
       if (in_sig_bt[i] == T_ARRAY) {
         // Arrays are passed as int, elem* pair.
-        out_sig_bt[argc++] = T_LONG; // PPC64: pass ints as longs.
         out_sig_bt[argc++] = T_INT;
         out_sig_bt[argc++] = T_ADDRESS;
       } else {
@@ -1921,7 +1885,8 @@
           case T_BYTE:
           case T_SHORT:
           case T_CHAR:
-          case T_INT:  /*single_slots++;*/ break; // PPC64: pass ints as longs.
+          case T_INT:
+          // Fall through.
           case T_ARRAY:
           case T_LONG: double_slots++; break;
           default:  ShouldNotReachHere();
@@ -2019,7 +1984,7 @@
 
   __ save_LR_CR(r_temp_1);
   __ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
-  __ mr(r_callers_sp, R1_SP);                       // Remember frame pointer.
+  __ mr(r_callers_sp, R1_SP);                            // Remember frame pointer.
   __ push_frame(frame_size_in_bytes, r_temp_1);          // Push the c2n adapter's frame.
   frame_done_pc = (intptr_t)__ pc();
 
@@ -2098,24 +2063,16 @@
       case T_BYTE:
       case T_SHORT:
       case T_INT:
-        guarantee(in > 0 && in_sig_bt[in-1] == T_LONG,
-                  "expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
+        // Move int and do sign extension.
+        int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
         break;
       case T_LONG:
-        if (in_sig_bt[in+1] == T_VOID) {
-          long_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
-        } else {
-          guarantee(in_sig_bt[in+1] == T_BOOLEAN || in_sig_bt[in+1] == T_CHAR  ||
-                    in_sig_bt[in+1] == T_BYTE    || in_sig_bt[in+1] == T_SHORT ||
-                    in_sig_bt[in+1] == T_INT,
-                 "expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
-          int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
-        }
+        long_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
         break;
       case T_ARRAY:
         if (is_critical_native) {
           int body_arg = out;
-          out -= 2; // Point to length arg. PPC64: pass ints as longs.
+          out -= 1; // Point to length arg.
           unpack_array_argument(masm, in_regs[in], in_elem_bt[in], out_regs[body_arg], out_regs[out],
                                 r_callers_sp, r_temp_1, r_temp_2);
           break;
@@ -2187,7 +2144,6 @@
   // Make sure that thread is non-volatile; it crosses a bunch of VM calls below.
   assert(R16_thread->is_nonvolatile(), "thread must be in non-volatile register");
 
-
 # if 0
   // DTrace method entry
 # endif
--- a/hotspot/src/cpu/sparc/vm/globalDefinitions_sparc.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/globalDefinitions_sparc.hpp	Thu Jul 09 22:46:16 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
@@ -30,12 +30,6 @@
 
 const int StackAlignmentInBytes = (2*wordSize);
 
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = false;
-
 #define SUPPORTS_NATIVE_CX8
 
 // The expected size in bytes of a cache line, used to pad data structures.
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -483,7 +483,7 @@
   bool has_mh = (strstr(adaptername, "/static") == NULL &&
                  strstr(adaptername, "linkTo") == NULL);    // static linkers don't have MH
   const char* mh_reg_name = has_mh ? "G3_mh" : "G3";
-  tty->print_cr("MH %s %s="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT,
+  tty->print_cr("MH %s %s=" INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT,
                 adaptername, mh_reg_name,
                 p2i(mh), p2i(saved_sp), p2i(args));
 
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -329,39 +329,35 @@
     FLAG_SET_DEFAULT(UseSHA, false);
   }
 
-  if (!UseSHA) {
+  if (UseSHA && has_sha1()) {
+    if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
+      FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
+    }
+  } else if (UseSHA1Intrinsics) {
+    warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
-    FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
-    FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
-  } else {
-    if (has_sha1()) {
-      if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
-        FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
-      }
-    } else if (UseSHA1Intrinsics) {
-      warning("SHA1 instruction is not available on this CPU.");
-      FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+  }
+
+  if (UseSHA && has_sha256()) {
+    if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
+      FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
     }
-    if (has_sha256()) {
-      if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
-        FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
-      }
-    } else if (UseSHA256Intrinsics) {
-      warning("SHA256 instruction (for SHA-224 and SHA-256) is not available on this CPU.");
-      FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
-    }
+  } else if (UseSHA256Intrinsics) {
+    warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
+    FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
+  }
 
-    if (has_sha512()) {
-      if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
-        FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
-      }
-    } else if (UseSHA512Intrinsics) {
-      warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU.");
-      FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+  if (UseSHA && has_sha512()) {
+    if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
+      FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
     }
-    if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
-      FLAG_SET_DEFAULT(UseSHA, false);
-    }
+  } else if (UseSHA512Intrinsics) {
+    warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
+    FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+  }
+
+  if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
+    FLAG_SET_DEFAULT(UseSHA, false);
   }
 
   // SPARC T4 and above should have support for CRC32C instruction
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -110,7 +110,7 @@
   masm->flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
                   vtable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
@@ -205,7 +205,7 @@
   masm->flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
                   itable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
--- a/hotspot/src/cpu/x86/vm/globalDefinitions_x86.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/globalDefinitions_x86.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -27,12 +27,6 @@
 
 const int StackAlignmentInBytes  = 16;
 
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = false;
-
 #define SUPPORTS_NATIVE_CX8
 
 // The expected size in bytes of a cache line, used to pad data structures.
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -5152,7 +5152,7 @@
       {
         ResourceMark rm;
         stringStream ss;
-        ss.print("DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
+        ss.print("DelayedValue=" INTPTR_FORMAT, delayed_value_addr[1]);
         buf = code_string(ss.as_string());
       }
       jcc(Assembler::notZero, L);
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -484,7 +484,7 @@
   bool has_mh = (strstr(adaptername, "/static") == NULL &&
                  strstr(adaptername, "linkTo") == NULL);    // static linkers don't have MH
   const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx";
-  tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT,
+  tty->print_cr("MH %s %s=" PTR_FORMAT " sp=" PTR_FORMAT,
                 adaptername, mh_reg_name,
                 (void *)mh, entry_sp);
 
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -23,6 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#ifndef _WINDOWS
+#include "alloca.h"
+#endif
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "code/debugInfoRec.hpp"
@@ -3511,6 +3514,250 @@
 }
 
 
+//------------------------------Montgomery multiplication------------------------
+//
+
+#ifndef _WINDOWS
+
+#define ASM_SUBTRACT
+
+#ifdef ASM_SUBTRACT
+// Subtract 0:b from carry:a.  Return carry.
+static unsigned long
+sub(unsigned long a[], unsigned long b[], unsigned long carry, long len) {
+  long i = 0, cnt = len;
+  unsigned long tmp;
+  asm volatile("clc; "
+               "0: ; "
+               "mov (%[b], %[i], 8), %[tmp]; "
+               "sbb %[tmp], (%[a], %[i], 8); "
+               "inc %[i]; dec %[cnt]; "
+               "jne 0b; "
+               "mov %[carry], %[tmp]; sbb $0, %[tmp]; "
+               : [i]"+r"(i), [cnt]"+r"(cnt), [tmp]"=&r"(tmp)
+               : [a]"r"(a), [b]"r"(b), [carry]"r"(carry)
+               : "memory");
+  return tmp;
+}
+#else // ASM_SUBTRACT
+typedef int __attribute__((mode(TI))) int128;
+
+// Subtract 0:b from carry:a.  Return carry.
+static unsigned long
+sub(unsigned long a[], unsigned long b[], unsigned long carry, int len) {
+  int128 tmp = 0;
+  int i;
+  for (i = 0; i < len; i++) {
+    tmp += a[i];
+    tmp -= b[i];
+    a[i] = tmp;
+    tmp >>= 64;
+    assert(-1 <= tmp && tmp <= 0, "invariant");
+  }
+  return tmp + carry;
+}
+#endif // ! ASM_SUBTRACT
+
+// Multiply (unsigned) Long A by Long B, accumulating the double-
+// length result into the accumulator formed of T0, T1, and T2.
+#define MACC(A, B, T0, T1, T2)                                  \
+do {                                                            \
+  unsigned long hi, lo;                                         \
+  __asm__ ("mul %5; add %%rax, %2; adc %%rdx, %3; adc $0, %4"   \
+           : "=&d"(hi), "=a"(lo), "+r"(T0), "+r"(T1), "+g"(T2)  \
+           : "r"(A), "a"(B) : "cc");                            \
+ } while(0)
+
+// As above, but add twice the double-length result into the
+// accumulator.
+#define MACC2(A, B, T0, T1, T2)                                 \
+do {                                                            \
+  unsigned long hi, lo;                                         \
+  __asm__ ("mul %5; add %%rax, %2; adc %%rdx, %3; adc $0, %4; " \
+           "add %%rax, %2; adc %%rdx, %3; adc $0, %4"           \
+           : "=&d"(hi), "=a"(lo), "+r"(T0), "+r"(T1), "+g"(T2)  \
+           : "r"(A), "a"(B) : "cc");                            \
+ } while(0)
+
+// Fast Montgomery multiplication.  The derivation of the algorithm is
+// in  A Cryptographic Library for the Motorola DSP56000,
+// Dusse and Kaliski, Proc. EUROCRYPT 90, pp. 230-237.
+
+static void __attribute__((noinline))
+montgomery_multiply(unsigned long a[], unsigned long b[], unsigned long n[],
+                    unsigned long m[], unsigned long inv, int len) {
+  unsigned long t0 = 0, t1 = 0, t2 = 0; // Triple-precision accumulator
+  int i;
+
+  assert(inv * n[0] == -1UL, "broken inverse in Montgomery multiply");
+
+  for (i = 0; i < len; i++) {
+    int j;
+    for (j = 0; j < i; j++) {
+      MACC(a[j], b[i-j], t0, t1, t2);
+      MACC(m[j], n[i-j], t0, t1, t2);
+    }
+    MACC(a[i], b[0], t0, t1, t2);
+    m[i] = t0 * inv;
+    MACC(m[i], n[0], t0, t1, t2);
+
+    assert(t0 == 0, "broken Montgomery multiply");
+
+    t0 = t1; t1 = t2; t2 = 0;
+  }
+
+  for (i = len; i < 2*len; i++) {
+    int j;
+    for (j = i-len+1; j < len; j++) {
+      MACC(a[j], b[i-j], t0, t1, t2);
+      MACC(m[j], n[i-j], t0, t1, t2);
+    }
+    m[i-len] = t0;
+    t0 = t1; t1 = t2; t2 = 0;
+  }
+
+  while (t0)
+    t0 = sub(m, n, t0, len);
+}
+
+// Fast Montgomery squaring.  This uses asymptotically 25% fewer
+// multiplies so it should be up to 25% faster than Montgomery
+// multiplication.  However, its loop control is more complex and it
+// may actually run slower on some machines.
+
+static void __attribute__((noinline))
+montgomery_square(unsigned long a[], unsigned long n[],
+                  unsigned long m[], unsigned long inv, int len) {
+  unsigned long t0 = 0, t1 = 0, t2 = 0; // Triple-precision accumulator
+  int i;
+
+  assert(inv * n[0] == -1UL, "broken inverse in Montgomery multiply");
+
+  for (i = 0; i < len; i++) {
+    int j;
+    int end = (i+1)/2;
+    for (j = 0; j < end; j++) {
+      MACC2(a[j], a[i-j], t0, t1, t2);
+      MACC(m[j], n[i-j], t0, t1, t2);
+    }
+    if ((i & 1) == 0) {
+      MACC(a[j], a[j], t0, t1, t2);
+    }
+    for (; j < i; j++) {
+      MACC(m[j], n[i-j], t0, t1, t2);
+    }
+    m[i] = t0 * inv;
+    MACC(m[i], n[0], t0, t1, t2);
+
+    assert(t0 == 0, "broken Montgomery square");
+
+    t0 = t1; t1 = t2; t2 = 0;
+  }
+
+  for (i = len; i < 2*len; i++) {
+    int start = i-len+1;
+    int end = start + (len - start)/2;
+    int j;
+    for (j = start; j < end; j++) {
+      MACC2(a[j], a[i-j], t0, t1, t2);
+      MACC(m[j], n[i-j], t0, t1, t2);
+    }
+    if ((i & 1) == 0) {
+      MACC(a[j], a[j], t0, t1, t2);
+    }
+    for (; j < len; j++) {
+      MACC(m[j], n[i-j], t0, t1, t2);
+    }
+    m[i-len] = t0;
+    t0 = t1; t1 = t2; t2 = 0;
+  }
+
+  while (t0)
+    t0 = sub(m, n, t0, len);
+}
+
+// Swap words in a longword.
+static unsigned long swap(unsigned long x) {
+  return (x << 32) | (x >> 32);
+}
+
+// Copy len longwords from s to d, word-swapping as we go.  The
+// destination array is reversed.
+static void reverse_words(unsigned long *s, unsigned long *d, int len) {
+  d += len;
+  while(len-- > 0) {
+    d--;
+    *d = swap(*s);
+    s++;
+  }
+}
+
+// The threshold at which squaring is advantageous was determined
+// experimentally on an i7-3930K (Ivy Bridge) CPU @ 3.5GHz.
+#define MONTGOMERY_SQUARING_THRESHOLD 64
+
+void SharedRuntime::montgomery_multiply(jint *a_ints, jint *b_ints, jint *n_ints,
+                                        jint len, jlong inv,
+                                        jint *m_ints) {
+  assert(len % 2 == 0, "array length in montgomery_multiply must be even");
+  int longwords = len/2;
+
+  // Make very sure we don't use so much space that the stack might
+  // overflow.  512 jints corresponds to an 16384-bit integer and
+  // will use here a total of 8k bytes of stack space.
+  int total_allocation = longwords * sizeof (unsigned long) * 4;
+  guarantee(total_allocation <= 8192, "must be");
+  unsigned long *scratch = (unsigned long *)alloca(total_allocation);
+
+  // Local scratch arrays
+  unsigned long
+    *a = scratch + 0 * longwords,
+    *b = scratch + 1 * longwords,
+    *n = scratch + 2 * longwords,
+    *m = scratch + 3 * longwords;
+
+  reverse_words((unsigned long *)a_ints, a, longwords);
+  reverse_words((unsigned long *)b_ints, b, longwords);
+  reverse_words((unsigned long *)n_ints, n, longwords);
+
+  ::montgomery_multiply(a, b, n, m, (unsigned long)inv, longwords);
+
+  reverse_words(m, (unsigned long *)m_ints, longwords);
+}
+
+void SharedRuntime::montgomery_square(jint *a_ints, jint *n_ints,
+                                      jint len, jlong inv,
+                                      jint *m_ints) {
+  assert(len % 2 == 0, "array length in montgomery_square must be even");
+  int longwords = len/2;
+
+  // Make very sure we don't use so much space that the stack might
+  // overflow.  512 jints corresponds to an 16384-bit integer and
+  // will use here a total of 6k bytes of stack space.
+  int total_allocation = longwords * sizeof (unsigned long) * 3;
+  guarantee(total_allocation <= 8192, "must be");
+  unsigned long *scratch = (unsigned long *)alloca(total_allocation);
+
+  // Local scratch arrays
+  unsigned long
+    *a = scratch + 0 * longwords,
+    *n = scratch + 1 * longwords,
+    *m = scratch + 2 * longwords;
+
+  reverse_words((unsigned long *)a_ints, a, longwords);
+  reverse_words((unsigned long *)n_ints, n, longwords);
+
+  if (len >= MONTGOMERY_SQUARING_THRESHOLD) {
+    ::montgomery_square(a, n, m, (unsigned long)inv, longwords);
+  } else {
+    ::montgomery_multiply(a, a, n, m, (unsigned long)inv, longwords);
+  }
+
+  reverse_words(m, (unsigned long *)m_ints, longwords);
+}
+
+#endif // WINDOWS
+
 #ifdef COMPILER2
 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
 //
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -4318,7 +4318,18 @@
     if (UseMulAddIntrinsic) {
       StubRoutines::_mulAdd = generate_mulAdd();
     }
-#endif
+
+#ifndef _WINDOWS
+    if (UseMontgomeryMultiplyIntrinsic) {
+      StubRoutines::_montgomeryMultiply
+        = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_multiply);
+    }
+    if (UseMontgomerySquareIntrinsic) {
+      StubRoutines::_montgomerySquare
+        = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square);
+    }
+#endif // WINDOWS
+#endif // COMPILER2
   }
 
  public:
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -692,10 +692,19 @@
     warning("SHA instructions are not available on this CPU");
     FLAG_SET_DEFAULT(UseSHA, false);
   }
-  if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) {
-    warning("SHA intrinsics are not available on this CPU");
+
+  if (UseSHA1Intrinsics) {
+    warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+  }
+
+  if (UseSHA256Intrinsics) {
+    warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
+  }
+
+  if (UseSHA512Intrinsics) {
+    warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
   }
 
@@ -813,6 +822,12 @@
   if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
     UseMulAddIntrinsic = true;
   }
+  if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
+    UseMontgomeryMultiplyIntrinsic = true;
+  }
+  if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
+    UseMontgomerySquareIntrinsic = true;
+  }
 #else
   if (UseMultiplyToLenIntrinsic) {
     if (!FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
@@ -820,6 +835,18 @@
     }
     FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, false);
   }
+  if (UseMontgomeryMultiplyIntrinsic) {
+    if (!FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
+      warning("montgomeryMultiply intrinsic is not available in 32-bit VM");
+    }
+    FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, false);
+  }
+  if (UseMontgomerySquareIntrinsic) {
+    if (!FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
+      warning("montgomerySquare intrinsic is not available in 32-bit VM");
+    }
+    FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, false);
+  }
   if (UseSquareToLenIntrinsic) {
     if (!FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
       warning("squareToLen intrinsic is not available in 32-bit VM");
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -117,7 +117,7 @@
   masm->flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
                   vtable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
@@ -198,7 +198,7 @@
   masm->flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
                   itable_index, p2i(s->entry_point()),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -112,7 +112,7 @@
   __ flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
                   vtable_index, s->entry_point(),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
@@ -205,7 +205,7 @@
   __ flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
+    tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
                   itable_index, s->entry_point(),
                   (int)(s->code_end() - s->entry_point()),
                   (int)(s->code_end() - __ pc()));
--- a/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2015, Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,4 @@
 
 #include <ffi.h>
 
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = false;
-
 #endif // CPU_ZERO_VM_GLOBALDEFINITIONS_ZERO_HPP
--- a/hotspot/src/os/bsd/vm/jsig.c	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/os/bsd/vm/jsig.c	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
 
 static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
 static unsigned int jvmsigs = 0; /* signals used by jvm */
+static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */
 
 /* used to synchronize the installation of signal handlers */
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -76,6 +77,8 @@
 
 static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
                                    bool is_sigset) {
+  sa_handler_t res;
+
   if (os_signal == NULL) {
     if (!is_sigset) {
       os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
@@ -87,7 +90,10 @@
       exit(0);
     }
   }
-  return (*os_signal)(sig, disp);
+  reentry = true;
+  res = (*os_signal)(sig, disp);
+  reentry = false;
+  return res;
 }
 
 static void save_signal_handler(int sig, sa_handler_t disp) {
@@ -161,6 +167,10 @@
   bool sigused;
   struct sigaction oldAct;
 
+  if (reentry) {
+    return call_os_sigaction(sig, act, oact);
+  }
+
   signal_lock();
 
   sigused = (MASK(sig) & jvmsigs) != 0;
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -59,6 +59,7 @@
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
 #include "runtime/timer.hpp"
+#include "semaphore_bsd.hpp"
 #include "services/attachListener.hpp"
 #include "services/memTracker.hpp"
 #include "services/runtimeService.hpp"
@@ -1940,47 +1941,54 @@
   #define SEM_DESTROY(sem)        sem_destroy(&sem)
 #endif
 
-class Semaphore : public StackObj {
- public:
-  Semaphore();
-  ~Semaphore();
-  void signal();
-  void wait();
-  bool trywait();
-  bool timedwait(unsigned int sec, int nsec);
- private:
-  jlong currenttime() const;
-  os_semaphore_t _semaphore;
-};
-
-Semaphore::Semaphore() : _semaphore(0) {
-  SEM_INIT(_semaphore, 0);
+#ifdef __APPLE__
+// OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used.
+
+static const char* sem_init_strerror(kern_return_t value) {
+  switch (value) {
+    case KERN_INVALID_ARGUMENT:  return "Invalid argument";
+    case KERN_RESOURCE_SHORTAGE: return "Resource shortage";
+    default:                     return "Unknown";
+  }
 }
 
-Semaphore::~Semaphore() {
+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)));
+}
+
+OSXSemaphore::~OSXSemaphore() {
   SEM_DESTROY(_semaphore);
 }
 
-void Semaphore::signal() {
-  SEM_POST(_semaphore);
+void OSXSemaphore::signal(uint count) {
+  for (uint i = 0; i < count; i++) {
+    kern_return_t ret = SEM_POST(_semaphore);
+
+    assert(ret == KERN_SUCCESS, "Failed to signal semaphore");
+  }
 }
 
-void Semaphore::wait() {
-  SEM_WAIT(_semaphore);
+void OSXSemaphore::wait() {
+  kern_return_t ret;
+  while ((ret = SEM_WAIT(_semaphore)) == KERN_ABORTED) {
+    // Semaphore was interrupted. Retry.
+  }
+  assert(ret == KERN_SUCCESS, "Failed to wait on semaphore");
 }
 
-jlong Semaphore::currenttime() const {
+jlong OSXSemaphore::currenttime() {
   struct timeval tv;
   gettimeofday(&tv, NULL);
   return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
 }
 
-#ifdef __APPLE__
-bool Semaphore::trywait() {
+bool OSXSemaphore::trywait() {
   return timedwait(0, 0);
 }
 
-bool Semaphore::timedwait(unsigned int sec, int nsec) {
+bool OSXSemaphore::timedwait(unsigned int sec, int nsec) {
   kern_return_t kr = KERN_ABORTED;
   mach_timespec_t waitspec;
   waitspec.tv_sec = sec;
@@ -2011,33 +2019,24 @@
 }
 
 #else
-
-bool Semaphore::trywait() {
-  return sem_trywait(&_semaphore) == 0;
-}
-
-bool Semaphore::timedwait(unsigned int sec, int nsec) {
+// Use POSIX implementation of semaphores.
+
+struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {
   struct timespec ts;
   unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
 
-  while (1) {
-    int result = sem_timedwait(&_semaphore, &ts);
-    if (result == 0) {
-      return true;
-    } else if (errno == EINTR) {
-      continue;
-    } else if (errno == ETIMEDOUT) {
-      return false;
-    } else {
-      return false;
-    }
-  }
+  return ts;
 }
 
 #endif // __APPLE__
 
 static os_semaphore_t sig_sem;
-static Semaphore sr_semaphore;
+
+#ifdef __APPLE__
+static OSXSemaphore sr_semaphore;
+#else
+static PosixSemaphore sr_semaphore;
+#endif
 
 void os::signal_init_pd() {
   // Initialize signal structures
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/bsd/vm/semaphore_bsd.hpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#ifndef OS_BSD_VM_SEMAPHORE_BSD_HPP
+#define OS_BSD_VM_SEMAPHORE_BSD_HPP
+
+#ifndef __APPLE__
+// Use POSIX semaphores.
+# include "semaphore_posix.hpp"
+
+#else
+// OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used.
+# include "memory/allocation.hpp"
+# include <mach/semaphore.h>
+
+class OSXSemaphore : public CHeapObj<mtInternal>{
+  semaphore_t _semaphore;
+
+  // Prevent copying and assignment.
+  OSXSemaphore(const OSXSemaphore&);
+  OSXSemaphore& operator=(const OSXSemaphore&);
+
+ public:
+  OSXSemaphore(uint value = 0);
+  ~OSXSemaphore();
+
+  void signal(uint count = 1);
+
+  void wait();
+
+  bool trywait();
+  bool timedwait(unsigned int sec, int nsec);
+
+ private:
+  static jlong currenttime();
+};
+
+typedef OSXSemaphore SemaphoreImpl;
+
+#endif // __APPLE__
+
+#endif // OS_BSD_VM_SEMAPHORE_BSD_HPP
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -60,6 +60,7 @@
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
 #include "runtime/timer.hpp"
+#include "semaphore_posix.hpp"
 #include "services/attachListener.hpp"
 #include "services/memTracker.hpp"
 #include "services/runtimeService.hpp"
@@ -2315,40 +2316,7 @@
   return CAST_FROM_FN_PTR(void*, UserHandler);
 }
 
-class Semaphore : public StackObj {
- public:
-  Semaphore();
-  ~Semaphore();
-  void signal();
-  void wait();
-  bool trywait();
-  bool timedwait(unsigned int sec, int nsec);
- private:
-  sem_t _semaphore;
-};
-
-Semaphore::Semaphore() {
-  sem_init(&_semaphore, 0, 0);
-}
-
-Semaphore::~Semaphore() {
-  sem_destroy(&_semaphore);
-}
-
-void Semaphore::signal() {
-  sem_post(&_semaphore);
-}
-
-void Semaphore::wait() {
-  sem_wait(&_semaphore);
-}
-
-bool Semaphore::trywait() {
-  return sem_trywait(&_semaphore) == 0;
-}
-
-bool Semaphore::timedwait(unsigned int sec, int nsec) {
-
+struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {
   struct timespec ts;
   // Semaphore's are always associated with CLOCK_REALTIME
   os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
@@ -2365,18 +2333,7 @@
     }
   }
 
-  while (1) {
-    int result = sem_timedwait(&_semaphore, &ts);
-    if (result == 0) {
-      return true;
-    } else if (errno == EINTR) {
-      continue;
-    } else if (errno == ETIMEDOUT) {
-      return false;
-    } else {
-      return false;
-    }
-  }
+  return ts;
 }
 
 extern "C" {
@@ -2416,7 +2373,7 @@
 
 // Linux(POSIX) specific hand shaking semaphore.
 static sem_t sig_sem;
-static Semaphore sr_semaphore;
+static PosixSemaphore sr_semaphore;
 
 void os::signal_init_pd() {
   // Initialize signal structures
--- a/hotspot/src/os/posix/vm/os_posix.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/os/posix/vm/os_posix.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -24,6 +24,7 @@
 
 #include "utilities/globalDefinitions.hpp"
 #include "prims/jvm.h"
+#include "semaphore_posix.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/os.hpp"
@@ -34,6 +35,7 @@
 #include <sys/resource.h>
 #include <sys/utsname.h>
 #include <pthread.h>
+#include <semaphore.h>
 #include <signal.h>
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
@@ -1015,3 +1017,73 @@
     }
   }
 }
+
+#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)); \
+} while (false)
+
+#define assert_with_errno(cond, msg)    check_with_errno(assert, cond, msg)
+#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
+
+// POSIX unamed semaphores are not supported on OS X.
+#ifndef __APPLE__
+
+PosixSemaphore::PosixSemaphore(uint value) {
+  int ret = sem_init(&_semaphore, 0, value);
+
+  guarantee_with_errno(ret == 0, "Failed to initialize semaphore");
+}
+
+PosixSemaphore::~PosixSemaphore() {
+  sem_destroy(&_semaphore);
+}
+
+void PosixSemaphore::signal(uint count) {
+  for (uint i = 0; i < count; i++) {
+    int ret = sem_post(&_semaphore);
+
+    assert_with_errno(ret == 0, "sem_post failed");
+  }
+}
+
+void PosixSemaphore::wait() {
+  int ret;
+
+  do {
+    ret = sem_wait(&_semaphore);
+  } while (ret != 0 && errno == EINTR);
+
+  assert_with_errno(ret == 0, "sem_wait failed");
+}
+
+bool PosixSemaphore::trywait() {
+  int ret;
+
+  do {
+    ret = sem_trywait(&_semaphore);
+  } while (ret != 0 && errno == EINTR);
+
+  assert_with_errno(ret == 0 || errno == EAGAIN, "trywait failed");
+
+  return ret == 0;
+}
+
+bool PosixSemaphore::timedwait(const struct timespec ts) {
+  while (true) {
+    int result = sem_timedwait(&_semaphore, &ts);
+    if (result == 0) {
+      return true;
+    } else if (errno == EINTR) {
+      continue;
+    } else if (errno == ETIMEDOUT) {
+      return false;
+    } else {
+      assert_with_errno(false, "timedwait failed");
+      return false;
+    }
+  }
+}
+
+#endif // __APPLE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/posix/vm/semaphore_posix.hpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#ifndef OS_POSIX_VM_SEMAPHORE_POSIX_HPP
+#define OS_POSIX_VM_SEMAPHORE_POSIX_HPP
+
+#include "memory/allocation.hpp"
+
+#include <semaphore.h>
+
+class PosixSemaphore : public CHeapObj<mtInternal> {
+  sem_t _semaphore;
+
+  // Prevent copying and assignment.
+  PosixSemaphore(const PosixSemaphore&);
+  PosixSemaphore& operator=(const PosixSemaphore&);
+
+ public:
+  PosixSemaphore(uint value = 0);
+  ~PosixSemaphore();
+
+  void signal(uint count = 1);
+
+  void wait();
+
+  bool trywait();
+  bool timedwait(unsigned int sec, int nsec) {
+    return timedwait(create_timespec(sec, nsec));
+  }
+
+ private:
+  bool timedwait(struct timespec ts);
+
+  // OS specific implementation to create a timespec suitable for semaphores.
+  struct timespec create_timespec(unsigned int set, int nsec);
+};
+
+typedef PosixSemaphore SemaphoreImpl;
+
+#endif // OS_POSIX_VM_SEMAPHORE_POSIX_HPP
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -60,6 +60,7 @@
 #include "runtime/threadCritical.hpp"
 #include "runtime/timer.hpp"
 #include "runtime/vm_version.hpp"
+#include "semaphore_posix.hpp"
 #include "services/attachListener.hpp"
 #include "services/memTracker.hpp"
 #include "services/runtimeService.hpp"
@@ -2263,55 +2264,11 @@
   return CAST_FROM_FN_PTR(void*, UserHandler);
 }
 
-class Semaphore : public StackObj {
- public:
-  Semaphore();
-  ~Semaphore();
-  void signal();
-  void wait();
-  bool trywait();
-  bool timedwait(unsigned int sec, int nsec);
- private:
-  sema_t _semaphore;
-};
-
-
-Semaphore::Semaphore() {
-  sema_init(&_semaphore, 0, NULL, NULL);
-}
-
-Semaphore::~Semaphore() {
-  sema_destroy(&_semaphore);
-}
-
-void Semaphore::signal() {
-  sema_post(&_semaphore);
-}
-
-void Semaphore::wait() {
-  sema_wait(&_semaphore);
-}
-
-bool Semaphore::trywait() {
-  return sema_trywait(&_semaphore) == 0;
-}
-
-bool Semaphore::timedwait(unsigned int sec, int nsec) {
+struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {
   struct timespec ts;
   unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
 
-  while (1) {
-    int result = sema_timedwait(&_semaphore, &ts);
-    if (result == 0) {
-      return true;
-    } else if (errno == EINTR) {
-      continue;
-    } else if (errno == ETIME) {
-      return false;
-    } else {
-      return false;
-    }
-  }
+  return ts;
 }
 
 extern "C" {
@@ -3711,7 +3668,7 @@
   osthread->set_ucontext(context);
 }
 
-static Semaphore sr_semaphore;
+static PosixSemaphore sr_semaphore;
 
 void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
   // Save and restore errno to avoid confusing native code with EINTR
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -63,6 +63,7 @@
 #include "runtime/threadCritical.hpp"
 #include "runtime/timer.hpp"
 #include "runtime/vm_version.hpp"
+#include "semaphore_windows.hpp"
 #include "services/attachListener.hpp"
 #include "services/memTracker.hpp"
 #include "services/runtimeService.hpp"
@@ -1901,6 +1902,30 @@
   return (int)error;
 }
 
+WindowsSemaphore::WindowsSemaphore(uint value) {
+  _semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL);
+
+  guarantee(_semaphore != NULL, err_msg("CreateSemaphore failed with error code: %lu", GetLastError()));
+}
+
+WindowsSemaphore::~WindowsSemaphore() {
+  ::CloseHandle(_semaphore);
+}
+
+void WindowsSemaphore::signal(uint count) {
+  if (count > 0) {
+    BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL);
+
+    assert(ret != 0, err_msg("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));
+}
+
 // sun.misc.Signal
 // NOTE that this is a workaround for an apparent kernel bug where if
 // a signal handler for SIGBREAK is installed then that signal handler
@@ -5890,7 +5915,7 @@
   char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
   if (result == NULL) {
     if (VerboseInternalVMTests) {
-      gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.",
+      gclog_or_tty->print("Failed to allocate control block with size " SIZE_FORMAT ". Skipping remainder of test.",
                           large_allocation_size);
     }
   } else {
@@ -5903,7 +5928,7 @@
     char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
     if (actual_location == NULL) {
       if (VerboseInternalVMTests) {
-        gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.",
+        gclog_or_tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",
                             expected_location, large_allocation_size);
       }
     } else {
@@ -5911,7 +5936,7 @@
       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",
+             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));
     }
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/windows/vm/semaphore_windows.hpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#ifndef OS_WINDOWS_VM_SEMAPHORE_WINDOWS_HPP
+#define OS_WINDOWS_VM_SEMAPHORE_WINDOWS_HPP
+
+#include "memory/allocation.hpp"
+
+#include <windef.h>
+
+class WindowsSemaphore : public CHeapObj<mtInternal> {
+  HANDLE _semaphore;
+
+  // Prevent copying and assignment.
+  WindowsSemaphore(const WindowsSemaphore&);
+  WindowsSemaphore& operator=(const WindowsSemaphore&);
+
+ public:
+  WindowsSemaphore(uint value = 0);
+  ~WindowsSemaphore();
+
+  void signal(uint count = 1);
+
+  void wait();
+};
+
+typedef WindowsSemaphore SemaphoreImpl;
+
+#endif // OS_WINDOWS_VM_SEMAPHORE_WINDOWS_HPP
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -191,7 +191,7 @@
     return CPUVisitor::visit(nodeh, state);
   }
 
-  PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
+  PICL(bool is_fujitsu, bool is_sun4v) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
     if (!open_library()) {
       return;
     }
@@ -203,7 +203,7 @@
         if (is_fujitsu) {
           cpu_class = "core";
         }
-        CPUVisitor cpu_visitor(this, os::processor_count());
+        CPUVisitor cpu_visitor(this, (is_sun4v && !is_fujitsu) ? 1 : os::processor_count());
         _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper);
         if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value?
           _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
@@ -447,7 +447,7 @@
   }
 
   // Figure out cache line sizes using PICL
-  PICL picl((features & sparc64_family_m) != 0);
+  PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0);
   _L1_data_cache_line_size = picl.L1_data_cache_line_size();
   _L2_data_cache_line_size = picl.L2_data_cache_line_size();
 
--- a/hotspot/src/share/tools/hsdis/Makefile	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/tools/hsdis/Makefile	Thu Jul 09 22:46:16 2015 -0700
@@ -70,7 +70,8 @@
 else   #linux
 CPU             = $(shell uname -m)
 ARCH1=$(CPU:x86_64=amd64)
-ARCH=$(ARCH1:i686=i386)
+ARCH2=$(ARCH1:i686=i386)
+ARCH=$(ARCH2:ppc64le=ppc64)
 ifdef LP64
 CFLAGS/sparcv9	+= -m64
 CFLAGS/amd64	+= -m64
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1093,9 +1093,11 @@
 
 void CodeStrings::assign(CodeStrings& other) {
   other.check_valid();
-  // Cannot do following because CodeStrings constructor is not alway run!
   assert(is_null(), "Cannot assign onto non-empty CodeStrings");
   _strings = other._strings;
+#ifdef ASSERT
+  _defunct = false;
+#endif
   other.set_null_and_invalidate();
 }
 
@@ -1115,13 +1117,15 @@
   }
 }
 
+const char* CodeStrings::_prefix = " ;; ";  // default: can be changed via set_prefix
+
 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
     check_valid();
     if (_strings != NULL) {
     CodeString* c = find(offset);
     while (c && c->offset() == offset) {
       stream->bol();
-      stream->print("  ;; ");
+      stream->print("%s", _prefix);
       stream->print_cr("%s", c->string());
       c = c->next_comment();
     }
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp	Thu Jul 09 22:46:16 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
@@ -249,6 +249,7 @@
   // Becomes true after copy-out, forbids further use.
   bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
 #endif
+  static const char* _prefix; // defaults to " ;; "
 #endif
 
   CodeString* find(intptr_t offset) const;
@@ -289,13 +290,20 @@
   void assign(CodeStrings& other)  PRODUCT_RETURN;
   // COPY strings from other to this; leave other valid.
   void copy(CodeStrings& other)  PRODUCT_RETURN;
+  // FREE strings; invalidate this.
   void free() PRODUCT_RETURN;
-  // Guarantee that _strings are used at most once; assign invalidates a buffer.
+  // Guarantee that _strings are used at most once; assign and free invalidate a buffer.
   inline void check_valid() const {
 #ifdef ASSERT
     assert(!_defunct, "Use of invalid CodeStrings");
 #endif
   }
+
+  static void set_prefix(const char *prefix) {
+#ifndef PRODUCT
+    _prefix = prefix;
+#endif
+  }
 };
 
 // A CodeBuffer describes a memory space into which assembly
@@ -379,6 +387,7 @@
     _oop_recorder    = NULL;
     _decode_begin    = NULL;
     _overflow_arena  = NULL;
+    _code_strings    = CodeStrings();
   }
 
   void initialize(address code_start, csize_t code_size) {
@@ -495,6 +504,7 @@
 
   // Properties
   const char* name() const                  { return _name; }
+  void set_name(const char* name)           { _name = name; }
   CodeBuffer* before_expand() const         { return _before_expand; }
   BufferBlob* blob() const                  { return _blob; }
   void    set_blob(BufferBlob* blob);
--- a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -161,7 +161,7 @@
 
   print("name \"%s\"", method_name(_compilation->method(), true));
   print("method \"%s\"", method_name(_compilation->method()));
-  print("date "INT64_FORMAT, (int64_t) os::javaTimeMillis());
+  print("date " INT64_FORMAT, (int64_t) os::javaTimeMillis());
 
   print_end("compilation");
 }
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -3157,6 +3157,9 @@
       // code for the inlined version will be different than the root
       // compiled version which could lead to monotonicity problems on
       // intel.
+      if (CheckIntrinsics && !scope->method()->intrinsic_candidate()) {
+        BAILOUT("failed to inline intrinsic, method not annotated");
+      }
 
       // Set up a stream so that appending instructions works properly.
       ciBytecodeStream s(scope->method());
@@ -3197,6 +3200,9 @@
         // result in the referent being marked live and the reference
         // object removed from the list of discovered references during
         // reference processing.
+        if (CheckIntrinsics && !scope->method()->intrinsic_candidate()) {
+          BAILOUT("failed to inline intrinsic, method not annotated");
+        }
 
         // Also we need intrinsic to prevent commoning reads from this field
         // across safepoint since GC can change its value.
@@ -3317,7 +3323,8 @@
   }
 
   // handle intrinsics
-  if (callee->intrinsic_id() != vmIntrinsics::_none) {
+  if (callee->intrinsic_id() != vmIntrinsics::_none &&
+      (CheckIntrinsics ? callee->intrinsic_candidate() : true)) {
     if (try_inline_intrinsics(callee)) {
       print_inlining(callee, "intrinsic");
       return true;
@@ -4278,7 +4285,7 @@
   assert(result_type->is_int(), "int result");
   Values* args = state()->pop_arguments(callee->arg_size());
 
-  // Pop off some args to speically handle, then push back
+  // Pop off some args to specially handle, then push back
   Value newval = args->pop();
   Value cmpval = args->pop();
   Value offset = args->pop();
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -33,6 +33,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeBlob.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "code/compiledIC.hpp"
 #include "code/pcDesc.hpp"
 #include "code/scopeDesc.hpp"
@@ -183,20 +184,25 @@
   // create code buffer for code storage
   CodeBuffer code(buffer_blob);
 
-  Compilation::setup_code_buffer(&code, 0);
+  OopMapSet* oop_maps;
+  int frame_size;
+  bool must_gc_arguments;
 
-  // create assembler for code generation
-  StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
-  // generate code for runtime stub
-  OopMapSet* oop_maps;
-  oop_maps = generate_code_for(id, sasm);
-  assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
-         "if stub has an oop map it must have a valid frame size");
+  if (!CodeCacheExtensions::skip_compiler_support()) {
+    // bypass useless code generation
+    Compilation::setup_code_buffer(&code, 0);
+
+    // create assembler for code generation
+    StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
+    // generate code for runtime stub
+    oop_maps = generate_code_for(id, sasm);
+    assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
+           "if stub has an oop map it must have a valid frame size");
 
 #ifdef ASSERT
-  // Make sure that stubs that need oopmaps have them
-  switch (id) {
-    // These stubs don't need to have an oopmap
+    // Make sure that stubs that need oopmaps have them
+    switch (id) {
+      // These stubs don't need to have an oopmap
     case dtrace_object_alloc_id:
     case g1_pre_barrier_slow_id:
     case g1_post_barrier_slow_id:
@@ -209,23 +215,32 @@
 #endif
       break;
 
-    // All other stubs should have oopmaps
+      // All other stubs should have oopmaps
     default:
       assert(oop_maps != NULL, "must have an oopmap");
-  }
+    }
 #endif
 
-  // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
-  sasm->align(BytesPerWord);
-  // make sure all code is in code buffer
-  sasm->flush();
+    // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
+    sasm->align(BytesPerWord);
+    // make sure all code is in code buffer
+    sasm->flush();
+
+    frame_size = sasm->frame_size();
+    must_gc_arguments = sasm->must_gc_arguments();
+  } else {
+    /* ignored values */
+    oop_maps = NULL;
+    frame_size = 0;
+    must_gc_arguments = false;
+  }
   // create blob - distinguish a few special cases
   CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
                                                  &code,
                                                  CodeOffsets::frame_never_safe,
-                                                 sasm->frame_size(),
+                                                 frame_size,
                                                  oop_maps,
-                                                 sasm->must_gc_arguments());
+                                                 must_gc_arguments);
   // install blob
   assert(blob != NULL, "blob must exist");
   _blobs[id] = blob;
@@ -399,7 +414,7 @@
   CompLevel level = (CompLevel)nm->comp_level();
   int bci = InvocationEntryBci;
   if (branch_bci != InvocationEntryBci) {
-    // Compute desination bci
+    // Compute destination bci
     address pc = method()->code_base() + branch_bci;
     Bytecodes::Code branch = Bytecodes::code_at(method(), pc);
     int offset = 0;
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1185,7 +1185,6 @@
   vmIntrinsics::ID iid = method()->intrinsic_id();
 
   if (iid == vmIntrinsics::_getClass ||
-      iid ==  vmIntrinsics::_fillInStackTrace ||
       iid == vmIntrinsics::_hashCode)
     return iid;
   else
@@ -1199,10 +1198,6 @@
   case vmIntrinsics::_getClass:
     _return_local = false;
     break;
-  case vmIntrinsics::_fillInStackTrace:
-    arg.set(0); // 'this'
-    set_returned(arg);
-    break;
   case vmIntrinsics::_hashCode:
     // initialized state is correct
     break;
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -178,9 +178,10 @@
   // Code size for inlining decisions.
   int code_size_for_inlining();
 
-  bool caller_sensitive()   const { return get_Method()->caller_sensitive();   }
-  bool force_inline()       const { return get_Method()->force_inline();       }
-  bool dont_inline()        const { return get_Method()->dont_inline();        }
+  bool caller_sensitive()    const { return get_Method()->caller_sensitive();    }
+  bool force_inline()        const { return get_Method()->force_inline();        }
+  bool dont_inline()         const { return get_Method()->dont_inline();         }
+  bool intrinsic_candidate() const { return get_Method()->intrinsic_candidate(); }
 
   int comp_level();
   int highest_osr_comp_level();
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1751,6 +1751,10 @@
     if (_location != _in_method)  break;  // only allow for methods
     if (!privileged)              break;  // only allow in privileged code
     return _method_LambdaForm_Hidden;
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_HotSpotIntrinsicCandidate_signature):
+    if (_location != _in_method)  break;  // only allow for methods
+    if (!privileged)              break;  // only allow in privileged code
+    return _method_HotSpotIntrinsicCandidate;
   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
@@ -1790,6 +1794,8 @@
     m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
   if (has_annotation(_method_LambdaForm_Hidden))
     m->set_hidden(true);
+  if (has_annotation(_method_HotSpotIntrinsicCandidate) && !m->is_synthetic())
+    m->set_intrinsic_candidate(true);
 }
 
 void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) {
@@ -4132,9 +4138,78 @@
     // (We used to do this lazily, but now we query it in Rewriter,
     // which is eagerly done for every method, so we might as well do it now,
     // when everything is fresh in memory.)
-    if (Method::klass_id_for_intrinsics(this_klass()) != vmSymbols::NO_SID) {
+    vmSymbols::SID klass_id = Method::klass_id_for_intrinsics(this_klass());
+    if (klass_id != vmSymbols::NO_SID) {
       for (int j = 0; j < methods->length(); j++) {
-        methods->at(j)->init_intrinsic_id();
+        Method* method = methods->at(j);
+        method->init_intrinsic_id();
+
+        if (CheckIntrinsics) {
+          // Check if an intrinsic is defined for method 'method',
+          // but the method is not annotated with @HotSpotIntrinsicCandidate.
+          if (method->intrinsic_id() != vmIntrinsics::_none &&
+              !method->intrinsic_candidate()) {
+            tty->print("Compiler intrinsic is defined for method [%s], "
+                       "but the method is not annotated with @HotSpotIntrinsicCandidate.%s",
+                       method->name_and_sig_as_C_string(),
+                       NOT_DEBUG(" Method will not be inlined.") DEBUG_ONLY(" Exiting.")
+                       );
+            tty->cr();
+            DEBUG_ONLY(vm_exit(1));
+          }
+          // Check is the method 'method' is annotated with @HotSpotIntrinsicCandidate,
+          // but there is no intrinsic available for it.
+          if (method->intrinsic_candidate() &&
+              method->intrinsic_id() == vmIntrinsics::_none) {
+            tty->print("Method [%s] is annotated with @HotSpotIntrinsicCandidate, "
+                       "but no compiler intrinsic is defined for the method.%s",
+                       method->name_and_sig_as_C_string(),
+                       NOT_DEBUG("") DEBUG_ONLY(" Exiting.")
+                       );
+            tty->cr();
+            DEBUG_ONLY(vm_exit(1));
+          }
+        }
+      }
+
+      if (CheckIntrinsics) {
+        // Check for orphan methods in the current class. A method m
+        // of a class C is orphan if an intrinsic is defined for method m,
+        // but class C does not declare m.
+
+        for (int id = vmIntrinsics::FIRST_ID; id < (int)vmIntrinsics::ID_LIMIT; id++) {
+          if (id == vmIntrinsics::_compiledLambdaForm) {
+            // The _compiledLamdbdaForm intrinsic is a special marker for bytecode
+            // generated for the JVM from a LambdaForm and therefore no method
+            // is defined for it.
+            continue;
+          }
+
+          if (vmIntrinsics::class_for(vmIntrinsics::ID_from(id)) == klass_id) {
+            // Check if the current class contains a method with the same
+            // name, flags, signature.
+            bool match = false;
+            for (int j = 0; j < methods->length(); j++) {
+              Method* method = methods->at(j);
+              if (id == method->intrinsic_id()) {
+                match = true;
+                break;
+              }
+            }
+
+            if (!match) {
+              char buf[1000];
+              tty->print("Compiler intrinsic is defined for method [%s], "
+                         "but the method is not available in class [%s].%s",
+                         vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID_from(id), buf, sizeof(buf)),
+                         this_klass->name()->as_C_string(),
+                         NOT_DEBUG("") DEBUG_ONLY(" Exiting.")
+                         );
+              tty->cr();
+              DEBUG_ONLY(vm_exit(1));
+            }
+          }
+        }
       }
     }
 
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -130,6 +130,7 @@
       _method_InjectedProfile,
       _method_LambdaForm_Compiled,
       _method_LambdaForm_Hidden,
+      _method_HotSpotIntrinsicCandidate,
       _sun_misc_Contended,
       _field_Stable,
       _annotation_LIMIT
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -68,7 +68,6 @@
 #include "classfile/sharedPathsMiscInfo.hpp"
 #endif
 
-
 // Entry points in zip.dll for loading zip/jar file entries and image file entries
 
 typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg);
@@ -157,17 +156,12 @@
 }
 
 
-bool ClassPathEntry::is_lazy() {
-  return false;
-}
-
 ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
   char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
   strcpy(copy, dir);
   _dir = copy;
 }
 
-
 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
   // construct full path name
   char path[JVM_MAXPATHLEN];
@@ -278,90 +272,25 @@
   }
 }
 
-LazyClassPathEntry::LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception) : ClassPathEntry() {
-  _path = os::strdup_check_oom(path);
-  _st = *st;
-  _resolved_entry = NULL;
-  _has_error = false;
-  _throw_exception = throw_exception;
-}
-
-LazyClassPathEntry::~LazyClassPathEntry() {
-  os::free((void*)_path);
-}
-
-bool LazyClassPathEntry::is_jar_file() {
-  size_t len = strlen(_path);
-  if (len < 4 || strcmp(_path + len - 4, ".jar") != 0) return false;
-  return ((_st.st_mode & S_IFREG) == S_IFREG);
-}
-
-ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) {
-  if (_resolved_entry != NULL) {
-    return (ClassPathEntry*) _resolved_entry;
-  }
-  ClassPathEntry* new_entry = NULL;
-  new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, _throw_exception, CHECK_NULL);
-  if (!_throw_exception && new_entry == NULL) {
-    assert(!HAS_PENDING_EXCEPTION, "must be");
-    return NULL;
-  }
-  {
-    ThreadCritical tc;
-    if (_resolved_entry == NULL) {
-      _resolved_entry = new_entry;
-      return new_entry;
-    }
-  }
-  assert(_resolved_entry != NULL, "bug in MT-safe resolution logic");
-  delete new_entry;
-  return (ClassPathEntry*) _resolved_entry;
-}
+ClassPathImageEntry::ClassPathImageEntry(ImageFileReader* image) :
+  ClassPathEntry(),
+  _image(image),
+  _module_data(NULL) {
+  guarantee(image != NULL, "image file is null");
 
-ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) {
-  if (_has_error) {
-    return NULL;
-  }
-  ClassPathEntry* cpe = resolve_entry(THREAD);
-  if (cpe == NULL) {
-    _has_error = true;
-    return NULL;
-  } else {
-    return cpe->open_stream(name, THREAD);
-  }
-}
-
-bool LazyClassPathEntry::is_lazy() {
-  return true;
-}
-
-u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
-  if (_has_error) {
-    return NULL;
-  }
-  ClassPathEntry* cpe = resolve_entry(THREAD);
-  if (cpe == NULL) {
-    _has_error = true;
-    return NULL;
-  } else if (cpe->is_jar_file()) {
-    return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD);
-  } else {
-    ShouldNotReachHere();
-    *filesize = 0;
-    return NULL;
-  }
-}
-
-ClassPathImageEntry::ClassPathImageEntry(char* name) : ClassPathEntry(), _image(new ImageFile(name)) {
-  bool opened = _image->open();
-  if (!opened) {
-    _image = NULL;
-  }
+  char module_data_name[JVM_MAXPATHLEN];
+  ImageModuleData::module_data_name(module_data_name, _image->name());
+  _module_data = new ImageModuleData(_image, module_data_name);
 }
 
 ClassPathImageEntry::~ClassPathImageEntry() {
-  if (_image) {
-    _image->close();
+  if (_module_data != NULL) {
+    delete _module_data;
+    _module_data = NULL;
+  }
+
+  if (_image != NULL) {
+    ImageFileReader::close(_image);
     _image = NULL;
   }
 }
@@ -371,15 +300,39 @@
 }
 
 ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
-  u1* buffer;
-  u8 size;
-  _image->get_resource(name, buffer, size);
+  ImageLocation location;
+  bool found = _image->find_location(name, location);
+
+  if (!found) {
+    const char *pslash = strrchr(name, '/');
+    int len = pslash - name;
+
+    // NOTE: IMAGE_MAX_PATH is used here since this path is internal to the jimage
+    // (effectively unlimited.)  There are several JCK tests that use paths over
+    // 1024 characters long, the limit on Windows systems.
+    if (pslash && 0 < len && len < IMAGE_MAX_PATH) {
 
-  if (buffer) {
+      char path[IMAGE_MAX_PATH];
+      strncpy(path, name, len);
+      path[len] = '\0';
+      const char* moduleName = _module_data->package_to_module(path);
+
+      if (moduleName != NULL && (len + strlen(moduleName) + 2) < IMAGE_MAX_PATH) {
+        jio_snprintf(path, IMAGE_MAX_PATH - 1, "/%s/%s", moduleName, name);
+        location.clear_data();
+        found = _image->find_location(path, location);
+      }
+    }
+  }
+
+  if (found) {
+    u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
     if (UsePerfData) {
       ClassLoader::perf_sys_classfile_bytes_read()->inc(size);
     }
-    return new ClassFileStream(buffer, (int)size, (char*)name);  // Resource allocated
+    u1* data = NEW_RESOURCE_ARRAY(u1, size);
+    _image->get_resource(location, data);
+    return new ClassFileStream(data, (int)size, _image->name());  // Resource allocated
   }
 
   return NULL;
@@ -391,20 +344,14 @@
   tty->cr();
   const ImageStrings strings = _image->get_strings();
   // Retrieve each path component string.
-  u4 count = _image->get_location_count();
-  for (u4 i = 0; i < count; i++) {
+  u4 length = _image->table_length();
+  for (u4 i = 0; i < length; i++) {
     u1* location_data = _image->get_location_data(i);
 
-    if (location_data) {
+    if (location_data != NULL) {
        ImageLocation location(location_data);
-       const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
-       const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
-       const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
-       assert((strlen(parent) + strlen(base) + strlen(extension)) < JVM_MAXPATHLEN, "path exceeds buffer");
-       char path[JVM_MAXPATHLEN];
-       strcpy(path, parent);
-       strcat(path, base);
-       strcat(path, extension);
+       char path[IMAGE_MAX_PATH];
+       _image->location_path(location, path, IMAGE_MAX_PATH);
        ClassLoader::compile_the_world_in(path, loader, CHECK);
     }
   }
@@ -420,7 +367,7 @@
 }
 
 bool ClassPathImageEntry::is_jrt() {
-  return string_ends_with(name(), "bootmodules.jimage");
+  return string_ends_with(name(), BOOT_IMAGE_NAME);
 }
 #endif
 
@@ -539,11 +486,8 @@
 }
 
 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
-                                                     bool lazy, bool throw_exception, TRAPS) {
+                                                     bool throw_exception, TRAPS) {
   JavaThread* thread = JavaThread::current();
-  if (lazy) {
-    return new LazyClassPathEntry(path, st, throw_exception);
-  }
   ClassPathEntry* new_entry = NULL;
   if ((st->st_mode & S_IFREG) == S_IFREG) {
     // Regular file, should be a zip or image file
@@ -557,38 +501,38 @@
         return NULL;
       }
     }
-    // TODO - add proper criteria for selecting image file
-    ClassPathImageEntry* entry = new ClassPathImageEntry(canonical_path);
-    if (entry->is_open()) {
-      new_entry = entry;
-    } else {
-    char* error_msg = NULL;
-    jzfile* zip;
-    {
-      // enable call to C land
-      ThreadToNativeFromVM ttn(thread);
-      HandleMark hm(thread);
-      zip = (*ZipOpen)(canonical_path, &error_msg);
-    }
-    if (zip != NULL && error_msg == NULL) {
-      new_entry = new ClassPathZipEntry(zip, path);
+    ImageFileReader* image = ImageFileReader::open(canonical_path);
+    if (image != NULL) {
+      new_entry = new ClassPathImageEntry(image);
     } else {
-      ResourceMark rm(thread);
-      char *msg;
-      if (error_msg == NULL) {
-        msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ;
-        jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
+      char* error_msg = NULL;
+      jzfile* zip;
+      {
+        // enable call to C land
+        ThreadToNativeFromVM ttn(thread);
+        HandleMark hm(thread);
+        zip = (*ZipOpen)(canonical_path, &error_msg);
+      }
+      if (zip != NULL && error_msg == NULL) {
+        new_entry = new ClassPathZipEntry(zip, path);
       } else {
-        int len = (int)(strlen(path) + strlen(error_msg) + 128);
-        msg = NEW_RESOURCE_ARRAY(char, len); ;
-        jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
+        ResourceMark rm(thread);
+        char *msg;
+        if (error_msg == NULL) {
+          msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ;
+          jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
+        } else {
+          int len = (int)(strlen(path) + strlen(error_msg) + 128);
+          msg = NEW_RESOURCE_ARRAY(char, len); ;
+          jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
+        }
+        // Don't complain about bad jar files added via -Xbootclasspath/a:.
+        if (throw_exception && is_init_completed()) {
+          THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
+        } else {
+          return NULL;
+        }
       }
-      if (throw_exception) {
-        THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
-      } else {
-        return NULL;
-      }
-    }
     }
     if (TraceClassLoading || TraceClassPaths) {
       tty->print_cr("[Opened %s]", path);
@@ -666,7 +610,7 @@
     // File or directory found
     ClassPathEntry* new_entry = NULL;
     Thread* THREAD = Thread::current();
-    new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, throw_exception, CHECK_(false));
+    new_entry = create_class_path_entry(path, &st, throw_exception, CHECK_(false));
     if (new_entry == NULL) {
       return false;
     }
@@ -1319,19 +1263,6 @@
   return false;
 }
 
-void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) {
-  ClassPathEntry* cpe = resolve_entry(THREAD);
-  if (cpe != NULL) {
-    cpe->compile_the_world(loader, CHECK);
-  }
-}
-
-bool LazyClassPathEntry::is_jrt() {
-  Thread* THREAD = Thread::current();
-  ClassPathEntry* cpe = resolve_entry(THREAD);
-  return (cpe != NULL) ? cpe->is_jar_file() : false;
-}
-
 void ClassLoader::compile_the_world() {
   EXCEPTION_MARK;
   HandleMark hm(THREAD);
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -32,9 +32,14 @@
 // The VM class loader.
 #include <sys/stat.h>
 
+// Name of boot module image
+#define  BOOT_IMAGE_NAME "bootmodules.jimage"
 
 // Class path entry (directory or zip file)
 
+class ImageFileReader;
+class ImageModuleData;
+
 class ClassPathEntry: public CHeapObj<mtClass> {
  private:
   ClassPathEntry* _next;
@@ -47,7 +52,7 @@
   }
   virtual bool is_jar_file() = 0;
   virtual const char* name() = 0;
-  virtual bool is_lazy();
+  virtual ImageFileReader* image() = 0;
   // Constructor
   ClassPathEntry();
   // Attempt to locate file_name through this class path entry.
@@ -63,8 +68,9 @@
  private:
   const char* _dir;           // Name of directory
  public:
-  bool is_jar_file()  { return false;  }
-  const char* name()  { return _dir; }
+  bool is_jar_file()       { return false;  }
+  const char* name()       { return _dir; }
+  ImageFileReader* image() { return NULL; }
   ClassPathDirEntry(const char* dir);
   ClassFileStream* open_stream(const char* name, TRAPS);
   // Debugging
@@ -92,8 +98,9 @@
   jzfile* _zip;              // The zip archive
   const char*   _zip_name;   // Name of zip archive
  public:
-  bool is_jar_file()  { return true;  }
-  const char* name()  { return _zip_name; }
+  bool is_jar_file()       { return true;  }
+  const char* name()       { return _zip_name; }
+  ImageFileReader* image() { return NULL; }
   ClassPathZipEntry(jzfile* zip, const char* zip_name);
   ~ClassPathZipEntry();
   u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
@@ -105,39 +112,18 @@
 };
 
 
-// For lazier loading of boot class path entries
-class LazyClassPathEntry: public ClassPathEntry {
- private:
-  const char* _path; // dir or file
-  struct stat _st;
-  bool _has_error;
-  bool _throw_exception;
-  volatile ClassPathEntry* _resolved_entry;
-  ClassPathEntry* resolve_entry(TRAPS);
- public:
-  bool is_jar_file();
-  const char* name()  { return _path; }
-  LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception);
-  virtual ~LazyClassPathEntry();
-  u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
-
-  ClassFileStream* open_stream(const char* name, TRAPS);
-  virtual bool is_lazy();
-  // Debugging
-  NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
-  NOT_PRODUCT(bool is_jrt();)
-};
-
 // For java image files
-class ImageFile;
 class ClassPathImageEntry: public ClassPathEntry {
 private:
-  ImageFile *_image;
+  ImageFileReader* _image;
+  ImageModuleData* _module_data;
 public:
   bool is_jar_file()  { return false;  }
   bool is_open()  { return _image != NULL; }
   const char* name();
-  ClassPathImageEntry(char* name);
+  ImageFileReader* image() { return _image; }
+  ImageModuleData* module_data() { return _module_data; }
+  ClassPathImageEntry(ImageFileReader* image);
   ~ClassPathImageEntry();
   ClassFileStream* open_stream(const char* name, TRAPS);
 
@@ -157,7 +143,6 @@
     package_hash_table_size = 31  // Number of buckets
   };
  protected:
-  friend class LazyClassPathEntry;
 
   // Performance counters
   static PerfCounter* _perf_accumulated_time;
@@ -222,7 +207,7 @@
 
   static void load_zip_library();
   static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
-                                                 bool lazy, bool throw_exception, TRAPS);
+                                                 bool throw_exception, TRAPS);
 
   // Canonicalizes path names, so strcmp will work properly. This is mainly
   // to avoid confusing the zip library
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -494,7 +494,7 @@
 
 void ClassLoaderData::dump(outputStream * const out) {
   ResourceMark rm;
-  out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {",
+  out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: " PTR_FORMAT " %s {",
       p2i(this), p2i((void *)class_loader()),
       p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name());
   if (claimed()) out->print(" claimed ");
@@ -513,7 +513,7 @@
     ResourceMark rm;
     Klass* k = _klasses;
     while (k != NULL) {
-      out->print_cr("klass "PTR_FORMAT", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(),
+      out->print_cr("klass " PTR_FORMAT ", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(),
           k->has_modified_oops(), k->has_accumulated_modified_oops());
       assert(k != k->next_link(), "no loops!");
       k = k->next_link();
--- a/hotspot/src/share/vm/classfile/dictionary.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -557,7 +557,7 @@
 }
 
 void ProtectionDomainCacheEntry::print() {
-  tty->print_cr("entry "PTR_FORMAT" value "PTR_FORMAT" strongly_reachable %d next "PTR_FORMAT,
+  tty->print_cr("entry " PTR_FORMAT " value " PTR_FORMAT " strongly_reachable %d next " PTR_FORMAT,
                 this, (void*)literal(), _strongly_reachable, next());
 }
 #endif
--- a/hotspot/src/share/vm/classfile/dictionary.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -370,7 +370,7 @@
 
   void print_on(outputStream* st) const {
     symbol()->print_value_on(st);
-    st->print("/mode="INTX_FORMAT, symbol_mode());
+    st->print("/mode=" INTX_FORMAT, symbol_mode());
     st->print(" -> ");
     bool printed = false;
     if (method() != NULL) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/imageDecompressor.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,121 @@
+/*
+ * 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 "runtime/thread.inline.hpp"
+#include "precompiled.hpp"
+#include "classfile/imageDecompressor.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/bytes.hpp"
+
+/*
+ * Allocate in C Heap not in resource area, otherwise JVM crashes.
+ * This array life time is the VM life time. Array is never freed and
+ * is not expected to contain more than few references.
+ */
+GrowableArray<ImageDecompressor*>* ImageDecompressor::_decompressors =
+  new(ResourceObj::C_HEAP, mtInternal) GrowableArray<ImageDecompressor*>(2, true);
+
+static Symbol* createSymbol(const char* str) {
+  Thread* THREAD = Thread::current();
+  Symbol* sym = SymbolTable::lookup(str, (int) strlen(str), THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    warning("can't create symbol\n");
+    CLEAR_PENDING_EXCEPTION;
+    return NULL;
+  }
+  return sym;
+}
+
+/*
+ * Initialize the array of decompressors.
+ */
+bool image_decompressor_init() {
+  Symbol* zipSymbol = createSymbol("zip");
+  if (zipSymbol == NULL) {
+    return false;
+  }
+  ImageDecompressor::add_decompressor(new ZipDecompressor(zipSymbol));
+
+  return true;
+}
+
+/*
+ * Decompression entry point. Called from ImageFileReader::get_resource.
+ */
+void ImageDecompressor::decompress_resource(u1* compressed, u1* uncompressed,
+        u4 uncompressed_size, const ImageStrings* strings, bool is_C_heap) {
+  bool has_header = false;
+  u1* decompressed_resource = compressed;
+  u1* compressed_resource = compressed;
+
+  // Resource could have been transformed by a stack of decompressors.
+  // Iterate and decompress resources until there is no more header.
+  do {
+    ResourceHeader _header;
+    memcpy(&_header, compressed_resource, sizeof (ResourceHeader));
+    has_header = _header._magic == ResourceHeader::resource_header_magic;
+    if (has_header) {
+      // decompressed_resource array contains the result of decompression
+      // when a resource content is terminal, it means that it is an actual resource,
+      // not an intermediate not fully uncompressed content. In this case
+      // the resource is allocated as an mtClass, otherwise as an mtOther
+      decompressed_resource = is_C_heap && _header._is_terminal ?
+              NEW_C_HEAP_ARRAY(u1, _header._uncompressed_size, mtClass) :
+              NEW_C_HEAP_ARRAY(u1, _header._uncompressed_size, mtOther);
+      // Retrieve the decompressor name
+      const char* decompressor_name = strings->get(_header._decompressor_name_offset);
+      if (decompressor_name == NULL) warning("image decompressor not found\n");
+      guarantee(decompressor_name, "image decompressor not found");
+      // Retrieve the decompressor instance
+      ImageDecompressor* decompressor = get_decompressor(decompressor_name);
+      if (decompressor == NULL) {
+        warning("image decompressor %s not found\n", decompressor_name);
+      }
+      guarantee(decompressor, "image decompressor not found");
+      u1* compressed_resource_base = compressed_resource;
+      compressed_resource += ResourceHeader::resource_header_length;
+      // Ask the decompressor to decompress the compressed content
+      decompressor->decompress_resource(compressed_resource, decompressed_resource,
+        &_header, strings);
+      if (compressed_resource_base != compressed) {
+        FREE_C_HEAP_ARRAY(char, compressed_resource_base);
+      }
+      compressed_resource = decompressed_resource;
+    }
+  } while (has_header);
+  memcpy(uncompressed, decompressed_resource, uncompressed_size);
+}
+
+// Zip decompressor
+
+void ZipDecompressor::decompress_resource(u1* data, u1* uncompressed,
+        ResourceHeader* header, const ImageStrings* strings) {
+  char* msg = NULL;
+  jboolean res = ClassLoader::decompress(data, header->_size, uncompressed,
+          header->_uncompressed_size, &msg);
+  if (!res) warning("decompression failed due to %s\n", msg);
+  guarantee(res, "decompression failed");
+}
+
+// END Zip Decompressor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/imageDecompressor.hpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#ifndef SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP
+#define SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP
+
+#include "runtime/thread.inline.hpp"
+#include "precompiled.hpp"
+#include "classfile/classLoader.hpp"
+#include "classfile/imageFile.hpp"
+#include "classfile/symbolTable.hpp"
+#include "oops/symbol.hpp"
+#include "utilities/growableArray.hpp"
+
+/*
+ * Compressed resources located in image have an header.
+ * This header contains:
+ * - _magic: A magic u4, required to retrieved the header in the compressed content
+ * - _size: The size of the compressed resource.
+ * - _uncompressed_size: The uncompressed size of the compressed resource.
+ * - _decompressor_name_offset: The ImageDecompressor instance name StringsTable offset.
+ * - _decompressor_config_offset: StringsTable offset of configuration that could be needed by
+ *   the decompressor in order to decompress.
+ * - _is_terminal: 1: the compressed content is terminal. Uncompressing it would
+ *   create the actual resource. 0: the compressed content is not terminal. Uncompressing it
+ *   will result in a compressed content to be decompressed (This occurs when a stack of compressors
+ *   have been used to compress the resource.
+ */
+struct ResourceHeader {
+  /* Length of header, needed to retrieve content offset */
+  static const u1 resource_header_length = 21;
+  /* magic bytes that identifies a compressed resource header*/
+  static const u4 resource_header_magic = 0xCAFEFAFA;
+  u4 _magic; // Resource header
+  u4 _size;  // Resource size
+  u4 _uncompressed_size;  // Expected uncompressed size
+  u4 _decompressor_name_offset;  // Strings table decompressor offset
+  u4 _decompressor_config_offset; // Strings table config offset
+  u1 _is_terminal; // Last decompressor 1, otherwise 0.
+};
+
+/*
+ * Resources located in jimage file can be compressed. Compression occurs at
+ * jimage file creation time. When compressed a resource is added an header that
+ * contains the name of the compressor that compressed it.
+ * Various compression strategies can be applied to compress a resource.
+ * The same resource can even be compressed multiple time by a stack of compressors.
+ * At runtime, a resource is decompressed in a loop until there is no more header
+ * meaning that the resource is equivalent to the not compressed resource.
+ * In each iteration, the name of the compressor located in the current header
+ * is used to retrieve the associated instance of ImageDecompressor.
+ * For example “zip” is the name of the compressor that compresses resources
+ * using the zip algorithm. The ZipDecompressor class name is also “zip”.
+ * ImageDecompressor instances are retrieved from a static array in which
+ * they are registered.
+ */
+class ImageDecompressor: public CHeapObj<mtClass> {
+
+private:
+  const Symbol* _name;
+
+  /*
+   * Array of concrete decompressors. This array is used to retrieve the decompressor
+   * that can handle resource decompression.
+   */
+  static GrowableArray<ImageDecompressor*>* _decompressors;
+
+  /*
+   * Identifier of a decompressor. This name is the identification key to retrieve
+   * decompressor from a resource header.
+   */
+  inline const Symbol* get_name() const { return _name; }
+
+protected:
+  ImageDecompressor(const Symbol* name) : _name(name) {
+  }
+  virtual void decompress_resource(u1* data, u1* uncompressed,
+    ResourceHeader* header, const ImageStrings* strings) = 0;
+
+public:
+  inline static void add_decompressor(ImageDecompressor* decompressor) {
+    _decompressors->append(decompressor);
+  }
+  inline static ImageDecompressor* get_decompressor(const char * decompressor_name) {
+    Thread* THREAD = Thread::current();
+    TempNewSymbol sym = SymbolTable::new_symbol(decompressor_name,
+            (int) strlen(decompressor_name), CHECK_NULL);
+    if (HAS_PENDING_EXCEPTION) {
+      warning("can't create symbol\n");
+      CLEAR_PENDING_EXCEPTION;
+      return NULL;
+    }
+    for (int i = 0; i < _decompressors->length(); i++) {
+      ImageDecompressor* decompressor = _decompressors->at(i);
+      if (decompressor->get_name()->fast_compare(sym) == 0) {
+        return decompressor;
+      }
+    }
+    guarantee(false, "No decompressor found.");
+    return NULL;
+  }
+  static void decompress_resource(u1* compressed, u1* uncompressed,
+    u4 uncompressed_size, const ImageStrings* strings, bool is_C_heap);
+};
+
+/**
+ * Zip decompressor.
+ */
+class ZipDecompressor : public ImageDecompressor {
+public:
+  ZipDecompressor(const Symbol* sym) : ImageDecompressor(sym) { }
+  void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
+    const ImageStrings* strings);
+};
+
+#endif // SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP
--- a/hotspot/src/share/vm/classfile/imageFile.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/imageFile.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,77 +23,311 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/imageDecompressor.hpp"
 #include "classfile/imageFile.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/mutex.hpp"
+#include "runtime/mutexLocker.hpp"
 #include "runtime/os.inline.hpp"
-#include "utilities/bytes.hpp"
-
+#include "utilities/endian.hpp"
+#include "utilities/growableArray.hpp"
 
-// Compute the Perfect Hashing hash code for the supplied string.
-u4 ImageStrings::hash_code(const char* string, u4 seed) {
+// Image files are an alternate file format for storing classes and resources. The
+// goal is to supply file access which is faster and smaller than the jar format.
+//
+// (More detailed nodes in the header.)
+//
+
+// Compute the Perfect Hashing hash code for the supplied UTF-8 string.
+s4 ImageStrings::hash_code(const char* string, s4 seed) {
+  // Access bytes as unsigned.
   u1* bytes = (u1*)string;
-
   // Compute hash code.
   for (u1 byte = *bytes++; byte; byte = *bytes++) {
     seed = (seed * HASH_MULTIPLIER) ^ byte;
   }
-
-  // Ensure the result is unsigned.
+  // Ensure the result is not signed.
   return seed & 0x7FFFFFFF;
 }
 
-// Test to see if string begins with start.  If so returns remaining portion
-// of string.  Otherwise, NULL.
+// Match up a string in a perfect hash table.  Result still needs validation
+// for precise match (false positive.)
+s4 ImageStrings::find(Endian* endian, const char* name, s4* redirect, u4 length) {
+  // If the table is empty, then short cut.
+  if (redirect == NULL || length == 0) {
+    return NOT_FOUND;
+  }
+  // Compute the basic perfect hash for name.
+  s4 hash_code = ImageStrings::hash_code(name);
+  // Modulo table size.
+  s4 index = hash_code % length;
+  // Get redirect entry.
+  //   value == 0 then not found
+  //   value < 0 then -1 - value is true index
+  //   value > 0 then value is seed for recomputing hash.
+  s4 value = endian->get(redirect[index]);
+  // if recompute is required.
+  if (value > 0) {
+    // Entry collision value, need to recompute hash.
+    hash_code = ImageStrings::hash_code(name, value);
+    // Modulo table size.
+    return hash_code % length;
+  } else if (value < 0) {
+    // Compute direct index.
+    return -1 - value;
+  }
+  // No entry found.
+  return NOT_FOUND;
+}
+
+// Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
+// return non-NULL address of remaining portion of string.  Otherwise, return
+// NULL.  Used to test sections of a path without copying from image string
+// table.
 const char* ImageStrings::starts_with(const char* string, const char* start) {
   char ch1, ch2;
-
   // Match up the strings the best we can.
   while ((ch1 = *string) && (ch2 = *start)) {
     if (ch1 != ch2) {
       // Mismatch, return NULL.
       return NULL;
     }
-
+    // Next characters.
     string++, start++;
   }
-
   // Return remainder of string.
   return string;
 }
 
-ImageLocation::ImageLocation(u1* data) {
+// Inflates the attribute stream into individual values stored in the long
+// array _attributes. This allows an attribute value to be quickly accessed by
+// direct indexing.  Unspecified values default to zero (from constructor.)
+void ImageLocation::set_data(u1* data) {
   // Deflate the attribute stream into an array of attributes.
-  memset(_attributes, 0, sizeof(_attributes));
   u1 byte;
-
-  while ((byte = *data) != ATTRIBUTE_END) {
+  // Repeat until end header is found.
+  while ((byte = *data)) {
+    // Extract kind from header byte.
     u1 kind = attribute_kind(byte);
+    guarantee(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
+    // Extract length of data (in bytes).
     u1 n = attribute_length(byte);
-    assert(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
+    // Read value (most significant first.)
     _attributes[kind] = attribute_value(data + 1, n);
+    // Position to next attribute by skipping attribute header and data bytes.
     data += n + 1;
   }
 }
 
-ImageFile::ImageFile(const char* name) {
+// Zero all attribute values.
+void ImageLocation::clear_data() {
+  // Set defaults to zero.
+  memset(_attributes, 0, sizeof(_attributes));
+}
+
+// ImageModuleData constructor maps out sub-tables for faster access.
+ImageModuleData::ImageModuleData(const ImageFileReader* image_file,
+        const char* module_data_name) :
+    _image_file(image_file),
+    _endian(image_file->endian()),
+    _strings(image_file->get_strings()) {
+  // Retrieve the resource containing the module data for the image file.
+  ImageLocation location;
+  bool found = image_file->find_location(module_data_name, location);
+  guarantee(found, "missing module data");
+  u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+  _data = (u1*)NEW_C_HEAP_ARRAY(char, data_size, mtClass);
+  _image_file->get_resource(location, _data);
+  // Map out the header.
+  _header = (Header*)_data;
+  // Get the package to module entry count.
+  u4 ptm_count = _header->ptm_count(_endian);
+  // Get the module to package entry count.
+  u4 mtp_count = _header->mtp_count(_endian);
+  // Compute the offset of the package to module perfect hash redirect.
+  u4 ptm_redirect_offset = sizeof(Header);
+  // Compute the offset of the package to module data.
+  u4 ptm_data_offset = ptm_redirect_offset + ptm_count * sizeof(s4);
+  // Compute the offset of the module to package perfect hash redirect.
+  u4 mtp_redirect_offset = ptm_data_offset + ptm_count * sizeof(PTMData);
+  // Compute the offset of the module to package data.
+  u4 mtp_data_offset = mtp_redirect_offset + mtp_count * sizeof(s4);
+  // Compute the offset of the module to package tables.
+  u4 mtp_packages_offset = mtp_data_offset + mtp_count * sizeof(MTPData);
+  // Compute the address of the package to module perfect hash redirect.
+  _ptm_redirect = (s4*)(_data + ptm_redirect_offset);
+  // Compute the address of the package to module data.
+  _ptm_data = (PTMData*)(_data + ptm_data_offset);
+  // Compute the address of the module to package perfect hash redirect.
+  _mtp_redirect = (s4*)(_data + mtp_redirect_offset);
+  // Compute the address of the module to package data.
+  _mtp_data = (MTPData*)(_data + mtp_data_offset);
+  // Compute the address of the module to package tables.
+  _mtp_packages = (s4*)(_data + mtp_packages_offset);
+}
+
+// Release module data resource.
+ImageModuleData::~ImageModuleData() {
+  if (_data != NULL) {
+    FREE_C_HEAP_ARRAY(u1, _data);
+  }
+}
+
+// Return the name of the module data resource.  Ex. "./lib/modules/file.jimage"
+// yields "file.jdata"
+void ImageModuleData::module_data_name(char* buffer, const char* image_file_name) {
+  // Locate the last slash in the file name path.
+  const char* slash = strrchr(image_file_name, os::file_separator()[0]);
+  // Trim the path to name and extension.
+  const char* name = slash != NULL ? slash + 1 : (char *)image_file_name;
+  // Locate the extension period.
+  const char* dot = strrchr(name, '.');
+  guarantee(dot, "missing extension on jimage name");
+  // Trim to only base name.
+  int length = dot - name;
+  strncpy(buffer, name, length);
+  buffer[length] = '\0';
+  // Append extension.
+  strcat(buffer, ".jdata");
+}
+
+// Return the module in which a package resides.  Returns NULL if not found.
+const char* ImageModuleData::package_to_module(const char* package_name) {
+  // Search the package to module table.
+  s4 index = ImageStrings::find(_endian, package_name, _ptm_redirect,
+                                  _header->ptm_count(_endian));
+  // If entry is found.
+  if (index != ImageStrings::NOT_FOUND) {
+    // Retrieve the package to module entry.
+    PTMData* data = _ptm_data + index;
+    // Verify that it is the correct data.
+    if (strcmp(package_name, get_string(data->name_offset(_endian))) != 0) {
+      return NULL;
+    }
+    // Return the module name.
+    return get_string(data->module_name_offset(_endian));
+  }
+  return NULL;
+}
+
+// Returns all the package names in a module.  Returns NULL if module not found.
+GrowableArray<const char*>* ImageModuleData::module_to_packages(const char* module_name) {
+  // Search the module to package table.
+  s4 index = ImageStrings::find(_endian, module_name, _mtp_redirect,
+                                  _header->mtp_count(_endian));
+  // If entry is found.
+  if (index != ImageStrings::NOT_FOUND) {
+    // Retrieve the module to package entry.
+    MTPData* data = _mtp_data + index;
+    // Verify that it is the correct data.
+    if (strcmp(module_name, get_string(data->name_offset(_endian))) != 0) {
+      return NULL;
+    }
+    // Construct an array of all the package entries.
+    GrowableArray<const char*>* packages = new GrowableArray<const char*>();
+    s4 package_offset = data->package_offset(_endian);
+    for (u4 i = 0; i < data->package_count(_endian); i++) {
+      u4 package_name_offset = mtp_package(package_offset + i);
+      const char* package_name = get_string(package_name_offset);
+      packages->append(package_name);
+    }
+    return packages;
+  }
+  return NULL;
+}
+
+// Table to manage multiple opens of an image file.
+GrowableArray<ImageFileReader*>* ImageFileReader::_reader_table =
+  new(ResourceObj::C_HEAP, mtInternal) GrowableArray<ImageFileReader*>(2, true);
+
+// Open an image file, reuse structure if file already open.
+ImageFileReader* ImageFileReader::open(const char* name, bool big_endian) {
+  // Lock out _reader_table.
+  MutexLocker ml(ImageFileReaderTable_lock);
+  ImageFileReader* reader;
+  // Search for an exist image file.
+  for (int i = 0; i < _reader_table->length(); i++) {
+    // Retrieve table entry.
+    reader = _reader_table->at(i);
+    // If name matches, then reuse (bump up use count.)
+    if (strcmp(reader->name(), name) == 0) {
+      reader->inc_use();
+      return reader;
+    }
+  }
+  // Need a new image reader.
+  reader = new ImageFileReader(name, big_endian);
+  bool opened = reader->open();
+  // If failed to open.
+  if (!opened) {
+    delete reader;
+    return NULL;
+  }
+  // Bump use count and add to table.
+  reader->inc_use();
+  _reader_table->append(reader);
+  return reader;
+}
+
+// Close an image file if the file is not in use elsewhere.
+void ImageFileReader::close(ImageFileReader *reader) {
+  // Lock out _reader_table.
+  MutexLocker ml(ImageFileReaderTable_lock);
+  // If last use then remove from table and then close.
+  if (reader->dec_use()) {
+    _reader_table->remove(reader);
+    delete reader;
+  }
+}
+
+// Return an id for the specifed ImageFileReader.
+u8 ImageFileReader::readerToID(ImageFileReader *reader) {
+  // ID is just the cloaked reader address.
+  return (u8)reader;
+}
+
+// Validate the image id.
+bool ImageFileReader::idCheck(u8 id) {
+  // Make sure the ID is a managed (_reader_table) reader.
+  MutexLocker ml(ImageFileReaderTable_lock);
+  return _reader_table->contains((ImageFileReader*)id);
+}
+
+// Return an id for the specifed ImageFileReader.
+ImageFileReader* ImageFileReader::idToReader(u8 id) {
+#ifdef PRODUCT
+  // Fast convert.
+  return (ImageFileReader*)id;
+#else
+  // Do a slow check before fast convert.
+  return idCheck(id) ? (ImageFileReader*)id : NULL;
+#endif
+}
+
+// Constructor intializes to a closed state.
+ImageFileReader::ImageFileReader(const char* name, bool big_endian) {
   // Copy the image file name.
-  _name = NEW_C_HEAP_ARRAY(char, strlen(name)+1, mtClass);
+  _name = NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtClass);
   strcpy(_name, name);
-
   // Initialize for a closed file.
   _fd = -1;
-  _memory_mapped = true;
+  _endian = Endian::get_handler(big_endian);
   _index_data = NULL;
 }
 
-ImageFile::~ImageFile() {
+// Close image and free up data structures.
+ImageFileReader::~ImageFileReader() {
   // Ensure file is closed.
   close();
-
   // Free up name.
-  FREE_C_HEAP_ARRAY(char, _name);
+  if (_name != NULL) {
+    FREE_C_HEAP_ARRAY(char, _name);
+    _name = NULL;
+  }
 }
 
-bool ImageFile::open() {
+// Open image file for read access.
+bool ImageFileReader::open() {
   // If file exists open for reading.
   struct stat st;
   if (os::stat(_name, &st) != 0 ||
@@ -101,186 +335,212 @@
     (_fd = os::open(_name, 0, O_RDONLY)) == -1) {
     return false;
   }
-
-  // Read image file header and verify.
-  u8 header_size = sizeof(ImageHeader);
-  if (os::read(_fd, &_header, header_size) != header_size ||
-    _header._magic != IMAGE_MAGIC ||
-    _header._major_version != MAJOR_VERSION ||
-    _header._minor_version != MINOR_VERSION) {
+  // Retrieve the file size.
+  _file_size = (u8)st.st_size;
+  // Read image file header and verify it has a valid header.
+  size_t header_size = sizeof(ImageHeader);
+  if (_file_size < header_size ||
+    !read_at((u1*)&_header, header_size, 0) ||
+    _header.magic(_endian) != IMAGE_MAGIC ||
+    _header.major_version(_endian) != MAJOR_VERSION ||
+    _header.minor_version(_endian) != MINOR_VERSION) {
     close();
     return false;
   }
-
-  // Memory map index.
+  // Size of image index.
   _index_size = index_size();
-  _index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, _index_size, true, false);
-
-  // Failing that, read index into C memory.
-  if (_index_data == NULL) {
-    _memory_mapped = false;
-    _index_data = NEW_RESOURCE_ARRAY(u1, _index_size);
-
-    if (os::seek_to_file_offset(_fd, 0) == -1) {
-      close();
-      return false;
-    }
-
-    if (os::read(_fd, _index_data, _index_size) != _index_size) {
-      close();
-      return false;
-    }
-
-    return true;
+  // Make sure file is large enough to contain the index.
+  if (_file_size < _index_size) {
+    return false;
   }
-
-// Used to advance a pointer, unstructured.
-#undef nextPtr
-#define nextPtr(base, fromType, count, toType) (toType*)((fromType*)(base) + (count))
-  // Pull tables out from the index.
-  _redirect_table = nextPtr(_index_data, u1, header_size, s4);
-  _offsets_table = nextPtr(_redirect_table, s4, _header._location_count, u4);
-  _location_bytes = nextPtr(_offsets_table, u4, _header._location_count, u1);
-  _string_bytes = nextPtr(_location_bytes, u1, _header._locations_size, u1);
-#undef nextPtr
-
+  // Determine how much of the image is memory mapped.
+  off_t map_size = (off_t)(MemoryMapImage ? _file_size : _index_size);
+  // Memory map image (minimally the index.)
+  _index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, map_size, true, false);
+  guarantee(_index_data, "image file not memory mapped");
+  // Retrieve length of index perfect hash table.
+  u4 length = table_length();
+  // Compute offset of the perfect hash table redirect table.
+  u4 redirect_table_offset = (u4)header_size;
+  // Compute offset of index attribute offsets.
+  u4 offsets_table_offset = redirect_table_offset + length * sizeof(s4);
+  // Compute offset of index location attribute data.
+  u4 location_bytes_offset = offsets_table_offset + length * sizeof(u4);
+  // Compute offset of index string table.
+  u4 string_bytes_offset = location_bytes_offset + locations_size();
+  // Compute address of the perfect hash table redirect table.
+  _redirect_table = (s4*)(_index_data + redirect_table_offset);
+  // Compute address of index attribute offsets.
+  _offsets_table = (u4*)(_index_data + offsets_table_offset);
+  // Compute address of index location attribute data.
+  _location_bytes = _index_data + location_bytes_offset;
+  // Compute address of index string table.
+  _string_bytes = _index_data + string_bytes_offset;
   // Successful open.
   return true;
 }
 
-void ImageFile::close() {
+// Close image file.
+void ImageFileReader::close() {
   // Dealllocate the index.
-  if (_index_data) {
-    if (_memory_mapped) {
-      os::unmap_memory((char*)_index_data, _index_size);
-    } else {
-      FREE_RESOURCE_ARRAY(u1, _index_data, _index_size);
-    }
-
+  if (_index_data != NULL) {
+    os::unmap_memory((char*)_index_data, _index_size);
     _index_data = NULL;
   }
-
-  // close file.
+  // Close file.
   if (_fd != -1) {
     os::close(_fd);
     _fd = -1;
   }
+}
 
+// Read directly from the file.
+bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const {
+  return os::read_at(_fd, data, size, offset) == size;
 }
 
-// Return the attribute stream for a named resourced.
-u1* ImageFile::find_location_data(const char* path) const {
-  // Compute hash.
-  u4 hash = ImageStrings::hash_code(path) % _header._location_count;
-  s4 redirect = _redirect_table[hash];
-
-  if (!redirect) {
-    return NULL;
-  }
-
-  u4 index;
-
-  if (redirect < 0) {
-    // If no collision.
-    index = -redirect - 1;
-  } else {
-    // If collision, recompute hash code.
-    index = ImageStrings::hash_code(path, redirect) % _header._location_count;
+// Find the location attributes associated with the path.  Returns true if
+// the location is found, false otherwise.
+bool ImageFileReader::find_location(const char* path, ImageLocation& location) const {
+  // Locate the entry in the index perfect hash table.
+  s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
+  // If is found.
+  if (index != ImageStrings::NOT_FOUND) {
+    // Get address of first byte of location attribute stream.
+    u1* data = get_location_data(index);
+    // Expand location attributes.
+    location.set_data(data);
+    // Make sure result is not a false positive.
+    return verify_location(location, path);
   }
-
-  assert(index < _header._location_count, "index exceeds location count");
-  u4 offset = _offsets_table[index];
-  assert(offset < _header._locations_size, "offset exceeds location attributes size");
-
-  if (offset == 0) {
-    return NULL;
-  }
-
-  return _location_bytes + offset;
-}
-
-// Verify that a found location matches the supplied path.
-bool ImageFile::verify_location(ImageLocation& location, const char* path) const {
-  // Retrieve each path component string.
-  ImageStrings strings(_string_bytes, _header._strings_size);
-  // Match a path with each subcomponent without concatenation (copy).
-  // Match up path parent.
-  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
-  const char* next = ImageStrings::starts_with(path, parent);
-  // Continue only if a complete match.
-  if (!next) return false;
-  // Match up path base.
-  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
-  next = ImageStrings::starts_with(next, base);
-  // Continue only if a complete match.
-  if (!next) return false;
-  // Match up path extension.
-  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
-  next = ImageStrings::starts_with(next, extension);
-
-  // True only if complete match and no more characters.
-  return next && *next == '\0';
+  return false;
 }
 
-// Return the resource for the supplied location.
-u1* ImageFile::get_resource(ImageLocation& location) const {
-  // Retrieve the byte offset and size of the resource.
-  u8 offset = _index_size + location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
-  u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
-  u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
-  u8 read_size = compressed_size ? compressed_size : size;
-
-  // Allocate space for the resource.
-  u1* data = NEW_RESOURCE_ARRAY(u1, read_size);
-
-  bool is_read = os::read_at(_fd, data, read_size, offset) == read_size;
-  guarantee(is_read, "error reading from image or short read");
-
-  // If not compressed, just return the data.
-  if (!compressed_size) {
-    return data;
+// Assemble the location path from the string fragments indicated in the location attributes.
+void ImageFileReader::location_path(ImageLocation& location, char* path, size_t max) const {
+  // Manage the image string table.
+  ImageStrings strings(_string_bytes, _header.strings_size(_endian));
+  // Position to first character of the path buffer.
+  char* next = path;
+  // Temp for string length.
+  size_t length;
+  // Get module string.
+  const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
+  // If module string is not empty string.
+  if (*module != '\0') {
+    // Get length of module name.
+    length = strlen(module);
+    // Make sure there is no buffer overflow.
+    guarantee(next - path + length + 2 < max, "buffer overflow");
+    // Append '/module/'.
+    *next++ = '/';
+    strcpy(next, module); next += length;
+    *next++ = '/';
   }
-
-  u1* uncompressed = NEW_RESOURCE_ARRAY(u1, size);
-  char* msg = NULL;
-  jboolean res = ClassLoader::decompress(data, compressed_size, uncompressed, size, &msg);
-  if (!res) warning("decompression failed due to %s\n", msg);
-  guarantee(res, "decompression failed");
-
-  return uncompressed;
+  // Get parent (package) string.
+  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+  // If parent string is not empty string.
+  if (*parent != '\0') {
+    // Get length of module string.
+    length = strlen(parent);
+    // Make sure there is no buffer overflow.
+    guarantee(next - path + length + 1 < max, "buffer overflow");
+    // Append 'patent/' .
+    strcpy(next, parent); next += length;
+    *next++ = '/';
+  }
+  // Get base name string.
+  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+  // Get length of base name.
+  length = strlen(base);
+  // Make sure there is no buffer overflow.
+  guarantee(next - path + length < max, "buffer overflow");
+  // Append base name.
+  strcpy(next, base); next += length;
+  // Get extension string.
+  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+  // If extension string is not empty string.
+  if (*extension != '\0') {
+    // Get length of extension string.
+    length = strlen(extension);
+    // Make sure there is no buffer overflow.
+    guarantee(next - path + length + 1 < max, "buffer overflow");
+    // Append '.extension' .
+    *next++ = '.';
+    strcpy(next, extension); next += length;
+  }
+  // Make sure there is no buffer overflow.
+  guarantee((size_t)(next - path) < max, "buffer overflow");
+  // Terminate string.
+  *next = '\0';
 }
 
-void ImageFile::get_resource(const char* path, u1*& buffer, u8& size) const {
-  buffer = NULL;
-  size = 0;
-  u1* data = find_location_data(path);
-  if (data) {
-    ImageLocation location(data);
-    if (verify_location(location, path)) {
-      size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
-      buffer = get_resource(location);
-    }
+// Verify that a found location matches the supplied path (without copying.)
+bool ImageFileReader::verify_location(ImageLocation& location, const char* path) const {
+  // Manage the image string table.
+  ImageStrings strings(_string_bytes, _header.strings_size(_endian));
+  // Position to first character of the path string.
+  const char* next = path;
+  // Get module name string.
+  const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
+  // If module string is not empty.
+  if (*module != '\0') {
+    // Compare '/module/' .
+    if (*next++ != '/') return false;
+    if (!(next = ImageStrings::starts_with(next, module))) return false;
+    if (*next++ != '/') return false;
   }
+  // Get parent (package) string
+  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+  // If parent string is not empty string.
+  if (*parent != '\0') {
+    // Compare 'parent/' .
+    if (!(next = ImageStrings::starts_with(next, parent))) return false;
+    if (*next++ != '/') return false;
+  }
+  // Get base name string.
+  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+  // Compare with basne name.
+  if (!(next = ImageStrings::starts_with(next, base))) return false;
+  // Get extension string.
+  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+  // If extension is not empty.
+  if (*extension != '\0') {
+    // Compare '.extension' .
+    if (*next++ != '.') return false;
+    if (!(next = ImageStrings::starts_with(next, extension))) return false;
+  }
+  // True only if complete match and no more characters.
+  return *next == '\0';
 }
 
-GrowableArray<const char*>* ImageFile::packages(const char* name) {
-  char entry[JVM_MAXPATHLEN];
-  bool overflow = jio_snprintf(entry, sizeof(entry), "%s/packages.offsets", name) == -1;
-  guarantee(!overflow, "package name overflow");
-
-  u1* buffer;
-  u8 size;
-
-  get_resource(entry, buffer, size);
-  guarantee(buffer, "missing module packages reource");
-  ImageStrings strings(_string_bytes, _header._strings_size);
-  GrowableArray<const char*>* pkgs = new GrowableArray<const char*>();
-  int count = size / 4;
-  for (int i = 0; i < count; i++) {
-    u4 offset = Bytes::get_Java_u4(buffer + (i*4));
-    const char* p = strings.get(offset);
-    pkgs->append(p);
+// Return the resource data for the supplied location.
+void ImageFileReader::get_resource(ImageLocation& location, u1* uncompressed_data) const {
+  // Retrieve the byte offset and size of the resource.
+  u8 offset = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
+  u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+  u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
+  if (compressed_size != 0) {
+    ResourceMark rm;
+    u1* compressed_data;
+    // If not memory mapped read in bytes.
+    if (!MemoryMapImage) {
+      // Allocate buffer for compression.
+      compressed_data = NEW_RESOURCE_ARRAY(u1, compressed_size);
+      // Read bytes from offset beyond the image index.
+      bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
+      guarantee(is_read, "error reading from image or short read");
+    } else {
+      compressed_data = get_data_address() + offset;
+    }
+    // Get image string table.
+    const ImageStrings strings = get_strings();
+    // Decompress resource.
+    ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, uncompressed_size,
+            &strings, false);
+  } else {
+    // Read bytes from offset beyond the image index.
+    bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
+    guarantee(is_read, "error reading from image or short read");
   }
-
-  return pkgs;
 }
--- a/hotspot/src/share/vm/classfile/imageFile.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/imageFile.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -28,13 +28,15 @@
 #include "classfile/classLoader.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
+#include "utilities/endian.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
 
 // Image files are an alternate file format for storing classes and resources. The
-// goal is to supply file access which is faster and smaller that the jar format.
-// It should be noted that unlike jars information stored in an image is in native
-// endian format. This allows the image to be memory mapped into memory without
-// endian translation.  This also means that images are platform dependent.
+// goal is to supply file access which is faster and smaller than the jar format.
+// It should be noted that unlike jars, information stored in an image is in native
+// endian format. This allows the image to be mapped into memory without endian
+// translation.  This also means that images are platform dependent.
 //
 // Image files are structured as three sections;
 //
@@ -42,7 +44,7 @@
 //         |  Header   |
 //         +-----------+
 //         |           |
-//         | Directory |
+//         |   Index   |
 //         |           |
 //         +-----------+
 //         |           |
@@ -60,7 +62,11 @@
 //         +------------+------------+
 //         | Major Vers | Minor Vers |
 //         +------------+------------+
-//         |      Location Count     |
+//         |          Flags          |
+//         +-------------------------+
+//         |      Resource Count     |
+//         +-------------------------+
+//         |       Table Length      |
 //         +-------------------------+
 //         |      Attributes Size    |
 //         +-------------------------+
@@ -71,23 +77,24 @@
 //         special file extension.
 // Major vers, minor vers - differences in version numbers indicate structural
 //                          changes in the image.
-// Location count - number of locations/resources in the file.  This count is also
-//                  the length of lookup tables used in the directory.
+// Flags - various image wide flags (future).
+// Resource count - number of resources in the file.
+// Table length - the length of lookup tables used in the index.
 // Attributes size - number of bytes in the region used to store location attribute
 //                   streams.
 // Strings size - the size of the region used to store strings used by the
-//                directory and meta data.
+//                index and meta data.
 //
-// The directory contains information related to resource lookup. The algorithm
+// The index contains information related to resource lookup. The algorithm
 // used for lookup is "A Practical Minimal Perfect Hashing Method"
 // (http://homepages.dcc.ufmg.br/~nivio/papers/wea05.pdf). Given a path string
-// in the form <package>/<base>.<extension>  return the resource location
+// in the form /<module>/<package>/<base>.<extension>  return the resource location
 // information;
 //
-//     redirectIndex = hash(path, DEFAULT_SEED) % count;
+//     redirectIndex = hash(path, DEFAULT_SEED) % table_length;
 //     redirect = redirectTable[redirectIndex];
 //     if (redirect == 0) return not found;
-//     locationIndex = redirect < 0 ? -1 - redirect : hash(path, redirect) % count;
+//     locationIndex = redirect < 0 ? -1 - redirect : hash(path, redirect) % table_length;
 //     location = locationTable[locationIndex];
 //     if (!verify(location, path)) return not found;
 //     return location;
@@ -97,7 +104,7 @@
 // other seeds. The verify function guarantees the found resource location is
 // indeed the resource we are looking for.
 //
-// The following is the format of the directory;
+// The following is the format of the index;
 //
 //         +-------------------+
 //         |   Redirect Table  |
@@ -117,54 +124,74 @@
 //                  offsets.  Zero indicates not found.
 // Attribute Offsets - Array of 32-bit unsigned values representing offsets into
 //                     attribute data.  Attribute offsets can be iterated to do a
-//                     full survey of resources in the image.
+//                     full survey of resources in the image.  Offset of zero
+//                     indicates no attributes.
 // Attribute Data - Bytes representing compact attribute data for locations. (See
 //                  comments in ImageLocation.)
-// Strings - Collection of zero terminated UTF-8 strings used by the directory and
+// Strings - Collection of zero terminated UTF-8 strings used by the index and
 //           image meta data.  Each string is accessed by offset.  Each string is
 //           unique.  Offset zero is reserved for the empty string.
 //
-// Note that the memory mapped directory assumes 32 bit alignment of the image
-// header, the redirect table and the attribute offsets.
+// Note that the memory mapped index assumes 32 bit alignment of each component
+// in the index.
+//
+// Endianness of an image.
+// An image booted by hotspot is always in native endian.  However, it is possible
+// to read (by the JDK) in alternate endian format.  Primarily, this is during
+// cross platform scenarios.  Ex, where javac needs to read an embedded image
+// to access classes for crossing compilation.
 //
 
+class ImageFileReader; // forward declaration
 
 // Manage image file string table.
-class ImageStrings {
+class ImageStrings VALUE_OBJ_CLASS_SPEC {
 private:
-  // Data bytes for strings.
-  u1* _data;
-  // Number of bytes in the string table.
-  u4 _size;
-
+  u1* _data; // Data bytes for strings.
+  u4 _size; // Number of bytes in the string table.
 public:
-  // Prime used to generate hash for Perfect Hashing.
-  static const u4 HASH_MULTIPLIER = 0x01000193;
+  enum {
+    // Not found result from find routine.
+    NOT_FOUND = -1,
+    // Prime used to generate hash for Perfect Hashing.
+    HASH_MULTIPLIER = 0x01000193
+  };
 
   ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
 
   // Return the UTF-8 string beginning at offset.
   inline const char* get(u4 offset) const {
-    assert(offset < _size, "offset exceeds string table size");
+    guarantee(offset < _size, "offset exceeds string table size");
     return (const char*)(_data + offset);
   }
 
-  // Compute the Perfect Hashing hash code for the supplied string.
+  // Compute the Perfect Hashing hash code for the supplied UTF-8 string.
   inline static u4 hash_code(const char* string) {
     return hash_code(string, HASH_MULTIPLIER);
   }
 
   // Compute the Perfect Hashing hash code for the supplied string, starting at seed.
-  static u4 hash_code(const char* string, u4 seed);
+  static s4 hash_code(const char* string, s4 seed);
 
-  // Test to see if string begins with start.  If so returns remaining portion
-  // of string.  Otherwise, NULL.  Used to test sections of a path without
-  // copying.
+  // Match up a string in a perfect hash table.  Result still needs validation
+  // for precise match.
+  static s4 find(Endian* endian, const char* name, s4* redirect, u4 length);
+
+  // Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
+  // return non-NULL address of remaining portion of string.  Otherwise, return
+  // NULL.  Used to test sections of a path without copying from image string
+  // table.
   static const char* starts_with(const char* string, const char* start);
 
+  // Test to see if UTF-8 string begins with start char.  If so, return non-NULL
+  // address of remaining portion of string.  Otherwise, return NULL.  Used
+  // to test a character of a path without copying.
+  inline static const char* starts_with(const char* string, const char ch) {
+    return *string == ch ? string + 1 : NULL;
+  }
 };
 
-// Manage image file location attribute streams.  Within an image, a location's
+// Manage image file location attribute data.  Within an image, a location's
 // attributes are compressed into a stream of bytes.  An attribute stream is
 // composed of individual attribute sequences.  Each attribute sequence begins with
 // a header byte containing the attribute 'kind' (upper 5 bits of header) and the
@@ -188,7 +215,7 @@
 //    stream.
 //  - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
 //    storing the resources.  Thus, in an image this represents the number of bytes
-//    after the directory.
+//    after the index.
 //  - Currently, compressed resources are represented by having a non-zero
 //    ATTRIBUTE_COMPRESSED value.  This represents the number of bytes stored in the
 //    image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
@@ -198,17 +225,19 @@
 //    represented differently.
 //  - Package strings include trailing slash and extensions include prefix period.
 //
-class ImageLocation {
+class ImageLocation VALUE_OBJ_CLASS_SPEC {
 public:
-  // Attribute kind enumeration.
-  static const u1 ATTRIBUTE_END = 0; // End of attribute stream marker
-  static const u1 ATTRIBUTE_BASE = 1; // String table offset of resource path base
-  static const u1 ATTRIBUTE_PARENT = 2; // String table offset of resource path parent
-  static const u1 ATTRIBUTE_EXTENSION = 3; // String table offset of resource path extension
-  static const u1 ATTRIBUTE_OFFSET = 4; // Container byte offset of resource
-  static const u1 ATTRIBUTE_COMPRESSED = 5; // In image byte size of the compressed resource
-  static const u1 ATTRIBUTE_UNCOMPRESSED = 6; // In memory byte size of the uncompressed resource
-  static const u1 ATTRIBUTE_COUNT = 7; // Number of attribute kinds
+  enum {
+    ATTRIBUTE_END,          // End of attribute stream marker
+    ATTRIBUTE_MODULE,       // String table offset of module name
+    ATTRIBUTE_PARENT,       // String table offset of resource path parent
+    ATTRIBUTE_BASE,         // String table offset of resource path base
+    ATTRIBUTE_EXTENSION,    // String table offset of resource path extension
+    ATTRIBUTE_OFFSET,       // Container byte offset of resource
+    ATTRIBUTE_COMPRESSED,   // In image byte size of the compressed resource
+    ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
+    ATTRIBUTE_COUNT         // Number of attribute kinds
+  };
 
 private:
   // Values of inflated attributes.
@@ -222,30 +251,43 @@
   // Return the attribute kind.
   inline static u1 attribute_kind(u1 data) {
     u1 kind = data >> 3;
-    assert(kind < ATTRIBUTE_COUNT, "invalid attribute kind");
+    guarantee(kind < ATTRIBUTE_COUNT, "invalid attribute kind");
     return kind;
   }
 
   // Return the attribute length.
   inline static u8 attribute_value(u1* data, u1 n) {
-    assert(0 < n && n <= 8, "invalid attribute value length");
+    guarantee(0 < n && n <= 8, "invalid attribute value length");
     u8 value = 0;
-
     // Most significant bytes first.
     for (u1 i = 0; i < n; i++) {
       value <<= 8;
       value |= data[i];
     }
-
     return value;
   }
 
 public:
-  ImageLocation(u1* data);
+  ImageLocation() {
+    clear_data();
+  }
+
+  ImageLocation(u1* data) {
+    clear_data();
+    set_data(data);
+  }
+
+  // Inflates the attribute stream into individual values stored in the long
+  // array _attributes. This allows an attribute value to be quickly accessed by
+  // direct indexing. Unspecified values default to zero.
+  void set_data(u1* data);
+
+  // Zero all attribute values.
+  void clear_data();
 
   // Retrieve an attribute value from the inflated array.
   inline u8 get_attribute(u1 kind) const {
-    assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT, "invalid attribute kind");
+    guarantee(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT, "invalid attribute kind");
     return _attributes[kind];
   }
 
@@ -255,89 +297,306 @@
   }
 };
 
-// Manage the image file.
-class ImageFile: public CHeapObj<mtClass> {
-private:
-  // Image file marker.
-  static const u4 IMAGE_MAGIC = 0xCAFEDADA;
-  // Image file major version number.
-  static const u2 MAJOR_VERSION = 0;
-  // Image file minor version number.
-  static const u2 MINOR_VERSION = 1;
+//
+// NOTE: needs revision.
+// Each loader requires set of module meta data to identify which modules and
+// packages are managed by that loader.  Currently, there is one image file per
+// builtin loader, so only one  module meta data resource per file.
+//
+// Each element in the module meta data is a native endian 4 byte integer.  Note
+// that entries with zero offsets for string table entries should be ignored (
+// padding for hash table lookup.)
+//
+// Format:
+//    Count of package to module entries
+//    Count of module to package entries
+//    Perfect Hash redirect table[Count of package to module entries]
+//    Package to module entries[Count of package to module entries]
+//        Offset to package name in string table
+//        Offset to module name in string table
+//    Perfect Hash redirect table[Count of module to package entries]
+//    Module to package entries[Count of module to package entries]
+//        Offset to module name in string table
+//        Count of packages in module
+//        Offset to first package in packages table
+//    Packages[]
+//        Offset to package name in string table
+//
+// Manage the image module meta data.
+class ImageModuleData : public CHeapObj<mtClass> {
+  class Header VALUE_OBJ_CLASS_SPEC {
+  private:
+    u4 _ptm_count;      // Count of package to module entries
+    u4 _mtp_count;      // Count of module to package entries
+  public:
+    inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); }
+    inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); }
+  };
 
-  struct ImageHeader {
-    u4 _magic;          // Image file marker
-    u2 _major_version;  // Image file major version number
-    u2 _minor_version;  // Image file minor version number
-    u4 _location_count; // Number of locations managed in index.
-    u4 _locations_size; // Number of bytes in attribute table.
-    u4 _strings_size;   // Number of bytes in string table.
+  // Hashtable entry
+  class HashData VALUE_OBJ_CLASS_SPEC {
+  private:
+    u4 _name_offset;    // Name offset in string table
+  public:
+    inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); }
+  };
+
+  // Package to module hashtable entry
+  class PTMData : public HashData {
+  private:
+    u4 _module_name_offset; // Module name offset in string table
+  public:
+    inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); }
+  };
+
+  // Module to package hashtable entry
+  class MTPData : public HashData {
+  private:
+    u4 _package_count;     // Number of packages in module
+    u4 _package_offset;    // Offset in package list
+  public:
+    inline u4 package_count(Endian* endian)  const { return endian->get(_package_count); }
+    inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); }
   };
 
-  char* _name;          // Name of image
-  int _fd;              // File descriptor
-  bool _memory_mapped;  // Is file memory mapped
-  ImageHeader _header;  // Image header
-  u8 _index_size;       // Total size of index
-  u1* _index_data;      // Raw index data
-  s4* _redirect_table;  // Perfect hash redirect table
-  u4* _offsets_table;   // Location offset table
-  u1* _location_bytes;  // Location attributes
-  u1* _string_bytes;    // String table
+  const ImageFileReader* _image_file; // Source image file
+  Endian* _endian;                    // Endian handler
+  ImageStrings _strings;              // Image file strings
+  u1* _data;                          // Module data resource data
+  u8 _data_size;                      // Size of resource data
+  Header* _header;                    // Module data header
+  s4* _ptm_redirect;                  // Package to module hashtable redirect
+  PTMData* _ptm_data;                 // Package to module data
+  s4* _mtp_redirect;                  // Module to packages hashtable redirect
+  MTPData* _mtp_data;                 // Module to packages data
+  s4* _mtp_packages;                  // Package data (name offsets)
+
+  // Return a string from the string table.
+  inline const char* get_string(u4 offset) {
+    return _strings.get(offset);
+  }
+
+  inline u4 mtp_package(u4 index) {
+    return _endian->get(_mtp_packages[index]);
+  }
+
+public:
+  ImageModuleData(const ImageFileReader* image_file, const char* module_data_name);
+  ~ImageModuleData();
+
+  // Return the name of the module data resource.
+  static void module_data_name(char* buffer, const char* image_file_name);
+
+  // Return the module in which a package resides.  Returns NULL if not found.
+  const char* package_to_module(const char* package_name);
+
+  // Returns all the package names in a module.  Returns NULL if module not found.
+  GrowableArray<const char*>* module_to_packages(const char* module_name);
+};
+
+// Image file header, starting at offset 0.
+class ImageHeader VALUE_OBJ_CLASS_SPEC {
+private:
+  u4 _magic;           // Image file marker
+  u4 _version;         // Image file major version number
+  u4 _flags;           // Image file flags
+  u4 _resource_count;  // Number of resources in file
+  u4 _table_length;    // Number of slots in index tables
+  u4 _locations_size;  // Number of bytes in attribute table
+  u4 _strings_size;    // Number of bytes in string table
+
+public:
+  u4 magic() const { return _magic; }
+  u4 magic(Endian* endian) const { return endian->get(_magic); }
+  void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
+
+  u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
+  u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
+  void set_version(Endian* endian, u4 major_version, u4 minor_version) {
+    return endian->set(_version, major_version << 16 | minor_version);
+  }
+
+  u4 flags(Endian* endian) const { return endian->get(_flags); }
+  void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); }
+
+  u4 resource_count(Endian* endian) const { return endian->get(_resource_count); }
+  void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); }
+
+  u4 table_length(Endian* endian) const { return endian->get(_table_length); }
+  void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); }
+
+  u4 locations_size(Endian* endian) const { return endian->get(_locations_size); }
+  void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); }
+
+  u4 strings_size(Endian* endian) const { return endian->get(_strings_size); }
+  void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); }
+};
+
+// Max path length limit independent of platform.  Windows max path is 1024,
+// other platforms use 4096.  The JCK fails several tests when 1024 is used.
+#define IMAGE_MAX_PATH 4096
+
+// Manage the image file.
+// ImageFileReader manages the content of an image file.
+// Initially, the header of the image file is read for validation.  If valid,
+// values in the header are used calculate the size of the image index.  The
+// index is then memory mapped to allow load on demand and sharing.  The
+// -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
+// An image can be used by Hotspot and multiple reference points in the JDK, thus
+// it is desirable to share a reader.  To accomodate sharing, a share table is
+// defined (see ImageFileReaderTable in imageFile.cpp)  To track the number of
+// uses, ImageFileReader keeps a use count (_use).  Use is incremented when
+// 'opened' by reference point and decremented when 'closed'.  Use of zero
+// leads the ImageFileReader to be actually closed and discarded.
+class ImageFileReader : public CHeapObj<mtClass> {
+private:
+  // Manage a number of image files such that an image can be shared across
+  // multiple uses (ex. loader.)
+  static GrowableArray<ImageFileReader*>* _reader_table;
+
+  char* _name;         // Name of image
+  s4 _use;             // Use count
+  int _fd;             // File descriptor
+  Endian* _endian;     // Endian handler
+  u8 _file_size;       // File size in bytes
+  ImageHeader _header; // Image header
+  size_t _index_size;  // Total size of index
+  u1* _index_data;     // Raw index data
+  s4* _redirect_table; // Perfect hash redirect table
+  u4* _offsets_table;  // Location offset table
+  u1* _location_bytes; // Location attributes
+  u1* _string_bytes;   // String table
+
+  ImageFileReader(const char* name, bool big_endian);
+  ~ImageFileReader();
 
   // Compute number of bytes in image file index.
   inline u8 index_size() {
     return sizeof(ImageHeader) +
-    _header._location_count * sizeof(u4) * 2 +
-    _header._locations_size +
-    _header._strings_size;
+      table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
   }
 
 public:
-  ImageFile(const char* name);
-  ~ImageFile();
+  enum {
+    // Image file marker.
+    IMAGE_MAGIC = 0xCAFEDADA,
+    // Endian inverted Image file marker.
+    IMAGE_MAGIC_INVERT = 0xDADAFECA,
+    // Image file major version number.
+    MAJOR_VERSION = 1,
+    // Image file minor version number.
+    MINOR_VERSION = 0
+  };
+
+  // Open an image file, reuse structure if file already open.
+  static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
 
-  // Open image file for access.
+  // Close an image file if the file is not in use elsewhere.
+  static void close(ImageFileReader *reader);
+
+  // Return an id for the specifed ImageFileReader.
+  static u8 readerToID(ImageFileReader *reader);
+
+  // Validate the image id.
+  static bool idCheck(u8 id);
+
+  // Return an id for the specifed ImageFileReader.
+  static ImageFileReader* idToReader(u8 id);
+
+  // Open image file for read access.
   bool open();
+
   // Close image file.
   void close();
 
+  // Read directly from the file.
+  bool read_at(u1* data, u8 size, u8 offset) const;
+
+  inline Endian* endian() const { return _endian; }
+
   // Retrieve name of image file.
   inline const char* name() const {
     return _name;
   }
 
+  // Retrieve size of image file.
+  inline u8 file_size() const {
+    return _file_size;
+  }
+
+  // Return first address of index data.
+  inline u1* get_index_address() const {
+    return _index_data;
+  }
+
+  // Return first address of resource data.
+  inline u1* get_data_address() const {
+    return _index_data + _index_size;
+  }
+
+  // Get the size of the index data.
+  size_t get_index_size() const {
+    return _index_size;
+  }
+
+  inline u4 table_length() const {
+    return _header.table_length(_endian);
+  }
+
+  inline u4 locations_size() const {
+    return _header.locations_size(_endian);
+  }
+
+  inline u4 strings_size()const  {
+    return _header.strings_size(_endian);
+  }
+
+  inline u4* offsets_table() const {
+    return _offsets_table;
+  }
+
+  // Increment use count.
+  inline void inc_use() {
+    _use++;
+  }
+
+  // Decrement use count.
+  inline bool dec_use() {
+    return --_use == 0;
+  }
+
   // Return a string table accessor.
   inline const ImageStrings get_strings() const {
-    return ImageStrings(_string_bytes, _header._strings_size);
+    return ImageStrings(_string_bytes, _header.strings_size(_endian));
   }
 
-  // Return number of locations in image file index.
-  inline u4 get_location_count() const {
-    return _header._location_count;
+  // Return location attribute stream at offset.
+  inline u1* get_location_offset_data(u4 offset) const {
+    guarantee((u4)offset < _header.locations_size(_endian),
+              "offset exceeds location attributes size");
+    return offset != 0 ? _location_bytes + offset : NULL;
   }
 
   // Return location attribute stream for location i.
-  inline u1* get_location_data(u4 i) const {
-    u4 offset = _offsets_table[i];
+  inline u1* get_location_data(u4 index) const {
+    guarantee((u4)index < _header.table_length(_endian),
+              "index exceeds location count");
+    u4 offset = _endian->get(_offsets_table[index]);
 
-    return offset != 0 ? _location_bytes + offset : NULL;
+    return get_location_offset_data(offset);
   }
 
-  // Return the attribute stream for a named resourced.
-  u1* find_location_data(const char* path) const;
+  // Find the location attributes associated with the path.  Returns true if
+  // the location is found, false otherwise.
+  bool find_location(const char* path, ImageLocation& location) const;
+
+  // Assemble the location path.
+  void location_path(ImageLocation& location, char* path, size_t max) const;
 
   // Verify that a found location matches the supplied path.
   bool verify_location(ImageLocation& location, const char* path) const;
 
-  // Return the resource for the supplied location info.
-  u1* get_resource(ImageLocation& location) const;
-
-  // Return the resource associated with the path else NULL if not found.
-  void get_resource(const char* path, u1*& buffer, u8& size) const;
-
-  // Return an array of packages for a given module
-  GrowableArray<const char*>* packages(const char* name);
+  // Return the resource for the supplied path.
+  void get_resource(ImageLocation& location, u1* uncompressed_data) const;
 };
-
 #endif // SHARE_VM_CLASSFILE_IMAGEFILE_HPP
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1707,8 +1707,7 @@
     // - rest of the stack
 
     if (!skip_fillInStackTrace_check) {
-      if ((method->name() == vmSymbols::fillInStackTrace_name() ||
-           method->name() == vmSymbols::fillInStackTrace0_name()) &&
+      if (method->name() == vmSymbols::fillInStackTrace_name() &&
           throwable->is_a(method->method_holder())) {
         continue;
       }
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -258,6 +258,8 @@
   /* Type Annotations (JDK 8 and above) */                                                        \
   template(type_annotations_name,                     "typeAnnotations")                          \
                                                                                                   \
+  /* Intrinsic Annotation (JDK 9 and above) */                                                    \
+  template(jdk_internal_HotSpotIntrinsicCandidate_signature, "Ljdk/internal/HotSpotIntrinsicCandidate;") \
                                                                                                   \
   /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */                                   \
   template(java_lang_invoke_CallSite,                 "java/lang/invoke/CallSite")                \
@@ -345,7 +347,6 @@
   template(dispatch_name,                             "dispatch")                                 \
   template(getSystemClassLoader_name,                 "getSystemClassLoader")                     \
   template(fillInStackTrace_name,                     "fillInStackTrace")                         \
-  template(fillInStackTrace0_name,                    "fillInStackTrace0")                        \
   template(getCause_name,                             "getCause")                                 \
   template(initCause_name,                            "initCause")                                \
   template(setProperty_name,                          "setProperty")                              \
@@ -635,7 +636,43 @@
 // The F_xx is one of the Flags enum; see below.
 //
 // for Emacs: (let ((c-backslash-column 120) (c-backslash-max-column 120)) (c-backslash-region (point) (point-max) nil t))
+//
+//
+// There are two types of intrinsic methods: (1) Library intrinsics and (2) bytecode intrinsics.
+//
+// (1) A library intrinsic method may be replaced with hand-crafted assembly code,
+// with hand-crafted compiler IR, or with a combination of the two. The semantics
+// of the replacement code may differ from the semantics of the replaced code.
+//
+// (2) Bytecode intrinsic methods are not replaced by special code, but they are
+// treated in some other special way by the compiler. For example, the compiler
+// may delay inlining for some String-related intrinsic methods (e.g., some methods
+// defined in the StringBuilder and StringBuffer classes, see
+// Compile::should_delay_string_inlining() for more details).
+//
+// Due to the difference between the semantics of an intrinsic method as defined
+// in the (Java) source code and the semantics of the method as defined
+// by the code in the VM, intrinsic methods must be explicitly marked.
+//
+// Intrinsic methods are marked by the jdk.internal.HotSpotIntrinsicCandidate
+// annotation. If CheckIntrinsics is enabled, the VM performs the following
+// checks when a class C is loaded: (1) all intrinsics defined by the VM for
+// class C are present in the loaded class file and are marked;
+// (2) an intrinsic is defined by the VM for all marked methods of class C.
+//
+// If a mismatch is detected for a method, the VM behaves differently depending
+// on the type of build. A fastdebug build exits and reports an error on a mismatch.
+// A product build will not replace an unmarked library intrinsic method with
+// hand-crafted code, that is, unmarked library intrinsics are treated as ordinary
+// methods in a product build. The special treatment of a bytecode intrinsic method
+// persists even if the method not marked.
+//
+// When adding an intrinsic for a method, please make sure to appropriately
+// annotate the method in the source code. The list below contains all
+// library intrinsics followed by bytecode intrinsics. Please also make sure to
+// add the declaration of the intrinsic to the approriate section of the list.
 #define VM_INTRINSICS_DO(do_intrinsic, do_class, do_name, do_signature, do_alias)                                       \
+  /* (1) Library intrinsics                                                                        */                   \
   do_intrinsic(_hashCode,                 java_lang_Object,       hashCode_name, void_int_signature,             F_R)   \
    do_name(     hashCode_name,                                   "hashCode")                                            \
   do_intrinsic(_getClass,                 java_lang_Object,       getClass_name, void_class_signature,           F_R)   \
@@ -792,12 +829,12 @@
                                                                                                                         \
   do_class(sun_nio_cs_iso8859_1_Encoder,  "sun/nio/cs/ISO_8859_1$Encoder")                                              \
   do_intrinsic(_encodeISOArray,     sun_nio_cs_iso8859_1_Encoder, encodeISOArray_name, encodeISOArray_signature, F_S)   \
-   do_name(     encodeISOArray_name,                             "encodeISOArray")                                      \
+   do_name(     encodeISOArray_name,                             "implEncodeISOArray")                                  \
    do_signature(encodeISOArray_signature,                        "([CI[BII)I")                                          \
                                                                                                                         \
   do_class(java_math_BigInteger,                      "java/math/BigInteger")                                           \
-  do_intrinsic(_multiplyToLen,      java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_R)             \
-   do_name(     multiplyToLen_name,                             "multiplyToLen")                                        \
+  do_intrinsic(_multiplyToLen,      java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_S)             \
+   do_name(     multiplyToLen_name,                             "implMultiplyToLen")                                    \
    do_signature(multiplyToLen_signature,                        "([II[II[I)[I")                                         \
                                                                                                                         \
   do_intrinsic(_squareToLen, java_math_BigInteger, squareToLen_name, squareToLen_signature, F_S)                        \
@@ -808,6 +845,14 @@
    do_name(     mulAdd_name,                                  "implMulAdd")                                             \
    do_signature(mulAdd_signature,                             "([I[IIII)I")                                             \
                                                                                                                         \
+  do_intrinsic(_montgomeryMultiply,      java_math_BigInteger, montgomeryMultiply_name, montgomeryMultiply_signature, F_S) \
+   do_name(     montgomeryMultiply_name,                             "implMontgomeryMultiply")                          \
+   do_signature(montgomeryMultiply_signature,                        "([I[I[IIJ[I)[I")                                  \
+                                                                                                                        \
+  do_intrinsic(_montgomerySquare,      java_math_BigInteger, montgomerySquare_name, montgomerySquare_signature, F_S)    \
+   do_name(     montgomerySquare_name,                             "implMontgomerySquare")                              \
+   do_signature(montgomerySquare_signature,                        "([I[IIJ[I)[I")                                      \
+                                                                                                                        \
   /* java/lang/ref/Reference */                                                                                         \
   do_intrinsic(_Reference_get,            java_lang_ref_Reference, get_name,    void_object_signature, F_R)             \
                                                                                                                         \
@@ -815,21 +860,21 @@
   do_class(com_sun_crypto_provider_aescrypt,      "com/sun/crypto/provider/AESCrypt")                                   \
   do_intrinsic(_aescrypt_encryptBlock, com_sun_crypto_provider_aescrypt, encryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
   do_intrinsic(_aescrypt_decryptBlock, com_sun_crypto_provider_aescrypt, decryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
-   do_name(     encryptBlock_name,                                 "encryptBlock")                                      \
-   do_name(     decryptBlock_name,                                 "decryptBlock")                                      \
+   do_name(     encryptBlock_name,                                 "implEncryptBlock")                                  \
+   do_name(     decryptBlock_name,                                 "implDecryptBlock")                                  \
    do_signature(byteArray_int_byteArray_int_signature,             "([BI[BI)V")                                         \
                                                                                                                         \
   do_class(com_sun_crypto_provider_cipherBlockChaining,            "com/sun/crypto/provider/CipherBlockChaining")       \
    do_intrinsic(_cipherBlockChaining_encryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, encrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
    do_intrinsic(_cipherBlockChaining_decryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, decrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
-   do_name(     encrypt_name,                                      "encrypt")                                           \
-   do_name(     decrypt_name,                                      "decrypt")                                           \
+   do_name(     encrypt_name,                                      "implEncrypt")                                       \
+   do_name(     decrypt_name,                                      "implDecrypt")                                       \
    do_signature(byteArray_int_int_byteArray_int_signature,         "([BII[BI)I")                                        \
                                                                                                                         \
   /* support for sun.security.provider.SHA */                                                                           \
   do_class(sun_security_provider_sha,                              "sun/security/provider/SHA")                         \
   do_intrinsic(_sha_implCompress, sun_security_provider_sha, implCompress_name, implCompress_signature, F_R)            \
-   do_name(     implCompress_name,                                 "implCompress")                                      \
+   do_name(     implCompress_name,                                 "implCompress0")                                     \
    do_signature(implCompress_signature,                            "([BI)V")                                            \
                                                                                                                         \
   /* support for sun.security.provider.SHA2 */                                                                          \
@@ -843,7 +888,7 @@
   /* support for sun.security.provider.DigestBase */                                                                    \
   do_class(sun_security_provider_digestbase,                       "sun/security/provider/DigestBase")                  \
   do_intrinsic(_digestBase_implCompressMB, sun_security_provider_digestbase, implCompressMB_name, implCompressMB_signature, F_R)   \
-   do_name(     implCompressMB_name,                               "implCompressMultiBlock")                            \
+   do_name(     implCompressMB_name,                               "implCompressMultiBlock0")                           \
    do_signature(implCompressMB_signature,                          "([BII)I")                                           \
                                                                                                                         \
   /* support for com.sun.crypto.provider.GHASH */                                                                       \
@@ -857,17 +902,18 @@
   do_intrinsic(_updateCRC32,               java_util_zip_CRC32,   update_name, int2_int_signature,               F_SN)  \
    do_name(     update_name,                                      "update")                                             \
   do_intrinsic(_updateBytesCRC32,          java_util_zip_CRC32,   updateBytes_name, updateBytes_signature,       F_SN)  \
-   do_name(     updateBytes_name,                                "updateBytes")                                         \
+   do_name(     updateBytes_name,                                "updateBytes0")                                        \
    do_signature(updateBytes_signature,                           "(I[BII)I")                                            \
   do_intrinsic(_updateByteBufferCRC32,     java_util_zip_CRC32,   updateByteBuffer_name, updateByteBuffer_signature, F_SN) \
-   do_name(     updateByteBuffer_name,                           "updateByteBuffer")                                    \
+   do_name(     updateByteBuffer_name,                           "updateByteBuffer0")                                   \
    do_signature(updateByteBuffer_signature,                      "(IJII)I")                                             \
                                                                                                                         \
   /* support for java.util.zip.CRC32C */                                                                                \
   do_class(java_util_zip_CRC32C,          "java/util/zip/CRC32C")                                                       \
-  do_intrinsic(_updateBytesCRC32C,         java_util_zip_CRC32C,  updateBytes_name, updateBytes_signature,       F_S)   \
-  do_intrinsic(_updateDirectByteBufferCRC32C, java_util_zip_CRC32C, updateDirectByteBuffer_name, updateByteBuffer_signature, F_S) \
-   do_name(     updateDirectByteBuffer_name,                     "updateDirectByteBuffer")                              \
+  do_intrinsic(_updateBytesCRC32C,         java_util_zip_CRC32C,  updateBytes_C_name, updateBytes_signature,       F_S) \
+   do_name(     updateBytes_C_name,                               "updateBytes")                                        \
+  do_intrinsic(_updateDirectByteBufferCRC32C, java_util_zip_CRC32C, updateDirectByteBuffer_C_name, updateByteBuffer_signature, F_S) \
+   do_name(    updateDirectByteBuffer_C_name,                     "updateDirectByteBuffer")                             \
                                                                                                                         \
   /* support for sun.misc.Unsafe */                                                                                     \
   do_class(sun_misc_Unsafe,               "sun/misc/Unsafe")                                                            \
@@ -878,12 +924,6 @@
   do_intrinsic(_copyMemory,               sun_misc_Unsafe,        copyMemory_name, copyMemory_signature,         F_RN)  \
    do_name(     copyMemory_name,                                 "copyMemory")                                          \
    do_signature(copyMemory_signature,         "(Ljava/lang/Object;JLjava/lang/Object;JJ)V")                             \
-  do_intrinsic(_park,                     sun_misc_Unsafe,        park_name, park_signature,                     F_RN)  \
-   do_name(     park_name,                                       "park")                                                \
-   do_signature(park_signature,                                  "(ZJ)V")                                               \
-  do_intrinsic(_unpark,                   sun_misc_Unsafe,        unpark_name, unpark_signature,                 F_RN)  \
-   do_name(     unpark_name,                                     "unpark")                                              \
-   do_alias(    unpark_signature,                               /*(LObject;)V*/ object_void_signature)                  \
   do_intrinsic(_loadFence,                sun_misc_Unsafe,        loadFence_name, loadFence_signature,           F_RN)  \
    do_name(     loadFence_name,                                  "loadFence")                                           \
    do_alias(    loadFence_signature,                              void_method_signature)                                \
@@ -1066,11 +1106,15 @@
   do_intrinsic(_getAndSetObject,          sun_misc_Unsafe,        getAndSetObject_name, getAndSetObject_signature,  F_R)\
    do_name(     getAndSetObject_name,                             "getAndSetObject")                                    \
    do_signature(getAndSetObject_signature,                        "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
-    /*== LAST_COMPILER_INLINE*/                                                                                         \
-    /*the compiler does have special inlining code for these; bytecode inline is just fine */                           \
+                                                                                                                        \
+   /* (2) Bytecode intrinsics                                                                        */                 \
                                                                                                                         \
-  do_intrinsic(_fillInStackTrace,         java_lang_Throwable, fillInStackTrace_name, void_throwable_signature,  F_RNY) \
-                                                                                                                          \
+  do_intrinsic(_park,                     sun_misc_Unsafe,        park_name, park_signature,                     F_RN)  \
+   do_name(     park_name,                                       "park")                                                \
+   do_signature(park_signature,                                  "(ZJ)V")                                               \
+  do_intrinsic(_unpark,                   sun_misc_Unsafe,        unpark_name, unpark_signature,                 F_RN)  \
+   do_name(     unpark_name,                                     "unpark")                                              \
+   do_alias(    unpark_signature,                               /*(LObject;)V*/ object_void_signature)                  \
   do_intrinsic(_StringBuilder_void,   java_lang_StringBuilder, object_initializer_name, void_method_signature,     F_R)   \
   do_intrinsic(_StringBuilder_int,    java_lang_StringBuilder, object_initializer_name, int_void_signature,        F_R)   \
   do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature,     F_R)   \
--- a/hotspot/src/share/vm/code/codeBlob.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/codeBlob.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, 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
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "code/codeBlob.hpp"
 #include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "code/relocInfo.hpp"
 #include "compiler/disassembler.hpp"
 #include "interpreter/bytecode.hpp"
@@ -88,6 +89,7 @@
   _data_offset           = size;
   _frame_size            =  0;
   set_oop_maps(NULL);
+  _strings               = CodeStrings();
 }
 
 
@@ -114,6 +116,7 @@
   _code_offset           = _content_offset + cb->total_offset_of(cb->insts());
   _data_offset           = _content_offset + round_to(cb->total_content_size(), oopSize);
   assert(_data_offset <= size, "codeBlob is too small");
+  _strings               = CodeStrings();
 
   cb->copy_code_and_locs_to(this);
   set_oop_maps(oop_maps);
@@ -192,6 +195,7 @@
 
   BufferBlob* blob = NULL;
   unsigned int size = sizeof(BufferBlob);
+  CodeCacheExtensions::size_blob(name, &buffer_size);
   // align the size to CodeEntryAlignment
   size = align_code_offset(size);
   size += round_to(buffer_size, oopSize);
@@ -275,6 +279,7 @@
 
   MethodHandlesAdapterBlob* blob = NULL;
   unsigned int size = sizeof(MethodHandlesAdapterBlob);
+  CodeCacheExtensions::size_blob("MethodHandles adapters", &buffer_size);
   // align the size to CodeEntryAlignment
   size = align_code_offset(size);
   size += round_to(buffer_size, oopSize);
@@ -315,11 +320,13 @@
 {
   RuntimeStub* stub = NULL;
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
-  {
+  if (!CodeCacheExtensions::skip_code_generation()) {
+    // bypass useless code generation
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     unsigned int size = allocation_size(cb, sizeof(RuntimeStub));
     stub = new (size) RuntimeStub(stub_name, cb, size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments);
   }
+  stub = (RuntimeStub*) CodeCacheExtensions::handle_generated_blob(stub, stub_name);
 
   trace_new_stub(stub, "RuntimeStub - ", stub_name);
 
--- a/hotspot/src/share/vm/code/codeBlob.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/codeBlob.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, 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
@@ -38,7 +38,8 @@
     MethodProfiled      = 1,    // Execution level 2 and 3 (profiled) nmethods
     NonNMethod          = 2,    // Non-nmethods like Buffers, Adapters and Runtime Stubs
     All                 = 3,    // All types (No code cache segmentation)
-    NumTypes            = 4     // Number of CodeBlobTypes
+    Pregenerated        = 4,    // Special blobs, managed by CodeCacheExtensions
+    NumTypes            = 5     // Number of CodeBlobTypes
   };
 };
 
@@ -63,6 +64,7 @@
 class CodeBlob VALUE_OBJ_CLASS_SPEC {
 
   friend class VMStructs;
+  friend class CodeCacheDumper;
 
  private:
   const char* _name;
@@ -206,6 +208,14 @@
   void set_strings(CodeStrings& strings) {
     _strings.assign(strings);
   }
+
+  static ByteSize name_field_offset() {
+    return byte_offset_of(CodeBlob, _name);
+  }
+
+  static ByteSize oop_maps_field_offset() {
+    return byte_offset_of(CodeBlob, _oop_maps);
+  }
 };
 
 class WhiteBox;
--- a/hotspot/src/share/vm/code/codeCache.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -409,7 +409,7 @@
     }
     if (PrintCodeCacheExtension) {
       ResourceMark rm;
-      if (SegmentedCodeCache) {
+      if (_heaps->length() >= 1) {
         tty->print("%s", heap->name());
       } else {
         tty->print("CodeCache");
@@ -1211,7 +1211,7 @@
 
   int i = 0;
   FOR_ALL_HEAPS(heap) {
-    if (SegmentedCodeCache && Verbose) {
+    if ((_heaps->length() >= 1) && Verbose) {
       tty->print_cr("-- %s --", (*heap)->name());
     }
     FOR_ALL_BLOBS(cb, *heap) {
@@ -1360,7 +1360,7 @@
   FOR_ALL_HEAPS(heap_iterator) {
     CodeHeap* heap = (*heap_iterator);
     size_t total = (heap->high_boundary() - heap->low_boundary());
-    if (SegmentedCodeCache) {
+    if (_heaps->length() >= 1) {
       st->print("%s:", heap->name());
     } else {
       st->print("CodeCache:");
@@ -1397,7 +1397,7 @@
     nmethod* nm = iter.method();
     ResourceMark rm;
     char *method_name = nm->method()->name_and_sig_as_C_string();
-    st->print_cr("%d %d %s ["INTPTR_FORMAT", "INTPTR_FORMAT" - "INTPTR_FORMAT"]",
+    st->print_cr("%d %d %s [" INTPTR_FORMAT ", " INTPTR_FORMAT " - " INTPTR_FORMAT "]",
                  nm->compile_id(), nm->comp_level(), method_name, (intptr_t)nm->header_begin(),
                  (intptr_t)nm->code_begin(), (intptr_t)nm->code_end());
   }
--- a/hotspot/src/share/vm/code/codeCache.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -78,6 +78,7 @@
   friend class VMStructs;
   friend class NMethodIterator;
   friend class WhiteBox;
+  friend class CodeCacheLoader;
  private:
   // CodeHeaps of the cache
   static GrowableArray<CodeHeap*>* _heaps;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/code/codeCacheExtensions.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,52 @@
+/*
+ * 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_CODE_CODE_CACHE_EXTENSIONS_HPP
+#define SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_HPP
+
+#include "memory/allocation.hpp"
+
+class CodeCacheExtensionsSteps: AllStatic {
+public:
+  enum Step {
+    // Support for optional fine grain initialization hooks
+    // Note: these hooks must support refining the granularity
+    // (e.g. adding intermediate steps in the ordered enum
+    // if needed for future features)
+    Start,
+    VMVersion,
+    StubRoutines1,
+    Universe,
+    TemplateInterpreter,
+    Interpreter,
+    StubRoutines2,
+    InitGlobals,
+    CreateVM,
+    LastStep
+  };
+};
+
+#include "code/codeCacheExtensions_ext.hpp"
+
+#endif // SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/code/codeCacheExtensions_ext.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,130 @@
+/*
+ * 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_CODE_CODE_CACHE_EXTENSIONS_EXT_HPP
+#define SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_EXT_HPP
+
+#include "utilities/macros.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "interpreter/bytecodes.hpp"
+
+class AdapterHandlerEntry;
+class CodeBlob;
+class CodeBuffer;
+class InterpreterMacroAssembler;
+class Template;
+
+// All the methods defined here are placeholders for possible extensions.
+
+class CodeCacheExtensions: AllStatic {
+  friend class CodeCacheDumper;
+
+public:
+  // init both code saving and loading
+  // Must be called very early, before any code is generated.
+  static void initialize() {}
+
+  // Check whether the generated interpreter will be saved.
+  static bool saving_generated_interpreter() { return false; }
+
+  // Check whether a pregenerated interpreter is used.
+  static bool use_pregenerated_interpreter() { return false; }
+
+  // Placeholder for additional VM initialization code
+  static void complete_step(CodeCacheExtensionsSteps::Step phase) {}
+
+  // Return false for newly generated code, on systems where it is not
+  // executable.
+  static bool is_executable(void *pc) { return true; }
+
+  // Return whether dynamically generated code can be executable
+  static bool support_dynamic_code() { return true; }
+
+  // Skip new code generation when known to be useless.
+  static bool skip_code_generation() { return false; }
+
+  // Skip stubs used only for compiled code support.
+  static bool skip_compiler_support() { return false; }
+
+  // Ignore UseFastSignatureHandlers when returning false
+  static bool support_fast_signature_handlers() { return true; }
+
+  /////////////////////////
+  // Handle generated code:
+  // - allow newly generated code to be shared
+  // - allow pregenerated code to be used in place of the newly generated one
+  //   (modifying pc).
+  // - support remapping when doing both save and load
+  // 'remap' can be set to false if the addresses handled are not referenced
+  // from code generated later.
+
+  // Associate a name to a generated codelet and possibly modify the pc
+  // Note: use instead the specialized versions when they exist:
+  // - handle_generated_blob for CodeBlob
+  // - handle_generated_handler for SignatureHandlers
+  // See also the optimized calls below that handle several PCs at once.
+  static void handle_generated_pc(address &pc, const char *name) {}
+
+  // Adds a safe definition of the codelet, for codelets used right after
+  // generation (else we would need to immediately stop the JVM and convert
+  // the generated code to executable format before being able to go further).
+  static void handle_generated_pc(address &pc, const char *name, address default_entry) {}
+
+  // Special cases
+
+  // Special case for CodeBlobs, which may require blob specific actions.
+  static CodeBlob* handle_generated_blob(CodeBlob* blob, const char *name = NULL) { return blob; }
+
+  // Special case for Signature Handlers.
+  static void handle_generated_handler(address &handler_start, const char *name, address handler_end) {}
+
+  // Support for generating different variants of the interpreter
+  // that can be dynamically selected after reload.
+  //
+  // - init_interpreter_assembler allows to configure the assembler for
+  //   the current variant
+  //
+  // - needs_other_interpreter_variant returns true as long as other
+  //   variants are needed.
+  //
+  // - skip_template_interpreter_entries returns true if new entries
+  //   need not be generated for this masm setup and this bytecode
+  //
+  // - completed_template_interpreter_entries is called after new
+  //   entries have been generated and installed, for any non skipped
+  //   bytecode.
+  static void init_interpreter_assembler(InterpreterMacroAssembler* masm, CodeBuffer* code) {}
+  static bool needs_other_interpreter_variant() { return false; }
+  static bool skip_template_interpreter_entries(Bytecodes::Code code) { return false; }
+  static void completed_template_interpreter_entries(InterpreterMacroAssembler* masm, Bytecodes::Code code) {}
+
+  // Code size optimization. May optimize the requested size.
+  static void size_blob(const char* name, int *updatable_size) {}
+
+  // ergonomics
+  static void set_ergonomics_flags() {}
+};
+
+#endif // SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_EXT_HPP
--- a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -186,7 +186,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 " > ",base + *adr(i), base + *(adr(i)+1));
   tty->print_cr("}");
 }
 
--- a/hotspot/src/share/vm/code/nmethod.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -2118,7 +2118,7 @@
   void maybe_print(oop* p) {
     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")",
+    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);
     (*p)->print();
@@ -2518,7 +2518,7 @@
       _nm->print_nmethod(true);
       _ok = false;
     }
-    tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
+    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));
   }
   virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
@@ -2642,7 +2642,7 @@
       _nm->print_nmethod(true);
       _ok = false;
     }
-    tty->print_cr("*** scavengable oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
+    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));
     (*p)->print();
   }
@@ -2687,7 +2687,7 @@
   print_on(tty, NULL);
 
   if (WizardMode) {
-    tty->print("((nmethod*) "INTPTR_FORMAT ") ", this);
+    tty->print("((nmethod*) " INTPTR_FORMAT ") ", this);
     tty->print(" for method " INTPTR_FORMAT , (address)method());
     tty->print(" { ");
     if (is_in_use())      tty->print("in_use ");
--- a/hotspot/src/share/vm/code/stubs.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/stubs.cpp	Thu Jul 09 22:46:16 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
@@ -261,3 +261,17 @@
     stub_print(s);
   }
 }
+
+// Fixup for pregenerated code
+void StubQueue::fix_buffer(address buffer, address queue_end, address buffer_end, int number_of_stubs) {
+  const int extra_bytes = CodeEntryAlignment;
+  _stub_buffer = buffer;
+  _queue_begin = 0;
+  _queue_end = queue_end - buffer;
+  _number_of_stubs = number_of_stubs;
+  int size = buffer_end - buffer;
+  // Note: _buffer_limit must differ from _queue_end in the iteration loops
+  // => add extra space at the end (preserving alignment for asserts) if needed
+  if (buffer_end == queue_end) size += extra_bytes;
+  _buffer_limit = _buffer_size = size;
+}
--- a/hotspot/src/share/vm/code/stubs.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/code/stubs.hpp	Thu Jul 09 22:46:16 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
@@ -216,6 +216,9 @@
   // Debugging/printing
   void  verify();                                // verifies the stub queue
   void  print();                                 // prints information about the stub queue
+
+  // Fixup for pregenerated code
+  void fix_buffer(address buffer, address queue_end, address buffer_end, int number_of_stubs);
 };
 
 #endif // SHARE_VM_CODE_STUBS_HPP
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -172,7 +172,7 @@
   }
 
   void log_nmethod(JavaThread* thread, nmethod* nm) {
-    log(thread, "nmethod %d%s " INTPTR_FORMAT " code ["INTPTR_FORMAT ", " INTPTR_FORMAT "]",
+    log(thread, "nmethod %d%s " INTPTR_FORMAT " code [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",
         nm->compile_id(), nm->is_osr_method() ? "%" : "",
         p2i(nm), p2i(nm->code_begin()), p2i(nm->code_end()));
   }
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, 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
@@ -578,7 +578,7 @@
                       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)) {
+  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;
@@ -586,8 +586,6 @@
   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.
@@ -665,7 +663,7 @@
           jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
         }
       } else {
-        jio_snprintf(errorbuf, sizeof(errorbuf), "  Value cannot be read for flag %s of type %s", flag, type);
+        jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
       }
     } else if (strcmp(type, "double") == 0) {
       char buffer[2][256];
@@ -680,10 +678,10 @@
         jio_snprintf(errorbuf, buf_size, "  Value cannot be read for flag %s of type %s", flag, type);
       }
     } else {
-      jio_snprintf(errorbuf, sizeof(errorbuf), "  Type %s not supported ", type);
+      jio_snprintf(errorbuf, buf_size, "  Type %s not supported ", type);
     }
   } else {
-    jio_snprintf(errorbuf, sizeof(errorbuf), "  Flag name for type %s should be alphanumeric ", type);
+    jio_snprintf(errorbuf, buf_size, "  Flag name for type %s should be alphanumeric ", type);
   }
   return NULL;
 }
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -65,7 +65,7 @@
 Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL;
 Disassembler::decode_func Disassembler::_decode_instructions = NULL;
 
-static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH;
+static const char hsdis_library_name[] = "hsdis-" HOTSPOT_LIB_ARCH;
 static const char decode_instructions_virtual_name[] = "decode_instructions_virtual";
 static const char decode_instructions_name[] = "decode_instructions";
 static bool use_new_version = true;
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -688,18 +688,18 @@
            "The CMS generation should be the old generation");
     uint level = 1;
     if (Verbose) {
-      gclog_or_tty->print("[%u %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
+      gclog_or_tty->print("[%u %s-%s: " SIZE_FORMAT "(" SIZE_FORMAT ")]",
         level, short_name(), s, used(), capacity());
     } else {
-      gclog_or_tty->print("[%u %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
+      gclog_or_tty->print("[%u %s-%s: " SIZE_FORMAT "K(" SIZE_FORMAT "K)]",
         level, short_name(), s, used() / K, capacity() / K);
     }
   }
   if (Verbose) {
-    gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
+    gclog_or_tty->print(" " SIZE_FORMAT "(" SIZE_FORMAT ")",
               gch->used(), gch->capacity());
   } else {
-    gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
+    gclog_or_tty->print(" " SIZE_FORMAT "K(" SIZE_FORMAT "K)",
               gch->used() / K, gch->capacity() / K);
   }
 }
@@ -729,8 +729,8 @@
   bool   res = (available >= av_promo) || (available >= max_promotion_in_bytes);
   if (Verbose && PrintGCDetails) {
     gclog_or_tty->print_cr(
-      "CMS: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT"),"
-      "max_promo("SIZE_FORMAT")",
+      "CMS: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "),"
+      "max_promo(" SIZE_FORMAT ")",
       res? "":" not", available, res? ">=":"<",
       av_promo, max_promotion_in_bytes);
   }
@@ -805,18 +805,18 @@
               desired_free_percentage);
       gclog_or_tty->print_cr("  Maximum free fraction %f",
               maximum_free_percentage);
-      gclog_or_tty->print_cr("  Capacity "SIZE_FORMAT, capacity()/1000);
-      gclog_or_tty->print_cr("  Desired capacity "SIZE_FORMAT,
+      gclog_or_tty->print_cr("  Capacity " SIZE_FORMAT, capacity()/1000);
+      gclog_or_tty->print_cr("  Desired capacity " SIZE_FORMAT,
               desired_capacity/1000);
       GenCollectedHeap* gch = GenCollectedHeap::heap();
       assert(gch->is_old_gen(this), "The CMS generation should always be the old generation");
       size_t young_size = gch->young_gen()->capacity();
       gclog_or_tty->print_cr("  Young gen size " SIZE_FORMAT, young_size / 1000);
-      gclog_or_tty->print_cr("  unsafe_max_alloc_nogc "SIZE_FORMAT,
+      gclog_or_tty->print_cr("  unsafe_max_alloc_nogc " SIZE_FORMAT,
               unsafe_max_alloc_nogc()/1000);
-      gclog_or_tty->print_cr("  contiguous available "SIZE_FORMAT,
+      gclog_or_tty->print_cr("  contiguous available " SIZE_FORMAT,
               contiguous_available()/1000);
-      gclog_or_tty->print_cr("  Expand by "SIZE_FORMAT" (bytes)",
+      gclog_or_tty->print_cr("  Expand by " SIZE_FORMAT " (bytes)",
               expand_bytes);
     }
     // safe if expansion fails
@@ -1182,8 +1182,8 @@
     stats().print_on(gclog_or_tty);
     gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
       stats().time_until_cms_gen_full());
-    gclog_or_tty->print_cr("free="SIZE_FORMAT, _cmsGen->free());
-    gclog_or_tty->print_cr("contiguous_available="SIZE_FORMAT,
+    gclog_or_tty->print_cr("free=" SIZE_FORMAT, _cmsGen->free());
+    gclog_or_tty->print_cr("contiguous_available=" SIZE_FORMAT,
                            _cmsGen->contiguous_available());
     gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
     gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
@@ -2160,8 +2160,8 @@
     assert(_numObjectsPromoted == 0, "check");
     assert(_numWordsPromoted   == 0, "check");
     if (Verbose && PrintGC) {
-      gclog_or_tty->print("Allocated "SIZE_FORMAT" objects, "
-                          SIZE_FORMAT" bytes concurrently",
+      gclog_or_tty->print("Allocated " SIZE_FORMAT " objects, "
+                          SIZE_FORMAT " bytes concurrently",
       _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
     }
     _numObjectsAllocated = 0;
@@ -2241,8 +2241,8 @@
     assert(_numObjectsAllocated == 0, "check");
     assert(_numWordsAllocated == 0, "check");
     if (Verbose && PrintGC) {
-      gclog_or_tty->print("Promoted "SIZE_FORMAT" objects, "
-                          SIZE_FORMAT" bytes",
+      gclog_or_tty->print("Promoted " SIZE_FORMAT " objects, "
+                          SIZE_FORMAT " bytes",
                  _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
     }
     _numObjectsPromoted = 0;
@@ -2252,7 +2252,7 @@
   if (PrintGC && Verbose) {
     // Call down the chain in contiguous_available needs the freelistLock
     // so print this out before releasing the freeListLock.
-    gclog_or_tty->print(" Contiguous available "SIZE_FORMAT" bytes ",
+    gclog_or_tty->print(" Contiguous available " SIZE_FORMAT " bytes ",
                         contiguous_available());
   }
 }
@@ -2340,7 +2340,7 @@
     HeapWord* addr = _marks->offsetToHeapWord(offset);
     if (!_marks->isMarked(addr)) {
       oop(addr)->print_on(gclog_or_tty);
-      gclog_or_tty->print_cr(" ("INTPTR_FORMAT" should have been marked)", p2i(addr));
+      gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
       _failed = true;
     }
     return true;
@@ -2702,9 +2702,11 @@
   // Not unloading classes this cycle
   assert(!should_unload_classes(), "Inconsistency!");
 
+  // If we are not unloading classes then add SO_AllCodeCache to root
+  // scanning options.
+  add_root_scanning_option(rso);
+
   if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
-    // Include symbols, strings and code cache elements to prevent their resurrection.
-    add_root_scanning_option(rso);
     set_verifying(true);
   } else if (verifying() && !should_verify) {
     // We were verifying, but some verification flags got disabled.
@@ -4269,7 +4271,7 @@
   verify_overflow_empty();
 
   if (PrintGCDetails) {
-    gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
+    gclog_or_tty->print("[YG occupancy: " SIZE_FORMAT " K (" SIZE_FORMAT " K)]",
                         _young_gen->used() / K,
                         _young_gen->capacity() / K);
   }
@@ -4381,8 +4383,8 @@
   if (ser_ovflw > 0) {
     if (PrintCMSStatistics != 0) {
       gclog_or_tty->print_cr("Marking stack overflow (benign) "
-        "(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT
-        ", kac_preclean="SIZE_FORMAT")",
+        "(pmc_pc=" SIZE_FORMAT ", pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT
+        ", kac_preclean=" SIZE_FORMAT ")",
         _ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw,
         _ser_kac_ovflw, _ser_kac_preclean_ovflw);
     }
@@ -4395,7 +4397,7 @@
   if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
     if (PrintCMSStatistics != 0) {
       gclog_or_tty->print_cr("Work queue overflow (benign) "
-        "(pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
+        "(pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT ")",
         _par_pmc_remark_ovflw, _par_kac_ovflw);
     }
     _par_pmc_remark_ovflw = 0;
@@ -4403,12 +4405,12 @@
   }
   if (PrintCMSStatistics != 0) {
      if (_markStack._hit_limit > 0) {
-       gclog_or_tty->print_cr(" (benign) Hit max stack size limit ("SIZE_FORMAT")",
+       gclog_or_tty->print_cr(" (benign) Hit max stack size limit (" SIZE_FORMAT ")",
                               _markStack._hit_limit);
      }
      if (_markStack._failed_double > 0) {
-       gclog_or_tty->print_cr(" (benign) Failed stack doubling ("SIZE_FORMAT"),"
-                              " current capacity "SIZE_FORMAT,
+       gclog_or_tty->print_cr(" (benign) Failed stack doubling (" SIZE_FORMAT "),"
+                              " current capacity " SIZE_FORMAT,
                               _markStack._failed_double,
                               _markStack.capacity());
      }
@@ -5161,7 +5163,7 @@
                                                &markFromDirtyCardsClosure);
       verify_work_stacks_empty();
       if (PrintCMSStatistics != 0) {
-        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in cms gen) ",
+        gclog_or_tty->print(" (re-scanned " SIZE_FORMAT " dirty cards in cms gen) ",
           markFromDirtyCardsClosure.num_dirty_cards());
       }
     }
@@ -6035,8 +6037,8 @@
   } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
     // Failed to double capacity, continue;
     // we print a detail message only once per CMS cycle.
-    gclog_or_tty->print(" (benign) Failed to expand marking stack from "SIZE_FORMAT"K to "
-            SIZE_FORMAT"K",
+    gclog_or_tty->print(" (benign) Failed to expand marking stack from " SIZE_FORMAT "K to "
+            SIZE_FORMAT "K",
             _capacity / K, new_capacity / K);
   }
 }
@@ -7335,25 +7337,25 @@
     ShouldNotReachHere();
   }
   if (Verbose && PrintGC) {
-    gclog_or_tty->print("Collected "SIZE_FORMAT" objects, " SIZE_FORMAT " bytes",
+    gclog_or_tty->print("Collected " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
                         _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
-    gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects,  "
-                           SIZE_FORMAT" bytes  "
-      "Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
+    gclog_or_tty->print_cr("\nLive " SIZE_FORMAT " objects,  "
+                           SIZE_FORMAT " bytes  "
+      "Already free " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
       _numObjectsLive, _numWordsLive*sizeof(HeapWord),
       _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
     size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree)
                         * sizeof(HeapWord);
-    gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
+    gclog_or_tty->print_cr("Total sweep: " SIZE_FORMAT " bytes", totalBytes);
 
     if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
       size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
       size_t dict_returned_bytes = _sp->dictionary()->sum_dict_returned_bytes();
       size_t returned_bytes = indexListReturnedBytes + dict_returned_bytes;
-      gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returned_bytes);
-      gclog_or_tty->print("   Indexed List Returned "SIZE_FORMAT" bytes",
+      gclog_or_tty->print("Returned " SIZE_FORMAT " bytes", returned_bytes);
+      gclog_or_tty->print("   Indexed List Returned " SIZE_FORMAT " bytes",
         indexListReturnedBytes);
-      gclog_or_tty->print_cr("        Dictionary Returned "SIZE_FORMAT" bytes",
+      gclog_or_tty->print_cr("        Dictionary Returned " SIZE_FORMAT " bytes",
         dict_returned_bytes);
     }
   }
@@ -7432,12 +7434,12 @@
     // 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())));
+             err_msg("freeFinger() " PTR_FORMAT " is out-of-bounds", p2i(freeFinger())));
       flush_cur_free_chunk(freeFinger(),
                            pointer_delta(addr, freeFinger()));
       if (CMSTraceSweeper) {
         gclog_or_tty->print("Sweep: last chunk: ");
-        gclog_or_tty->print("put_free_blk " PTR_FORMAT " ("SIZE_FORMAT") "
+        gclog_or_tty->print("put_free_blk " PTR_FORMAT " (" SIZE_FORMAT ") "
                    "[coalesced:%d]\n",
                    p2i(freeFinger()), pointer_delta(addr, freeFinger()),
                    lastFreeRangeCoalesced() ? 1 : 0);
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1021,7 +1021,7 @@
   to()->set_concurrent_iteration_safe_limit(to()->top());
 
   if (ResizePLAB) {
-    plab_stats()->adjust_desired_plab_sz(active_workers);
+    plab_stats()->adjust_desired_plab_sz();
   }
 
   if (PrintGC && !PrintGCDetails) {
@@ -1059,6 +1059,10 @@
   _gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
 }
 
+size_t ParNewGeneration::desired_plab_sz() {
+  return _plab_stats.desired_plab_sz(GenCollectedHeap::heap()->workers()->active_workers());
+}
+
 static int sum;
 void ParNewGeneration::waste_some_time() {
   for (int i = 0; i < 100; i++) {
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -411,9 +411,7 @@
     return &_plab_stats;
   }
 
-  size_t desired_plab_sz() {
-    return _plab_stats.desired_plab_sz();
-  }
+  size_t desired_plab_sz();
 
   const ParNewTracer* gc_tracer() const {
     return &_gc_tracer;
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -119,7 +119,7 @@
   }
   guarantee(sum_of_reclaimable_bytes == _remaining_reclaimable_bytes,
             err_msg("reclaimable bytes inconsistent, "
-                    "remaining: "SIZE_FORMAT" sum: "SIZE_FORMAT,
+                    "remaining: " SIZE_FORMAT " sum: " SIZE_FORMAT,
                     _remaining_reclaimable_bytes, sum_of_reclaimable_bytes));
 }
 #endif // !PRODUCT
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -92,7 +92,7 @@
     regions_at_put(_curr_index, NULL);
     assert(hr->reclaimable_bytes() <= _remaining_reclaimable_bytes,
            err_msg("remaining reclaimable bytes inconsistent "
-                   "from region: "SIZE_FORMAT" remaining: "SIZE_FORMAT,
+                   "from region: " SIZE_FORMAT " remaining: " SIZE_FORMAT,
                    hr->reclaimable_bytes(), _remaining_reclaimable_bytes));
     _remaining_reclaimable_bytes -= hr->reclaimable_bytes();
     _curr_index += 1;
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -307,7 +307,7 @@
     if (PrintGCDetails && Verbose) {
       // Failed to double capacity, continue;
       gclog_or_tty->print(" (benign) Failed to expand marking stack capacity from "
-                          SIZE_FORMAT"K to " SIZE_FORMAT"K",
+                          SIZE_FORMAT "K to " SIZE_FORMAT "K",
                           _capacity / K, new_capacity / K);
     }
   }
@@ -555,7 +555,7 @@
   _verbose_level = verbose_level;
 
   if (verbose_low()) {
-    gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", "
+    gclog_or_tty->print_cr("[global] init, heap start = " PTR_FORMAT ", "
                            "heap end = " PTR_FORMAT, p2i(_heap_start), p2i(_heap_end));
   }
 
@@ -802,7 +802,7 @@
     // 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,
+           err_msg("only way to get here: _finger: " PTR_FORMAT ", _heap_end: " PTR_FORMAT,
                    p2i(_finger), p2i(_heap_end)));
   }
 }
@@ -1424,7 +1424,7 @@
 
     assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
            err_msg("Preconditions not met - "
-                   "start: "PTR_FORMAT", ntams: "PTR_FORMAT", end: "PTR_FORMAT,
+                   "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".
@@ -1725,10 +1725,10 @@
       }
 
       assert(end_idx <= _card_bm->size(),
-             err_msg("oob: end_idx=  "SIZE_FORMAT", bitmap size= "SIZE_FORMAT,
+             err_msg("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,
+             err_msg("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 */);
@@ -2133,7 +2133,7 @@
       oop obj = oopDesc::load_decode_heap_oop(p);
       if (_cm->verbose_high()) {
         gclog_or_tty->print_cr("\t[%u] we're looking at location "
-                               "*"PTR_FORMAT" = "PTR_FORMAT,
+                               "*" PTR_FORMAT " = " PTR_FORMAT,
                                _task->worker_id(), p2i(p), p2i((void*) obj));
       }
 
@@ -2660,9 +2660,9 @@
       HeapWord*   limit         = curr_region->next_top_at_mark_start();
 
       if (verbose_low()) {
-        gclog_or_tty->print_cr("[%u] curr_region = "PTR_FORMAT" "
-                               "["PTR_FORMAT", "PTR_FORMAT"), "
-                               "limit = "PTR_FORMAT,
+        gclog_or_tty->print_cr("[%u] curr_region = " PTR_FORMAT " "
+                               "[" PTR_FORMAT ", " PTR_FORMAT "), "
+                               "limit = " PTR_FORMAT,
                                worker_id, p2i(curr_region), p2i(bottom), p2i(end), p2i(limit));
       }
 
@@ -2677,7 +2677,7 @@
 
       if (limit > bottom) {
         if (verbose_low()) {
-          gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is not empty, "
+          gclog_or_tty->print_cr("[%u] region " PTR_FORMAT " is not empty, "
                                  "returning it ", worker_id, p2i(curr_region));
         }
         return curr_region;
@@ -2685,7 +2685,7 @@
         assert(limit == bottom,
                "the region limit should be at bottom");
         if (verbose_low()) {
-          gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is empty, "
+          gclog_or_tty->print_cr("[%u] region " PTR_FORMAT " is empty, "
                                  "returning NULL", worker_id, p2i(curr_region));
         }
         // we return NULL and the caller should try calling
@@ -2697,13 +2697,13 @@
       if (verbose_low()) {
         if (curr_region == NULL) {
           gclog_or_tty->print_cr("[%u] found uncommitted region, moving finger, "
-                                 "global finger = "PTR_FORMAT", "
-                                 "our finger = "PTR_FORMAT,
+                                 "global finger = " PTR_FORMAT ", "
+                                 "our finger = " PTR_FORMAT,
                                  worker_id, p2i(_finger), p2i(finger));
         } else {
           gclog_or_tty->print_cr("[%u] somebody else moved the finger, "
-                                 "global finger = "PTR_FORMAT", "
-                                 "our finger = "PTR_FORMAT,
+                                 "global finger = " PTR_FORMAT ", "
+                                 "our finger = " PTR_FORMAT,
                                  worker_id, p2i(_finger), p2i(finger));
         }
       }
@@ -2739,7 +2739,7 @@
 
   void do_object_work(oop obj) {
     guarantee(!_g1h->obj_in_cs(obj),
-              err_msg("obj: "PTR_FORMAT" in CSet, phase: %s, info: %d",
+              err_msg("obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
                       p2i((void*) obj), phase_str(), _info));
   }
 
@@ -2800,7 +2800,7 @@
     // 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,
+              err_msg("global finger: " PTR_FORMAT " region: " HR_FORMAT,
                       p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
   }
 
@@ -2814,7 +2814,7 @@
       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,
+                err_msg("task finger: " PTR_FORMAT " region: " HR_FORMAT,
                         p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
     }
   }
@@ -2856,8 +2856,8 @@
 
     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,
+                   "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");
@@ -3118,7 +3118,7 @@
 #ifndef PRODUCT
 // for debugging purposes
 void ConcurrentMark::print_finger() {
-  gclog_or_tty->print_cr("heap ["PTR_FORMAT", "PTR_FORMAT"), global finger = "PTR_FORMAT,
+  gclog_or_tty->print_cr("heap [" PTR_FORMAT ", " PTR_FORMAT "), global finger = " PTR_FORMAT,
                          p2i(_heap_start), p2i(_heap_end), p2i(_finger));
   for (uint i = 0; i < _max_worker_id; ++i) {
     gclog_or_tty->print("   %u: " PTR_FORMAT, i, p2i(_tasks[i]->finger()));
@@ -3203,7 +3203,7 @@
         "claim_region() should have filtered out continues humongous regions");
 
   if (_cm->verbose_low()) {
-    gclog_or_tty->print_cr("[%u] setting up for region "PTR_FORMAT,
+    gclog_or_tty->print_cr("[%u] setting up for region " PTR_FORMAT,
                            _worker_id, p2i(hr));
   }
 
@@ -3220,7 +3220,7 @@
   if (limit == bottom) {
     if (_cm->verbose_low()) {
       gclog_or_tty->print_cr("[%u] found an empty region "
-                             "["PTR_FORMAT", "PTR_FORMAT")",
+                             "[" PTR_FORMAT ", " PTR_FORMAT ")",
                              _worker_id, p2i(bottom), p2i(limit));
     }
     // The region was collected underneath our feet.
@@ -3252,7 +3252,7 @@
 void CMTask::giveup_current_region() {
   assert(_curr_region != NULL, "invariant");
   if (_cm->verbose_low()) {
-    gclog_or_tty->print_cr("[%u] giving up region "PTR_FORMAT,
+    gclog_or_tty->print_cr("[%u] giving up region " PTR_FORMAT,
                            _worker_id, p2i(_curr_region));
   }
   clear_region_fields();
@@ -3374,7 +3374,7 @@
 
   if (_cm->verbose_medium()) {
       gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, "
-                        "scanned = "SIZE_FORMAT"%s, refs reached = "SIZE_FORMAT"%s",
+                        "scanned = " SIZE_FORMAT "%s, refs reached = " SIZE_FORMAT "%s",
                         _worker_id, last_interval_ms,
                         _words_scanned,
                         (_words_scanned >= _words_scanned_limit) ? " (*)" : "",
@@ -3543,7 +3543,7 @@
       statsOnly( ++_local_pops );
 
       if (_cm->verbose_high()) {
-        gclog_or_tty->print_cr("[%u] popped "PTR_FORMAT, _worker_id,
+        gclog_or_tty->print_cr("[%u] popped " PTR_FORMAT, _worker_id,
                                p2i((void*) obj));
       }
 
@@ -3900,8 +3900,8 @@
 
       if (_cm->verbose_low()) {
         gclog_or_tty->print_cr("[%u] we're scanning part "
-                               "["PTR_FORMAT", "PTR_FORMAT") "
-                               "of region "HR_FORMAT,
+                               "[" PTR_FORMAT ", " PTR_FORMAT ") "
+                               "of region " HR_FORMAT,
                                _worker_id, p2i(_finger), p2i(_region_limit),
                                HR_FORMAT_PARAMS(_curr_region));
       }
@@ -3988,7 +3988,7 @@
 
         if (_cm->verbose_low()) {
           gclog_or_tty->print_cr("[%u] we successfully claimed "
-                                 "region "PTR_FORMAT,
+                                 "region " PTR_FORMAT,
                                  _worker_id, p2i(claimed_region));
         }
 
@@ -4049,7 +4049,7 @@
 
       if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) {
         if (_cm->verbose_medium()) {
-          gclog_or_tty->print_cr("[%u] stolen "PTR_FORMAT" successfully",
+          gclog_or_tty->print_cr("[%u] stolen " PTR_FORMAT " successfully",
                                  _worker_id, p2i((void*) obj));
         }
 
@@ -4257,7 +4257,7 @@
 // identify them easily in a large log file.
 #define G1PPRL_LINE_PREFIX            "###"
 
-#define G1PPRL_ADDR_BASE_FORMAT    " "PTR_FORMAT"-"PTR_FORMAT
+#define G1PPRL_ADDR_BASE_FORMAT    " " PTR_FORMAT "-" PTR_FORMAT
 #ifdef _LP64
 #define G1PPRL_ADDR_BASE_H_FORMAT  " %37s"
 #else // _LP64
@@ -4267,16 +4267,16 @@
 // For per-region info
 #define G1PPRL_TYPE_FORMAT            "   %-4s"
 #define G1PPRL_TYPE_H_FORMAT          "   %4s"
-#define G1PPRL_BYTE_FORMAT            "  "SIZE_FORMAT_W(9)
+#define G1PPRL_BYTE_FORMAT            "  " SIZE_FORMAT_W(9)
 #define G1PPRL_BYTE_H_FORMAT          "  %9s"
 #define G1PPRL_DOUBLE_FORMAT          "  %14.1f"
 #define G1PPRL_DOUBLE_H_FORMAT        "  %14s"
 
 // For summary info
-#define G1PPRL_SUM_ADDR_FORMAT(tag)    "  "tag":"G1PPRL_ADDR_BASE_FORMAT
-#define G1PPRL_SUM_BYTE_FORMAT(tag)    "  "tag": "SIZE_FORMAT
-#define G1PPRL_SUM_MB_FORMAT(tag)      "  "tag": %1.2f MB"
-#define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag)" / %1.2f %%"
+#define G1PPRL_SUM_ADDR_FORMAT(tag)    "  " tag ":" G1PPRL_ADDR_BASE_FORMAT
+#define G1PPRL_SUM_BYTE_FORMAT(tag)    "  " tag ": " SIZE_FORMAT
+#define G1PPRL_SUM_MB_FORMAT(tag)      "  " tag ": %1.2f MB"
+#define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag) " / %1.2f %%"
 
 G1PrintRegionLivenessInfoClosure::
 G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -197,8 +197,8 @@
   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)",                        \
+         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)));
 
 inline void CMBitMap::mark(HeapWord* addr) {
@@ -344,7 +344,7 @@
 
 inline void CMTask::deal_with_reference(oop obj) {
   if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
+    gclog_or_tty->print_cr("[%u] we're dealing with reference = " PTR_FORMAT,
                            _worker_id, p2i((void*) obj));
   }
 
@@ -393,7 +393,7 @@
   // 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,
+         err_msg("size: " SIZE_FORMAT " capacity: " SIZE_FORMAT " " HR_FORMAT,
                  word_size * HeapWordSize, hr->capacity(),
                  HR_FORMAT_PARAMS(hr)));
 
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -44,8 +44,7 @@
 ConcurrentMarkThread::ConcurrentMarkThread(ConcurrentMark* cm) :
   ConcurrentGCThread(),
   _cm(cm),
-  _started(false),
-  _in_progress(false),
+  _state(Idle),
   _vtime_accum(0.0),
   _vtime_mark_accum(0.0) {
 
@@ -307,7 +306,6 @@
 
   if (started()) {
     set_in_progress();
-    clear_started();
   }
 }
 
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -47,8 +47,14 @@
 
  private:
   ConcurrentMark*                  _cm;
-  volatile bool                    _started;
-  volatile bool                    _in_progress;
+
+  enum State {
+    Idle,
+    Started,
+    InProgress
+  };
+
+  volatile State _state;
 
   void sleepBeforeNextCycle();
 
@@ -68,23 +74,22 @@
 
   ConcurrentMark* cm()     { return _cm; }
 
-  void set_started()       { assert(!_in_progress, "cycle in progress"); _started = true;  }
-  void clear_started()     { assert(_in_progress, "must be starting a cycle"); _started = false; }
-  bool started()           { return _started;  }
+  void set_idle()          { assert(_state != Started, "must not be starting a new cycle"); _state = Idle; }
+  bool idle()              { return _state == Idle; }
+  void set_started()       { assert(_state == Idle, "cycle in progress"); _state = Started; }
+  bool started()           { return _state == Started; }
+  void set_in_progress()   { assert(_state == Started, "must be starting a cycle"); _state = InProgress; }
+  bool in_progress()       { return _state == InProgress; }
 
-  void set_in_progress()   { assert(_started, "must be starting a cycle"); _in_progress = true;  }
-  void clear_in_progress() { assert(!_started, "must not be starting a new cycle"); _in_progress = false; }
-  bool in_progress()       { return _in_progress;  }
-
-  // This flag returns true from the moment a marking cycle is
+  // Returns true from the moment a marking cycle is
   // initiated (during the initial-mark pause when started() is set)
   // to the moment when the cycle completes (just after the next
   // marking bitmap has been cleared and in_progress() is
-  // cleared). While this flag is true we will not start another cycle
+  // cleared). While during_cycle() is true we will not start another cycle
   // so that cycles do not overlap. We cannot use just in_progress()
   // as the CM thread might take some time to wake up before noticing
   // that started() is set and set in_progress().
-  bool during_cycle()      { return started() || in_progress(); }
+  bool during_cycle()      { return !idle(); }
 
   // shutdown
   void stop();
--- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -140,7 +140,7 @@
 }
 
 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,
+  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);
 }
@@ -217,7 +217,7 @@
 
     if (G1_ALLOC_REGION_TRACING > 1) {
       if (result != NULL) {
-        jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT" "PTR_FORMAT,
+        jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT " " PTR_FORMAT,
                      word_size, result);
       } else if (word_size != 0) {
         jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT, word_size);
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -86,7 +86,7 @@
                             &_retained_old_gc_alloc_region);
 }
 
-void G1DefaultAllocator::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) {
+void G1DefaultAllocator::release_gc_alloc_regions(EvacuationInfo& evacuation_info) {
   AllocationContext_t context = AllocationContext::current();
   evacuation_info.set_allocation_regions(survivor_gc_alloc_region(context)->count() +
                                          old_gc_alloc_region(context)->count());
@@ -102,8 +102,8 @@
   }
 
   if (ResizePLAB) {
-    _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz(no_of_gc_workers);
-    _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz(no_of_gc_workers);
+    _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz();
+    _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz();
   }
 }
 
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -53,7 +53,7 @@
    virtual void release_mutator_alloc_region() = 0;
 
    virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
-   virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) = 0;
+   virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
    virtual void abandon_gc_alloc_regions() = 0;
 
    virtual MutatorAllocRegion*    mutator_alloc_region(AllocationContext_t context) = 0;
@@ -76,7 +76,7 @@
 
    void decrease_used(size_t bytes) {
      assert(_summary_bytes_used >= bytes,
-            err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" should be >= bytes: "SIZE_FORMAT,
+            err_msg("invariant: _summary_bytes_used: " SIZE_FORMAT " should be >= bytes: " SIZE_FORMAT,
                 _summary_bytes_used, bytes));
      _summary_bytes_used -= bytes;
    }
@@ -114,7 +114,7 @@
   virtual void release_mutator_alloc_region();
 
   virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
-  virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
+  virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info);
   virtual void abandon_gc_alloc_regions();
 
   virtual bool is_retained_old_region(HeapRegion* hr) {
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -36,19 +36,19 @@
 #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(), err_msg("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()));
+    err_msg("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()));
+    err_msg("Biased index out of inclusive bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT, biased_index, bias(), length()));
 }
 
 class TestMappedArray : public G1BiasedMappedArray<int> {
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -71,10 +71,10 @@
     assert(is_power_of_2(mapping_granularity_in_bytes),
       err_msg("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,
+      err_msg("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,
+      err_msg("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;
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -69,10 +69,10 @@
 #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,
+         err_msg("%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
+         err_msg("Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
                  " (%u) is not in committed area.",
                  (index),
                  p2i(address_for_index_raw(index)),
@@ -430,11 +430,11 @@
 G1BlockOffsetArray::print_on(outputStream* out) {
   size_t from_index = _array->index_for(_bottom);
   size_t to_index = _array->index_for(_end);
-  out->print_cr(">> BOT for area ["PTR_FORMAT","PTR_FORMAT") "
-                "cards ["SIZE_FORMAT","SIZE_FORMAT")",
+  out->print_cr(">> BOT for area [" PTR_FORMAT "," PTR_FORMAT ") "
+                "cards [" SIZE_FORMAT "," SIZE_FORMAT ")",
                 p2i(_bottom), p2i(_end), from_index, to_index);
   for (size_t i = from_index; i < to_index; ++i) {
-    out->print_cr("  entry "SIZE_FORMAT_W(8)" | "PTR_FORMAT" : %3u",
+    out->print_cr("  entry " SIZE_FORMAT_W(8) " | " PTR_FORMAT " : %3u",
                   i, p2i(_array->address_for_index(i)),
                   (uint) _array->offset_array(i));
   }
@@ -514,7 +514,7 @@
 void
 G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
   G1BlockOffsetArray::print_on(out);
-  out->print_cr("  next offset threshold: "PTR_FORMAT, p2i(_next_offset_threshold));
-  out->print_cr("  next offset index:     "SIZE_FORMAT, _next_offset_index);
+  out->print_cr("  next offset threshold: " PTR_FORMAT, p2i(_next_offset_threshold));
+  out->print_cr("  next offset index:     " SIZE_FORMAT, _next_offset_index);
 }
 #endif // !PRODUCT
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -150,7 +150,7 @@
   void check_offset(size_t offset, const char* msg) const {
     assert(offset <= N_words,
            err_msg("%s - "
-                   "offset: " SIZE_FORMAT", N_words: %u",
+                   "offset: " SIZE_FORMAT ", N_words: %u",
                    msg, offset, (uint)N_words));
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1CardCounts.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CardCounts.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -53,7 +53,7 @@
 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,
+           err_msg("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,7 +96,7 @@
   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")",
+           err_msg("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) {
--- a/hotspot/src/share/vm/gc/g1/g1CardCounts.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CardCounts.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -91,7 +91,7 @@
 
   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));
+           err_msg("card num out of range: " SIZE_FORMAT, card_num));
     return (jbyte*) (_ct_bot + card_num);
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -350,11 +350,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()));
+          err_msg("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()));
+          SIZE_FORMAT " elements", set1.length()));
 
       const size_t num_to_add = (size_t)G1CodeRootSet::Threshold + 1;
 
@@ -363,14 +363,14 @@
       }
       assert(set1.length() == 1,
           err_msg("Duplicate detection should not have increased the set size but "
-              "is "SIZE_FORMAT, set1.length()));
+              "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,
+          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()));
 
       assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
@@ -385,7 +385,7 @@
         }
       }
       assert(num_popped == num_to_add,
-          err_msg("Managed to pop "SIZE_FORMAT" code roots, but only "SIZE_FORMAT" "
+          err_msg("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");
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -197,7 +197,7 @@
   HeapRegion* last = NULL;
   while (curr != NULL) {
     if (!curr->is_young()) {
-      gclog_or_tty->print_cr("### YOUNG REGION "PTR_FORMAT"-"PTR_FORMAT" "
+      gclog_or_tty->print_cr("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
                              "incorrectly tagged (y: %d, surv: %d)",
                              p2i(curr->bottom()), p2i(curr->end()),
                              curr->is_young(), curr->is_survivor());
@@ -326,7 +326,7 @@
     if (curr == NULL)
       gclog_or_tty->print_cr("  empty");
     while (curr != NULL) {
-      gclog_or_tty->print_cr("  "HR_FORMAT", P: "PTR_FORMAT ", N: "PTR_FORMAT", age: %4d",
+      gclog_or_tty->print_cr("  " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
                              HR_FORMAT_PARAMS(curr),
                              p2i(curr->prev_top_at_mark_start()),
                              p2i(curr->next_top_at_mark_start()),
@@ -430,7 +430,7 @@
       HeapRegion* res = _hrm.allocate_free_region(is_old);
       if (G1ConcRegionFreeingVerbose) {
         gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
-                               "allocated "HR_FORMAT" from secondary_free_list",
+                               "allocated " HR_FORMAT " from secondary_free_list",
                                HR_FORMAT_PARAMS(res));
       }
       return res;
@@ -1670,8 +1670,8 @@
   // 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,
+         err_msg("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
@@ -2332,7 +2332,7 @@
   virtual bool doHeapRegion(HeapRegion* hr) {
     unsigned region_gc_time_stamp = hr->get_gc_time_stamp();
     if (_gc_time_stamp != region_gc_time_stamp) {
-      gclog_or_tty->print_cr("Region "HR_FORMAT" has GC time stamp = %d, "
+      gclog_or_tty->print_cr("Region " HR_FORMAT " has GC time stamp = %d, "
                              "expected %d", HR_FORMAT_PARAMS(hr),
                              region_gc_time_stamp, _gc_time_stamp);
       _failures = true;
@@ -2487,7 +2487,7 @@
   // is set) so that if a waiter requests another System.gc() it doesn't
   // incorrectly see that a marking cycle is still in progress.
   if (concurrent) {
-    _cmThread->clear_in_progress();
+    _cmThread->set_idle();
   }
 
   // This notify_all() will ensure that a thread that called
@@ -2926,10 +2926,10 @@
     if (!oopDesc::is_null(heap_oop)) {
       oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
       if (_g1h->is_obj_dead_cond(obj, _vo)) {
-        gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
-                               "points to dead obj "PTR_FORMAT, p2i(p), p2i(obj));
+        gclog_or_tty->print_cr("Root location " PTR_FORMAT " "
+                               "points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
         if (_vo == VerifyOption_G1UseMarkWord) {
-          gclog_or_tty->print_cr("  Mark word: "INTPTR_FORMAT, (intptr_t)obj->mark());
+          gclog_or_tty->print_cr("  Mark word: " INTPTR_FORMAT, (intptr_t)obj->mark());
         }
         obj->print_on(gclog_or_tty);
         _failures = true;
@@ -2976,9 +2976,9 @@
       // Verify that the strong code root list for this region
       // contains the nmethod
       if (!hrrs->strong_code_roots_list_contains(_nm)) {
-        gclog_or_tty->print_cr("Code root location "PTR_FORMAT" "
-                               "from nmethod "PTR_FORMAT" not in strong "
-                               "code roots for region ["PTR_FORMAT","PTR_FORMAT")",
+        gclog_or_tty->print_cr("Code root location " PTR_FORMAT " "
+                               "from nmethod " PTR_FORMAT " not in strong "
+                               "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
                                p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
         _failures = true;
       }
@@ -3157,9 +3157,9 @@
         r->object_iterate(&not_dead_yet_cl);
         if (_vo != VerifyOption_G1UseNextMarking) {
           if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
-            gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] "
-                                   "max_live_bytes "SIZE_FORMAT" "
-                                   "< calculated "SIZE_FORMAT,
+            gclog_or_tty->print_cr("[" PTR_FORMAT "," PTR_FORMAT "] "
+                                   "max_live_bytes " SIZE_FORMAT " "
+                                   "< calculated " SIZE_FORMAT,
                                    p2i(r->bottom()), p2i(r->end()),
                                    r->max_live_bytes(),
                                  not_dead_yet_cl.live_bytes());
@@ -3444,7 +3444,7 @@
     size_t occupied = hrrs->occupied();
     _occupied_sum += occupied;
 
-    gclog_or_tty->print_cr("Printing RSet for region "HR_FORMAT,
+    gclog_or_tty->print_cr("Printing RSet for region " HR_FORMAT,
                            HR_FORMAT_PARAMS(r));
     if (occupied == 0) {
       gclog_or_tty->print_cr("  RSet is empty");
@@ -3463,7 +3463,7 @@
   }
 
   ~PrintRSetsClosure() {
-    gclog_or_tty->print_cr("Occupied Sum: "SIZE_FORMAT, _occupied_sum);
+    gclog_or_tty->print_cr("Occupied Sum: " SIZE_FORMAT, _occupied_sum);
     gclog_or_tty->print_cr("========================================");
     gclog_or_tty->cr();
   }
@@ -4273,7 +4273,7 @@
 void G1CollectedHeap::remove_self_forwarding_pointers() {
   double remove_self_forwards_start = os::elapsedTime();
 
-  G1ParRemoveSelfForwardPtrsTask rsfp_task(this);
+  G1ParRemoveSelfForwardPtrsTask rsfp_task;
   workers()->run_task(&rsfp_task);
 
   // Now restore saved marks, if any.
@@ -4308,7 +4308,7 @@
 G1CollectedHeap::handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_state,
                                                oop old) {
   assert(obj_in_cs(old),
-         err_msg("obj: "PTR_FORMAT" should still be in the CSet",
+         err_msg("obj: " PTR_FORMAT " should still be in the CSet",
                  p2i(old)));
   markOop m = old->mark();
   oop forward_ptr = old->forward_to_atomic(old);
@@ -4342,7 +4342,7 @@
     // space for this object (old != forward_ptr) or they beat us in
     // self-forwarding it (old == forward_ptr).
     assert(old == forward_ptr || !obj_in_cs(forward_ptr),
-           err_msg("obj: "PTR_FORMAT" forwarded to: "PTR_FORMAT" "
+           err_msg("obj: " PTR_FORMAT " forwarded to: " PTR_FORMAT " "
                    "should not be in the CSet",
                    p2i(old), p2i(forward_ptr)));
     return forward_ptr;
@@ -4730,8 +4730,8 @@
 
     if (G1TraceStringSymbolTableScrubbing) {
       gclog_or_tty->print_cr("Cleaned string and symbol table, "
-                             "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, "
-                             "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed",
+                             "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
+                             "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
                              strings_processed(), strings_removed(),
                              symbols_processed(), symbols_removed());
     }
@@ -5644,7 +5644,7 @@
     phase_times->record_string_dedup_fixup_time(fixup_time_ms);
   }
 
-  _allocator->release_gc_alloc_regions(n_workers, evacuation_info);
+  _allocator->release_gc_alloc_regions(evacuation_info);
   g1_rem_set()->cleanup_after_oops_into_collection_set_do();
 
   // Reset and re-enable the hot card cache.
@@ -5828,13 +5828,13 @@
 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)));
+            err_msg("tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end)));
   HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
   if (result < end) {
     gclog_or_tty->cr();
-    gclog_or_tty->print_cr("## wrong marked address on %s bitmap: "PTR_FORMAT,
+    gclog_or_tty->print_cr("## wrong marked address on %s bitmap: " PTR_FORMAT,
                            bitmap_name, p2i(result));
-    gclog_or_tty->print_cr("## %s tams: "PTR_FORMAT" end: "PTR_FORMAT,
+    gclog_or_tty->print_cr("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT,
                            bitmap_name, p2i(tams), p2i(end));
     return false;
   }
@@ -5860,7 +5860,7 @@
     res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end);
   }
   if (!res_p || !res_n) {
-    gclog_or_tty->print_cr("#### Bitmap verification failed for "HR_FORMAT,
+    gclog_or_tty->print_cr("#### Bitmap verification failed for " HR_FORMAT,
                            HR_FORMAT_PARAMS(hr));
     gclog_or_tty->print_cr("#### Caller: %s", caller);
     return false;
@@ -6157,7 +6157,7 @@
         !r->rem_set()->is_empty()) {
 
       if (G1TraceEagerReclaimHumongousObjects) {
-        gclog_or_tty->print_cr("Live 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",
+        gclog_or_tty->print_cr("Live 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",
                                region_idx,
                                (size_t)obj->size() * HeapWordSize,
                                p2i(r->bottom()),
@@ -6179,7 +6179,7 @@
                       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",
+      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",
                              region_idx,
                              (size_t)obj->size() * HeapWordSize,
                              p2i(r->bottom()),
@@ -6333,7 +6333,7 @@
   NoYoungRegionsClosure() : _success(true) { }
   bool doHeapRegion(HeapRegion* r) {
     if (r->is_young()) {
-      gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young",
+      gclog_or_tty->print_cr("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
                              p2i(r->bottom()), p2i(r->end()));
       _success = false;
     }
@@ -6470,7 +6470,7 @@
   }
   assert(_allocator->used_unlocked() == recalculate_used(),
          err_msg("inconsistent _allocator->used_unlocked(), "
-                 "value: "SIZE_FORMAT" recalculated: "SIZE_FORMAT,
+                 "value: " SIZE_FORMAT " recalculated: " SIZE_FORMAT,
                  _allocator->used_unlocked(), recalculate_used()));
 }
 
@@ -6697,8 +6697,8 @@
       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,
+             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())));
 
       // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries.
@@ -6724,8 +6724,8 @@
       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,
+             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())));
 
       hr->remove_strong_code_root(_nm);
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -281,7 +281,7 @@
   void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
 
   // It releases the GC alloc regions at the end of a GC.
-  void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
+  void release_gc_alloc_regions(EvacuationInfo& evacuation_info);
 
   // It does any cleanup that needs to be done on the GC alloc regions
   // before a Full GC.
@@ -1109,6 +1109,8 @@
   // The STW reference processor....
   ReferenceProcessor* ref_processor_stw() const { return _ref_processor_stw; }
 
+  G1NewTracer* gc_tracer_stw() const { return _gc_tracer_stw; }
+
   // The Concurrent Marking reference processor...
   ReferenceProcessor* ref_processor_cm() const { return _ref_processor_cm; }
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -49,7 +49,7 @@
 }
 
 size_t G1CollectedHeap::desired_plab_sz(InCSetState dest) {
-  size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz();
+  size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz(G1CollectedHeap::heap()->workers()->active_workers());
   // Prevent humongous PLAB sizes for two reasons:
   // * PLABs are allocated using a similar paths as oops, but should
   //   never be in a humongous region
@@ -82,7 +82,7 @@
 
 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")",
+         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())));
   return (uint)(pointer_delta(addr, reserved_region().start(), sizeof(uint8_t)) >> HeapRegion::LogOfHRGrainBytes);
 }
@@ -95,7 +95,7 @@
 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")",
+      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())));
   return _hrm.addr_to_region((HeapWord*) addr);
 }
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -184,7 +184,7 @@
   const size_t region_size = HeapRegion::GrainWords;
   if (YoungPLABSize > region_size || OldPLABSize > region_size) {
     char buffer[128];
-    jio_snprintf(buffer, sizeof(buffer), "%sPLABSize should be at most "SIZE_FORMAT,
+    jio_snprintf(buffer, sizeof(buffer), "%sPLABSize should be at most " SIZE_FORMAT,
                  OldPLABSize > region_size ? "Old" : "Young", region_size);
     vm_exit_during_initialization(buffer);
   }
@@ -821,7 +821,7 @@
   update_survivors_policy();
 
   assert(_g1->used() == _g1->recalculate_used(),
-         err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
+         err_msg("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;
@@ -865,7 +865,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, true);
+  _mmu_tracker->add_pause(_mark_remark_start_sec, end_time_sec, _g1->gc_tracer_cm()->gc_id());
 }
 
 void G1CollectorPolicy::record_concurrent_mark_cleanup_start() {
@@ -961,7 +961,7 @@
   }
 
   _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
-                          end_time_sec, false);
+                          end_time_sec, _g1->gc_tracer_stw()->gc_id());
 
   evacuation_info.set_collectionset_used_before(_collection_set_bytes_used_before);
   evacuation_info.set_bytes_copied(_bytes_copied_during_gc);
@@ -1216,10 +1216,10 @@
     (_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
 
   gclog_or_tty->print(
-    "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
-    "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
-    "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
-    EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
+    "   [Eden: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->" EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ") "
+    "Survivors: " EXT_SIZE_FORMAT "->" EXT_SIZE_FORMAT " "
+    "Heap: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->"
+    EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")]",
     EXT_SIZE_PARAMS(_eden_used_bytes_before_gc),
     EXT_SIZE_PARAMS(_eden_capacity_bytes_before_gc),
     EXT_SIZE_PARAMS(eden_used_bytes_after_gc),
@@ -1597,7 +1597,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, true);
+  _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, _g1->gc_tracer_cm()->gc_id());
 }
 
 // Add the heap region at the head of the non-incremental collection set
@@ -1787,7 +1787,7 @@
   while (csr != NULL) {
     HeapRegion* next = csr->next_in_collection_set();
     assert(csr->in_collection_set(), "bad CS");
-    st->print_cr("  "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
+    st->print_cr("  " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
                  HR_FORMAT_PARAMS(csr),
                  p2i(csr->prev_top_at_mark_start()), p2i(csr->next_top_at_mark_start()),
                  csr->age_in_surv_rate_group_cond());
--- a/hotspot/src/share/vm/gc/g1/g1ErgoVerbose.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1ErgoVerbose.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -121,15 +121,15 @@
 // Single parameter format strings
 #define ergo_format_str(_name_)      ", " _name_ ": %s"
 #define ergo_format_region(_name_)   ", " _name_ ": %u regions"
-#define ergo_format_byte(_name_)     ", " _name_ ": "SIZE_FORMAT" bytes"
+#define ergo_format_byte(_name_)     ", " _name_ ": " SIZE_FORMAT " bytes"
 #define ergo_format_double(_name_)   ", " _name_ ": %1.2f"
 #define ergo_format_perc(_name_)     ", " _name_ ": %1.2f %%"
 #define ergo_format_ms(_name_)       ", " _name_ ": %1.2f ms"
-#define ergo_format_size(_name_)     ", " _name_ ": "SIZE_FORMAT
+#define ergo_format_size(_name_)     ", " _name_ ": " SIZE_FORMAT
 
 // Double parameter format strings
 #define ergo_format_byte_perc(_name_)                                   \
-                             ", " _name_ ": "SIZE_FORMAT" bytes (%1.2f %%)"
+                             ", " _name_ ": " SIZE_FORMAT " bytes (%1.2f %%)"
 
 // Generates the format string
 #define ergo_format(_extra_format_)                           \
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -40,8 +40,8 @@
   G1SATBCardTableModRefBS* _ct_bs;
 
 public:
-  UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
-    _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
+  UpdateRSetDeferred(DirtyCardQueue* dcq) :
+    _g1(G1CollectedHeap::heap()), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
 
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   virtual void do_oop(      oop* p) { do_oop_work(p); }
@@ -65,60 +65,41 @@
   size_t _marked_bytes;
   OopsInHeapRegionClosure *_update_rset_cl;
   bool _during_initial_mark;
-  bool _during_conc_mark;
   uint _worker_id;
-  HeapWord* _end_of_last_gap;
-  HeapWord* _last_gap_threshold;
-  HeapWord* _last_obj_threshold;
+  HeapWord* _last_forwarded_object_end;
 
 public:
-  RemoveSelfForwardPtrObjClosure(G1CollectedHeap* g1, ConcurrentMark* cm,
-                                 HeapRegion* hr,
+  RemoveSelfForwardPtrObjClosure(HeapRegion* hr,
                                  OopsInHeapRegionClosure* update_rset_cl,
                                  bool during_initial_mark,
-                                 bool during_conc_mark,
                                  uint worker_id) :
-    _g1(g1), _cm(cm), _hr(hr), _marked_bytes(0),
+    _g1(G1CollectedHeap::heap()),
+    _cm(_g1->concurrent_mark()),
+    _hr(hr),
+    _marked_bytes(0),
     _update_rset_cl(update_rset_cl),
     _during_initial_mark(during_initial_mark),
-    _during_conc_mark(during_conc_mark),
     _worker_id(worker_id),
-    _end_of_last_gap(hr->bottom()),
-    _last_gap_threshold(hr->bottom()),
-    _last_obj_threshold(hr->bottom()) { }
+    _last_forwarded_object_end(hr->bottom()) { }
 
   size_t marked_bytes() { return _marked_bytes; }
 
-  // <original comment>
-  // The original idea here was to coalesce evacuated and dead objects.
-  // However that caused complications with the block offset table (BOT).
-  // In particular if there were two TLABs, one of them partially refined.
-  // |----- TLAB_1--------|----TLAB_2-~~~(partially refined part)~~~|
-  // The BOT entries of the unrefined part of TLAB_2 point to the start
-  // of TLAB_2. If the last object of the TLAB_1 and the first object
-  // of TLAB_2 are coalesced, then the cards of the unrefined part
-  // would point into middle of the filler object.
-  // The current approach is to not coalesce and leave the BOT contents intact.
-  // </original comment>
-  //
-  // We now reset the BOT when we start the object iteration over the
-  // region and refine its entries for every object we come across. So
-  // the above comment is not really relevant and we should be able
-  // to coalesce dead objects if we want to.
+  // Iterate over the live objects in the region to find self-forwarded objects
+  // that need to be kept live. We need to update the remembered sets of these
+  // objects. Further update the BOT and marks.
+  // We can coalesce and overwrite the remaining heap contents with dummy objects
+  // as they have either been dead or evacuated (which are unreferenced now, i.e.
+  // dead too) already.
   void do_object(oop obj) {
     HeapWord* obj_addr = (HeapWord*) obj;
     assert(_hr->is_in(obj_addr), "sanity");
     size_t obj_size = obj->size();
     HeapWord* obj_end = obj_addr + obj_size;
 
-    if (_end_of_last_gap != obj_addr) {
-      // there was a gap before obj_addr
-      _last_gap_threshold = _hr->cross_threshold(_end_of_last_gap, obj_addr);
-    }
-
     if (obj->is_forwarded() && obj->forwardee() == obj) {
       // The object failed to move.
 
+      zap_dead_objects(_last_forwarded_object_end, obj_addr);
       // We consider all objects that we find self-forwarded to be
       // live. What we'll do is that we'll update the prev marking
       // info so that they are all under PTAMS and explicitly marked.
@@ -154,24 +135,52 @@
       // remembered set entries missing given that we skipped cards on
       // the collection set. So, we'll recreate such entries now.
       obj->oop_iterate(_update_rset_cl);
-    } else {
+
+      _last_forwarded_object_end = obj_end;
+      _hr->cross_threshold(obj_addr, obj_end);
+    }
+  }
+
+  // Fill the memory area from start to end with filler objects, and update the BOT
+  // and the mark bitmap accordingly.
+  void zap_dead_objects(HeapWord* start, HeapWord* end) {
+    if (start == end) {
+      return;
+    }
+
+    size_t gap_size = pointer_delta(end, start);
+    MemRegion mr(start, gap_size);
+    if (gap_size >= CollectedHeap::min_fill_size()) {
+      CollectedHeap::fill_with_objects(start, gap_size);
 
-      // The object has been either evacuated or is dead. Fill it with a
-      // dummy object.
-      MemRegion mr(obj_addr, obj_size);
-      CollectedHeap::fill_with_object(mr);
+      HeapWord* end_first_obj = start + ((oop)start)->size();
+      _hr->cross_threshold(start, end_first_obj);
+      // Fill_with_objects() may have created multiple (i.e. two)
+      // objects, as the max_fill_size() is half a region.
+      // After updating the BOT for the first object, also update the
+      // BOT for the second object to make the BOT complete.
+      if (end_first_obj != end) {
+        _hr->cross_threshold(end_first_obj, end);
+#ifdef ASSERT
+        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)));
+#endif
+      }
+    }
+    _cm->clearRangePrevBitmap(mr);
+  }
 
-      // must nuke all dead objects which we skipped when iterating over the region
-      _cm->clearRangePrevBitmap(MemRegion(_end_of_last_gap, obj_end));
-    }
-    _end_of_last_gap = obj_end;
-    _last_obj_threshold = _hr->cross_threshold(obj_addr, obj_end);
+  void zap_remainder() {
+    zap_dead_objects(_last_forwarded_object_end, _hr->top());
   }
 };
 
 class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
-  ConcurrentMark* _cm;
   uint _worker_id;
   HeapRegionClaimer* _hrclaimer;
 
@@ -179,11 +188,27 @@
   UpdateRSetDeferred _update_rset_cl;
 
 public:
-  RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h,
-                                uint worker_id,
+  RemoveSelfForwardPtrHRClosure(uint worker_id,
                                 HeapRegionClaimer* hrclaimer) :
-      _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq),
-      _worker_id(worker_id), _cm(_g1h->concurrent_mark()), _hrclaimer(hrclaimer) {
+    _g1h(G1CollectedHeap::heap()),
+    _dcq(&_g1h->dirty_card_queue_set()),
+    _update_rset_cl(&_dcq),
+    _worker_id(worker_id),
+    _hrclaimer(hrclaimer) {
+  }
+
+  size_t remove_self_forward_ptr_by_walking_hr(HeapRegion* hr,
+                                               bool during_initial_mark) {
+    RemoveSelfForwardPtrObjClosure rspc(hr,
+                                        &_update_rset_cl,
+                                        during_initial_mark,
+                                        _worker_id);
+    _update_rset_cl.set_region(hr);
+    hr->object_iterate(&rspc);
+    // Need to zap the remainder area of the processed region.
+    rspc.zap_remainder();
+
+    return rspc.marked_bytes();
   }
 
   bool doHeapRegion(HeapRegion *hr) {
@@ -195,11 +220,6 @@
 
     if (_hrclaimer->claim_region(hr->hrm_index())) {
       if (hr->evacuation_failed()) {
-        RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, &_update_rset_cl,
-                                            during_initial_mark,
-                                            during_conc_mark,
-                                            _worker_id);
-
         hr->note_self_forwarding_removal_start(during_initial_mark,
                                                during_conc_mark);
         _g1h->check_bitmaps("Self-Forwarding Ptr Removal", hr);
@@ -214,26 +234,27 @@
         // whenever this might be required in the future.
         hr->rem_set()->reset_for_par_iteration();
         hr->reset_bot();
-        _update_rset_cl.set_region(hr);
-        hr->object_iterate(&rspc);
+
+        size_t live_bytes = remove_self_forward_ptr_by_walking_hr(hr, during_initial_mark);
 
         hr->rem_set()->clean_strong_code_roots(hr);
 
         hr->note_self_forwarding_removal_end(during_initial_mark,
                                              during_conc_mark,
-                                             rspc.marked_bytes());
+                                             live_bytes);
       }
     }
     return false;
   }
 };
 
-G1ParRemoveSelfForwardPtrsTask::G1ParRemoveSelfForwardPtrsTask(G1CollectedHeap* g1h) :
-    AbstractGangTask("G1 Remove Self-forwarding Pointers"), _g1h(g1h),
-    _hrclaimer(g1h->workers()->active_workers()) {}
+G1ParRemoveSelfForwardPtrsTask::G1ParRemoveSelfForwardPtrsTask() :
+  AbstractGangTask("G1 Remove Self-forwarding Pointers"),
+  _g1h(G1CollectedHeap::heap()),
+  _hrclaimer(_g1h->workers()->active_workers()) { }
 
 void G1ParRemoveSelfForwardPtrsTask::work(uint worker_id) {
-  RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id, &_hrclaimer);
+  RemoveSelfForwardPtrHRClosure rsfp_cl(worker_id, &_hrclaimer);
 
   HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
   _g1h->collection_set_iterate_from(hr, &rsfp_cl);
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -40,7 +40,7 @@
   HeapRegionClaimer _hrclaimer;
 
 public:
-  G1ParRemoveSelfForwardPtrsTask(G1CollectedHeap* g1h);
+  G1ParRemoveSelfForwardPtrsTask();
 
   void work(uint worker_id);
 };
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -331,7 +331,7 @@
 }
 
 void G1GCPhaseTimes::print_stats(int level, const char* str, size_t value) {
-  LineBuffer(level).append_and_print_cr("[%s: "SIZE_FORMAT"]", str, value);
+  LineBuffer(level).append_and_print_cr("[%s: " SIZE_FORMAT "]", str, value);
 }
 
 void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) {
@@ -451,7 +451,7 @@
 
     if (phase->_thread_work_items != NULL) {
       LineBuffer buf2(phase->_thread_work_items->_indent_level);
-      buf2.append_and_print_cr("[%s:  "SIZE_FORMAT"]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id));
+      buf2.append_and_print_cr("[%s:  " SIZE_FORMAT "]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id));
     }
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1HRPrinter.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1HRPrinter.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -83,18 +83,18 @@
 
   if (type_str != NULL) {
     if (top != NULL) {
-      gclog_or_tty->print_cr(G1HR_PREFIX" %s(%s) "PTR_FORMAT" "PTR_FORMAT,
+      gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT " " PTR_FORMAT,
                              action_str, type_str, p2i(bottom), p2i(top));
     } else {
-      gclog_or_tty->print_cr(G1HR_PREFIX" %s(%s) "PTR_FORMAT,
+      gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT,
                              action_str, type_str, p2i(bottom));
     }
   } else {
     if (top != NULL) {
-      gclog_or_tty->print_cr(G1HR_PREFIX" %s "PTR_FORMAT" "PTR_FORMAT,
+      gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT " " PTR_FORMAT,
                              action_str, p2i(bottom), p2i(top));
     } else {
-      gclog_or_tty->print_cr(G1HR_PREFIX" %s "PTR_FORMAT,
+      gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT,
                              action_str, p2i(bottom));
     }
   }
@@ -103,11 +103,11 @@
 void G1HRPrinter::print(ActionType action, HeapWord* bottom, HeapWord* end) {
   const char* action_str = action_name(action);
 
-  gclog_or_tty->print_cr(G1HR_PREFIX" %s ["PTR_FORMAT","PTR_FORMAT"]",
+  gclog_or_tty->print_cr(G1HR_PREFIX " %s [" PTR_FORMAT "," PTR_FORMAT "]",
                          action_str, p2i(bottom), p2i(end));
 }
 
 void G1HRPrinter::print(PhaseType phase, size_t phase_num) {
   const char* phase_str = phase_name(phase);
-  gclog_or_tty->print_cr(G1HR_PREFIX" #%s "SIZE_FORMAT, phase_str, phase_num);
+  gclog_or_tty->print_cr(G1HR_PREFIX " #%s " SIZE_FORMAT, phase_str, phase_num);
 }
--- a/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -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()));
+           err_msg("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()));
+           err_msg("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()));
+           err_msg("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	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1MMUTracker.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/g1/g1MMUTracker.hpp"
+#include "gc/shared/gcTrace.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "utilities/ostream.hpp"
 
@@ -75,7 +76,7 @@
   return gc_time;
 }
 
-void G1MMUTrackerQueue::add_pause(double start, double end, bool gc_thread) {
+void G1MMUTrackerQueue::add_pause(double start, double end, const GCId& gcId) {
   double duration = end - start;
 
   remove_expired_entries(end);
@@ -102,6 +103,10 @@
     ++_no_entries;
   }
   _array[_head_index] = G1MMUTrackerQueueElem(start, end);
+
+  // 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);
 }
 
 // basically the _internal call does not remove expired entries
--- a/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_G1_G1MMUTRACKER_HPP
 #define SHARE_VM_GC_G1_G1MMUTRACKER_HPP
 
+#include "gc/shared/gcId.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/debug.hpp"
 
@@ -42,7 +43,7 @@
 public:
   G1MMUTracker(double time_slice, double max_gc_time);
 
-  virtual void add_pause(double start, double end, bool gc_thread) = 0;
+  virtual void add_pause(double start, double end, const GCId& gcId) = 0;
   virtual double when_sec(double current_time, double pause_time) = 0;
 
   double max_gc_time() {
@@ -126,7 +127,7 @@
 public:
   G1MMUTrackerQueue(double time_slice, double max_gc_time);
 
-  virtual void add_pause(double start, double end, bool gc_thread);
+  virtual void add_pause(double start, double end, const GCId& gcId);
 
   virtual double when_sec(double current_time, double pause_time);
 };
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -118,7 +118,7 @@
   oop obj = oopDesc::load_decode_heap_oop(p);
   if (_cm->verbose_high()) {
     gclog_or_tty->print_cr("[%u] we're looking at location "
-                           "*"PTR_FORMAT" = "PTR_FORMAT,
+                           "*" PTR_FORMAT " = " PTR_FORMAT,
                            _task->worker_id(), p2i(p), p2i((void*) obj));
   }
   _task->deal_with_reference(obj);
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -424,7 +424,7 @@
 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",
+         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)),
--- a/hotspot/src/share/vm/gc/g1/g1RemSetSummary.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSetSummary.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -187,22 +187,22 @@
   size_t code_root_elems() const { return _code_root_elems; }
 
   void print_rs_mem_info_on(outputStream * out, size_t total) {
-    out->print_cr("    "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions",
+    out->print_cr("    " SIZE_FORMAT_W(8) "K (%5.1f%%) by " SIZE_FORMAT " %s regions",
         round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name);
   }
 
   void print_cards_occupied_info_on(outputStream * out, size_t total) {
-    out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) entries by "SIZE_FORMAT" %s regions",
+    out->print_cr("     " SIZE_FORMAT_W(8) " (%5.1f%%) entries by " SIZE_FORMAT " %s regions",
         cards_occupied(), cards_occupied_percent_of(total), amount(), _name);
   }
 
   void print_code_root_mem_info_on(outputStream * out, size_t total) {
-    out->print_cr("    "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions",
+    out->print_cr("    " SIZE_FORMAT_W(8) "K (%5.1f%%) by " SIZE_FORMAT " %s regions",
         round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name);
   }
 
   void print_code_root_elems_info_on(outputStream * out, size_t total) {
-    out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) elements by "SIZE_FORMAT" %s regions",
+    out->print_cr("     " SIZE_FORMAT_W(8) " (%5.1f%%) elements by " SIZE_FORMAT " %s regions",
         code_root_elems(), code_root_elems_percent_of(total), amount(), _name);
   }
 };
@@ -280,19 +280,19 @@
     RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
 
     out->print_cr("\n Current rem set statistics");
-    out->print_cr("  Total per region rem sets sizes = "SIZE_FORMAT"K."
-                  " Max = "SIZE_FORMAT"K.",
+    out->print_cr("  Total per region rem sets sizes = " SIZE_FORMAT "K."
+                  " Max = " SIZE_FORMAT "K.",
                   round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
     for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
       (*current)->print_rs_mem_info_on(out, total_rs_mem_sz());
     }
 
-    out->print_cr("   Static structures = "SIZE_FORMAT"K,"
-                  " free_lists = "SIZE_FORMAT"K.",
+    out->print_cr("   Static structures = " SIZE_FORMAT "K,"
+                  " free_lists = " SIZE_FORMAT "K.",
                   round_to_K(HeapRegionRemSet::static_mem_size()),
                   round_to_K(HeapRegionRemSet::fl_mem_size()));
 
-    out->print_cr("    "SIZE_FORMAT" occupied cards represented.",
+    out->print_cr("    " SIZE_FORMAT " occupied cards represented.",
                   total_cards_occupied());
     for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
       (*current)->print_cards_occupied_info_on(out, total_cards_occupied());
@@ -300,30 +300,30 @@
 
     // Largest sized rem set region statistics
     HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set();
-    out->print_cr("    Region with largest rem set = "HR_FORMAT", "
-                  "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
+    out->print_cr("    Region with largest rem set = " HR_FORMAT ", "
+                  "size = " SIZE_FORMAT "K, occupied = " SIZE_FORMAT "K.",
                   HR_FORMAT_PARAMS(max_rs_mem_sz_region()),
                   round_to_K(rem_set->mem_size()),
                   round_to_K(rem_set->occupied()));
 
     // Strong code root statistics
     HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set();
-    out->print_cr("  Total heap region code root sets sizes = "SIZE_FORMAT"K."
-                  "  Max = "SIZE_FORMAT"K.",
+    out->print_cr("  Total heap region code root sets sizes = " SIZE_FORMAT "K."
+                  "  Max = " SIZE_FORMAT "K.",
                   round_to_K(total_code_root_mem_sz()),
                   round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()));
     for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
       (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz());
     }
 
-    out->print_cr("    "SIZE_FORMAT" code roots represented.",
+    out->print_cr("    " SIZE_FORMAT " code roots represented.",
                   total_code_root_elems());
     for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
       (*current)->print_code_root_elems_info_on(out, total_code_root_elems());
     }
 
-    out->print_cr("    Region with largest amount of code roots = "HR_FORMAT", "
-                  "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
+    out->print_cr("    Region with largest amount of code roots = " HR_FORMAT ", "
+                  "size = " SIZE_FORMAT "K, num_elems = " SIZE_FORMAT ".",
                   HR_FORMAT_PARAMS(max_code_root_mem_sz_region()),
                   round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()),
                   round_to_K(max_code_root_rem_set->strong_code_roots_list_length()));
@@ -332,16 +332,16 @@
 
 void G1RemSetSummary::print_on(outputStream* out) {
   out->print_cr("\n Recent concurrent refinement statistics");
-  out->print_cr("  Processed "SIZE_FORMAT" cards",
+  out->print_cr("  Processed " SIZE_FORMAT " cards",
                 num_concurrent_refined_cards());
-  out->print_cr("  Of "SIZE_FORMAT" completed buffers:", num_processed_buf_total());
-  out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) by concurrent RS threads.",
+  out->print_cr("  Of " SIZE_FORMAT " completed buffers:", num_processed_buf_total());
+  out->print_cr("     " SIZE_FORMAT_W(8) " (%5.1f%%) by concurrent RS threads.",
                 num_processed_buf_total(),
                 percent_of(num_processed_buf_rs_threads(), num_processed_buf_total()));
-  out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) by mutator threads.",
+  out->print_cr("     " SIZE_FORMAT_W(8) " (%5.1f%%) by mutator threads.",
                 num_processed_buf_mutator(),
                 percent_of(num_processed_buf_mutator(), num_processed_buf_total()));
-  out->print_cr("  Did "SIZE_FORMAT" coarsenings.", num_coarsenings());
+  out->print_cr("  Did " SIZE_FORMAT " coarsenings.", num_coarsenings());
   out->print_cr("  Concurrent RS threads times (s)");
   out->print("     ");
   for (uint i = 0; i < _num_vtimes; i++) {
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -155,7 +155,7 @@
 void G1StringDedupQueue::print_statistics(outputStream* st) {
   st->print_cr(
     "   [Queue]\n"
-    "      [Dropped: "UINTX_FORMAT"]", _queue->_dropped);
+    "      [Dropped: " UINTX_FORMAT "]", _queue->_dropped);
 }
 
 void G1StringDedupQueue::verify() {
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupStat.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupStat.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -80,8 +80,8 @@
   st->stamp(PrintGCTimeStamps);
   st->print_cr(
     "[GC concurrent-string-deduplication, "
-    G1_STRDEDUP_BYTES_FORMAT_NS"->"G1_STRDEDUP_BYTES_FORMAT_NS"("G1_STRDEDUP_BYTES_FORMAT_NS"), avg "
-    G1_STRDEDUP_PERCENT_FORMAT_NS", "G1_STRDEDUP_TIME_FORMAT"]",
+    G1_STRDEDUP_BYTES_FORMAT_NS "->" G1_STRDEDUP_BYTES_FORMAT_NS "(" G1_STRDEDUP_BYTES_FORMAT_NS "), avg "
+    G1_STRDEDUP_PERCENT_FORMAT_NS ", " G1_STRDEDUP_TIME_FORMAT "]",
     G1_STRDEDUP_BYTES_PARAM(last_stat._new_bytes),
     G1_STRDEDUP_BYTES_PARAM(last_stat._new_bytes - last_stat._deduped_bytes),
     G1_STRDEDUP_BYTES_PARAM(last_stat._deduped_bytes),
@@ -135,22 +135,22 @@
 
   if (total) {
     st->print_cr(
-      "   [Total Exec: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT", Idle: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT", Blocked: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT"]",
+      "   [Total Exec: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Idle: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
       stat._exec, stat._exec_elapsed, stat._idle, stat._idle_elapsed, stat._block, stat._block_elapsed);
   } else {
     st->print_cr(
-      "   [Last Exec: "G1_STRDEDUP_TIME_FORMAT", Idle: "G1_STRDEDUP_TIME_FORMAT", Blocked: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT"]",
+      "   [Last Exec: " G1_STRDEDUP_TIME_FORMAT ", Idle: " G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
       stat._exec_elapsed, stat._idle_elapsed, stat._block, stat._block_elapsed);
   }
   st->print_cr(
-    "      [Inspected:    "G1_STRDEDUP_OBJECTS_FORMAT"]\n"
-    "         [Skipped:   "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
-    "         [Hashed:    "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
-    "         [Known:     "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
-    "         [New:       "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"]\n"
-    "      [Deduplicated: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
-    "         [Young:     "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
-    "         [Old:       "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]",
+    "      [Inspected:    " G1_STRDEDUP_OBJECTS_FORMAT "]\n"
+    "         [Skipped:   " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
+    "         [Hashed:    " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
+    "         [Known:     " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
+    "         [New:       " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "]\n"
+    "      [Deduplicated: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
+    "         [Young:     " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
+    "         [Old:       " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
     stat._inspected,
     stat._skipped, skipped_percent,
     stat._hashed, hashed_percent,
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -556,12 +556,12 @@
 void G1StringDedupTable::print_statistics(outputStream* st) {
   st->print_cr(
     "   [Table]\n"
-    "      [Memory Usage: "G1_STRDEDUP_BYTES_FORMAT_NS"]\n"
-    "      [Size: "SIZE_FORMAT", Min: "SIZE_FORMAT", Max: "SIZE_FORMAT"]\n"
-    "      [Entries: "UINTX_FORMAT", Load: "G1_STRDEDUP_PERCENT_FORMAT_NS", Cached: " UINTX_FORMAT ", Added: "UINTX_FORMAT", Removed: "UINTX_FORMAT"]\n"
-    "      [Resize Count: "UINTX_FORMAT", Shrink Threshold: "UINTX_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT_NS"), Grow Threshold: "UINTX_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT_NS")]\n"
-    "      [Rehash Count: "UINTX_FORMAT", Rehash Threshold: "UINTX_FORMAT", Hash Seed: 0x%x]\n"
-    "      [Age Threshold: "UINTX_FORMAT"]",
+    "      [Memory Usage: " G1_STRDEDUP_BYTES_FORMAT_NS "]\n"
+    "      [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]\n"
+    "      [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " UINTX_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]\n"
+    "      [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]\n"
+    "      [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]\n"
+    "      [Age Threshold: " UINTX_FORMAT "]",
     G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)),
     _table->_size, _min_size, _max_size,
     _table->_entries, (double)_table->_entries / (double)_table->_size * 100.0, _entry_cache->size(), _entries_added, _entries_removed,
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -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()));
+         err_msg("marked: " SIZE_FORMAT " used: " SIZE_FORMAT, marked_bytes, used()));
   _prev_top_at_mark_start = top();
   _prev_marked_bytes = marked_bytes;
 }
@@ -504,9 +504,9 @@
         // Object is in the region. Check that its less than top
         if (_hr->top() <= (HeapWord*)obj) {
           // Object is above top
-          gclog_or_tty->print_cr("Object "PTR_FORMAT" in region "
-                                 "["PTR_FORMAT", "PTR_FORMAT") is above "
-                                 "top "PTR_FORMAT,
+          gclog_or_tty->print_cr("Object " PTR_FORMAT " in region "
+                                 "[" PTR_FORMAT ", " PTR_FORMAT ") is above "
+                                 "top " PTR_FORMAT,
                                  p2i(obj), p2i(_hr->bottom()), p2i(_hr->end()), p2i(_hr->top()));
           _failures = true;
           return;
@@ -540,22 +540,22 @@
     if (nm != NULL) {
       // Verify that the nemthod is live
       if (!nm->is_alive()) {
-        gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has dead nmethod "
-                               PTR_FORMAT" in its strong code roots",
+        gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod "
+                               PTR_FORMAT " in its strong code roots",
                                p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
         _failures = true;
       } else {
         VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
         nm->oops_do(&oop_cl);
         if (!oop_cl.has_oops_in_region()) {
-          gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has nmethod "
-                                 PTR_FORMAT" in its strong code roots "
+          gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod "
+                                 PTR_FORMAT " in its strong code roots "
                                  "with no pointers into region",
                                  p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
           _failures = true;
         } else if (oop_cl.failures()) {
-          gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has other "
-                                 "failures for nmethod "PTR_FORMAT,
+          gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has other "
+                                 "failures for nmethod " PTR_FORMAT,
                                  p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
           _failures = true;
         }
@@ -589,8 +589,8 @@
   // on its strong code root list
   if (is_empty()) {
     if (strong_code_roots_length > 0) {
-      gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty "
-                             "but has "SIZE_FORMAT" code root entries",
+      gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is empty "
+                             "but has " SIZE_FORMAT " code root entries",
                              p2i(bottom()), p2i(end()), strong_code_roots_length);
       *failures = true;
     }
@@ -599,8 +599,8 @@
 
   if (is_continues_humongous()) {
     if (strong_code_roots_length > 0) {
-      gclog_or_tty->print_cr("region "HR_FORMAT" is a continuation of a humongous "
-                             "region but has "SIZE_FORMAT" code root entries",
+      gclog_or_tty->print_cr("region " HR_FORMAT " is a continuation of a humongous "
+                             "region but has " SIZE_FORMAT " code root entries",
                              HR_FORMAT_PARAMS(this), strong_code_roots_length);
       *failures = true;
     }
@@ -625,7 +625,7 @@
   else
     st->print("   ");
   st->print(" TS %5d", _gc_time_stamp);
-  st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT,
+  st->print(" PTAMS " PTR_FORMAT " NTAMS " PTR_FORMAT,
             p2i(prev_top_at_mark_start()), p2i(next_top_at_mark_start()));
   G1OffsetTableContigSpace::print_on(st);
 }
@@ -686,25 +686,25 @@
         }
         if (!_g1h->is_in_closed_subset(obj)) {
           HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
-          gclog_or_tty->print_cr("Field "PTR_FORMAT
-                                 " of live obj "PTR_FORMAT" in region "
-                                 "["PTR_FORMAT", "PTR_FORMAT")",
+          gclog_or_tty->print_cr("Field " PTR_FORMAT
+                                 " of live obj " PTR_FORMAT " in region "
+                                 "[" PTR_FORMAT ", " PTR_FORMAT ")",
                                  p2i(p), p2i(_containing_obj),
                                  p2i(from->bottom()), p2i(from->end()));
           print_object(gclog_or_tty, _containing_obj);
-          gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
+          gclog_or_tty->print_cr("points to obj " PTR_FORMAT " not in the heap",
                                  p2i(obj));
         } else {
           HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
           HeapRegion* to   = _g1h->heap_region_containing((HeapWord*)obj);
-          gclog_or_tty->print_cr("Field "PTR_FORMAT
-                                 " of live obj "PTR_FORMAT" in region "
-                                 "["PTR_FORMAT", "PTR_FORMAT")",
+          gclog_or_tty->print_cr("Field " PTR_FORMAT
+                                 " of live obj " PTR_FORMAT " in region "
+                                 "[" PTR_FORMAT ", " PTR_FORMAT ")",
                                  p2i(p), p2i(_containing_obj),
                                  p2i(from->bottom()), p2i(from->end()));
           print_object(gclog_or_tty, _containing_obj);
-          gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
-                                 "["PTR_FORMAT", "PTR_FORMAT")",
+          gclog_or_tty->print_cr("points to dead obj " PTR_FORMAT " in region "
+                                 "[" PTR_FORMAT ", " PTR_FORMAT ")",
                                  p2i(obj), p2i(to->bottom()), p2i(to->end()));
           print_object(gclog_or_tty, obj);
         }
@@ -740,14 +740,14 @@
               gclog_or_tty->print_cr("----------");
             }
             gclog_or_tty->print_cr("Missing rem set entry:");
-            gclog_or_tty->print_cr("Field "PTR_FORMAT" "
-                                   "of obj "PTR_FORMAT", "
-                                   "in region "HR_FORMAT,
+            gclog_or_tty->print_cr("Field " PTR_FORMAT " "
+                                   "of obj " PTR_FORMAT ", "
+                                   "in region " HR_FORMAT,
                                    p2i(p), p2i(_containing_obj),
                                    HR_FORMAT_PARAMS(from));
             _containing_obj->print_on(gclog_or_tty);
-            gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
-                                   "in region "HR_FORMAT,
+            gclog_or_tty->print_cr("points to obj " PTR_FORMAT " "
+                                   "in region " HR_FORMAT,
                                    p2i(obj),
                                    HR_FORMAT_PARAMS(to));
             obj->print_on(gclog_or_tty);
@@ -783,8 +783,8 @@
 
     if (is_region_humongous != g1->is_humongous(obj_size) &&
         !g1->is_obj_dead(obj, this)) { // Dead objects may have bigger block_size since they span several objects.
-      gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size ("
-                             SIZE_FORMAT" words) in a %shumongous region",
+      gclog_or_tty->print_cr("obj " PTR_FORMAT " is of %shumongous size ("
+                             SIZE_FORMAT " words) in a %shumongous region",
                              p2i(p), g1->is_humongous(obj_size) ? "" : "non-",
                              obj_size, is_region_humongous ? "" : "non-");
        *failures = true;
@@ -798,12 +798,12 @@
                                    (vo == VerifyOption_G1UsePrevMarking &&
                                    ClassLoaderDataGraph::unload_list_contains(klass));
         if (!is_metaspace_object) {
-          gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
+          gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " "
                                  "not metadata", p2i(klass), p2i(obj));
           *failures = true;
           return;
         } else if (!klass->is_klass()) {
-          gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
+          gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " "
                                  "not a klass", p2i(klass), p2i(obj));
           *failures = true;
           return;
@@ -819,7 +819,7 @@
           }
         }
       } else {
-        gclog_or_tty->print_cr(PTR_FORMAT" no an oop", p2i(obj));
+        gclog_or_tty->print_cr(PTR_FORMAT " no an oop", p2i(obj));
         *failures = true;
         return;
       }
@@ -833,8 +833,8 @@
   }
 
   if (p != top()) {
-    gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
-                           "does not match top "PTR_FORMAT, p2i(p), p2i(top()));
+    gclog_or_tty->print_cr("end of last object " PTR_FORMAT " "
+                           "does not match top " PTR_FORMAT, p2i(p), p2i(top()));
     *failures = true;
     return;
   }
@@ -849,8 +849,8 @@
     HeapWord* addr_1 = p;
     HeapWord* b_start_1 = _offsets.block_start_const(addr_1);
     if (b_start_1 != p) {
-      gclog_or_tty->print_cr("BOT look up for top: "PTR_FORMAT" "
-                             " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
+      gclog_or_tty->print_cr("BOT look up for top: " PTR_FORMAT " "
+                             " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
                              p2i(addr_1), p2i(b_start_1), p2i(p));
       *failures = true;
       return;
@@ -861,8 +861,8 @@
     if (addr_2 < the_end) {
       HeapWord* b_start_2 = _offsets.block_start_const(addr_2);
       if (b_start_2 != p) {
-        gclog_or_tty->print_cr("BOT look up for top + 1: "PTR_FORMAT" "
-                               " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
+        gclog_or_tty->print_cr("BOT look up for top + 1: " PTR_FORMAT " "
+                               " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
                                p2i(addr_2), p2i(b_start_2), p2i(p));
         *failures = true;
         return;
@@ -875,8 +875,8 @@
     if (addr_3 < the_end) {
       HeapWord* b_start_3 = _offsets.block_start_const(addr_3);
       if (b_start_3 != p) {
-        gclog_or_tty->print_cr("BOT look up for top + diff: "PTR_FORMAT" "
-                               " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
+        gclog_or_tty->print_cr("BOT look up for top + diff: " PTR_FORMAT " "
+                               " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
                                p2i(addr_3), p2i(b_start_3), p2i(p));
         *failures = true;
         return;
@@ -887,8 +887,8 @@
     HeapWord* addr_4 = the_end - 1;
     HeapWord* b_start_4 = _offsets.block_start_const(addr_4);
     if (b_start_4 != p) {
-      gclog_or_tty->print_cr("BOT look up for end - 1: "PTR_FORMAT" "
-                             " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
+      gclog_or_tty->print_cr("BOT look up for end - 1: " PTR_FORMAT " "
+                             " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
                              p2i(addr_4), p2i(b_start_4), p2i(p));
       *failures = true;
       return;
@@ -896,8 +896,8 @@
   }
 
   if (is_region_humongous && object_num > 1) {
-    gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous "
-                           "but has "SIZE_FORMAT", objects",
+    gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is humongous "
+                           "but has " SIZE_FORMAT ", objects",
                            p2i(bottom()), p2i(end()), object_num);
     *failures = true;
     return;
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -51,7 +51,7 @@
 class HeapRegionSetBase;
 class nmethod;
 
-#define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
+#define HR_FORMAT "%u:(%s)[" PTR_FORMAT "," PTR_FORMAT "," PTR_FORMAT "]"
 #define HR_FORMAT_PARAMS(_hr_) \
                 (_hr_)->hrm_index(), \
                 (_hr_)->get_short_type_str(), \
@@ -538,8 +538,8 @@
   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,
+           err_msg("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	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -113,7 +113,7 @@
 
   assert(ClassUnloadingWithConcurrentMark,
       err_msg("All blocks should be objects if G1 Class Unloading isn't used. "
-              "HR: ["PTR_FORMAT", "PTR_FORMAT", "PTR_FORMAT") "
+              "HR: [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ") "
               "addr: " PTR_FORMAT,
               p2i(bottom()), p2i(top()), p2i(end()), p2i(addr)));
 
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -486,7 +486,7 @@
     HeapRegion* hr = _regions.get_by_index(i);
     guarantee(hr != NULL, err_msg("invariant: i: %u", i));
     guarantee(!prev_committed || hr->bottom() == prev_end,
-              err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
+              err_msg("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()));
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.inline.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.inline.hpp	Thu Jul 09 22:46:16 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())));
+        err_msg("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())));
+        err_msg("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	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -90,7 +90,7 @@
     // concurrency.
 
     if (G1TraceHeapRegionRememberedSet) {
-      gclog_or_tty->print_cr("    PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT").",
+      gclog_or_tty->print_cr("    PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
                              p2i(from),
                              UseCompressedOops
                              ? p2i(oopDesc::load_decode_heap_oop((narrowOop*)from))
@@ -376,7 +376,7 @@
 
 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,
+            err_msg("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);
@@ -630,13 +630,13 @@
 
   assert(_coarse_map.size() == region_bm->size(), "Precondition");
   if (G1RSScrubVerbose) {
-    gclog_or_tty->print("   Coarse map: before = "SIZE_FORMAT"...",
+    gclog_or_tty->print("   Coarse map: before = " SIZE_FORMAT "...",
                         _n_coarse_entries);
   }
   _coarse_map.set_intersection(*region_bm);
   _n_coarse_entries = _coarse_map.count_one_bits();
   if (G1RSScrubVerbose) {
-    gclog_or_tty->print_cr("   after = "SIZE_FORMAT".", _n_coarse_entries);
+    gclog_or_tty->print_cr("   after = " SIZE_FORMAT ".", _n_coarse_entries);
   }
 
   // Now do the fine-grained maps.
@@ -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));
+            err_msg("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));
+         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));
   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	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -30,7 +30,7 @@
 uint FreeRegionList::_unrealistically_long_length = 0;
 
 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
-  msg->append("[%s] %s ln: %u cy: "SIZE_FORMAT,
+  msg->append("[%s] %s ln: %u cy: " SIZE_FORMAT,
               name(), message, length(), total_capacity_bytes());
   fill_in_ext_msg_extra(msg);
 }
@@ -83,13 +83,13 @@
 
 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
   out->cr();
-  out->print_cr("Set: %s ("PTR_FORMAT")", name(), p2i(this));
+  out->print_cr("Set: %s (" PTR_FORMAT ")", name(), p2i(this));
   out->print_cr("  Region Assumptions");
   out->print_cr("    humongous         : %s", BOOL_TO_STR(regions_humongous()));
   out->print_cr("    free              : %s", BOOL_TO_STR(regions_free()));
   out->print_cr("  Attributes");
   out->print_cr("    length            : %14u", length());
-  out->print_cr("    total capacity    : "SIZE_FORMAT_W(14)" bytes",
+  out->print_cr("    total capacity    : " SIZE_FORMAT_W(14) " bytes",
                 total_capacity_bytes());
 }
 
@@ -105,7 +105,7 @@
 }
 
 void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
-  msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, p2i(_head), p2i(_tail));
+  msg->append(" hd: " PTR_FORMAT " tl: " PTR_FORMAT, p2i(_head), p2i(_tail));
 }
 
 void FreeRegionList::remove_all() {
@@ -276,8 +276,8 @@
 void FreeRegionList::print_on(outputStream* out, bool print_contents) {
   HeapRegionSetBase::print_on(out, print_contents);
   out->print_cr("  Linking");
-  out->print_cr("    head              : "PTR_FORMAT, p2i(_head));
-  out->print_cr("    tail              : "PTR_FORMAT, p2i(_tail));
+  out->print_cr("    head              : " PTR_FORMAT, p2i(_head));
+  out->print_cr("    tail              : " PTR_FORMAT, p2i(_tail));
 
   if (print_contents) {
     out->print_cr("  Contents");
@@ -305,7 +305,7 @@
 
     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",
+        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()));
 
     if (curr->next() != NULL) {
--- a/hotspot/src/share/vm/gc/g1/satbQueue.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/satbQueue.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -200,8 +200,8 @@
 
 void ObjPtrQueue::print(const char* name,
                         void** buf, size_t index, size_t sz) {
-  gclog_or_tty->print_cr("  SATB BUFFER [%s] buf: "PTR_FORMAT" "
-                         "index: "SIZE_FORMAT" sz: "SIZE_FORMAT,
+  gclog_or_tty->print_cr("  SATB BUFFER [%s] buf: " PTR_FORMAT " "
+                         "index: " SIZE_FORMAT " sz: " SIZE_FORMAT,
                          name, p2i(buf), index, sz);
 }
 #endif // PRODUCT
--- a/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -85,7 +85,7 @@
         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 ")",
+            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()));
           CollectedHeap::fill_with_object((HeapWord*)cur_top, words_to_fill);
           if (!os::numa_has_static_binding()) {
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -130,8 +130,7 @@
   // Update the pause time.
   _major_timer.stop();
 
-  if (!GCCause::is_user_requested_gc(gc_cause) ||
-      UseAdaptiveSizePolicyWithSystemGC) {
+  if (should_update_promo_stats(gc_cause)) {
     double major_pause_in_seconds = _major_timer.seconds();
     double major_pause_in_ms = major_pause_in_seconds * MILLIUNITS;
 
--- a/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -272,8 +272,7 @@
       // Don't check if the size_policy is ready here.  Let
       // the size_policy check that internally.
       if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
-          (!GCCause::is_user_requested_gc(gc_cause) ||
-            UseAdaptiveSizePolicyWithSystemGC)) {
+          AdaptiveSizePolicy::should_update_promo_stats(gc_cause)) {
         // Swap the survivor spaces if from_space is empty. The
         // resize_young_gen() called below is normally used after
         // a successful young GC and swapping of survivor spaces;
--- a/hotspot/src/share/vm/gc/parallel/psOldGen.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psOldGen.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -65,9 +65,9 @@
     // 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" ]",
+           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()),
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -2089,8 +2089,7 @@
       // Don't check if the size_policy is ready here.  Let
       // the size_policy check that internally.
       if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
-          (!GCCause::is_user_requested_gc(gc_cause) ||
-            UseAdaptiveSizePolicyWithSystemGC)) {
+          AdaptiveSizePolicy::should_update_promo_stats(gc_cause)) {
         // Swap the survivor spaces if from_space is empty. The
         // resize_young_gen() called below is normally used after
         // a successful young GC and swapping of survivor spaces;
--- a/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -290,8 +290,7 @@
 
   AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
 
-  if (!GCCause::is_user_requested_gc(gc_cause) ||
-       UseAdaptiveSizePolicyWithSystemGC) {
+  if (AdaptiveSizePolicy::should_update_eden_stats(gc_cause)) {
     // Gather the feedback data for eden occupancy.
     young_gen->eden_space()->accumulate_statistics();
   }
@@ -559,9 +558,7 @@
         // Don't check if the size_policy is ready at this
         // level.  Let the size_policy check that internally.
         if (UseAdaptiveGenerationSizePolicyAtMinorCollection &&
-            ((gc_cause != GCCause::_java_lang_system_gc) ||
-              UseAdaptiveSizePolicyWithSystemGC)) {
-
+            (AdaptiveSizePolicy::should_update_eden_stats(gc_cause))) {
           // Calculate optimal free space amounts
           assert(young_gen->max_size() >
             young_gen->from_space()->capacity_in_bytes() +
--- a/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -168,8 +168,8 @@
   bool   res = (available >= av_promo) || (available >= max_promotion_in_bytes);
   if (PrintGC && Verbose) {
     gclog_or_tty->print_cr(
-      "Tenured: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT"),"
-      "max_promo("SIZE_FORMAT")",
+      "Tenured: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "),"
+      "max_promo(" SIZE_FORMAT ")",
       res? "":" not", available, res? ">=":"<",
       av_promo, max_promotion_in_bytes);
   }
--- a/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -487,6 +487,18 @@
                                GCCause::Cause gc_cause,
                                CollectorPolicy* collector_policy);
 
+  static bool should_update_promo_stats(GCCause::Cause cause) {
+    return ((GCCause::is_user_requested_gc(cause)  &&
+               UseAdaptiveSizePolicyWithSystemGC) ||
+            GCCause::is_tenured_allocation_failure_gc(cause));
+  }
+
+  static bool should_update_eden_stats(GCCause::Cause cause) {
+    return ((GCCause::is_user_requested_gc(cause)  &&
+               UseAdaptiveSizePolicyWithSystemGC) ||
+            GCCause::is_allocation_failure_gc(cause));
+  }
+
   // Printing support
   virtual bool print_adaptive_size_policy_on(outputStream* st) const;
   bool print_adaptive_size_policy_on(outputStream* st,
--- a/hotspot/src/share/vm/gc/shared/barrierSet.inline.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/barrierSet.inline.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -69,7 +69,7 @@
   assert(UseCompressedOops || (aligned_start == start && aligned_end == end),
          "Expected heap word alignment of start and end");
 #if 0
-  warning("Post:\t" INTPTR_FORMAT "[" SIZE_FORMAT "] : [" INTPTR_FORMAT","INTPTR_FORMAT")\t",
+  warning("Post:\t" INTPTR_FORMAT "[" SIZE_FORMAT "] : [" INTPTR_FORMAT "," INTPTR_FORMAT ")\t",
                    start,            count,              aligned_start,   aligned_end);
 #endif
   write_ref_array_work(MemRegion(aligned_start, aligned_end));
--- a/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -560,7 +560,7 @@
     q = n;
     n += _sp->block_size(n);
     assert(n > q,
-           err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT","
+           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())));
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -600,7 +600,7 @@
                       (val_equals) ? "" : "not ", val);
         failures = true;
       }
-      tty->print_cr("==   card "PTR_FORMAT" ["PTR_FORMAT","PTR_FORMAT"], "
+      tty->print_cr("==   card " PTR_FORMAT " [" PTR_FORMAT "," PTR_FORMAT "], "
                     "val: %d", p2i(curr), p2i(addr_for(curr)),
                     p2i((HeapWord*) (((size_t) addr_for(curr)) + card_size)),
                     (int) curr_val);
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -158,8 +158,8 @@
   // 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")",
+           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())));
     jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift];
     assert(result >= _byte_map && result < _byte_map + _byte_map_size,
@@ -399,8 +399,8 @@
     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")",
+           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())));
     return result;
   }
@@ -408,8 +408,8 @@
   // 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")",
+           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())));
     return byte_for(p) - _byte_map;
   }
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -488,19 +488,17 @@
   DEBUG_ONLY(fill_args_check(start, words);)
   HandleMark hm;  // Free handles before leaving.
 
-#ifdef _LP64
-  // A single array can fill ~8G, so multiple objects are needed only in 64-bit.
-  // First fill with arrays, ensuring that any remaining space is big enough to
-  // fill.  The remainder is filled with a single object.
+  // Multiple objects may be required depending on the filler array maximum size. Fill
+  // the range up to that with objects that are filler_array_max_size sized. The
+  // remainder is filled with a single object.
   const size_t min = min_fill_size();
   const size_t max = filler_array_max_size();
   while (words > max) {
-    const size_t cur = words - max >= min ? max : max - min;
+    const size_t cur = (words - max) >= min ? max : max - min;
     fill_with_array(start, cur, zap);
     start += cur;
     words -= cur;
   }
-#endif
 
   fill_with_object_impl(start, words, zap);
 }
--- a/hotspot/src/share/vm/gc/shared/gcCause.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcCause.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -92,6 +92,35 @@
             cause == GCCause::_heap_dump);
   }
 
+  // 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)));
+    // _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
+    // in the collection of the tenured generation if there is not enough space
+    // in the tenured generation to support a young GC.
+    // _last_ditch_collection is a collection done to include SoftReferences.
+    return (cause == GCCause::_tenured_generation_full ||
+            cause == GCCause::_cms_generation_full ||
+            cause == GCCause::_adaptive_size_policy ||
+            cause == GCCause::_allocation_failure ||
+            cause == GCCause::_last_ditch_collection);
+  }
+
+  // Causes for collection of the young generation
+  inline static bool is_allocation_failure_gc(GCCause::Cause cause) {
+    // _allocation_failure is the generic cause a collection for allocation failure
+    // _adaptive_size_policy is for a collecton done before a full GC
+    // _last_ditch_collection is a collection done to include SoftReferences.
+    return (cause == GCCause::_allocation_failure ||
+            cause == GCCause::_adaptive_size_policy ||
+            cause == GCCause::_last_ditch_collection);
+  }
+
   // Return a string describing the GCCause.
   static const char* to_string(GCCause::Cause cause);
 };
--- a/hotspot/src/share/vm/gc/shared/gcTrace.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -221,6 +221,12 @@
 }
 
 #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 G1NewTracer::report_yc_type(G1YCType type) {
   assert_set_gc_id();
 
--- a/hotspot/src/share/vm/gc/shared/gcTrace.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -239,6 +239,13 @@
 };
 
 #if INCLUDE_ALL_GCS
+class G1MMUTracer : public AllStatic {
+  static void send_g1_mmu_event(const GCId& gcId, double timeSlice, double gcTime, double maxTime);
+
+ public:
+  static void report_mmu(const GCId& gcId, double timeSlice, double gcTime, double maxTime);
+};
+
 class G1NewTracer : public YoungGCTracer {
   G1YoungGCInfo _g1_young_gc_info;
 
--- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -199,6 +199,17 @@
   }
 }
 
+void G1MMUTracer::send_g1_mmu_event(const GCId& gcId, double timeSlice, double gcTime, double maxTime) {
+  EventGCG1MMU e;
+  if (e.should_commit()) {
+    e.set_gcId(gcId.id());
+    e.set_timeSlice(timeSlice);
+    e.set_gcTime(gcTime);
+    e.set_maxGcTime(maxTime);
+    e.commit();
+  }
+}
+
 void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
   EventEvacuationInfo e;
   if (e.should_commit()) {
--- a/hotspot/src/share/vm/gc/shared/generation.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/generation.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -173,7 +173,7 @@
   bool   res = (available >= max_promotion_in_bytes);
   if (PrintGC && Verbose) {
     gclog_or_tty->print_cr(
-      "Generation: promo attempt is%s safe: available("SIZE_FORMAT") %s max_promo("SIZE_FORMAT")",
+      "Generation: promo attempt is%s safe: available(" SIZE_FORMAT ") %s max_promo(" SIZE_FORMAT ")",
       res? "":" not", available, res? ">=":"<",
       max_promotion_in_bytes);
   }
--- a/hotspot/src/share/vm/gc/shared/plab.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/plab.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -45,7 +45,7 @@
   // 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" "
+         err_msg("Minimum PLAB size " SIZE_FORMAT " must be larger than alignment reserve " SIZE_FORMAT " "
                  "to be able to contain objects", min_size(), AlignmentReserve));
 }
 
@@ -109,10 +109,15 @@
   }
 }
 
-// Compute desired plab size and latch result for later
+// Calculates plab size for current number of gc worker threads.
+size_t PLABStats::desired_plab_sz(uint no_of_gc_workers) {
+  return MAX2(min_size(), (size_t)align_object_size(_desired_net_plab_sz / no_of_gc_workers));
+}
+
+// Compute desired plab size for one gc worker thread and latch result for later
 // use. This should be called once at the end of parallel
 // scavenge; it clears the sensor accumulators.
-void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
+void PLABStats::adjust_desired_plab_sz() {
   assert(ResizePLAB, "Not set");
 
   assert(is_object_aligned(max_size()) && min_size() <= max_size(),
@@ -121,10 +126,10 @@
   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: " SIZE_FORMAT ", "
+                   "_wasted: " SIZE_FORMAT ", "
+                   "_unused: " SIZE_FORMAT ", "
+                   "_undo_wasted: " SIZE_FORMAT,
                    _allocated, _wasted, _unused, _undo_wasted));
 
     _allocated = 1;
@@ -135,7 +140,8 @@
     target_refills = 1;
   }
   size_t used = _allocated - _wasted - _unused;
-  size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
+  // Assumed to have 1 gc worker thread
+  size_t recent_plab_sz = used / target_refills;
   // Take historical weighted average
   _filter.sample(recent_plab_sz);
   // Clip from above and below, and align to object boundary
@@ -144,9 +150,9 @@
   new_plab_sz = align_object_size(new_plab_sz);
   // Latch the result
   if (PrintPLAB) {
-    gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz);
+    gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_net_plab_sz = " SIZE_FORMAT ") ", recent_plab_sz, new_plab_sz);
   }
-  _desired_plab_sz = new_plab_sz;
+  _desired_net_plab_sz = new_plab_sz;
 
   reset();
 }
--- a/hotspot/src/share/vm/gc/shared/plab.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/plab.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -150,13 +150,13 @@
 
 // PLAB book-keeping.
 class PLABStats VALUE_OBJ_CLASS_SPEC {
-  size_t _allocated;      // Total allocated
-  size_t _wasted;         // of which wasted (internal fragmentation)
-  size_t _undo_wasted;    // of which wasted on undo (is not used for calculation of PLAB size)
-  size_t _unused;         // Unused in last buffer
-  size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized
+  size_t _allocated;          // Total allocated
+  size_t _wasted;             // of which wasted (internal fragmentation)
+  size_t _undo_wasted;        // of which wasted on undo (is not used for calculation of PLAB size)
+  size_t _unused;             // Unused in last buffer
+  size_t _desired_net_plab_sz;// Output of filter (below), suitably trimmed and quantized
   AdaptiveWeightedAverage
-         _filter;         // Integrator with decay
+         _filter;             // Integrator with decay
 
   void reset() {
     _allocated   = 0;
@@ -165,12 +165,12 @@
     _unused      = 0;
   }
  public:
-  PLABStats(size_t desired_plab_sz_, unsigned wt) :
+  PLABStats(size_t desired_net_plab_sz_, unsigned wt) :
     _allocated(0),
     _wasted(0),
     _undo_wasted(0),
     _unused(0),
-    _desired_plab_sz(desired_plab_sz_),
+    _desired_net_plab_sz(desired_net_plab_sz_),
     _filter(wt)
   { }
 
@@ -182,13 +182,12 @@
     return PLAB::max_size();
   }
 
-  size_t desired_plab_sz() {
-    return _desired_plab_sz;
-  }
+  // Calculates plab size for current number of gc worker threads.
+  size_t desired_plab_sz(uint no_of_gc_workers);
 
-  // Updates the current desired PLAB size. Computes the new desired PLAB size,
+  // Updates the current desired PLAB size. Computes the new desired PLAB size with one gc worker thread,
   // updates _desired_plab_sz and clears sensor accumulators.
-  void adjust_desired_plab_sz(uint no_of_gc_workers);
+  void adjust_desired_plab_sz();
 
   void add_allocated(size_t v) {
     Atomic::add_ptr(v, &_allocated);
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.inline.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.inline.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -93,10 +93,10 @@
 
   if (PrintTLAB && Verbose) {
     Thread* thrd = myThread();
-    gclog_or_tty->print("TLAB: %s thread: "INTPTR_FORMAT" [id: %2d]"
-                        " obj: "SIZE_FORMAT
-                        " free: "SIZE_FORMAT
-                        " waste: "SIZE_FORMAT"\n",
+    gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
+                        " obj: " SIZE_FORMAT
+                        " free: " SIZE_FORMAT
+                        " waste: " SIZE_FORMAT "\n",
                         "slow", p2i(thrd), thrd->osthread()->thread_id(),
                         obj_size, free(), refill_waste_limit());
   }
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp	Thu Jul 09 22:46:16 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
@@ -134,8 +134,10 @@
   tty->print_cr("wasted space     = %6dK bytes", (int)_code->available_space()/1024);
   tty->cr();
   tty->print_cr("# of codelets    = %6d"      , _code->number_of_stubs());
-  tty->print_cr("avg codelet size = %6d bytes", _code->used_space() / _code->number_of_stubs());
-  tty->cr();
+  if (_code->number_of_stubs() != 0) {
+    tty->print_cr("avg codelet size = %6d bytes", _code->used_space() / _code->number_of_stubs());
+    tty->cr();
+  }
   _code->print();
   tty->print_cr("----------------------------------------------------------------------");
   tty->cr();
--- a/hotspot/src/share/vm/interpreter/interpreter.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreter.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -45,6 +45,7 @@
 
 class InterpreterCodelet: public Stub {
   friend class VMStructs;
+  friend class CodeCacheDumper; // possible extension [do not remove]
  private:
   int         _size;                             // the size in bytes
   const char* _description;                      // a description of the codelet, for debugging & printing
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -27,6 +27,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "gc/shared/collectedHeap.hpp"
@@ -1178,6 +1179,7 @@
     ICache::invalidate_range(handler, insts_size);
     _handler = handler + insts_size;
   }
+  CodeCacheExtensions::handle_generated_handler(handler, buffer->name(), _handler);
   return handler;
 }
 
@@ -1186,7 +1188,7 @@
     // use slow signature handler if we can't do better
     int handler_index = -1;
     // check if we can use customized (fast) signature handler
-    if (UseFastSignatureHandlers && method->size_of_parameters() <= Fingerprinter::max_size_of_parameters) {
+    if (UseFastSignatureHandlers && CodeCacheExtensions::support_fast_signature_handlers() && method->size_of_parameters() <= Fingerprinter::max_size_of_parameters) {
       // use customized signature handler
       MutexLocker mu(SignatureHandlerLibrary_lock);
       // make sure data structure is initialized
@@ -1203,14 +1205,23 @@
           round_to((intptr_t)_buffer, CodeEntryAlignment) - (address)_buffer;
         CodeBuffer buffer((address)(_buffer + align_offset),
                           SignatureHandlerLibrary::buffer_size - align_offset);
+        if (!CodeCacheExtensions::support_dynamic_code()) {
+          // we need a name for the signature (for lookups or saving)
+          const int SYMBOL_SIZE = 50;
+          char *symbolName = NEW_RESOURCE_ARRAY(char, SYMBOL_SIZE);
+          // support for named signatures
+          jio_snprintf(symbolName, SYMBOL_SIZE,
+                       "native_" UINT64_FORMAT, fingerprint);
+          buffer.set_name(symbolName);
+        }
         InterpreterRuntime::SignatureHandlerGenerator(method, &buffer).generate(fingerprint);
         // copy into code heap
         address handler = set_handler(&buffer);
         if (handler == NULL) {
-          // use slow signature handler
+          // use slow signature handler (without memorizing it in the fingerprints)
         } else {
           // debugging suppport
-          if (PrintSignatureHandlers) {
+          if (PrintSignatureHandlers && (handler != Interpreter::slow_signature_handler())) {
             tty->cr();
             tty->print_cr("argument handler #%d for: %s %s (fingerprint = " UINT64_FORMAT ", %d bytes generated)",
                           _handlers->length(),
@@ -1218,7 +1229,10 @@
                           method->name_and_sig_as_C_string(),
                           fingerprint,
                           buffer.insts_size());
-            Disassembler::decode(handler, handler + buffer.insts_size());
+            if (buffer.insts_size() > 0) {
+              // buffer may be empty for pregenerated handlers
+              Disassembler::decode(handler, handler + buffer.insts_size());
+            }
 #ifndef PRODUCT
             address rh_begin = Interpreter::result_handler(method()->result_type());
             if (CodeCache::contains(rh_begin)) {
@@ -1277,6 +1291,37 @@
 #endif // ASSERT
 }
 
+void SignatureHandlerLibrary::add(uint64_t fingerprint, address handler) {
+  int handler_index = -1;
+  // use customized signature handler
+  MutexLocker mu(SignatureHandlerLibrary_lock);
+  // make sure data structure is initialized
+  initialize();
+  fingerprint = InterpreterRuntime::normalize_fast_native_fingerprint(fingerprint);
+  handler_index = _fingerprints->find(fingerprint);
+  // create handler if necessary
+  if (handler_index < 0) {
+    if (PrintSignatureHandlers && (handler != Interpreter::slow_signature_handler())) {
+      tty->cr();
+      tty->print_cr("argument handler #%d at "PTR_FORMAT" for fingerprint " UINT64_FORMAT,
+                    _handlers->length(),
+                    handler,
+                    fingerprint);
+    }
+    _fingerprints->append(fingerprint);
+    _handlers->append(handler);
+  } else {
+    if (PrintSignatureHandlers) {
+      tty->cr();
+      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);
+    }
+  }
+}
+
 
 BufferBlob*              SignatureHandlerLibrary::_handler_blob = NULL;
 address                  SignatureHandlerLibrary::_handler      = NULL;
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -219,6 +219,7 @@
 
  public:
   static void add(methodHandle method);
+  static void add(uint64_t fingerprint, address handler);
 };
 
 #endif // SHARE_VM_INTERPRETER_INTERPRETERRUNTIME_HPP
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -107,7 +107,7 @@
 // more complicated solution is required.  A special return bytecode
 // is used only by Object.<init> to signal the finalization
 // registration point.  Additionally local 0 must be preserved so it's
-// available to pass to the registration function.  For simplicty we
+// available to pass to the registration function.  For simplicity we
 // require that local 0 is never overwritten so it's available as an
 // argument for registration.
 
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Thu Jul 09 22:46:16 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
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterGenerator.hpp"
 #include "interpreter/interpreterRuntime.hpp"
@@ -49,10 +50,33 @@
     TraceTime timer("Interpreter generation", TraceStartupTime);
     int code_size = InterpreterCodeSize;
     NOT_PRODUCT(code_size *= 4;)  // debug uses extra interpreter code space
+#if INCLUDE_JVMTI
+    if (CodeCacheExtensions::saving_generated_interpreter()) {
+      // May requires several versions of the codelets.
+      // Final size will automatically be optimized.
+      code_size *= 2;
+    }
+#endif
     _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
                           "Interpreter");
     InterpreterGenerator g(_code);
-    if (PrintInterpreter) print();
+  }
+  if (PrintInterpreter) {
+    if (CodeCacheExtensions::saving_generated_interpreter() &&
+        CodeCacheExtensions::use_pregenerated_interpreter()) {
+      ResourceMark rm;
+      tty->print("Printing the newly generated interpreter first");
+      print();
+      tty->print("Printing the pregenerated interpreter next");
+    }
+  }
+
+  // Install the pregenerated interpreter code before printing it
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::TemplateInterpreter);
+
+  if (PrintInterpreter) {
+    ResourceMark rm;
+    print();
   }
 
   // initialize dispatch table
@@ -214,194 +238,203 @@
 };
 
 void TemplateInterpreterGenerator::generate_all() {
-  AbstractInterpreterGenerator::generate_all();
+  // Loop, in case we need several variants of the interpreter entries
+  do {
+    if (!CodeCacheExtensions::skip_code_generation()) {
+      // bypass code generation when useless
+      AbstractInterpreterGenerator::generate_all();
 
-  { CodeletMark cm(_masm, "error exits");
-    _unimplemented_bytecode    = generate_error_exit("unimplemented bytecode");
-    _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
-  }
+      { CodeletMark cm(_masm, "error exits");
+        _unimplemented_bytecode    = generate_error_exit("unimplemented bytecode");
+        _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
+      }
 
 #ifndef PRODUCT
-  if (TraceBytecodes) {
-    CodeletMark cm(_masm, "bytecode tracing support");
-    Interpreter::_trace_code =
-      EntryPoint(
-        generate_trace_code(btos),
-        generate_trace_code(ctos),
-        generate_trace_code(stos),
-        generate_trace_code(atos),
-        generate_trace_code(itos),
-        generate_trace_code(ltos),
-        generate_trace_code(ftos),
-        generate_trace_code(dtos),
-        generate_trace_code(vtos)
-      );
-  }
+      if (TraceBytecodes) {
+        CodeletMark cm(_masm, "bytecode tracing support");
+        Interpreter::_trace_code =
+          EntryPoint(
+                     generate_trace_code(btos),
+                     generate_trace_code(ctos),
+                     generate_trace_code(stos),
+                     generate_trace_code(atos),
+                     generate_trace_code(itos),
+                     generate_trace_code(ltos),
+                     generate_trace_code(ftos),
+                     generate_trace_code(dtos),
+                     generate_trace_code(vtos)
+                     );
+      }
 #endif // !PRODUCT
 
-  { CodeletMark cm(_masm, "return entry points");
-    const int index_size = sizeof(u2);
-    for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
-      Interpreter::_return_entry[i] =
-        EntryPoint(
-          generate_return_entry_for(itos, i, index_size),
-          generate_return_entry_for(itos, i, index_size),
-          generate_return_entry_for(itos, i, index_size),
-          generate_return_entry_for(atos, i, index_size),
-          generate_return_entry_for(itos, i, index_size),
-          generate_return_entry_for(ltos, i, index_size),
-          generate_return_entry_for(ftos, i, index_size),
-          generate_return_entry_for(dtos, i, index_size),
-          generate_return_entry_for(vtos, i, index_size)
-        );
-    }
-  }
+      { CodeletMark cm(_masm, "return entry points");
+        const int index_size = sizeof(u2);
+        for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
+          Interpreter::_return_entry[i] =
+            EntryPoint(
+                       generate_return_entry_for(itos, i, index_size),
+                       generate_return_entry_for(itos, i, index_size),
+                       generate_return_entry_for(itos, i, index_size),
+                       generate_return_entry_for(atos, i, index_size),
+                       generate_return_entry_for(itos, i, index_size),
+                       generate_return_entry_for(ltos, i, index_size),
+                       generate_return_entry_for(ftos, i, index_size),
+                       generate_return_entry_for(dtos, i, index_size),
+                       generate_return_entry_for(vtos, i, index_size)
+                       );
+        }
+      }
 
-  { CodeletMark cm(_masm, "invoke return entry points");
-    const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos};
-    const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
-    const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
-    const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
+      { CodeletMark cm(_masm, "invoke return entry points");
+        const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos};
+        const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
+        const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
+        const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
 
-    for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {
-      TosState state = states[i];
-      Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));
-      Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));
-      Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
-    }
-  }
+        for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {
+          TosState state = states[i];
+          Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));
+          Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));
+          Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
+        }
+      }
 
-  { CodeletMark cm(_masm, "earlyret entry points");
-    Interpreter::_earlyret_entry =
-      EntryPoint(
-        generate_earlyret_entry_for(btos),
-        generate_earlyret_entry_for(ctos),
-        generate_earlyret_entry_for(stos),
-        generate_earlyret_entry_for(atos),
-        generate_earlyret_entry_for(itos),
-        generate_earlyret_entry_for(ltos),
-        generate_earlyret_entry_for(ftos),
-        generate_earlyret_entry_for(dtos),
-        generate_earlyret_entry_for(vtos)
-      );
-  }
+      { CodeletMark cm(_masm, "earlyret entry points");
+        Interpreter::_earlyret_entry =
+          EntryPoint(
+                     generate_earlyret_entry_for(btos),
+                     generate_earlyret_entry_for(ctos),
+                     generate_earlyret_entry_for(stos),
+                     generate_earlyret_entry_for(atos),
+                     generate_earlyret_entry_for(itos),
+                     generate_earlyret_entry_for(ltos),
+                     generate_earlyret_entry_for(ftos),
+                     generate_earlyret_entry_for(dtos),
+                     generate_earlyret_entry_for(vtos)
+                     );
+      }
 
-  { CodeletMark cm(_masm, "deoptimization entry points");
-    for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {
-      Interpreter::_deopt_entry[i] =
-        EntryPoint(
-          generate_deopt_entry_for(itos, i),
-          generate_deopt_entry_for(itos, i),
-          generate_deopt_entry_for(itos, i),
-          generate_deopt_entry_for(atos, i),
-          generate_deopt_entry_for(itos, i),
-          generate_deopt_entry_for(ltos, i),
-          generate_deopt_entry_for(ftos, i),
-          generate_deopt_entry_for(dtos, i),
-          generate_deopt_entry_for(vtos, i)
-        );
-    }
-  }
+      { CodeletMark cm(_masm, "deoptimization entry points");
+        for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {
+          Interpreter::_deopt_entry[i] =
+            EntryPoint(
+                       generate_deopt_entry_for(itos, i),
+                       generate_deopt_entry_for(itos, i),
+                       generate_deopt_entry_for(itos, i),
+                       generate_deopt_entry_for(atos, i),
+                       generate_deopt_entry_for(itos, i),
+                       generate_deopt_entry_for(ltos, i),
+                       generate_deopt_entry_for(ftos, i),
+                       generate_deopt_entry_for(dtos, i),
+                       generate_deopt_entry_for(vtos, i)
+                       );
+        }
+      }
 
-  { CodeletMark cm(_masm, "result handlers for native calls");
-    // The various result converter stublets.
-    int is_generated[Interpreter::number_of_result_handlers];
-    memset(is_generated, 0, sizeof(is_generated));
+      { CodeletMark cm(_masm, "result handlers for native calls");
+        // The various result converter stublets.
+        int is_generated[Interpreter::number_of_result_handlers];
+        memset(is_generated, 0, sizeof(is_generated));
 
-    for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
-      BasicType type = types[i];
-      if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
-        Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
+        for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
+          BasicType type = types[i];
+          if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
+            Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
+          }
+        }
       }
-    }
-  }
 
-  { CodeletMark cm(_masm, "continuation entry points");
-    Interpreter::_continuation_entry =
-      EntryPoint(
-        generate_continuation_for(btos),
-        generate_continuation_for(ctos),
-        generate_continuation_for(stos),
-        generate_continuation_for(atos),
-        generate_continuation_for(itos),
-        generate_continuation_for(ltos),
-        generate_continuation_for(ftos),
-        generate_continuation_for(dtos),
-        generate_continuation_for(vtos)
-      );
-  }
+      { CodeletMark cm(_masm, "continuation entry points");
+        Interpreter::_continuation_entry =
+          EntryPoint(
+                     generate_continuation_for(btos),
+                     generate_continuation_for(ctos),
+                     generate_continuation_for(stos),
+                     generate_continuation_for(atos),
+                     generate_continuation_for(itos),
+                     generate_continuation_for(ltos),
+                     generate_continuation_for(ftos),
+                     generate_continuation_for(dtos),
+                     generate_continuation_for(vtos)
+                     );
+      }
 
-  { CodeletMark cm(_masm, "safepoint entry points");
-    Interpreter::_safept_entry =
-      EntryPoint(
-        generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
-        generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
-      );
-  }
+      { CodeletMark cm(_masm, "safepoint entry points");
+        Interpreter::_safept_entry =
+          EntryPoint(
+                     generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
+                     );
+      }
 
-  { CodeletMark cm(_masm, "exception handling");
-    // (Note: this is not safepoint safe because thread may return to compiled code)
-    generate_throw_exception();
-  }
+      { CodeletMark cm(_masm, "exception handling");
+        // (Note: this is not safepoint safe because thread may return to compiled code)
+        generate_throw_exception();
+      }
 
-  { CodeletMark cm(_masm, "throw exception entrypoints");
-    Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
-    Interpreter::_throw_ArrayStoreException_entry            = generate_klass_exception_handler("java/lang/ArrayStoreException"                 );
-    Interpreter::_throw_ArithmeticException_entry            = generate_exception_handler("java/lang/ArithmeticException"           , "/ by zero");
-    Interpreter::_throw_ClassCastException_entry             = generate_ClassCastException_handler();
-    Interpreter::_throw_NullPointerException_entry           = generate_exception_handler("java/lang/NullPointerException"          , NULL       );
-    Interpreter::_throw_StackOverflowError_entry             = generate_StackOverflowError_handler();
-  }
+      { CodeletMark cm(_masm, "throw exception entrypoints");
+        Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
+        Interpreter::_throw_ArrayStoreException_entry            = generate_klass_exception_handler("java/lang/ArrayStoreException"                 );
+        Interpreter::_throw_ArithmeticException_entry            = generate_exception_handler("java/lang/ArithmeticException"           , "/ by zero");
+        Interpreter::_throw_ClassCastException_entry             = generate_ClassCastException_handler();
+        Interpreter::_throw_NullPointerException_entry           = generate_exception_handler("java/lang/NullPointerException"          , NULL       );
+        Interpreter::_throw_StackOverflowError_entry             = generate_StackOverflowError_handler();
+      }
 
 
 
-#define method_entry(kind)                                                                    \
-  { CodeletMark cm(_masm, "method entry point (kind = " #kind ")");                    \
-    Interpreter::_entry_table[Interpreter::kind] = ((InterpreterGenerator*)this)->generate_method_entry(Interpreter::kind);  \
-  }
+#define method_entry(kind)                                              \
+      { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
+        Interpreter::_entry_table[Interpreter::kind] = ((InterpreterGenerator*)this)->generate_method_entry(Interpreter::kind); \
+      }
 
-  // all non-native method kinds
-  method_entry(zerolocals)
-  method_entry(zerolocals_synchronized)
-  method_entry(empty)
-  method_entry(accessor)
-  method_entry(abstract)
-  method_entry(java_lang_math_sin  )
-  method_entry(java_lang_math_cos  )
-  method_entry(java_lang_math_tan  )
-  method_entry(java_lang_math_abs  )
-  method_entry(java_lang_math_sqrt )
-  method_entry(java_lang_math_log  )
-  method_entry(java_lang_math_log10)
-  method_entry(java_lang_math_exp  )
-  method_entry(java_lang_math_pow  )
-  method_entry(java_lang_ref_reference_get)
+      // all non-native method kinds
+      method_entry(zerolocals)
+        method_entry(zerolocals_synchronized)
+        method_entry(empty)
+        method_entry(accessor)
+        method_entry(abstract)
+        method_entry(java_lang_math_sin  )
+        method_entry(java_lang_math_cos  )
+        method_entry(java_lang_math_tan  )
+        method_entry(java_lang_math_abs  )
+        method_entry(java_lang_math_sqrt )
+        method_entry(java_lang_math_log  )
+        method_entry(java_lang_math_log10)
+        method_entry(java_lang_math_exp  )
+        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)
-  }
+        if (UseCRC32Intrinsics) {
+          method_entry(java_util_zip_CRC32_update)
+            method_entry(java_util_zip_CRC32_updateBytes)
+            method_entry(java_util_zip_CRC32_updateByteBuffer)
+            }
 
-  initialize_method_handle_entries();
+      initialize_method_handle_entries();
 
-  // all native method kinds (must be one contiguous block)
-  Interpreter::_native_entry_begin = Interpreter::code()->code_end();
-  method_entry(native)
-  method_entry(native_synchronized)
-  Interpreter::_native_entry_end = Interpreter::code()->code_end();
+      // all native method kinds (must be one contiguous block)
+      Interpreter::_native_entry_begin = Interpreter::code()->code_end();
+      method_entry(native)
+        method_entry(native_synchronized)
+        Interpreter::_native_entry_end = Interpreter::code()->code_end();
 
 #undef method_entry
 
-  // Bytecodes
-  set_entry_points_for_all_bytes();
+      // Bytecodes
+      set_entry_points_for_all_bytes();
+    }
+  } while (CodeCacheExtensions::needs_other_interpreter_variant());
+
+  // installation of code in other places in the runtime
+  // (ExcutableCodeManager calls not needed to copy the entries)
   set_safepoints_for_all_bytes();
 }
 
@@ -445,6 +478,9 @@
 
 
 void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {
+  if (CodeCacheExtensions::skip_template_interpreter_entries(code)) {
+    return;
+  }
   CodeletMark cm(_masm, Bytecodes::name(code), code);
   // initialize entry points
   assert(_unimplemented_bytecode    != NULL, "should have been generated before");
@@ -474,6 +510,7 @@
   EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
   Interpreter::_normal_table.set_entry(code, entry);
   Interpreter::_wentry_point[code] = wep;
+  CodeCacheExtensions::completed_template_interpreter_entries(_masm, code);
 }
 
 
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -87,6 +87,7 @@
   friend class TemplateInterpreterGenerator;
   friend class InterpreterGenerator;
   friend class TemplateTable;
+  friend class CodeCacheExtensions;
   // friend class Interpreter;
  public:
 
--- a/hotspot/src/share/vm/memory/allocation.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/memory/allocation.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -752,7 +752,7 @@
 julong  AllocStats::resource_bytes() { return Arena::_bytes_allocated - start_res_bytes; }
 void    AllocStats::print() {
   tty->print_cr(UINT64_FORMAT " mallocs (" UINT64_FORMAT "MB), "
-                UINT64_FORMAT" frees (" UINT64_FORMAT "MB), " UINT64_FORMAT "MB resrc",
+                UINT64_FORMAT " frees (" UINT64_FORMAT "MB), " UINT64_FORMAT "MB resrc",
                 num_mallocs(), alloc_bytes()/M, num_frees(), free_bytes()/M, resource_bytes()/M);
 }
 
--- a/hotspot/src/share/vm/memory/heap.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/memory/heap.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -28,6 +28,7 @@
 #include "code/codeBlob.hpp"
 #include "memory/allocation.hpp"
 #include "memory/virtualspace.hpp"
+#include "utilities/macros.hpp"
 
 // Blocks
 
@@ -80,6 +81,7 @@
 
 class CodeHeap : public CHeapObj<mtCode> {
   friend class VMStructs;
+  friend class PregeneratedCodeHeap;
  private:
   VirtualSpace _memory;                          // the memory holding the blocks
   VirtualSpace _segmap;                          // the memory holding the segment map
@@ -148,8 +150,8 @@
   char* high() const                             { return _memory.high(); }
   char* high_boundary() const                    { return _memory.high_boundary(); }
 
-  bool  contains(const void* p) const            { return low_boundary() <= p && p < high(); }
-  void* find_start(void* p)     const;           // returns the block containing p or NULL
+  virtual bool  contains(const void* p) const    { return low_boundary() <= p && p < high(); }
+  virtual void* find_start(void* p)     const;   // returns the block containing p or NULL
   size_t alignment_unit()       const;           // alignment of any block
   size_t alignment_offset()     const;           // offset of first byte of any block, within the enclosing alignment unit
   static size_t header_size();                   // returns the header size for each heap block
@@ -158,9 +160,9 @@
   int    freelist_length()       const           { return _freelist_length; } // number of elements in the freelist
 
   // returns the first block or NULL
-  void* first() const       { return next_used(first_block()); }
+  virtual void* first() const                    { return next_used(first_block()); }
   // returns the next block given a block p or NULL
-  void* next(void* p) const { return next_used(next_block(block_start(p))); }
+  virtual void* next(void* p) const              { return next_used(next_block(block_start(p))); }
 
   // Statistics
   size_t capacity() const;
--- a/hotspot/src/share/vm/memory/universe.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/memory/universe.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -805,7 +805,7 @@
 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,
+      err_msg("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);
--- a/hotspot/src/share/vm/memory/virtualspace.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/memory/virtualspace.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "memory/virtualspace.hpp"
 #include "oops/markOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -603,7 +604,7 @@
 ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
                                      size_t rs_align,
                                      bool large) :
-  ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
+  ReservedSpace(r_size, rs_align, large, /*executable*/ CodeCacheExtensions::support_dynamic_code()) {
   MemTracker::record_virtual_memory_type((address)base(), mtCode);
 }
 
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1467,7 +1467,7 @@
       }
       case JVM_CONSTANT_Long: {
         u8 val = Bytes::get_Java_u8(bytes);
-        printf("long         "INT64_FORMAT, (int64_t) *(jlong *) &val);
+        printf("long         " INT64_FORMAT, (int64_t) *(jlong *) &val);
         ent_size = 8;
         idx++; // Long takes two cpool slots
         break;
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -308,7 +308,7 @@
                    adapter->size_of_parameters());
 
   if (TraceInvokeDynamic) {
-    tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
+    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)"),
@@ -538,12 +538,12 @@
   // print separator
   if (index == 0) st->print_cr("                 -------------");
   // print entry
-  st->print("%3d  ("PTR_FORMAT")  ", index, (intptr_t)this);
+  st->print("%3d  (" PTR_FORMAT ")  ", index, (intptr_t)this);
   st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(),
                constant_pool_index());
-  st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f1);
-  st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f2);
-  st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_flags);
+  st->print_cr("                 [   " PTR_FORMAT "]", (intptr_t)_f1);
+  st->print_cr("                 [   " PTR_FORMAT "]", (intptr_t)_f2);
+  st->print_cr("                 [   " PTR_FORMAT "]", (intptr_t)_flags);
   st->print_cr("                 -------------");
 }
 
--- a/hotspot/src/share/vm/oops/markOop.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/oops/markOop.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -49,7 +49,7 @@
         st->print("monitor=NULL");
       else {
         BasicLock * bl = (BasicLock *) mon->owner();
-        st->print("monitor={count="INTPTR_FORMAT",waiters="INTPTR_FORMAT",recursions="INTPTR_FORMAT",owner="INTPTR_FORMAT"}",
+        st->print("monitor={count=" INTPTR_FORMAT ",waiters=" INTPTR_FORMAT ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
                 mon->count(), mon->waiters(), mon->recursions(), p2i(bl));
       }
     } else {
--- a/hotspot/src/share/vm/oops/method.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -2019,9 +2019,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, (intptr_t)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 " ", (address)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();
--- a/hotspot/src/share/vm/oops/method.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -82,7 +82,8 @@
     _dont_inline          = 1 << 3,
     _hidden               = 1 << 4,
     _has_injected_profile = 1 << 5,
-    _running_emcp         = 1 << 6
+    _running_emcp         = 1 << 6,
+    _intrinsic_candidate  = 1 << 7
   };
   u1 _flags;
 
@@ -815,6 +816,13 @@
     _flags = x ? (_flags | _hidden) : (_flags & ~_hidden);
   }
 
+  bool intrinsic_candidate() {
+    return (_flags & _intrinsic_candidate) != 0;
+  }
+  void set_intrinsic_candidate(bool x) {
+    _flags = x ? (_flags | _intrinsic_candidate) : (_flags & ~_intrinsic_candidate);
+  }
+
   bool has_injected_profile() {
     return (_flags & _has_injected_profile) != 0;
   }
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -466,7 +466,7 @@
       if (i > max_objArray_print_length) {
         st->print("..."); break;
       }
-      st->print(" "INTPTR_FORMAT, (intptr_t)(void*)objArrayOop(obj)->obj_at(i));
+      st->print(" " INTPTR_FORMAT, (intptr_t)(void*)objArrayOop(obj)->obj_at(i));
     }
     st->print(" }");
   }
--- a/hotspot/src/share/vm/oops/oop.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/oops/oop.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -47,7 +47,7 @@
 
 void oopDesc::print_address_on(outputStream* st) const {
   if (PrintOopAddress) {
-    st->print("{"INTPTR_FORMAT"}", this);
+    st->print("{" INTPTR_FORMAT "}", this);
   }
 }
 
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -688,6 +688,12 @@
   product(bool, UseMulAddIntrinsic, false,                                  \
           "Enables intrinsification of BigInteger.mulAdd()")                \
                                                                             \
+  product(bool, UseMontgomeryMultiplyIntrinsic, false,                      \
+          "Enables intrinsification of BigInteger.montgomeryMultiply()")    \
+                                                                            \
+  product(bool, UseMontgomerySquareIntrinsic, false,                        \
+          "Enables intrinsification of BigInteger.montgomerySquare()")      \
+                                                                            \
   product(bool, UseTypeSpeculation, true,                                   \
           "Speculatively propagate types from profiles")                    \
                                                                             \
--- a/hotspot/src/share/vm/opto/callnode.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -342,7 +342,7 @@
     const Type *t = n->bottom_type();
     switch (t->base()) {
     case Type::Int:
-      st->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con());
+      st->print(" %s%d]=#" INT32_FORMAT,msg,i,t->is_int()->get_con());
       break;
     case Type::AnyPtr:
       assert( t == TypePtr::NULL_PTR || n->in_dump(), "" );
@@ -371,7 +371,7 @@
       st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f);
       break;
     case Type::Long:
-      st->print(" %s%d]=#"INT64_FORMAT,msg,i,(int64_t)(t->is_long()->get_con()));
+      st->print(" %s%d]=#" INT64_FORMAT,msg,i,(int64_t)(t->is_long()->get_con()));
       break;
     case Type::Half:
     case Type::Top:
--- a/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/escape.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -976,8 +976,10 @@
                   strcmp(call->as_CallLeaf()->_name, "sha512_implCompressMB") == 0 ||
                   strcmp(call->as_CallLeaf()->_name, "multiplyToLen") == 0 ||
                   strcmp(call->as_CallLeaf()->_name, "squareToLen") == 0 ||
-                  strcmp(call->as_CallLeaf()->_name, "mulAdd") == 0)
-                  ))) {
+                  strcmp(call->as_CallLeaf()->_name, "mulAdd") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "montgomery_multiply") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "montgomery_square") == 0)
+                 ))) {
             call->dump();
             fatal(err_msg_res("EA unexpected CallLeaf %s", call->as_CallLeaf()->_name));
           }
--- a/hotspot/src/share/vm/opto/generateOptoStub.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, 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
@@ -118,19 +118,14 @@
   // The C routines gets the base of thread-local storage passed in as an
   // extra argument.  Not all calls need it, but its cheap to add here.
   for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) {
-    // Convert ints to longs if required.
-    if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(pcnt)->isa_int()) {
-      fields[cnt++] = TypeLong::LONG;
-      fields[cnt]   = Type::HALF; // must add an additional half for a long
-    } else {
-      fields[cnt] = jdomain->field_at(pcnt);
-    }
+    fields[cnt] = jdomain->field_at(pcnt);
   }
 
   fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
   // Also pass in the caller's PC, if asked for.
-  if( return_pc )
+  if (return_pc) {
     fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC
+  }
 
   const TypeTuple* domain = TypeTuple::make(cnt,fields);
   // The C routine we are about to call cannot return an oop; it can block on
@@ -143,21 +138,22 @@
   const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms);
   // Fixup oop returns
   int retval_ptr = retval->isa_oop_ptr();
-  if( retval_ptr ) {
+  if (retval_ptr) {
     assert( pass_tls, "Oop must be returned thru TLS" );
     // Fancy-jumps return address; others return void
     rfields[TypeFunc::Parms] = is_fancy_jump ? TypeRawPtr::BOTTOM : Type::TOP;
 
-  } else if( retval->isa_int() ) { // Returning any integer subtype?
+  } else if (retval->isa_int()) { // Returning any integer subtype?
     // "Fatten" byte, char & short return types to 'int' to show that
     // the native C code can return values with junk high order bits.
     // We'll sign-extend it below later.
     rfields[TypeFunc::Parms] = TypeInt::INT; // It's "dirty" and needs sign-ext
 
-  } else if( jrange->cnt() >= TypeFunc::Parms+1 ) { // Else copy other types
+  } else if (jrange->cnt() >= TypeFunc::Parms+1) { // Else copy other types
     rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms);
-    if( jrange->cnt() == TypeFunc::Parms+2 )
+    if (jrange->cnt() == TypeFunc::Parms+2) {
       rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1);
+    }
   }
   const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields);
 
@@ -181,14 +177,7 @@
   // A little too aggressive on the parm copy; return address is not an input
   call->set_req(TypeFunc::ReturnAdr, top());
   for (; i < parm_cnt; i++) { // Regular input arguments
-    // Convert ints to longs if required.
-    if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(i)->isa_int()) {
-      Node* int_as_long = _gvn.transform(new ConvI2LNode(map()->in(i)));
-      call->init_req(cnt++, int_as_long); // long
-      call->init_req(cnt++, top());       // half
-    } else {
-      call->init_req(cnt++, map()->in(i));
-    }
+    call->init_req(cnt++, map()->in(i));
   }
 
   call->init_req( cnt++, thread );
--- a/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -297,6 +297,8 @@
   bool inline_multiplyToLen();
   bool inline_squareToLen();
   bool inline_mulAdd();
+  bool inline_montgomeryMultiply();
+  bool inline_montgomerySquare();
 
   bool inline_profileBoolean();
   bool inline_isCompileConstant();
@@ -508,6 +510,13 @@
     if (!UseMulAddIntrinsic) return NULL;
     break;
 
+  case vmIntrinsics::_montgomeryMultiply:
+     if (!UseMontgomeryMultiplyIntrinsic) return NULL;
+    break;
+  case vmIntrinsics::_montgomerySquare:
+     if (!UseMontgomerySquareIntrinsic) return NULL;
+    break;
+
   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
     if (!UseAESIntrinsics) return NULL;
@@ -642,7 +651,8 @@
   const int bci    = kit.bci();
 
   // Try to inline the intrinsic.
-  if (kit.try_to_inline(_last_predicate)) {
+  if ((CheckIntrinsics ? callee->intrinsic_candidate() : true) &&
+      kit.try_to_inline(_last_predicate)) {
     if (C->print_intrinsics() || C->print_inlining()) {
       C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
     }
@@ -663,7 +673,13 @@
   if (C->print_intrinsics() || C->print_inlining()) {
     if (jvms->has_method()) {
       // Not a root compile.
-      const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
+      const char* msg;
+      if (callee->intrinsic_candidate()) {
+        msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
+      } else {
+        msg = is_virtual() ? "failed to inline (intrinsic, virtual), method not annotated"
+                           : "failed to inline (intrinsic), method not annotated";
+      }
       C->print_inlining(callee, jvms->depth() - 1, bci, msg);
     } else {
       // Root compile
@@ -942,6 +958,11 @@
   case vmIntrinsics::_mulAdd:
     return inline_mulAdd();
 
+  case vmIntrinsics::_montgomeryMultiply:
+    return inline_montgomeryMultiply();
+  case vmIntrinsics::_montgomerySquare:
+    return inline_montgomerySquare();
+
   case vmIntrinsics::_ghash_processBlocks:
     return inline_ghash_processBlocks();
 
@@ -5244,7 +5265,7 @@
 
 //-------------inline_multiplyToLen-----------------------------------
 bool LibraryCallKit::inline_multiplyToLen() {
-  assert(UseMultiplyToLenIntrinsic, "not implementated on this platform");
+  assert(UseMultiplyToLenIntrinsic, "not implemented on this platform");
 
   address stubAddr = StubRoutines::multiplyToLen();
   if (stubAddr == NULL) {
@@ -5254,11 +5275,12 @@
 
   assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters");
 
-  Node* x    = argument(1);
-  Node* xlen = argument(2);
-  Node* y    = argument(3);
-  Node* ylen = argument(4);
-  Node* z    = argument(5);
+  // no receiver because it is a static method
+  Node* x    = argument(0);
+  Node* xlen = argument(1);
+  Node* y    = argument(2);
+  Node* ylen = argument(3);
+  Node* z    = argument(4);
 
   const Type* x_type = x->Value(&_gvn);
   const Type* y_type = y->Value(&_gvn);
@@ -5437,6 +5459,121 @@
   return true;
 }
 
+//-------------inline_montgomeryMultiply-----------------------------------
+bool LibraryCallKit::inline_montgomeryMultiply() {
+  address stubAddr = StubRoutines::montgomeryMultiply();
+  if (stubAddr == NULL) {
+    return false; // Intrinsic's stub is not implemented on this platform
+  }
+
+  assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform");
+  const char* stubName = "montgomery_square";
+
+  assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters");
+
+  Node* a    = argument(0);
+  Node* b    = argument(1);
+  Node* n    = argument(2);
+  Node* len  = argument(3);
+  Node* inv  = argument(4);
+  Node* m    = argument(6);
+
+  const Type* a_type = a->Value(&_gvn);
+  const TypeAryPtr* top_a = a_type->isa_aryptr();
+  const Type* b_type = b->Value(&_gvn);
+  const TypeAryPtr* top_b = b_type->isa_aryptr();
+  const Type* n_type = a->Value(&_gvn);
+  const TypeAryPtr* top_n = n_type->isa_aryptr();
+  const Type* m_type = a->Value(&_gvn);
+  const TypeAryPtr* top_m = m_type->isa_aryptr();
+  if (top_a  == NULL || top_a->klass()  == NULL ||
+      top_b == NULL || top_b->klass()  == NULL ||
+      top_n == NULL || top_n->klass()  == NULL ||
+      top_m == NULL || top_m->klass()  == NULL) {
+    // failed array check
+    return false;
+  }
+
+  BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  BasicType b_elem = b_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  if (a_elem != T_INT || b_elem != T_INT || n_elem != T_INT || m_elem != T_INT) {
+    return false;
+  }
+
+  // Make the call
+  {
+    Node* a_start = array_element_address(a, intcon(0), a_elem);
+    Node* b_start = array_element_address(b, intcon(0), b_elem);
+    Node* n_start = array_element_address(n, intcon(0), n_elem);
+    Node* m_start = array_element_address(m, intcon(0), m_elem);
+
+    Node* call = make_runtime_call(RC_LEAF,
+                                   OptoRuntime::montgomeryMultiply_Type(),
+                                   stubAddr, stubName, TypePtr::BOTTOM,
+                                   a_start, b_start, n_start, len, inv, top(),
+                                   m_start);
+    set_result(m);
+  }
+
+  return true;
+}
+
+bool LibraryCallKit::inline_montgomerySquare() {
+  address stubAddr = StubRoutines::montgomerySquare();
+  if (stubAddr == NULL) {
+    return false; // Intrinsic's stub is not implemented on this platform
+  }
+
+  assert(UseMontgomerySquareIntrinsic, "not implemented on this platform");
+  const char* stubName = "montgomery_square";
+
+  assert(callee()->signature()->size() == 6, "montgomerySquare has 6 parameters");
+
+  Node* a    = argument(0);
+  Node* n    = argument(1);
+  Node* len  = argument(2);
+  Node* inv  = argument(3);
+  Node* m    = argument(5);
+
+  const Type* a_type = a->Value(&_gvn);
+  const TypeAryPtr* top_a = a_type->isa_aryptr();
+  const Type* n_type = a->Value(&_gvn);
+  const TypeAryPtr* top_n = n_type->isa_aryptr();
+  const Type* m_type = a->Value(&_gvn);
+  const TypeAryPtr* top_m = m_type->isa_aryptr();
+  if (top_a  == NULL || top_a->klass()  == NULL ||
+      top_n == NULL || top_n->klass()  == NULL ||
+      top_m == NULL || top_m->klass()  == NULL) {
+    // failed array check
+    return false;
+  }
+
+  BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  if (a_elem != T_INT || n_elem != T_INT || m_elem != T_INT) {
+    return false;
+  }
+
+  // Make the call
+  {
+    Node* a_start = array_element_address(a, intcon(0), a_elem);
+    Node* n_start = array_element_address(n, intcon(0), n_elem);
+    Node* m_start = array_element_address(m, intcon(0), m_elem);
+
+    Node* call = make_runtime_call(RC_LEAF,
+                                   OptoRuntime::montgomerySquare_Type(),
+                                   stubAddr, stubName, TypePtr::BOTTOM,
+                                   a_start, n_start, len, inv, top(),
+                                   m_start);
+    set_result(m);
+  }
+
+  return true;
+}
+
 
 /**
  * Calculate CRC32 for byte.
--- a/hotspot/src/share/vm/opto/loopTransform.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -2941,13 +2941,6 @@
     _igvn.register_new_node_with_optimizer(store_value);
   }
 
-  if (CCallingConventionRequiresIntsAsLongs &&
-      // See StubRoutines::select_fill_function for types. FLOAT has been converted to INT.
-      (t == T_FLOAT || t == T_INT ||  is_subword_type(t))) {
-    store_value = new ConvI2LNode(store_value);
-    _igvn.register_new_node_with_optimizer(store_value);
-  }
-
   Node* mem_phi = store->in(MemNode::Memory);
   Node* result_ctrl;
   Node* result_mem;
@@ -2957,9 +2950,6 @@
   uint cnt = 0;
   call->init_req(TypeFunc::Parms + cnt++, from);
   call->init_req(TypeFunc::Parms + cnt++, store_value);
-  if (CCallingConventionRequiresIntsAsLongs) {
-    call->init_req(TypeFunc::Parms + cnt++, C->top());
-  }
 #ifdef _LP64
   len = new ConvI2LNode(len);
   _igvn.register_new_node_with_optimizer(len);
--- a/hotspot/src/share/vm/opto/regmask.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/regmask.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -25,6 +25,8 @@
 #include "precompiled.hpp"
 #include "opto/ad.hpp"
 #include "opto/compile.hpp"
+#include "opto/matcher.hpp"
+#include "opto/node.hpp"
 #include "opto/regmask.hpp"
 
 #define RM_SIZE _RM_SIZE /* a constant private to the class RegMask */
--- a/hotspot/src/share/vm/opto/runtime.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/runtime.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -779,18 +779,10 @@
 const TypeFunc* OptoRuntime::array_fill_Type() {
   const Type** fields;
   int argp = TypeFunc::Parms;
-  if (CCallingConventionRequiresIntsAsLongs) {
   // create input type (domain): pointer, int, size_t
-    fields = TypeTuple::fields(3 LP64_ONLY( + 2));
-    fields[argp++] = TypePtr::NOTNULL;
-    fields[argp++] = TypeLong::LONG;
-    fields[argp++] = Type::HALF;
-  } else {
-    // create input type (domain): pointer, int, size_t
-    fields = TypeTuple::fields(3 LP64_ONLY( + 1));
-    fields[argp++] = TypePtr::NOTNULL;
-    fields[argp++] = TypeInt::INT;
-  }
+  fields = TypeTuple::fields(3 LP64_ONLY( + 1));
+  fields[argp++] = TypePtr::NOTNULL;
+  fields[argp++] = TypeInt::INT;
   fields[argp++] = TypeX_X;               // size in whatevers (size_t)
   LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
   const TypeTuple *domain = TypeTuple::make(argp, fields);
@@ -1010,6 +1002,53 @@
   return TypeFunc::make(domain, range);
 }
 
+const TypeFunc* OptoRuntime::montgomeryMultiply_Type() {
+  // create input type (domain)
+  int num_args      = 7;
+  int argcnt = num_args;
+  const Type** fields = TypeTuple::fields(argcnt);
+  int argp = TypeFunc::Parms;
+  fields[argp++] = TypePtr::NOTNULL;    // a
+  fields[argp++] = TypePtr::NOTNULL;    // b
+  fields[argp++] = TypePtr::NOTNULL;    // n
+  fields[argp++] = TypeInt::INT;        // len
+  fields[argp++] = TypeLong::LONG;      // inv
+  fields[argp++] = Type::HALF;
+  fields[argp++] = TypePtr::NOTNULL;    // result
+  assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
+  const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
+
+  // result type needed
+  fields = TypeTuple::fields(1);
+  fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
+
+  const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
+  return TypeFunc::make(domain, range);
+}
+
+const TypeFunc* OptoRuntime::montgomerySquare_Type() {
+  // create input type (domain)
+  int num_args      = 6;
+  int argcnt = num_args;
+  const Type** fields = TypeTuple::fields(argcnt);
+  int argp = TypeFunc::Parms;
+  fields[argp++] = TypePtr::NOTNULL;    // a
+  fields[argp++] = TypePtr::NOTNULL;    // n
+  fields[argp++] = TypeInt::INT;        // len
+  fields[argp++] = TypeLong::LONG;      // inv
+  fields[argp++] = Type::HALF;
+  fields[argp++] = TypePtr::NOTNULL;    // result
+  assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
+  const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
+
+  // result type needed
+  fields = TypeTuple::fields(1);
+  fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
+
+  const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
+  return TypeFunc::make(domain, range);
+}
+
 // GHASH block processing
 const TypeFunc* OptoRuntime::ghash_processBlocks_Type() {
     int argcnt = 4;
--- a/hotspot/src/share/vm/opto/runtime.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/opto/runtime.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -311,6 +311,8 @@
   static const TypeFunc* digestBase_implCompressMB_Type();
 
   static const TypeFunc* multiplyToLen_Type();
+  static const TypeFunc* montgomeryMultiply_Type();
+  static const TypeFunc* montgomerySquare_Type();
 
   static const TypeFunc* squareToLen_Type();
 
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -57,12 +57,15 @@
 # include "classfile/classFileParser.hpp"
 # include "classfile/classFileStream.hpp"
 # include "classfile/classLoader.hpp"
+# include "classfile/imageDecompressor.hpp"
+# include "classfile/imageFile.hpp"
 # include "classfile/javaClasses.hpp"
 # include "classfile/symbolTable.hpp"
 # include "classfile/systemDictionary.hpp"
 # include "classfile/vmSymbols.hpp"
 # include "code/codeBlob.hpp"
 # include "code/codeCache.hpp"
+# include "code/codeCacheExtensions.hpp"
 # include "code/compressedStream.hpp"
 # include "code/debugInfo.hpp"
 # include "code/debugInfoRec.hpp"
@@ -229,6 +232,7 @@
 # include "utilities/constantTag.hpp"
 # include "utilities/copy.hpp"
 # include "utilities/debug.hpp"
+# include "utilities/endian.hpp"
 # include "utilities/exceptions.hpp"
 # include "utilities/globalDefinitions.hpp"
 # include "utilities/growableArray.hpp"
--- a/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/prims/jni.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -3848,6 +3848,7 @@
   unit_test_function_call
 
 // Forward declaration
+void test_semaphore();
 void TestOS_test();
 void TestReservedSpace_test();
 void TestReserveMemorySpecial_test();
@@ -3873,6 +3874,7 @@
 void execute_internal_vm_tests() {
   if (ExecuteInternalVMTests) {
     tty->print_cr("Running internal VM tests");
+    run_unit_test(test_semaphore());
     run_unit_test(TestOS_test());
     run_unit_test(TestReservedSpace_test());
     run_unit_test(TestReserveMemorySpecial_test());
--- a/hotspot/src/share/vm/prims/jvm.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -24,6 +24,8 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
+#include "classfile/imageDecompressor.hpp"
+#include "classfile/imageFile.hpp"
 #include "classfile/javaAssertions.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/stringTable.hpp"
@@ -69,6 +71,7 @@
 #include "utilities/copy.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/dtrace.hpp"
+#include "utilities/endian.hpp"
 #include "utilities/events.hpp"
 #include "utilities/histogram.hpp"
 #include "utilities/macros.hpp"
@@ -3665,3 +3668,244 @@
   info->is_attachable = AttachListener::is_attach_supported();
 }
 JVM_END
+
+// jdk.internal.jimage /////////////////////////////////////////////////////////
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+
+// Java entry to open an image file for sharing.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong,
+JVM_ImageOpen(JNIEnv *env, const char *nativePath, jboolean big_endian)) {
+  JVMWrapper("JVM_ImageOpen");
+  // Open image file for reading.
+  ImageFileReader* reader = ImageFileReader::open(nativePath, big_endian != JNI_FALSE);
+  // Return image ID as a jlong.
+  return ImageFileReader::readerToID(reader);
+}
+JVM_END
+
+// Java entry for closing a shared image file.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(void,
+JVM_ImageClose(JNIEnv *env, jlong id)) {
+  JVMWrapper("JVM_ImageClose");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // If valid reader the close.
+  if (reader != NULL) {
+    ImageFileReader::close(reader);
+  }
+}
+JVM_END
+
+// Java entry for accessing the base address of the image index.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong,
+JVM_ImageGetIndexAddress(JNIEnv *env, jlong id)) {
+  JVMWrapper("JVM_ImageGetIndexAddress");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // If valid reader return index base address (as jlong) else zero.
+  return  reader != NULL ? (jlong)reader->get_index_address() : 0L;
+}
+JVM_END
+
+// Java entry for accessing the base address of the image data.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong,
+JVM_ImageGetDataAddress(JNIEnv *env, jlong id)) {
+  JVMWrapper("JVM_ImageGetDataAddress");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // If valid reader return data base address (as jlong) else zero.
+  return MemoryMapImage && reader != NULL ? (jlong)reader->get_data_address() : 0L;
+}
+JVM_END
+
+// Java entry for reading an uncompressed resource from the image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jboolean,
+JVM_ImageRead(JNIEnv *env, jlong id, jlong offset,
+              unsigned char* uncompressedAddress, jlong uncompressed_size)) {
+  JVMWrapper("JVM_ImageRead");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);\
+  // If not a valid reader the fail the read.
+  if (reader == NULL) return false;
+  // Get the file offset of resource data.
+  u8 file_offset = reader->get_index_size() + offset;
+  // Check validity of arguments.
+  if (offset < 0 ||
+      uncompressed_size < 0 ||
+      file_offset > reader->file_size() - uncompressed_size) {
+      return false;
+  }
+  // Read file content into buffer.
+  return (jboolean)reader->read_at((u1*)uncompressedAddress, uncompressed_size,
+                                   file_offset);
+}
+JVM_END
+
+// Java entry for reading a compressed resource from the image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jboolean,
+JVM_ImageReadCompressed(JNIEnv *env,
+                    jlong id, jlong offset,
+                    unsigned char* compressedAddress, jlong compressed_size,
+                    unsigned char* uncompressedAddress, jlong uncompressed_size)) {
+  JVMWrapper("JVM_ImageReadCompressed");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // If not a valid reader the fail the read.
+  if (reader == NULL) return false;
+  // Get the file offset of resource data.
+  u8 file_offset = reader->get_index_size() + offset;
+  // Check validity of arguments.
+  if (offset < 0 ||
+      compressed_size < 0 ||
+      uncompressed_size < 0 ||
+      file_offset > reader->file_size() - compressed_size) {
+      return false;
+  }
+
+  // Read file content into buffer.
+  bool is_read = reader->read_at(compressedAddress, compressed_size,
+                                 file_offset);
+  // If successfully read then decompress.
+  if (is_read) {
+    const ImageStrings strings = reader->get_strings();
+    ImageDecompressor::decompress_resource(compressedAddress, uncompressedAddress,
+    uncompressed_size, &strings, true);
+  }
+  return (jboolean)is_read;
+}
+JVM_END
+
+// Java entry for retrieving UTF-8 bytes from image string table.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(const char*, JVM_ImageGetStringBytes(JNIEnv *env, jlong id, jint offset)) {
+  JVMWrapper("JVM_ImageGetStringBytes");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // Fail if not valid reader.
+  if (reader == NULL) return NULL;
+  // Manage image string table.
+  ImageStrings strings = reader->get_strings();
+  // Retrieve string adrress from table.
+  const char* data = strings.get(offset);
+  return data;
+}
+JVM_END
+
+// Utility function to copy location information into a jlong array.
+// WARNING: This function is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+static void image_expand_location(JNIEnv *env, jlong* rawAttributes, ImageLocation& location) {
+  // Copy attributes from location.
+  for (int kind = ImageLocation::ATTRIBUTE_END + 1;
+           kind < ImageLocation::ATTRIBUTE_COUNT;
+           kind++) {
+    rawAttributes[kind] = location.get_attribute(kind);
+  }
+}
+
+// Java entry for retrieving location attributes for attribute offset.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong*, JVM_ImageGetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset)) {
+  JVMWrapper("JVM_ImageGetAttributes");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // Fail if not valid reader.
+  if (reader == NULL) return NULL;
+  // Retrieve first byte address of resource's location attribute stream.
+  u1* data = reader->get_location_offset_data(offset);
+  // Fail if not valid offset.
+  if (data == NULL) return NULL;
+  // Expand stream into array.
+  ImageLocation location(data);
+  image_expand_location(env, rawAttributes, location);
+  return rawAttributes;
+}
+JVM_END
+
+// Java entry for retrieving location attributes count for attribute offset.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jsize, JVM_ImageGetAttributesCount(JNIEnv *env)) {
+  JVMWrapper("JVM_ImageGetAttributesCount");
+  return ImageLocation::ATTRIBUTE_COUNT;
+}
+JVM_END
+
+// Java entry for retrieving location attributes for named resource.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong*,
+JVM_ImageFindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id)) {
+  JVMWrapper("JVM_ImageFindAttributes");
+  // Mark for temporary buffers.
+  ResourceMark rm;
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // Fail if not valid reader.
+  if (reader == NULL) return NULL;
+  // Convert byte array to a cstring.
+  char* path = NEW_RESOURCE_ARRAY(char, size + 1);
+  memcpy(path, rawBytes, size);
+  path[size] = '\0';
+  // Locate resource location data.
+  ImageLocation location;
+  bool found = reader->find_location(path, location);
+  // Resource not found.
+  if (!found) return NULL;
+  // Expand stream into array.
+  image_expand_location(env, rawAttributes, location);
+  return rawAttributes;
+}
+JVM_END
+
+// Java entry for retrieving all the attribute stream offsets from an image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jint*, JVM_ImageAttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id)) {
+  JVMWrapper("JVM_ImageAttributeOffsets");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // Fail if not valid reader.
+  if (reader == NULL) return NULL;
+  // Determine endian for reader.
+  Endian* endian = reader->endian();
+  // Get base address of attribute stream offsets table.
+  u4* offsets_table = reader->offsets_table();
+  // Allocate int array result.
+  // Copy values to result (converting endian.)
+  for (u4 i = 0; i < length; i++) {
+    rawOffsets[i] = endian->get(offsets_table[i]);
+  }
+  return rawOffsets;
+}
+JVM_END
+
+// Java entry for retrieving all the attribute stream offsets length from an image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(unsigned int, JVM_ImageAttributeOffsetsLength(JNIEnv *env, jlong id)) {
+  JVMWrapper("JVM_ImageAttributeOffsetsLength");
+  // Convert image ID to image reader structure.
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  // Fail if not valid reader.
+  if (reader == NULL) return 0;
+  // Get perfect hash table length.
+  u4 length = reader->table_length();
+  return (jint) length;
+}
+JVM_END
--- a/hotspot/src/share/vm/prims/jvm.h	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvm.h	Thu Jul 09 22:46:16 2015 -0700
@@ -571,6 +571,52 @@
 JNIEXPORT jboolean JNICALL
 JVM_SupportsCX8(void);
 
+/*
+ * jdk.internal.jimage
+ * WARNING: This API is experimental and temporary during JDK 9 development
+ * cycle. It will not be supported in the eventual JDK 9 release.
+ */
+
+JNIEXPORT jlong JNICALL
+JVM_ImageOpen(JNIEnv *env, const char *nativePath, jboolean big_endian);
+
+JNIEXPORT void JNICALL
+JVM_ImageClose(JNIEnv *env, jlong id);
+
+JNIEXPORT jlong JNICALL
+JVM_ImageGetIndexAddress(JNIEnv *env, jlong id);
+
+JNIEXPORT jlong JNICALL
+JVM_ImageGetDataAddress(JNIEnv *env,jlong id);
+
+JNIEXPORT jboolean JNICALL
+JVM_ImageRead(JNIEnv *env, jlong id, jlong offset,
+            unsigned char* uncompressedAddress, jlong uncompressed_size);
+
+
+JNIEXPORT jboolean JNICALL
+JVM_ImageReadCompressed(JNIEnv *env, jlong id, jlong offset,
+            unsigned char* compressedBuffer, jlong compressed_size,
+            unsigned char* uncompressedBuffer, jlong uncompressed_size);
+
+JNIEXPORT const char* JNICALL
+JVM_ImageGetStringBytes(JNIEnv *env, jlong id, jint offset);
+
+JNIEXPORT jlong* JNICALL
+JVM_ImageGetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset);
+
+JNIEXPORT jsize JNICALL
+JVM_ImageGetAttributesCount(JNIEnv *env);
+
+JNIEXPORT jlong* JNICALL
+JVM_ImageFindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id);
+
+JNIEXPORT jint* JNICALL
+JVM_ImageAttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id);
+
+JNIEXPORT unsigned int JNICALL
+JVM_ImageAttributeOffsetsLength(JNIEnv *env, jlong id);
+
 /*************************************************************************
  PART 2: Support for the Verifier and Class File Format Checker
  ************************************************************************/
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -26,6 +26,7 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/stringTable.hpp"
 #include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/oopMapCache.hpp"
@@ -100,6 +101,7 @@
     StubCodeMark mark(this, "MethodHandle::interpreter_entry", vmIntrinsics::name_at(iid));
     address entry = MethodHandles::generate_method_handle_interpreter_entry(_masm, iid);
     if (entry != NULL) {
+      CodeCacheExtensions::handle_generated_pc(entry, vmIntrinsics::name_at(iid));
       Interpreter::set_entry_for_kind(mk, entry);
     }
     // If the entry is not set, it will throw AbstractMethodError.
@@ -1389,41 +1391,41 @@
 #define LANG "Ljava/lang/"
 #define JLINV "Ljava/lang/invoke/"
 
-#define OBJ   LANG"Object;"
-#define CLS   LANG"Class;"
-#define STRG  LANG"String;"
-#define CS    JLINV"CallSite;"
-#define MT    JLINV"MethodType;"
-#define MH    JLINV"MethodHandle;"
-#define MEM   JLINV"MemberName;"
-#define CTX   JLINV"MethodHandleNatives$CallSiteContext;"
+#define OBJ   LANG "Object;"
+#define CLS   LANG "Class;"
+#define STRG  LANG "String;"
+#define CS    JLINV "CallSite;"
+#define MT    JLINV "MethodType;"
+#define MH    JLINV "MethodHandle;"
+#define MEM   JLINV "MemberName;"
+#define CTX   JLINV "MethodHandleNatives$CallSiteContext;"
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
 
 // These are the native methods on java.lang.invoke.MethodHandleNatives.
 static JNINativeMethod MHN_methods[] = {
-  {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
-  {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
-  {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
+  {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
+  {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
+  {CC "resolve",                   CC "(" MEM "" CLS ")" MEM,                FN_PTR(MHN_resolve_Mem)},
   //  static native int getNamedCon(int which, Object[] name)
-  {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
+  {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
-  {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
-  {CC"objectFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_objectFieldOffset)},
-  {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
-  {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)},
-  {CC"clearCallSiteContext",      CC"("CTX")V",                          FN_PTR(MHN_clearCallSiteContext)},
-  {CC"staticFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_staticFieldOffset)},
-  {CC"staticFieldBase",           CC"("MEM")"OBJ,                        FN_PTR(MHN_staticFieldBase)},
-  {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
+  {CC "getMembers",                CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
+  {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
+  {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
+  {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
+  {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
+  {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
+  {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
+  {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
 };
 
 static JNINativeMethod MH_methods[] = {
   // UnsupportedOperationException throwers
-  {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
-  {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
+  {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
+  {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
 };
 
 /**
--- a/hotspot/src/share/vm/prims/perf.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/prims/perf.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -295,17 +295,17 @@
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
 #define BB "Ljava/nio/ByteBuffer;"
 #define JLS "Ljava/lang/String;"
-#define CL_ARGS     CC"("JLS"IIJ)"BB
-#define CBA_ARGS    CC"("JLS"II[BI)"BB
+#define CL_ARGS     CC "(" JLS "IIJ)" BB
+#define CBA_ARGS    CC "(" JLS "II[BI)" BB
 
 static JNINativeMethod perfmethods[] = {
 
-  {CC"attach",              CC"("JLS"II)"BB,  FN_PTR(Perf_Attach)},
-  {CC"detach",              CC"("BB")V",      FN_PTR(Perf_Detach)},
-  {CC"createLong",          CL_ARGS,          FN_PTR(Perf_CreateLong)},
-  {CC"createByteArray",     CBA_ARGS,         FN_PTR(Perf_CreateByteArray)},
-  {CC"highResCounter",      CC"()J",          FN_PTR(Perf_HighResCounter)},
-  {CC"highResFrequency",    CC"()J",          FN_PTR(Perf_HighResFrequency)}
+  {CC "attach",              CC "(" JLS "II)" BB, FN_PTR(Perf_Attach)},
+  {CC "detach",              CC "(" BB ")V",      FN_PTR(Perf_Detach)},
+  {CC "createLong",          CL_ARGS,             FN_PTR(Perf_CreateLong)},
+  {CC "createByteArray",     CBA_ARGS,            FN_PTR(Perf_CreateByteArray)},
+  {CC "highResCounter",      CC "()J",            FN_PTR(Perf_HighResCounter)},
+  {CC "highResFrequency",    CC "()J",            FN_PTR(Perf_HighResFrequency)}
 };
 
 #undef CBA_ARGS
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1206,39 +1206,39 @@
 
 #define LANG "Ljava/lang/"
 
-#define OBJ LANG"Object;"
-#define CLS LANG"Class;"
-#define FLD LANG"reflect/Field;"
-#define THR LANG"Throwable;"
+#define OBJ LANG "Object;"
+#define CLS LANG "Class;"
+#define FLD LANG "reflect/Field;"
+#define THR LANG "Throwable;"
 
-#define DC_Args  LANG"String;[BII" LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
-#define DAC_Args CLS"[B["OBJ
+#define DC_Args  LANG "String;[BII" LANG "ClassLoader;" "Ljava/security/ProtectionDomain;"
+#define DAC_Args CLS "[B[" OBJ
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
 
 #define DECLARE_GETPUTOOP(Boolean, Z) \
-    {CC"get"#Boolean,      CC"("OBJ"J)"#Z,      FN_PTR(Unsafe_Get##Boolean)}, \
-    {CC"put"#Boolean,      CC"("OBJ"J"#Z")V",   FN_PTR(Unsafe_Set##Boolean)}, \
-    {CC"get"#Boolean"Volatile",      CC"("OBJ"J)"#Z,      FN_PTR(Unsafe_Get##Boolean##Volatile)}, \
-    {CC"put"#Boolean"Volatile",      CC"("OBJ"J"#Z")V",   FN_PTR(Unsafe_Set##Boolean##Volatile)}
+    {CC "get" #Boolean,      CC "(" OBJ "J)" #Z,       FN_PTR(Unsafe_Get##Boolean)}, \
+    {CC "put" #Boolean,      CC "(" OBJ "J" #Z ")V",   FN_PTR(Unsafe_Set##Boolean)}, \
+    {CC "get" #Boolean "Volatile",      CC "(" OBJ "J)" #Z,       FN_PTR(Unsafe_Get##Boolean##Volatile)}, \
+    {CC "put" #Boolean "Volatile",      CC "(" OBJ "J" #Z ")V",   FN_PTR(Unsafe_Set##Boolean##Volatile)}
 
 
 #define DECLARE_GETPUTNATIVE(Byte, B) \
-    {CC"get"#Byte,         CC"("ADR")"#B,       FN_PTR(Unsafe_GetNative##Byte)}, \
-    {CC"put"#Byte,         CC"("ADR#B")V",      FN_PTR(Unsafe_SetNative##Byte)}
+    {CC "get" #Byte,         CC "(" ADR ")" #B,       FN_PTR(Unsafe_GetNative##Byte)}, \
+    {CC "put" #Byte,         CC "(" ADR#B ")V",       FN_PTR(Unsafe_SetNative##Byte)}
 
 
 
 static JNINativeMethod methods[] = {
-    {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
-    {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
-    {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObjectVolatile)},
-    {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
+    {CC "getObject",        CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObject)},
+    {CC "putObject",        CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_SetObject)},
+    {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObjectVolatile)},
+    {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
 
-    {CC"getUncompressedObject", CC"("ADR")"OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
-    {CC"getJavaMirror",         CC"("ADR")"CLS, FN_PTR(Unsafe_GetJavaMirror)},
-    {CC"getKlassPointer",       CC"("OBJ")"ADR, FN_PTR(Unsafe_GetKlassPointer)},
+    {CC "getUncompressedObject", CC "(" ADR ")" OBJ,  FN_PTR(Unsafe_GetUncompressedObject)},
+    {CC "getJavaMirror",         CC "(" ADR ")" CLS,  FN_PTR(Unsafe_GetJavaMirror)},
+    {CC "getKlassPointer",       CC "(" OBJ ")" ADR,  FN_PTR(Unsafe_GetKlassPointer)},
 
     DECLARE_GETPUTOOP(Boolean, Z),
     DECLARE_GETPUTOOP(Byte, B),
@@ -1257,49 +1257,49 @@
     DECLARE_GETPUTNATIVE(Float, F),
     DECLARE_GETPUTNATIVE(Double, D),
 
-    {CC"getAddress",         CC"("ADR")"ADR,             FN_PTR(Unsafe_GetNativeAddress)},
-    {CC"putAddress",         CC"("ADR""ADR")V",          FN_PTR(Unsafe_SetNativeAddress)},
+    {CC "getAddress",         CC "(" ADR ")" ADR,        FN_PTR(Unsafe_GetNativeAddress)},
+    {CC "putAddress",         CC "(" ADR "" ADR ")V",    FN_PTR(Unsafe_SetNativeAddress)},
 
-    {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
-    {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-    {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
+    {CC "allocateMemory",     CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory)},
+    {CC "reallocateMemory",   CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory)},
+    {CC "freeMemory",         CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory)},
 
-    {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
-    {CC"staticFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_StaticFieldOffset)},
-    {CC"staticFieldBase",    CC"("FLD")"OBJ,             FN_PTR(Unsafe_StaticFieldBaseFromField)},
-    {CC"ensureClassInitialized",CC"("CLS")V",            FN_PTR(Unsafe_EnsureClassInitialized)},
-    {CC"arrayBaseOffset",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayBaseOffset)},
-    {CC"arrayIndexScale",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayIndexScale)},
-    {CC"addressSize",        CC"()I",                    FN_PTR(Unsafe_AddressSize)},
-    {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
+    {CC "objectFieldOffset",  CC "(" FLD ")J",           FN_PTR(Unsafe_ObjectFieldOffset)},
+    {CC "staticFieldOffset",  CC "(" FLD ")J",           FN_PTR(Unsafe_StaticFieldOffset)},
+    {CC "staticFieldBase",    CC "(" FLD ")" OBJ,        FN_PTR(Unsafe_StaticFieldBaseFromField)},
+    {CC "ensureClassInitialized",CC "(" CLS ")V",        FN_PTR(Unsafe_EnsureClassInitialized)},
+    {CC "arrayBaseOffset",    CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayBaseOffset)},
+    {CC "arrayIndexScale",    CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayIndexScale)},
+    {CC "addressSize",        CC "()I",                  FN_PTR(Unsafe_AddressSize)},
+    {CC "pageSize",           CC "()I",                  FN_PTR(Unsafe_PageSize)},
 
-    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
-    {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
-    {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)},
-    {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z",  FN_PTR(Unsafe_CompareAndSwapObject)},
-    {CC"compareAndSwapInt",  CC"("OBJ"J""I""I"")Z",      FN_PTR(Unsafe_CompareAndSwapInt)},
-    {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z",      FN_PTR(Unsafe_CompareAndSwapLong)},
-    {CC"putOrderedObject",   CC"("OBJ"J"OBJ")V",         FN_PTR(Unsafe_SetOrderedObject)},
-    {CC"putOrderedInt",      CC"("OBJ"JI)V",             FN_PTR(Unsafe_SetOrderedInt)},
-    {CC"putOrderedLong",     CC"("OBJ"JJ)V",             FN_PTR(Unsafe_SetOrderedLong)},
-    {CC"park",               CC"(ZJ)V",                  FN_PTR(Unsafe_Park)},
-    {CC"unpark",             CC"("OBJ")V",               FN_PTR(Unsafe_Unpark)},
+    {CC "defineClass",        CC "(" DC_Args ")" CLS,    FN_PTR(Unsafe_DefineClass)},
+    {CC "allocateInstance",   CC "(" CLS ")" OBJ,        FN_PTR(Unsafe_AllocateInstance)},
+    {CC "throwException",     CC "(" THR ")V",           FN_PTR(Unsafe_ThrowException)},
+    {CC "compareAndSwapObject", CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSwapObject)},
+    {CC "compareAndSwapInt",  CC "(" OBJ "J""I""I"")Z",  FN_PTR(Unsafe_CompareAndSwapInt)},
+    {CC "compareAndSwapLong", CC "(" OBJ "J""J""J"")Z",  FN_PTR(Unsafe_CompareAndSwapLong)},
+    {CC "putOrderedObject",   CC "(" OBJ "J" OBJ ")V",   FN_PTR(Unsafe_SetOrderedObject)},
+    {CC "putOrderedInt",      CC "(" OBJ "JI)V",         FN_PTR(Unsafe_SetOrderedInt)},
+    {CC "putOrderedLong",     CC "(" OBJ "JJ)V",         FN_PTR(Unsafe_SetOrderedLong)},
+    {CC "park",               CC "(ZJ)V",                FN_PTR(Unsafe_Park)},
+    {CC "unpark",             CC "(" OBJ ")V",           FN_PTR(Unsafe_Unpark)},
 
-    {CC"getLoadAverage",     CC"([DI)I",                 FN_PTR(Unsafe_Loadavg)},
+    {CC "getLoadAverage",     CC "([DI)I",               FN_PTR(Unsafe_Loadavg)},
 
-    {CC"copyMemory",         CC"("OBJ"J"OBJ"JJ)V",       FN_PTR(Unsafe_CopyMemory)},
-    {CC"setMemory",          CC"("OBJ"JJB)V",            FN_PTR(Unsafe_SetMemory)},
+    {CC "copyMemory",         CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory)},
+    {CC "setMemory",          CC "(" OBJ "JJB)V",        FN_PTR(Unsafe_SetMemory)},
 
-    {CC"defineAnonymousClass", CC"("DAC_Args")"CLS,      FN_PTR(Unsafe_DefineAnonymousClass)},
+    {CC "defineAnonymousClass", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
 
-    {CC"shouldBeInitialized",CC"("CLS")Z",               FN_PTR(Unsafe_ShouldBeInitialized)},
+    {CC "shouldBeInitialized",CC "(" CLS ")Z",           FN_PTR(Unsafe_ShouldBeInitialized)},
 
-    {CC"loadFence",          CC"()V",                    FN_PTR(Unsafe_LoadFence)},
-    {CC"storeFence",         CC"()V",                    FN_PTR(Unsafe_StoreFence)},
-    {CC"fullFence",          CC"()V",                    FN_PTR(Unsafe_FullFence)},
+    {CC "loadFence",          CC "()V",                  FN_PTR(Unsafe_LoadFence)},
+    {CC "storeFence",         CC "()V",                  FN_PTR(Unsafe_StoreFence)},
+    {CC "fullFence",          CC "()V",                  FN_PTR(Unsafe_FullFence)},
 
-    {CC"isBigEndian0",       CC"()Z",                    FN_PTR(Unsafe_isBigEndian0)},
-    {CC"unalignedAccess0",   CC"()Z",                    FN_PTR(Unsafe_unalignedAccess0)}
+    {CC "isBigEndian0",       CC "()Z",                  FN_PTR(Unsafe_isBigEndian0)},
+    {CC "unalignedAccess0",   CC "()Z",                  FN_PTR(Unsafe_unalignedAccess0)}
 };
 
 #undef CC
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -27,6 +27,7 @@
 #include <new>
 
 #include "classfile/classLoaderData.hpp"
+#include "classfile/imageFile.hpp"
 #include "classfile/stringTable.hpp"
 #include "code/codeCache.hpp"
 #include "jvmtifiles/jvmtiEnv.hpp"
@@ -159,8 +160,8 @@
 
 WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
   CollectorPolicy * p = Universe::heap()->collector_policy();
-  gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
-    SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Space alignment "SIZE_FORMAT" Heap alignment "SIZE_FORMAT,
+  gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
+    SIZE_FORMAT " Maximum heap " SIZE_FORMAT " Space alignment " SIZE_FORMAT " Heap alignment " SIZE_FORMAT,
     p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
     p->space_alignment(), p->heap_alignment());
 }
@@ -195,8 +196,8 @@
          Universe::narrow_oop_use_implicit_null_checks() )) {
     tty->print_cr("WB_ReadFromNoaccessArea method is useless:\n "
                   "\tUseCompressedOops is %d\n"
-                  "\trhs.base() is "PTR_FORMAT"\n"
-                  "\tUniverse::narrow_oop_base() is "PTR_FORMAT"\n"
+                  "\trhs.base() is " PTR_FORMAT "\n"
+                  "\tUniverse::narrow_oop_base() is " PTR_FORMAT "\n"
                   "\tUniverse::narrow_oop_use_implicit_null_checks() is %d",
                   UseCompressedOops,
                   rhs.base(),
@@ -249,8 +250,8 @@
 
 WB_ENTRY(jint, WB_StressVirtualSpaceResize(JNIEnv* env, jobject o,
         jlong reserved_space_size, jlong magnitude, jlong iterations))
-  tty->print_cr("reservedSpaceSize="JLONG_FORMAT", magnitude="JLONG_FORMAT", "
-                "iterations="JLONG_FORMAT"\n", reserved_space_size, magnitude,
+  tty->print_cr("reservedSpaceSize=" JLONG_FORMAT ", magnitude=" JLONG_FORMAT ", "
+                "iterations=" JLONG_FORMAT "\n", reserved_space_size, magnitude,
                 iterations);
   if (reserved_space_size < 0 || magnitude < 0 || iterations < 0) {
     tty->print_cr("One of variables printed above is negative. Can't proceed.\n");
@@ -1125,6 +1126,132 @@
   return (jlong) MetaspaceGC::capacity_until_GC();
 WB_END
 
+WB_ENTRY(jboolean, WB_ReadImageFile(JNIEnv* env, jobject wb, jstring imagefile))
+  const char* filename = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(imagefile));
+  return ImageFileReader::open(filename) != NULL;
+WB_END
+
+WB_ENTRY(jlong, WB_imageOpenImage(JNIEnv *env, jobject wb, jstring path, jboolean big_endian))
+  ThreadToNativeFromVM ttn(thread);
+  const char *nativePath = env->GetStringUTFChars(path, NULL);
+  jlong ret = JVM_ImageOpen(env, nativePath, big_endian);
+
+  env->ReleaseStringUTFChars(path, nativePath);
+  return ret;
+WB_END
+
+WB_ENTRY(void, WB_imageCloseImage(JNIEnv *env, jobject wb, jlong id))
+  ThreadToNativeFromVM ttn(thread);
+  JVM_ImageClose(env, id);
+WB_END
+
+WB_ENTRY(jlong, WB_imageGetIndexAddress(JNIEnv *env, jobject wb, jlong id))
+  ThreadToNativeFromVM ttn(thread);
+  return JVM_ImageGetIndexAddress(env, id);
+WB_END
+
+WB_ENTRY(jlong, WB_imageGetDataAddress(JNIEnv *env, jobject wb, jlong id))
+  ThreadToNativeFromVM ttn(thread);
+  return JVM_ImageGetDataAddress(env, id);
+WB_END
+
+WB_ENTRY(jboolean, WB_imageRead(JNIEnv *env, jobject wb, jlong id, jlong offset, jobject uncompressedBuffer, jlong uncompressed_size))
+  ThreadToNativeFromVM ttn(thread);
+  if (uncompressedBuffer == NULL) {
+    return JNI_FALSE;
+  }
+  unsigned char* uncompressedAddress =
+          (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
+  return JVM_ImageRead(env, id, offset, uncompressedAddress, uncompressed_size);
+WB_END
+
+WB_ENTRY(jboolean, WB_imageReadCompressed(JNIEnv *env, jobject wb, jlong id, jlong offset, jobject compressedBuffer, jlong compressed_size, jobject uncompressedBuffer, jlong uncompressed_size))
+  ThreadToNativeFromVM ttn(thread);
+  if (uncompressedBuffer == NULL || compressedBuffer == NULL) {
+    return false;
+  }
+  // Get address of read direct buffer.
+  unsigned char* compressedAddress =
+        (unsigned char*) env->GetDirectBufferAddress(compressedBuffer);
+  // Get address of decompression direct buffer.
+  unsigned char* uncompressedAddress =
+        (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
+  return JVM_ImageReadCompressed(env, id, offset, compressedAddress, compressed_size, uncompressedAddress, uncompressed_size);
+WB_END
+
+WB_ENTRY(jbyteArray, WB_imageGetStringBytes(JNIEnv *env, jobject wb, jlong id, jlong offset))
+  ThreadToNativeFromVM ttn(thread);
+  const char* data = JVM_ImageGetStringBytes(env, id, offset);
+  // Determine String length.
+  size_t size = strlen(data);
+  // Allocate byte array.
+  jbyteArray byteArray = env->NewByteArray((jsize) size);
+  // Get array base address.
+  jbyte* rawBytes = env->GetByteArrayElements(byteArray, NULL);
+  // Copy bytes from image string table.
+  memcpy(rawBytes, data, size);
+  // Release byte array base address.
+  env->ReleaseByteArrayElements(byteArray, rawBytes, 0);
+  return byteArray;
+WB_END
+
+WB_ENTRY(jlong, WB_imageGetStringsSize(JNIEnv *env, jobject wb, jlong id))
+  ImageFileReader* reader = ImageFileReader::idToReader(id);
+  return reader? reader->strings_size() : 0L;
+WB_END
+
+WB_ENTRY(jlongArray, WB_imageGetAttributes(JNIEnv *env, jobject wb, jlong id, jint offset))
+  ThreadToNativeFromVM ttn(thread);
+  // Allocate a jlong large enough for all location attributes.
+  jlongArray attributes = env->NewLongArray(JVM_ImageGetAttributesCount(env));
+  // Get base address for jlong array.
+  jlong* rawAttributes = env->GetLongArrayElements(attributes, NULL);
+  jlong* ret = JVM_ImageGetAttributes(env, rawAttributes, id, offset);
+  // Release jlong array base address.
+  env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
+    return ret == NULL ? NULL : attributes;
+WB_END
+
+WB_ENTRY(jlongArray, WB_imageFindAttributes(JNIEnv *env, jobject wb, jlong id, jbyteArray utf8))
+  ThreadToNativeFromVM ttn(thread);
+  // Allocate a jlong large enough for all location attributes.
+  jlongArray attributes = env->NewLongArray(JVM_ImageGetAttributesCount(env));
+  // Get base address for jlong array.
+  jlong* rawAttributes = env->GetLongArrayElements(attributes, NULL);
+  jsize size = env->GetArrayLength(utf8);
+  jbyte* rawBytes = env->GetByteArrayElements(utf8, NULL);
+  jlong* ret = JVM_ImageFindAttributes(env, rawAttributes, rawBytes, size, id);
+  env->ReleaseByteArrayElements(utf8, rawBytes, 0);
+  env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
+  return ret == NULL ? NULL : attributes;
+WB_END
+
+WB_ENTRY(jintArray, WB_imageAttributeOffsets(JNIEnv *env, jobject wb, jlong id))
+  ThreadToNativeFromVM ttn(thread);
+  unsigned int length = JVM_ImageAttributeOffsetsLength(env, id);
+  if (length == 0) {
+    return NULL;
+  }
+  jintArray offsets = env->NewIntArray(length);
+  // Get base address of result.
+  jint* rawOffsets = env->GetIntArrayElements(offsets, NULL);
+  jint* ret = JVM_ImageAttributeOffsets(env, rawOffsets, length, id);
+  // Release result base address.
+  env->ReleaseIntArrayElements(offsets, rawOffsets, 0);
+  return ret == NULL ? NULL : offsets;
+WB_END
+
+WB_ENTRY(jint, WB_imageGetIntAtAddress(JNIEnv *env, jobject wb, jlong address, jint offset, jboolean big_endian))
+  unsigned char* arr = (unsigned char*) address + offset;
+  jint uraw;
+  if (big_endian) {
+     uraw = arr[0] << 24 | arr[1]<<16 | (arr[2]<<8) | arr[3];
+  } else {
+      uraw = arr[0] | arr[1]<<8 | (arr[2]<<16) | arr[3]<<24;
+  }
+  return uraw;
+WB_END
+
 WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue))
   Monitor::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ?
                                            Monitor::_safepoint_check_always :
@@ -1428,8 +1555,23 @@
   {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"readImageFile",      CC"(Ljava/lang/String;)Z", (void*)&WB_ReadImageFile },
+  {CC"imageOpenImage",     CC"(Ljava/lang/String;Z)J",(void*)&WB_imageOpenImage },
+  {CC"imageCloseImage",    CC"(J)V",                  (void*)&WB_imageCloseImage },
+  {CC"imageGetIndexAddress",CC"(J)J",                 (void*)&WB_imageGetIndexAddress},
+  {CC"imageGetDataAddress",CC"(J)J",                  (void*)&WB_imageGetDataAddress},
+  {CC"imageRead",          CC"(JJLjava/nio/ByteBuffer;J)Z",
+                                                      (void*)&WB_imageRead    },
+  {CC"imageReadCompressed",CC"(JJLjava/nio/ByteBuffer;JLjava/nio/ByteBuffer;J)Z",
+                                                      (void*)&WB_imageReadCompressed},
+  {CC"imageGetStringBytes",CC"(JI)[B",                (void*)&WB_imageGetStringBytes},
+  {CC"imageGetStringsSize",CC"(J)J",                  (void*)&WB_imageGetStringsSize},
+  {CC"imageGetAttributes", CC"(JI)[J",                (void*)&WB_imageGetAttributes},
+  {CC"imageFindAttributes",CC"(J[B)[J",               (void*)&WB_imageFindAttributes},
+  {CC"imageAttributeOffsets",CC"(J)[I",               (void*)&WB_imageAttributeOffsets},
+  {CC"imageGetIntAtAddress",CC"(JIZ)I",                (void*)&WB_imageGetIntAtAddress},
   {CC"assertMatchingSafepointCalls", CC"(ZZ)V",       (void*)&WB_AssertMatchingSafepointCalls },
-  {CC"isMonitorInflated0",  CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
+  {CC"isMonitorInflated0", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
   {CC"forceSafepoint",     CC"()V",                   (void*)&WB_ForceSafepoint     },
   {CC"getMethodBooleanOption",
       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Boolean;",
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -27,6 +27,7 @@
 #include "classfile/javaAssertions.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "gc/shared/cardTableRS.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
@@ -275,6 +276,7 @@
   { "AdaptiveSizePausePolicy",       JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "ParallelGCRetainPLAB",          JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "ThreadSafetyMargin",            JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "LazyBootClassLoader",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { NULL, JDK_Version(0), JDK_Version(0) }
 };
 
@@ -835,16 +837,19 @@
     arg_len = equal_sign - argname;
   }
 
-  // Construct a string which consists only of the argument name without '+', '-', or '='.
-  char stripped_argname[256];
-  strncpy(stripped_argname, argname, arg_len);
-  stripped_argname[arg_len] = '\0'; //strncpy doesn't null terminate.
-
-  if (is_newly_obsolete(stripped_argname, &since)) {
-    char version[256];
-    since.to_string(version, sizeof(version));
-    warning("ignoring option %s; support was removed in %s", stripped_argname, version);
-    return true;
+  // Only make the obsolete check for valid arguments.
+  if (arg_len <= BUFLEN) {
+    // Construct a string which consists only of the argument name without '+', '-', or '='.
+    char stripped_argname[BUFLEN+1];
+    strncpy(stripped_argname, argname, arg_len);
+    stripped_argname[arg_len] = '\0';  // strncpy may not null terminate.
+
+    if (is_newly_obsolete(stripped_argname, &since)) {
+      char version[256];
+      since.to_string(version, sizeof(version));
+      warning("ignoring option %s; support was removed in %s", stripped_argname, version);
+      return true;
+    }
   }
 
   // For locked flags, report a custom error message if available.
@@ -1582,6 +1587,11 @@
   // in vm_version initialization code.
 #endif // _LP64
 #endif // !ZERO
+
+  // Set up runtime image flags.
+  set_runtime_image_flags();
+
+  CodeCacheExtensions::set_ergonomics_flags();
 }
 
 void Arguments::set_parallel_gc_flags() {
@@ -1837,6 +1847,16 @@
   }
 }
 
+  // Set up runtime image flags
+void Arguments::set_runtime_image_flags() {
+#ifdef _LP64
+  // Memory map image file by default on 64 bit machines.
+  if (FLAG_IS_DEFAULT(MemoryMapImage)) {
+    FLAG_SET_ERGO(bool, MemoryMapImage, true);
+  }
+#endif
+}
+
 // This must be called after ergonomics.
 void Arguments::set_bytecode_flags() {
   if (!RewriteBytecodes) {
@@ -2558,9 +2578,15 @@
                        round_to((int)long_ThreadStackSize, K) / K) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
-    // -Xoss
-    } else if (match_option(option, "-Xoss", &tail)) {
-          // HotSpot does not have separate native and Java stacks, ignore silently for compatibility
+    // -Xoss, -Xsqnopause, -Xoptimize, -Xboundthreads
+    } else if (match_option(option, "-Xoss", &tail) ||
+               match_option(option, "-Xsqnopause") ||
+               match_option(option, "-Xoptimize") ||
+               match_option(option, "-Xboundthreads")) {
+      // All these options are deprecated in JDK 9 and will be removed in a future release
+      char version[256];
+      JDK_Version::jdk(9).to_string(version, sizeof(version));
+      warning("ignoring option %s; support was removed in %s", option->optionString, version);
     } else if (match_option(option, "-XX:CodeCacheExpansionSize=", &tail)) {
       julong long_CodeCacheExpansionSize = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_CodeCacheExpansionSize, os::vm_page_size());
@@ -2633,9 +2659,6 @@
     // -native
     } else if (match_option(option, "-native")) {
           // HotSpot always uses native threads, ignore silently for compatibility
-    // -Xsqnopause
-    } else if (match_option(option, "-Xsqnopause")) {
-          // EVM option, ignore silently for compatibility
     // -Xrs
     } else if (match_option(option, "-Xrs")) {
           // Classic/EVM option, new functionality
@@ -2647,9 +2670,6 @@
       if (FLAG_SET_CMDLINE(bool, UseAltSigs, true) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
-    // -Xoptimize
-    } else if (match_option(option, "-Xoptimize")) {
-          // EVM option, ignore silently for compatibility
     // -Xprof
     } else if (match_option(option, "-Xprof")) {
 #if INCLUDE_FPROF
@@ -2795,8 +2815,6 @@
     // -Xnoagent
     } else if (match_option(option, "-Xnoagent")) {
       // For compatibility with classic. HotSpot refuses to load the old style agent.dll.
-    } else if (match_option(option, "-Xboundthreads")) {
-      // Ignore silently for compatibility
     } else if (match_option(option, "-Xloggc:", &tail)) {
       // Redirect GC output to the file. -Xloggc:<filename>
       // ostream_init_log(), when called will use this filename
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -224,6 +224,7 @@
 class Arguments : AllStatic {
   friend class VMStructs;
   friend class JvmtiExport;
+  friend class CodeCacheExtensions;
  public:
   // Operation modi
   enum Mode {
@@ -347,6 +348,8 @@
   static julong limit_by_allocatable_memory(julong size);
   // Setup heap size
   static void set_heap_size();
+  // Set up runtime image flags
+  static void set_runtime_image_flags();
   // Based on automatic selection criteria, should the
   // low pause collector be used.
   static bool should_auto_select_low_pause_collector();
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -84,7 +84,7 @@
   }
 
   void print(outputStream* st) {
-    st->print("[ "INTX_FORMAT_W(-25)" ... "INTX_FORMAT_W(25)" ]", _min, _max);
+    st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max);
   }
 };
 
@@ -140,7 +140,7 @@
   }
 
   void print(outputStream* st) {
-    st->print("[ "UINTX_FORMAT_W(-25)" ... "UINTX_FORMAT_W(25)" ]", _min, _max);
+    st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max);
   }
 };
 
@@ -168,7 +168,7 @@
   }
 
   void print(outputStream* st) {
-    st->print("[ "UINT64_FORMAT_W(-25)" ... "UINT64_FORMAT_W(25)" ]", _min, _max);
+    st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max);
   }
 };
 
@@ -196,7 +196,7 @@
   }
 
   void print(outputStream* st) {
-    st->print("[ "SIZE_FORMAT_W(-25)" ... "SIZE_FORMAT_W(25)" ]", _min, _max);
+    st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max);
   }
 };
 
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1340,7 +1340,7 @@
       ttyLocker ttyl;
       char buf[100];
       if (xtty != NULL) {
-        xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT"' %s",
+        xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT "' %s",
                          os::current_thread_id(),
                          format_trap_request(buf, sizeof(buf), trap_request));
         nm->log_identity(xtty);
--- a/hotspot/src/share/vm/runtime/globals.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1240,7 +1240,7 @@
         size_ranges += sizeof(CommandLineFlagRange*);
       }
     }
-    fprintf(stderr, "Size of %d ranges: "SIZE_FORMAT" bytes\n",
+    fprintf(stderr, "Size of %d ranges: " SIZE_FORMAT " bytes\n",
             CommandLineFlagRangeList::length(), size_ranges);
   }
   {
@@ -1270,7 +1270,7 @@
         size_constraints += sizeof(CommandLineFlagConstraint*);
       }
     }
-    fprintf(stderr, "Size of %d constraints: "SIZE_FORMAT" bytes\n",
+    fprintf(stderr, "Size of %d constraints: " SIZE_FORMAT " bytes\n",
             CommandLineFlagConstraintList::length(), size_constraints);
   }
 #endif // PRINT_RANGES_AND_CONSTRAINTS_SIZES
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -728,7 +728,8 @@
           "Control whether AES instructions can be used on x86/x64")        \
                                                                             \
   product(bool, UseSHA, false,                                              \
-          "Control whether SHA instructions can be used on SPARC")          \
+          "Control whether SHA instructions can be used "                   \
+          "on SPARC and on ARM")                                            \
                                                                             \
   product(bool, UseGHASHIntrinsics, false,                                  \
           "Use intrinsics for GHASH versions of crypto")                    \
@@ -837,13 +838,16 @@
           "Use intrinsics for AES versions of crypto")                      \
                                                                             \
   product(bool, UseSHA1Intrinsics, false,                                   \
-          "Use intrinsics for SHA-1 crypto hash function")                  \
+          "Use intrinsics for SHA-1 crypto hash function. "                 \
+          "Requires that UseSHA is enabled.")                                \
                                                                             \
   product(bool, UseSHA256Intrinsics, false,                                 \
-          "Use intrinsics for SHA-224 and SHA-256 crypto hash functions")   \
+          "Use intrinsics for SHA-224 and SHA-256 crypto hash functions. "  \
+          "Requires that UseSHA is enabled.")                               \
                                                                             \
   product(bool, UseSHA512Intrinsics, false,                                 \
-          "Use intrinsics for SHA-384 and SHA-512 crypto hash functions")   \
+          "Use intrinsics for SHA-384 and SHA-512 crypto hash functions. "  \
+          "Requires that UseSHA is enabled.")                               \
                                                                             \
   product(bool, UseCRC32Intrinsics, false,                                  \
           "use intrinsics for java.util.zip.CRC32")                         \
@@ -1032,6 +1036,10 @@
   product(bool, CreateCoredumpOnCrash, true,                                \
           "Create core/mini dump on VM fatal error")                        \
                                                                             \
+  product(uintx, ErrorLogTimeout, 2 * 60,                                   \
+          "Timeout, in seconds, to limit the time spent on writing an "     \
+          "error log in case of a crash.")                                  \
+                                                                            \
   product_pd(bool, UseOSErrorReporting,                                     \
           "Let VM fatal error propagate to the OS (ie. WER on Windows)")    \
                                                                             \
@@ -1099,6 +1107,9 @@
   product(bool, AlwaysRestoreFPU, false,                                    \
           "Restore the FPU control word after every JNI call (expensive)")  \
                                                                             \
+  product(bool, MemoryMapImage, false,                                      \
+          "Memory map entire runtime image")                                \
+                                                                            \
   diagnostic(bool, PrintCompilation2, false,                                \
           "Print additional statistics per compilation")                    \
                                                                             \
@@ -1361,9 +1372,6 @@
   develop(uintx, PreallocatedOutOfMemoryErrorCount, 4,                      \
           "Number of OutOfMemoryErrors preallocated with backtrace")        \
                                                                             \
-  product(bool, LazyBootClassLoader, true,                                  \
-          "Enable/disable lazy opening of boot class path entries")         \
-                                                                            \
   product(bool, UseXMMForArrayCopy, false,                                  \
           "Use SSE2 MOVQ instruction for Arraycopy")                        \
                                                                             \
@@ -4120,7 +4128,16 @@
                                                                             \
   product_pd(bool, PreserveFramePointer,                                    \
              "Use the FP register for holding the frame pointer "           \
-             "and not as a general purpose register.")
+             "and not as a general purpose register.")                      \
+                                                                            \
+  diagnostic(bool, CheckIntrinsics, trueInDebug,                            \
+             "When a class C is loaded, check that "                        \
+             "(1) all intrinsics defined by the VM for class C are present "\
+             "in the loaded class file and are marked with the "            \
+             "@HotSpotIntrinsicCandidate annotation and also that "         \
+             "(2) there is an intrinsic registered for all loaded methods " \
+             "that are annotated with the @HotSpotIntrinsicCandidate "      \
+             "annotation.")
 
 /*
  *  Macros for factoring of globals
--- a/hotspot/src/share/vm/runtime/init.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/init.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/stringTable.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "code/icBuffer.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/bytecodes.hpp"
@@ -82,6 +83,7 @@
 // during VM shutdown
 void perfMemory_exit();
 void ostream_exit();
+bool image_decompressor_init();
 
 void vm_init_globals() {
   check_ThreadShadow();
@@ -100,21 +102,29 @@
   classLoader_init();
   compilationPolicy_init();
   codeCache_init();
+  CodeCacheExtensions::initialize();
   VM_Version_init();
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::VMVersion);
   os_init_globals();
   stubRoutines_init1();
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::StubRoutines1);
   jint status = universe_init();  // dependent on codeCache_init and
                                   // stubRoutines_init1 and metaspace_init.
   if (status != JNI_OK)
     return status;
 
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Universe);
   interpreter_init();  // before any methods loaded
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Interpreter);
   invocationCounter_init();  // before any methods loaded
   marksweep_init();
   accessFlags_init();
   templateTable_init();
   InterfaceSupport_init();
   SharedRuntime::generate_stubs();
+  if (!image_decompressor_init()) {
+    return JNI_ERR;
+  }
   universe2_init();  // dependent on codeCache_init and stubRoutines_init1
   referenceProcessor_init();
   jni_handles_init();
@@ -133,6 +143,7 @@
   }
   javaClasses_init();   // must happen after vtable initialization
   stubRoutines_init2(); // note: StubRoutines need 2-phase init
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::StubRoutines2);
 
 #if INCLUDE_NMT
   // Solaris stack is walkable only after stubRoutines are set up.
@@ -146,6 +157,7 @@
     CommandLineFlags::printFlags(tty, false, PrintFlagsRanges);
   }
 
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::InitGlobals);
   return JNI_OK;
 }
 
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -100,6 +100,8 @@
 Mutex*   ExceptionCache_lock          = NULL;
 Monitor* ObjAllocPost_lock            = NULL;
 Mutex*   OsrList_lock                 = NULL;
+Mutex*   ImageFileReaderTable_lock    = NULL;
+
 #ifndef PRODUCT
 Mutex*   FullGCALot_lock              = NULL;
 #endif
@@ -227,6 +229,7 @@
   def(ProfilePrint_lock            , Mutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
   def(ExceptionCache_lock          , Mutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
   def(OsrList_lock                 , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);
+  def(ImageFileReaderTable_lock    , Mutex  , nonleaf,     false, Monitor::_safepoint_check_always);     // synchronize image readers open/close
   def(Debug1_lock                  , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);
 #ifndef PRODUCT
   def(FullGCALot_lock              , Mutex  , leaf,        false, Monitor::_safepoint_check_always);     // a lock to make FullGCALot MT safe
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -102,6 +102,7 @@
 extern Mutex*   ProfilePrint_lock;               // a lock used to serialize the printing of profiles
 extern Mutex*   ExceptionCache_lock;             // a lock used to synchronize exception cache updates
 extern Mutex*   OsrList_lock;                    // a lock used to serialize access to OSR queues
+extern Mutex*   ImageFileReaderTable_lock;       // a lock used to synchronize image readers open/close
 
 #ifndef PRODUCT
 extern Mutex*   FullGCALot_lock;                 // a lock to make FullGCALot MT safe
--- a/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/os.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1237,7 +1237,7 @@
   struct stat st;
 
   // modular image if bootmodules.jimage exists
-  char* jimage = format_boot_path("%/lib/modules/bootmodules.jimage", home, home_len, fileSep, pathSep);
+  char* jimage = format_boot_path("%/lib/modules/" BOOT_IMAGE_NAME, home, home_len, fileSep, pathSep);
   if (jimage == NULL) return false;
   bool has_jimage = (os::stat(jimage, &st) == 0);
   if (has_jimage) {
--- a/hotspot/src/share/vm/runtime/reflection.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/reflection.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1002,8 +1002,9 @@
                 vmSymbols::throwable_void_signature(),
                 &args);
   } else {
-    if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT)
+    if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) {
       narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
+    }
     return box((jvalue*) result.get_value_addr(), rtype, THREAD);
   }
 }
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -894,7 +894,7 @@
 
     case _running:
     default:
-       tty->print_cr("restart thread "INTPTR_FORMAT" with state %d",
+       tty->print_cr("restart thread " INTPTR_FORMAT " with state %d",
                       _thread, _type);
        _thread->print();
       ShouldNotReachHere();
@@ -1193,7 +1193,7 @@
     sstats = &_safepoint_stats[index];
     tty->print("%.3f: ", sstats->_time_stamp);
     tty->print("%-26s       ["
-               INT32_FORMAT_W(8)INT32_FORMAT_W(11)INT32_FORMAT_W(15)
+               INT32_FORMAT_W(8) INT32_FORMAT_W(11) INT32_FORMAT_W(15)
                "    ]    ",
                sstats->_vmop_type == -1 ? "no vm operation" :
                VM_Operation::name(sstats->_vmop_type),
@@ -1202,9 +1202,9 @@
                sstats->_nof_threads_wait_to_block);
     // "/ MICROUNITS " is to convert the unit from nanos to millis.
     tty->print("  ["
-               INT64_FORMAT_W(6)INT64_FORMAT_W(6)
-               INT64_FORMAT_W(6)INT64_FORMAT_W(6)
-               INT64_FORMAT_W(6)"    ]  ",
+               INT64_FORMAT_W(6) INT64_FORMAT_W(6)
+               INT64_FORMAT_W(6) INT64_FORMAT_W(6)
+               INT64_FORMAT_W(6) "    ]  ",
                sstats->_time_to_spin / MICROUNITS,
                sstats->_time_to_wait_to_block / MICROUNITS,
                sstats->_time_to_sync / MICROUNITS,
@@ -1212,9 +1212,9 @@
                sstats->_time_to_exec_vmop / MICROUNITS);
 
     if (need_to_track_page_armed_status) {
-      tty->print(INT32_FORMAT"         ", sstats->_page_armed);
+      tty->print(INT32_FORMAT "         ", sstats->_page_armed);
     }
-    tty->print_cr(INT32_FORMAT"   ", sstats->_nof_threads_hit_page_trap);
+    tty->print_cr(INT32_FORMAT "   ", sstats->_nof_threads_hit_page_trap);
   }
 }
 
@@ -1249,17 +1249,17 @@
 
   for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) {
     if (_safepoint_reasons[index] != 0) {
-      tty->print_cr("%-26s"UINT64_FORMAT_W(10), VM_Operation::name(index),
+      tty->print_cr("%-26s" UINT64_FORMAT_W(10), VM_Operation::name(index),
                     _safepoint_reasons[index]);
     }
   }
 
-  tty->print_cr(UINT64_FORMAT_W(5)" VM operations coalesced during safepoint",
+  tty->print_cr(UINT64_FORMAT_W(5) " VM operations coalesced during safepoint",
                 _coalesced_vmop_count);
-  tty->print_cr("Maximum sync time  "INT64_FORMAT_W(5)" ms",
+  tty->print_cr("Maximum sync time  " INT64_FORMAT_W(5) " ms",
                 _max_sync_time / MICROUNITS);
   tty->print_cr("Maximum vm operation time (except for Exit VM operation)  "
-                INT64_FORMAT_W(5)" ms",
+                INT64_FORMAT_W(5) " ms",
                 _max_vmop_time / MICROUNITS);
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/semaphore.cpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "utilities/debug.hpp"
+#include "runtime/semaphore.hpp"
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+static void test_semaphore_single_separate(uint count) {
+  Semaphore sem(0);
+
+  for (uint i = 0; i < count; i++) {
+    sem.signal();
+  }
+
+  for (uint i = 0; i < count; i++) {
+    sem.wait();
+  }
+}
+
+static void test_semaphore_single_combined(uint count) {
+  Semaphore sem(0);
+
+  for (uint i = 0; i < count; i++) {
+    sem.signal();
+    sem.wait();
+  }
+}
+
+static void test_semaphore_many(uint value, uint max, uint increments) {
+  Semaphore sem(value);
+
+  uint total = value;
+
+  for (uint i = value; i + increments <= max; i += increments) {
+    sem.signal(increments);
+
+    total += increments;
+  }
+
+  for (uint i = 0; i < total; i++) {
+    sem.wait();
+  }
+}
+
+static void test_semaphore_many() {
+  for (uint max = 0; max < 10; max++) {
+    for (uint value = 0; value < max; value++) {
+      for (uint inc = 1; inc <= max - value; inc++) {
+        test_semaphore_many(value, max, inc);
+      }
+    }
+  }
+}
+
+void test_semaphore() {
+  for (uint i = 1; i < 10; i++) {
+    test_semaphore_single_separate(i);
+  }
+
+  for (uint i = 0; i < 10; i++) {
+    test_semaphore_single_combined(i);
+  }
+
+  test_semaphore_many();
+}
+
+#endif // PRODUCT
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/semaphore.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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_RUNTIME_SEMAPHORE_HPP
+#define SHARE_VM_RUNTIME_SEMAPHORE_HPP
+
+#include "memory/allocation.hpp"
+
+#if defined(TARGET_OS_FAMILY_linux) || defined(TARGET_OS_FAMILY_solaris) || defined(TARGET_OS_FAMILY_aix)
+# include "semaphore_posix.hpp"
+#elif defined(TARGET_OS_FAMILY_bsd)
+# include "semaphore_bsd.hpp"
+#elif defined(TARGET_OS_FAMILY_windows)
+# include "semaphore_windows.hpp"
+#else
+# error "No semaphore implementation provided for this OS"
+#endif
+
+// Implements the limited, platform independent Semaphore API.
+class Semaphore : public CHeapObj<mtInternal> {
+  SemaphoreImpl _impl;
+
+  // Prevent copying and assignment of Semaphore instances.
+  Semaphore(const Semaphore&);
+  Semaphore& operator=(const Semaphore&);
+
+ public:
+  Semaphore(uint value = 0) : _impl(value) {}
+  ~Semaphore() {}
+
+  void signal(uint count = 1) { _impl.signal(count); }
+
+  void wait()                 { _impl.wait(); }
+};
+
+
+#endif // SHARE_VM_RUNTIME_SEMAPHORE_HPP
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -27,6 +27,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
 #include "code/compiledIC.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "code/scopeDesc.hpp"
 #include "code/vtableStubs.hpp"
 #include "compiler/abstractCompiler.hpp"
@@ -2307,19 +2308,35 @@
   return _buffer;
 }
 
+extern "C" void unexpected_adapter_call() {
+  ShouldNotCallThis();
+}
+
 void AdapterHandlerLibrary::initialize() {
   if (_adapters != NULL) return;
   _adapters = new AdapterHandlerTable();
 
-  // Create a special handler for abstract methods.  Abstract methods
-  // are never compiled so an i2c entry is somewhat meaningless, but
-  // throw AbstractMethodError just in case.
-  // Pass wrong_method_abstract for the c2i transitions to return
-  // AbstractMethodError for invalid invocations.
-  address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
-  _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
-                                                              StubRoutines::throw_AbstractMethodError_entry(),
-                                                              wrong_method_abstract, wrong_method_abstract);
+  if (!CodeCacheExtensions::skip_compiler_support()) {
+    // Create a special handler for abstract methods.  Abstract methods
+    // are never compiled so an i2c entry is somewhat meaningless, but
+    // throw AbstractMethodError just in case.
+    // Pass wrong_method_abstract for the c2i transitions to return
+    // AbstractMethodError for invalid invocations.
+    address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
+    _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
+                                                                StubRoutines::throw_AbstractMethodError_entry(),
+                                                                wrong_method_abstract, wrong_method_abstract);
+  } else {
+    // Adapters are not supposed to be used.
+    // Generate a special one to cause an error if used (and store this
+    // singleton in place of the useless _abstract_method_error adapter).
+    address entry = (address) &unexpected_adapter_call;
+    _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
+                                                                entry,
+                                                                entry,
+                                                                entry);
+
+  }
 }
 
 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
@@ -2346,6 +2363,15 @@
     // make sure data structure is initialized
     initialize();
 
+    if (CodeCacheExtensions::skip_compiler_support()) {
+      // adapters are useless and should not be used, including the
+      // abstract_method_handler. However, some callers check that
+      // an adapter was installed.
+      // Return the singleton adapter, stored into _abstract_method_handler
+      // and modified to cause an error if we ever call it.
+      return _abstract_method_handler;
+    }
+
     if (method->is_abstract()) {
       return _abstract_method_handler;
     }
@@ -2616,71 +2642,6 @@
   GC_locker::unlock_critical(thread);
 JRT_END
 
-int SharedRuntime::convert_ints_to_longints_argcnt(int in_args_count, BasicType* in_sig_bt) {
-  int argcnt = in_args_count;
-  if (CCallingConventionRequiresIntsAsLongs) {
-    for (int in = 0; in < in_args_count; in++) {
-      BasicType bt = in_sig_bt[in];
-      switch (bt) {
-        case T_BOOLEAN:
-        case T_CHAR:
-        case T_BYTE:
-        case T_SHORT:
-        case T_INT:
-          argcnt++;
-          break;
-        default:
-          break;
-      }
-    }
-  } else {
-    assert(0, "This should not be needed on this platform");
-  }
-
-  return argcnt;
-}
-
-void SharedRuntime::convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
-                                             BasicType*& in_sig_bt, VMRegPair*& in_regs) {
-  if (CCallingConventionRequiresIntsAsLongs) {
-    VMRegPair *new_in_regs   = NEW_RESOURCE_ARRAY(VMRegPair, i2l_argcnt);
-    BasicType *new_in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
-
-    int argcnt = 0;
-    for (int in = 0; in < in_args_count; in++, argcnt++) {
-      BasicType bt  = in_sig_bt[in];
-      VMRegPair reg = in_regs[in];
-      switch (bt) {
-        case T_BOOLEAN:
-        case T_CHAR:
-        case T_BYTE:
-        case T_SHORT:
-        case T_INT:
-          // Convert (bt) to (T_LONG,bt).
-          new_in_sig_bt[argcnt] = T_LONG;
-          new_in_sig_bt[argcnt+1] = bt;
-          assert(reg.first()->is_valid() && !reg.second()->is_valid(), "");
-          new_in_regs[argcnt].set2(reg.first());
-          new_in_regs[argcnt+1].set_bad();
-          argcnt++;
-          break;
-        default:
-          // No conversion needed.
-          new_in_sig_bt[argcnt] = bt;
-          new_in_regs[argcnt]   = reg;
-          break;
-      }
-    }
-    assert(argcnt == i2l_argcnt, "must match");
-
-    in_regs = new_in_regs;
-    in_sig_bt = new_in_sig_bt;
-    in_args_count = i2l_argcnt;
-  } else {
-    assert(0, "This should not be needed on this platform");
-  }
-}
-
 // -------------------------------------------------------------------------
 // Java-Java calling convention
 // (what you use when Java calls Java)
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -145,6 +145,12 @@
   static double dsqrt(double f);
 #endif
 
+  // Montgomery multiplication
+  static void montgomery_multiply(jint *a_ints, jint *b_ints, jint *n_ints,
+                                  jint len, jlong inv, jint *m_ints);
+  static void montgomery_square(jint *a_ints, jint *n_ints,
+                                jint len, jlong inv, jint *m_ints);
+
 #ifdef __SOFTFP__
   // C++ compiler generates soft float instructions as well as passing
   // float and double in registers.
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	Thu Jul 09 22:46:16 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
@@ -26,6 +26,7 @@
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "compiler/disassembler.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/forte.hpp"
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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
@@ -67,14 +67,14 @@
   static StubCodeDesc* desc_for_index(int);      // returns the code descriptor for the index or NULL
   static const char*   name_for(address pc);     // returns the name of the code containing pc or NULL
 
-  StubCodeDesc(const char* group, const char* name, address begin) {
+  StubCodeDesc(const char* group, const char* name, address begin, address end = NULL) {
     assert(name != NULL, "no name specified");
     _next           = _list;
     _group          = group;
     _name           = name;
     _index          = ++_count; // (never zero)
     _begin          = begin;
-    _end            = NULL;
+    _end            = end;
     _list           = this;
   };
 
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "asm/codeBuffer.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
@@ -142,6 +143,8 @@
 address StubRoutines::_multiplyToLen = NULL;
 address StubRoutines::_squareToLen = NULL;
 address StubRoutines::_mulAdd = NULL;
+address StubRoutines::_montgomeryMultiply = NULL;
+address StubRoutines::_montgomerySquare = NULL;
 
 double (* StubRoutines::_intrinsic_log   )(double) = NULL;
 double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
@@ -188,6 +191,12 @@
 
 // simple tests of generated arraycopy functions
 static void test_arraycopy_func(address func, int alignment) {
+  if (CodeCacheExtensions::use_pregenerated_interpreter() || !CodeCacheExtensions::is_executable(func)) {
+    // Exit safely if stubs were generated but cannot be used.
+    // Also excluding pregenerated interpreter since the code may depend on
+    // some registers being properly initialized (for instance Rthread)
+    return;
+  }
   int v = 0xcc;
   int v2 = 0x11;
   jlong lbuffer[8];
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -202,6 +202,8 @@
   static address _multiplyToLen;
   static address _squareToLen;
   static address _mulAdd;
+  static address _montgomeryMultiply;
+  static address _montgomerySquare;
 
   // These are versions of the java.lang.Math methods which perform
   // the same operations as the intrinsic version.  They are used for
@@ -366,6 +368,8 @@
   static address multiplyToLen()       {return _multiplyToLen; }
   static address squareToLen()         {return _squareToLen; }
   static address mulAdd()              {return _mulAdd; }
+  static address montgomeryMultiply()  { return _montgomeryMultiply; }
+  static address montgomerySquare()    { return _montgomerySquare; }
 
   static address select_fill_function(BasicType t, bool aligned, const char* &name);
 
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -28,6 +28,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "code/scopeDesc.hpp"
 #include "compiler/compileBroker.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
@@ -1291,7 +1292,7 @@
         if (!ShowMessageBoxOnError
             && (OnError == NULL || OnError[0] == '\0')
             && Arguments::abort_hook() == NULL) {
-          os::sleep(this, 2 * 60 * 1000, false);
+          os::sleep(this, ErrorLogTimeout * 60 * 1000, false);
           fdStream err(defaultStream::output_fd());
           err.print_raw_cr("# [ timer expired, abort... ]");
           // skip atexit/vm_exit/vm_abort hooks
@@ -3587,6 +3588,8 @@
     }
   }
 
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::CreateVM);
+
   create_vm_timer.end();
 #ifdef ASSERT
   _vm_complete = true;
--- a/hotspot/src/share/vm/runtime/unhandledOops.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/unhandledOops.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -105,7 +105,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, op);
   }
 
   int i = _oop_list->find_from_end(op, match_oop_entry);
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -182,6 +182,8 @@
 #include "runtime/vmStructs_trace.hpp"
 #endif
 
+#include "runtime/vmStructs_ext.hpp"
+
 #ifdef COMPILER2
 #include "opto/addnode.hpp"
 #include "opto/block.hpp"
@@ -2963,6 +2965,9 @@
                 GENERATE_STATIC_VM_STRUCT_ENTRY)
 #endif
 
+  VM_STRUCTS_EXT(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+                 GENERATE_STATIC_VM_STRUCT_ENTRY)
+
   VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
                  GENERATE_STATIC_VM_STRUCT_ENTRY,
                  GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3013,6 +3018,9 @@
               GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
 #endif
 
+  VM_TYPES_EXT(GENERATE_VM_TYPE_ENTRY,
+               GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
+
   VM_TYPES_CPU(GENERATE_VM_TYPE_ENTRY,
                GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
                GENERATE_OOP_VM_TYPE_ENTRY,
@@ -3122,6 +3130,9 @@
                 CHECK_STATIC_VM_STRUCT_ENTRY);
 #endif
 
+  VM_STRUCTS_EXT(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
+                 CHECK_STATIC_VM_STRUCT_ENTRY);
+
   VM_STRUCTS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
                  CHECK_STATIC_VM_STRUCT_ENTRY,
                  CHECK_NO_OP,
@@ -3168,6 +3179,9 @@
               CHECK_SINGLE_ARG_VM_TYPE_NO_OP);
 #endif
 
+  VM_TYPES_EXT(CHECK_VM_TYPE_ENTRY,
+               CHECK_SINGLE_ARG_VM_TYPE_NO_OP);
+
   VM_TYPES_CPU(CHECK_VM_TYPE_ENTRY,
                CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
                CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
@@ -3236,6 +3250,9 @@
                            ENSURE_FIELD_TYPE_PRESENT));
 #endif
 
+  debug_only(VM_STRUCTS_EXT(ENSURE_FIELD_TYPE_PRESENT,
+                            ENSURE_FIELD_TYPE_PRESENT));
+
   debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT,
                             ENSURE_FIELD_TYPE_PRESENT,
                             CHECK_NO_OP,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/vmStructs_ext.hpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_VMSTRUCTS_EXT_HPP
+#define SHARE_VM_RUNTIME_VMSTRUCTS_EXT_HPP
+
+#define VM_STRUCTS_EXT(a, b)
+
+#define VM_TYPES_EXT(a, b)
+
+
+#endif // SHARE_VM_RUNTIME_VMSTRUCTS_EXT_HPP
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -26,6 +26,7 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "compiler/compileBroker.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
@@ -369,6 +370,8 @@
 Thread * VM_Exit::_shutdown_thread = NULL;
 
 int VM_Exit::set_vm_exited() {
+  CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::LastStep);
+
   Thread * thr_cur = ThreadLocalStorage::get_thread_slow();
 
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
--- a/hotspot/src/share/vm/runtime/vm_version.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "code/codeCacheExtensions.hpp"
 #include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/arguments.hpp"
@@ -155,6 +156,9 @@
 
 
 const char* Abstract_VM_Version::vm_info_string() {
+  if (CodeCacheExtensions::use_pregenerated_interpreter()) {
+    return "interpreted mode, pregenerated";
+  }
   switch (Arguments::mode()) {
     case Arguments::_int:
       return UseSharedSpaces ? "interpreted mode, sharing" : "interpreted mode";
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -89,7 +89,7 @@
                                                   size_t len, TRAPS) {
   int scanned = -1;
   if (str == NULL
-      || sscanf(str, JLONG_FORMAT"%n", &_value, &scanned) != 1
+      || sscanf(str, JLONG_FORMAT "%n", &_value, &scanned) != 1
       || (size_t)scanned != len)
   {
     ResourceMark rm;
--- a/hotspot/src/share/vm/services/threadService.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/services/threadService.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -888,7 +888,7 @@
       st->print("  waiting to lock monitor " INTPTR_FORMAT, 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)", (address)obj,
                    (InstanceKlass::cast(obj->klass()))->external_name());
 
         if (!currentThread->current_pending_monitor_is_from_java()) {
--- a/hotspot/src/share/vm/trace/trace.xml	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/trace/trace.xml	Thu Jul 09 22:46:16 2015 -0700
@@ -305,6 +305,13 @@
       <value type="G1YCTYPE" field="type" label="Type" />
     </event>
 
+    <event id="GCG1MMU" path="vm/gc/detailed/g1_mmu_info" label="G1 MMU Information" is_instant="true">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="DOUBLE" field="timeSlice" label="Time slice used to calculate MMU"/>
+      <value type="DOUBLE" field="gcTime" label="Time spent on GC during last time slice"/>
+      <value type="DOUBLE" field="maxGcTime" label="Max time allowed to be spent on GC during last time slice"/>
+    </event>
+
     <event id="EvacuationInfo" path="vm/gc/detailed/evacuation_info" label="Evacuation Information" is_instant="true">
       <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
       <value type="UINT" field="cSetRegions" label="Collection Set Regions"/>
--- a/hotspot/src/share/vm/trace/traceStream.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/trace/traceStream.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -40,31 +40,31 @@
   TraceStream(outputStream& stream): _st(stream) {}
 
   void print_val(const char* label, u1 val) {
-    _st.print("%s = "UINT32_FORMAT, label, val);
+    _st.print("%s = " UINT32_FORMAT, label, val);
   }
 
   void print_val(const char* label, u2 val) {
-    _st.print("%s = "UINT32_FORMAT, label, val);
+    _st.print("%s = " UINT32_FORMAT, label, val);
   }
 
   void print_val(const char* label, s2 val) {
-    _st.print("%s = "INT32_FORMAT, label, val);
+    _st.print("%s = " INT32_FORMAT, label, val);
   }
 
   void print_val(const char* label, u4 val) {
-    _st.print("%s = "UINT32_FORMAT, label, val);
+    _st.print("%s = " UINT32_FORMAT, label, val);
   }
 
   void print_val(const char* label, s4 val) {
-    _st.print("%s = "INT32_FORMAT, label, val);
+    _st.print("%s = " INT32_FORMAT, label, val);
   }
 
   void print_val(const char* label, u8 val) {
-    _st.print("%s = "UINT64_FORMAT, label, val);
+    _st.print("%s = " UINT64_FORMAT, label, val);
   }
 
   void print_val(const char* label, s8 val) {
-    _st.print("%s = "INT64_FORMAT, label, (int64_t) val);
+    _st.print("%s = " INT64_FORMAT, label, (int64_t) val);
   }
 
   void print_val(const char* label, bool val) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/endian.cpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "utilities/endian.hpp"
+#include "utilities/bytes.hpp"
+
+#ifndef bswap_16
+extern "C" inline u2 bswap_16(u2 x) {
+  return ((x & 0xFF) << 8) |
+         ((x >> 8) & 0xFF);
+}
+#endif
+
+#ifndef bswap_32
+extern "C" inline u4 bswap_32(u4 x) {
+  return ((x & 0xFF) << 24) |
+       ((x & 0xFF00) << 8) |
+       ((x >> 8) & 0xFF00) |
+       ((x >> 24) & 0xFF);
+}
+#endif
+
+#ifndef bswap_64
+extern "C" inline u8 bswap_64(u8 x) {
+  return (u8)bswap_32((u4)x) << 32 |
+         (u8)bswap_32((u4)(x >> 32));
+}
+#endif
+
+u2 NativeEndian::get(u2 x) { return x; }
+u4 NativeEndian::get(u4 x) { return x; }
+u8 NativeEndian::get(u8 x) { return x; }
+s2 NativeEndian::get(s2 x) { return x; }
+s4 NativeEndian::get(s4 x) { return x; }
+s8 NativeEndian::get(s8 x) { return x; }
+
+void NativeEndian::set(u2& x, u2 y) { x = y; }
+void NativeEndian::set(u4& x, u4 y) { x = y; }
+void NativeEndian::set(u8& x, u8 y) { x = y; }
+void NativeEndian::set(s2& x, s2 y) { x = y; }
+void NativeEndian::set(s4& x, s4 y) { x = y; }
+void NativeEndian::set(s8& x, s8 y) { x = y; }
+
+NativeEndian NativeEndian::_native;
+
+u2 SwappingEndian::get(u2 x) { return bswap_16(x); }
+u4 SwappingEndian::get(u4 x) { return bswap_32(x); }
+u8 SwappingEndian::get(u8 x) { return bswap_64(x); }
+s2 SwappingEndian::get(s2 x) { return bswap_16(x); }
+s4 SwappingEndian::get(s4 x) { return bswap_32(x); }
+s8 SwappingEndian::get(s8 x) { return bswap_64(x); }
+
+void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); }
+void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); }
+void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); }
+void SwappingEndian::set(s2& x, s2 y) { x = bswap_16(y); }
+void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); }
+void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); }
+
+SwappingEndian SwappingEndian::_swapping;
+
+Endian* Endian::get_handler(bool big_endian) {
+  // If requesting little endian on a little endian machine or
+  // big endian on a big endian machine use native handler
+  if (big_endian == is_big_endian()) {
+    return NativeEndian::get_native();
+  } else {
+    // Use swapping handler.
+    return SwappingEndian::get_swapping();
+  }
+}
+
+Endian* Endian::get_native_handler() {
+  return NativeEndian::get_native();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/endian.hpp	Thu Jul 09 22:46:16 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.
+ *
+ */
+
+#ifndef SHARE_VM_UTILITIES_ENDIAN_HPP
+#define SHARE_VM_UTILITIES_ENDIAN_HPP
+
+#include "utilities/globalDefinitions.hpp"
+
+// Selectable endian handling. Endian handlers are used when accessing values
+// that are of unknown (until runtime) endian.  The only requirement of the values
+// accessed are that they are aligned to proper size boundaries (no misalignment.)
+// To select an endian handler, one should call Endian::get_handler(big_endian);
+// Where big_endian is true if big endian is required and false otherwise.  The
+// native endian handler can be fetched with Endian::get_native_handler();
+// To retrieve a value using the approprate endian, use one of the overloaded
+// calls to get. To set a value, then use one of the overloaded set calls.
+// Ex.
+//      s4 value; // Imported value;
+//      ...
+//      Endian* endian = Endian::get_handler(true);  // Use big endian
+//      s4 corrected = endian->get(value);
+//      endian->set(value, 1);
+//
+class Endian {
+public:
+  virtual u2 get(u2 x) = 0;
+  virtual u4 get(u4 x) = 0;
+  virtual u8 get(u8 x) = 0;
+  virtual s2 get(s2 x) = 0;
+  virtual s4 get(s4 x) = 0;
+  virtual s8 get(s8 x) = 0;
+
+  virtual void set(u2& x, u2 y) = 0;
+  virtual void set(u4& x, u4 y) = 0;
+  virtual void set(u8& x, u8 y) = 0;
+  virtual void set(s2& x, s2 y) = 0;
+  virtual void set(s4& x, s4 y) = 0;
+  virtual void set(s8& x, s8 y) = 0;
+
+  // Quick little endian test.
+  static bool is_little_endian() {  u4 x = 1; return *(u1 *)&x != 0; }
+
+  // Quick big endian test.
+  static bool is_big_endian() { return !is_little_endian(); }
+
+  // Select an appropriate endian handler.
+  static Endian* get_handler(bool big_endian);
+
+  // Return the native endian handler.
+  static Endian* get_native_handler();
+};
+
+// Normal endian handling.
+class NativeEndian : public Endian {
+private:
+  static NativeEndian _native;
+
+public:
+  u2 get(u2 x);
+  u4 get(u4 x);
+  u8 get(u8 x);
+  s2 get(s2 x);
+  s4 get(s4 x);
+  s8 get(s8 x);
+
+  void set(u2& x, u2 y);
+  void set(u4& x, u4 y);
+  void set(u8& x, u8 y);
+  void set(s2& x, s2 y);
+  void set(s4& x, s4 y);
+  void set(s8& x, s8 y);
+
+  static Endian* get_native() { return &_native; }
+};
+
+// Swapping endian handling.
+class SwappingEndian : public Endian {
+private:
+  static SwappingEndian _swapping;
+
+public:
+  u2 get(u2 x);
+  u4 get(u4 x);
+  u8 get(u8 x);
+  s2 get(s2 x);
+  s4 get(s4 x);
+  s8 get(s8 x);
+
+  void set(u2& x, u2 y);
+  void set(u4& x, u4 y);
+  void set(u8& x, u8 y);
+  void set(s2& x, s2 y);
+  void set(s4& x, s4 y);
+  void set(s8& x, s8 y);
+
+  static Endian* get_swapping() { return &_swapping; }
+};
+#endif // SHARE_VM_UTILITIES_ENDIAN_HPP
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Thu Jul 09 22:46:16 2015 -0700
@@ -1367,6 +1367,7 @@
 #define UINT32_FORMAT_W(width) "%" #width PRIu32
 
 #define PTR32_FORMAT           "0x%08" PRIx32
+#define PTR32_FORMAT_W(width)  "0x%" #width PRIx32
 
 // Format 64-bit quantities.
 #define INT64_FORMAT           "%" PRId64
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -274,7 +274,7 @@
   size_t limit = (len + 16) / 16 * 16;
   for (size_t i = 0; i < limit; ++i) {
     if (i % 16 == 0) {
-      indent().print(INTPTR_FORMAT_W(07)":", i);
+      indent().print(INTPTR_FORMAT_W(07) ":", i);
     }
     if (i % 2 == 0) {
       print(" ");
@@ -946,7 +946,7 @@
     // %%% Should be: jlong time_ms = os::start_time_milliseconds(), if
     // we ever get round to introduce that method on the os class
     xs->head("hotspot_log version='%d %d'"
-             " process='%d' time_ms='"INT64_FORMAT"'",
+             " process='%d' time_ms='" INT64_FORMAT "'",
              LOG_MAJOR_VERSION, LOG_MINOR_VERSION,
              os::current_process_id(), (int64_t)time_ms);
     // Write VM version header immediately.
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Thu Jul 09 22:46:16 2015 -0700
@@ -411,9 +411,10 @@
            }
            st->cr();
          } else {
-           if (_message != NULL)
+           if (_message != NULL) {
              st->print("# ");
              st->print_cr("%s", _message);
+           }
          }
          // In error file give some solutions
          if (_verbose) {
--- a/hotspot/test/TEST.groups	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/TEST.groups	Thu Jul 09 22:46:16 2015 -0700
@@ -241,7 +241,7 @@
   gc/arguments/TestParallelGCThreads.java \
   gc/arguments/TestUseCompressedOopsErgo.java \
   gc/class_unloading/TestG1ClassUnloadingHWM.java \
-  gc/ergonomics/TestDynamicNumberOfGCThreads.java
+  gc/ergonomics/TestDynamicNumberOfGCThreads.java \
   gc/g1/ \
   gc/metaspace/G1AddMetaspaceDependency.java \
   gc/metaspace/TestMetaspacePerfCounters.java \
--- a/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java	Thu Jul 09 22:46:16 2015 -0700
@@ -34,6 +34,7 @@
  * @library /testlibrary
  * @modules java.base/sun.misc
  *          java.management
+ *          java.base/jdk.internal
  * @compile -XDignore.symbol.file java/lang/Object.java TestMonomorphicObjectCall.java
  * @run main TestMonomorphicObjectCall
  */
--- a/hotspot/test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java	Thu Jul 09 22:46:16 2015 -0700
@@ -25,25 +25,33 @@
 
 package java.lang;
 
+import jdk.internal.HotSpotIntrinsicCandidate;
+
 /**
  * Slightly modified version of java.lang.Object that replaces
  * finalize() by finalizeObject() to avoid overriding in subclasses.
  */
 public class Object {
 
+    @HotSpotIntrinsicCandidate
+    public Object() {}
+
     private static native void registerNatives();
     static {
         registerNatives();
     }
 
+    @HotSpotIntrinsicCandidate
     public final native Class<?> getClass();
 
+    @HotSpotIntrinsicCandidate
     public native int hashCode();
 
     public boolean equals(Object obj) {
         return (this == obj);
     }
 
+    @HotSpotIntrinsicCandidate
     protected native Object clone() throws CloneNotSupportedException;
 
     public String toString() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/montgomerymultiply/MontgomeryMultiplyTest.java	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,277 @@
+//
+// Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2015, Red Hat Inc. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact 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.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * @test
+ * @bug 8130150
+ * @library /testlibrary
+ * @summary Verify that the Montgomery multiply intrinsic works and correctly checks its arguments.
+ */
+
+public class MontgomeryMultiplyTest {
+
+    static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+    static final MethodHandle montgomeryMultiplyHandle, montgomerySquareHandle;
+    static final MethodHandle bigIntegerConstructorHandle;
+    static final Field bigIntegerMagField;
+
+    static {
+       // Use reflection to gain access to the methods we want to test.
+        try {
+            Method m = BigInteger.class.getDeclaredMethod("montgomeryMultiply",
+                /*a*/int[].class, /*b*/int[].class, /*n*/int[].class, /*len*/int.class,
+                /*inv*/long.class, /*product*/int[].class);
+            m.setAccessible(true);
+            montgomeryMultiplyHandle = lookup.unreflect(m);
+
+            m = BigInteger.class.getDeclaredMethod("montgomerySquare",
+                /*a*/int[].class, /*n*/int[].class, /*len*/int.class,
+                /*inv*/long.class, /*product*/int[].class);
+            m.setAccessible(true);
+            montgomerySquareHandle = lookup.unreflect(m);
+
+            Constructor c
+                = BigInteger.class.getDeclaredConstructor(int.class, int[].class);
+            c.setAccessible(true);
+            bigIntegerConstructorHandle = lookup.unreflectConstructor(c);
+
+            bigIntegerMagField = BigInteger.class.getDeclaredField("mag");
+            bigIntegerMagField.setAccessible(true);
+
+        } catch (Throwable ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    // Invoke either BigInteger.montgomeryMultiply or BigInteger.montgomerySquare.
+    int[] montgomeryMultiply(int[] a, int[] b, int[] n, int len, long inv,
+                             int[] product) throws Throwable {
+        int[] result =
+            (a == b) ? (int[]) montgomerySquareHandle.invokeExact(a, n, len, inv, product)
+                     : (int[]) montgomeryMultiplyHandle.invokeExact(a, b, n, len, inv, product);
+        return Arrays.copyOf(result, len);
+    }
+
+    // Invoke the private constructor BigInteger(int[]).
+    BigInteger newBigInteger(int[] val) throws Throwable {
+        return (BigInteger) bigIntegerConstructorHandle.invokeExact(1, val);
+    }
+
+    // Get the private field BigInteger.mag
+    int[] mag(BigInteger n) {
+        try {
+            return (int[]) bigIntegerMagField.get(n);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    // Montgomery multiplication
+    // Calculate a * b * r^-1 mod n)
+    //
+    // R is a power of the word size
+    // N' = R^-1 mod N
+    //
+    // T := ab
+    // m := (T mod R)N' mod R [so 0 <= m < R]
+    // t := (T + mN)/R
+    // if t >= N then return t - N else return t
+    //
+    BigInteger montgomeryMultiply(BigInteger a, BigInteger b, BigInteger N,
+            int len, BigInteger n_prime)
+            throws Throwable {
+        BigInteger T = a.multiply(b);
+        BigInteger R = BigInteger.ONE.shiftLeft(len*32);
+        BigInteger mask = R.subtract(BigInteger.ONE);
+        BigInteger m = (T.and(mask)).multiply(n_prime);
+        m = m.and(mask); // i.e. m.mod(R)
+        T = T.add(m.multiply(N));
+        T = T.shiftRight(len*32); // i.e. T.divide(R)
+        if (T.compareTo(N) > 0) {
+            T = T.subtract(N);
+        }
+        return T;
+    }
+
+    // Call the Montgomery multiply intrinsic.
+    BigInteger montgomeryMultiply(int[] a_words, int[] b_words, int[] n_words,
+            int len, BigInteger inv)
+            throws Throwable {
+        BigInteger t = montgomeryMultiply(
+                newBigInteger(a_words),
+                newBigInteger(b_words),
+                newBigInteger(n_words),
+                len, inv);
+        return t;
+    }
+
+    // Check that the Montgomery multiply intrinsic returns the same
+    // result as the longhand calculation.
+    void check(int[] a_words, int[] b_words, int[] n_words, int len, BigInteger inv)
+            throws Throwable {
+        BigInteger n = newBigInteger(n_words);
+        BigInteger slow = montgomeryMultiply(a_words, b_words, n_words, len, inv);
+        BigInteger fast
+            = newBigInteger(montgomeryMultiply
+                            (a_words, b_words, n_words, len, inv.longValue(), null));
+        // The intrinsic may not return the same value as the longhand
+        // calculation but they must have the same residue mod N.
+        if (!slow.mod(n).equals(fast.mod(n))) {
+            throw new RuntimeException();
+        }
+    }
+
+    Random rnd = new Random(0);
+
+    // Return a random value of length <= bits in an array of even length
+    int[] random_val(int bits) {
+        int len = (bits+63)/64;  // i.e. length in longs
+        int[] val = new int[len*2];
+        for (int i = 0; i < val.length; i++)
+            val[i] = rnd.nextInt();
+        int leadingZeros = 64 - (bits & 64);
+        if (leadingZeros >= 32) {
+            val[0] = 0;
+            val[1] &= ~(-1l << (leadingZeros & 31));
+        } else {
+            val[0] &= ~(-1l << leadingZeros);
+        }
+        return val;
+    }
+
+    void testOneLength(int lenInBits, int lenInInts) throws Throwable {
+        BigInteger mod = new BigInteger(lenInBits, 2, rnd);
+        BigInteger r = BigInteger.ONE.shiftLeft(lenInInts * 32);
+        BigInteger n_prime = mod.modInverse(r).negate();
+
+        // Make n.length even, padding with a zero if necessary
+        int[] n = mag(mod);
+        if (n.length < lenInInts) {
+            int[] x = new int[lenInInts];
+            System.arraycopy(n, 0, x, lenInInts-n.length, n.length);
+            n = x;
+        }
+
+        for (int i = 0; i < 10000; i++) {
+            // multiply
+            check(random_val(lenInBits), random_val(lenInBits), n, lenInInts, n_prime);
+            // square
+            int[] tmp = random_val(lenInBits);
+            check(tmp, tmp, n, lenInInts, n_prime);
+        }
+    }
+
+    // Test the Montgomery multiply intrinsic with a bunch of random
+    // values of varying lengths.  Do this for long enough that the
+    // caller of the intrinsic is C2-compiled.
+    void testResultValues() throws Throwable {
+        // Test a couple of interesting edge cases.
+        testOneLength(1024, 32);
+        testOneLength(1025, 34);
+        for (int j = 10; j > 0; j--) {
+            // Construct a random prime whose length in words is even
+            int lenInBits = rnd.nextInt(2048) + 64;
+            int lenInInts = (lenInBits + 63)/64*2;
+            testOneLength(lenInBits, lenInInts);
+        }
+    }
+
+    // Range checks
+    void testOneMontgomeryMultiplyCheck(int[] a, int[] b, int[] n, int len, long inv,
+                                        int[] product, Class klass) {
+        try {
+            montgomeryMultiply(a, b, n, len, inv, product);
+        } catch (Throwable ex) {
+            if (klass.isAssignableFrom(ex.getClass()))
+                return;
+            throw new RuntimeException(klass + " expected, " + ex + " was thrown");
+        }
+        throw new RuntimeException(klass + " expected, was not thrown");
+    }
+
+    void testOneMontgomeryMultiplyCheck(int[] a, int[] b, BigInteger n, int len, BigInteger inv,
+            Class klass) {
+        testOneMontgomeryMultiplyCheck(a, b, mag(n), len, inv.longValue(), null, klass);
+    }
+
+    void testOneMontgomeryMultiplyCheck(int[] a, int[] b, BigInteger n, int len, BigInteger inv,
+            int[] product, Class klass) {
+        testOneMontgomeryMultiplyCheck(a, b, mag(n), len, inv.longValue(), product, klass);
+    }
+
+    void testMontgomeryMultiplyChecks() {
+        int[] blah = random_val(40);
+        int[] small = random_val(39);
+        BigInteger mod = new BigInteger(40*32 , 2, rnd);
+        BigInteger r = BigInteger.ONE.shiftLeft(40*32);
+        BigInteger n_prime = mod.modInverse(r).negate();
+
+        // Length out of range: square
+        testOneMontgomeryMultiplyCheck(blah, blah, mod, 41, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(blah, blah, mod, 0, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(blah, blah, mod, -1, n_prime, IllegalArgumentException.class);
+        // As above, but for multiply
+        testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 41, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 0, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 0, n_prime, IllegalArgumentException.class);
+
+        // Length odd
+        testOneMontgomeryMultiplyCheck(small, small, mod, 39, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(small, small, mod, 0, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(small, small, mod, -1, n_prime, IllegalArgumentException.class);
+        // As above, but for multiply
+        testOneMontgomeryMultiplyCheck(small, small.clone(), mod, 39, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(small, small.clone(), mod, 0, n_prime, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(small, small.clone(), mod, -1, n_prime, IllegalArgumentException.class);
+
+        // array too small
+        testOneMontgomeryMultiplyCheck(blah, blah, mod, 40, n_prime, small, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 40, n_prime, small, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(small, blah, mod, 40, n_prime, blah, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(blah, small, mod, 40, n_prime, blah, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(blah, blah, mod, 40, n_prime, small, IllegalArgumentException.class);
+        testOneMontgomeryMultiplyCheck(small, small, mod, 40, n_prime, blah, IllegalArgumentException.class);
+    }
+
+    public static void main(String args[]) {
+        try {
+            new MontgomeryMultiplyTest().testMontgomeryMultiplyChecks();
+            new MontgomeryMultiplyTest().testResultValues();
+        } catch (Throwable ex) {
+            throw new RuntimeException(ex);
+        }
+     }
+}
--- a/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java	Thu Jul 09 22:46:16 2015 -0700
@@ -47,16 +47,12 @@
     // expressions, not just a plain strings.
     protected static final String SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE
             = "SHA instructions are not available on this CPU";
-    protected static final String SHA1_INSTRUCTION_IS_NOT_AVAILABLE
-            = "SHA1 instruction is not available on this CPU\\.";
-    protected static final String SHA256_INSTRUCTION_IS_NOT_AVAILABLE
-            = "SHA256 instruction \\(for SHA-224 and SHA-256\\) "
-            + "is not available on this CPU\\.";
-    protected static final String SHA512_INSTRUCTION_IS_NOT_AVAILABLE
-            = "SHA512 instruction \\(for SHA-384 and SHA-512\\) "
-            + "is not available on this CPU\\.";
-    protected static final String SHA_INTRINSICS_ARE_NOT_AVAILABLE
-            = "SHA intrinsics are not available on this CPU";
+    protected static final String SHA1_INTRINSICS_ARE_NOT_AVAILABLE
+            = "Intrinsics for SHA-1 crypto hash functions not available on this CPU.";
+    protected static final String SHA256_INTRINSICS_ARE_NOT_AVAILABLE
+            = "Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.";
+    protected static final String SHA512_INTRINSICS_ARE_NOT_AVAILABLE
+            = "Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.";
 
     private final TestCase[] testCases;
 
@@ -71,33 +67,23 @@
      *         instructions required by the option are not supported.
      */
     protected static String getWarningForUnsupportedCPU(String optionName) {
-        if (Platform.isSparc() || Platform.isAArch64()) {
+        if (Platform.isSparc() || Platform.isAArch64() ||
+            Platform.isX64() || Platform.isX86()) {
             switch (optionName) {
-                case SHAOptionsBase.USE_SHA_OPTION:
-                    return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA1_INSTRUCTION_IS_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA256_INSTRUCTION_IS_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA512_INSTRUCTION_IS_NOT_AVAILABLE;
-                default:
-                    throw new Error("Unexpected option " + optionName);
-            }
-        } else if (Platform.isX64() || Platform.isX86()) {
-            switch (optionName) {
-                case SHAOptionsBase.USE_SHA_OPTION:
-                    return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
-                case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
-                case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA_INTRINSICS_ARE_NOT_AVAILABLE;
-                default:
-                    throw new Error("Unexpected option " + optionName);
+            case SHAOptionsBase.USE_SHA_OPTION:
+                return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
+            case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
+                return SHAOptionsBase.SHA1_INTRINSICS_ARE_NOT_AVAILABLE;
+            case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
+                return SHAOptionsBase.SHA256_INTRINSICS_ARE_NOT_AVAILABLE;
+            case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
+                return SHAOptionsBase.SHA512_INTRINSICS_ARE_NOT_AVAILABLE;
+            default:
+                throw new Error("Unexpected option " + optionName);
             }
         } else {
-            throw new Error("Support for CPUs other then X86 or SPARC is not "
-                    + "implemented.");
+            throw new Error("Support for CPUs different fromn X86, SPARC, and AARCH64 "
+                            + "is not implemented");
         }
     }
 
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedCPU.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedCPU.java	Thu Jul 09 22:46:16 2015 -0700
@@ -64,18 +64,20 @@
                         SHAOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
 
-        // Verify that it is possible to enable the tested option and disable
-        // all SHA intrinsics via -UseSHA without any warnings.
-        CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
-                }, shouldPassMessage, String.format("It should be able to "
-                        + "enable option '%s' even if %s was passed to JVM",
-                        optionName, CommandLineOptionTest.prepareBooleanFlag(
-                            SHAOptionsBase.USE_SHA_OPTION, false)),
-                ExitCode.OK,
-                CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, false),
-                CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+        if (!optionName.equals(SHAOptionsBase.USE_SHA_OPTION)) {
+            // Verify that if -XX:-UseSHA is passed to the JVM, it is not possible
+            // to enable the tested option and a warning is printed.
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) },
+                    null,
+                    shouldPassMessage,
+                    String.format("Enabling option '%s' should not be possible and should result in a warning if %s was passed to JVM",
+                                  optionName,
+                                  CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false)),
+                    ExitCode.OK,
+                    CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false),
+                    CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+        }
     }
 
     @Override
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java	Thu Jul 09 22:46:16 2015 -0700
@@ -49,14 +49,22 @@
                 }, shouldPassMessage, shouldPassMessage, ExitCode.OK,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
 
-        shouldPassMessage = String.format("JVM should start with '-XX:+"
-                + "%s' flag, but output should contain warning.", optionName);
-        // Verify that when the tested option is explicitly enabled, then
-        // a warning will occur in VM output.
-        CommandLineOptionTest.verifySameJVMStartup(new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
-                }, null, shouldPassMessage, shouldPassMessage, ExitCode.OK,
-                CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+        shouldPassMessage = String.format("If JVM is started with '-XX:-"
+                + "%s' '-XX:+%s', output should contain warning.",
+                SHAOptionsBase.USE_SHA_OPTION, optionName);
+
+        // Verify that when the tested option is enabled, then
+        // a warning will occur in VM output if UseSHA is disabled.
+        if (!optionName.equals(SHAOptionsBase.USE_SHA_OPTION)) {
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) },
+                    null,
+                    shouldPassMessage,
+                    shouldPassMessage,
+                    ExitCode.OK,
+                    CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false),
+                    CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+        }
     }
 
     @Override
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java	Thu Jul 09 22:46:16 2015 -0700
@@ -48,6 +48,19 @@
                         SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, shouldPassMessage, shouldPassMessage, ExitCode.OK,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
+
+        // Verify that when the tested option is enabled, then
+        // a warning will occur in VM output if UseSHA is disabled.
+        if (!optionName.equals(SHAOptionsBase.USE_SHA_OPTION)) {
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) },
+                    null,
+                    shouldPassMessage,
+                    shouldPassMessage,
+                    ExitCode.OK,
+                    CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false),
+                    CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+        }
     }
 
     @Override
--- a/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java	Thu Jul 09 22:46:16 2015 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test TestShrinkDefragmentedHeap
- * @bug 8038423
+ * @bug 8038423 8129590
  * @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects
  *     1. allocate small objects mixed with humongous ones
  *        "ssssHssssHssssHssssHssssHssssHssssH"
@@ -51,12 +51,14 @@
     // To avoid this the Eden needs to be big enough to fit all the small objects.
     private static final int INITIAL_HEAP_SIZE  = 200 * 1024 * 1024;
     private static final int MINIMAL_YOUNG_SIZE = 190 * 1024 * 1024;
+    private static final int MAXIMUM_HEAP_SIZE  = 256 * 1024 * 1024;
     private static final int REGION_SIZE        = 1 * 1024 * 1024;
 
     public static void main(String[] args) throws Exception, Throwable {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
                 "-XX:InitialHeapSize=" + INITIAL_HEAP_SIZE,
                 "-Xmn" + MINIMAL_YOUNG_SIZE,
+                "-Xmx" + MAXIMUM_HEAP_SIZE,
                 "-XX:MinHeapFreeRatio=10",
                 "-XX:MaxHeapFreeRatio=11",
                 "-XX:+UseG1GC",
--- a/hotspot/test/gc/g1/TestSummarizeRSetStats.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/gc/g1/TestSummarizeRSetStats.java	Thu Jul 09 22:46:16 2015 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test TestSummarizeRSetStats.java
- * @bug 8013895
+ * @bug 8013895 8129977
  * @library /testlibrary
  * @modules java.base/sun.misc
  *          java.management/sun.management
--- a/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java	Thu Jul 09 22:46:16 2015 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test TestSummarizeRSetStatsPerRegion.java
- * @bug 8014078
+ * @bug 8014078 8129977
  * @library /testlibrary
  * @modules java.base/sun.misc
  *          java.management/sun.management
--- a/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java	Thu Jul 09 22:46:16 2015 -0700
@@ -87,6 +87,7 @@
         String[] defaultArgs = new String[] {
             "-XX:+UseG1GC",
             "-Xmn4m",
+            "-Xms20m",
             "-Xmx20m",
             "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
             "-XX:+PrintGC",
--- a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java	Thu Jul 09 22:46:16 2015 -0700
@@ -28,6 +28,7 @@
  *          when their age exceeded tenuring threshold are not aligned to
  *          SurvivorAlignmentInBytes value.
  * @library /testlibrary /../../test/lib
+ * @ignore 8130308
  * @modules java.base/sun.misc
  *          java.management
  * @build TestPromotionFromSurvivorToTenuredAfterMinorGC
--- a/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java	Thu Jul 09 22:46:16 2015 -0700
@@ -31,6 +31,7 @@
  *          java.management
  * @build TestPromotionToSurvivor
  *        SurvivorAlignmentTestMain AlignmentHelper
+ * @ignore 8129886
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/DoubleJVMOption.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/DoubleJVMOption.java	Thu Jul 09 22:46:16 2015 -0700
@@ -25,6 +25,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 public class DoubleJVMOption extends JVMOption {
 
@@ -109,7 +110,7 @@
     }
 
     private String formatValue(double value) {
-        return String.format("%f", value);
+        return String.format(Locale.US, "%f", value);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/TestLongUnrecognizedVMOption.java	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,48 @@
+/*
+ * 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 8129786
+ * @summary Verify that JVM correctly processes very long unrecognized VM option
+ * @library /testlibrary
+ * @modules java.management
+ * @run main TestLongUnrecognizedVMOption
+ */
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+
+public class TestLongUnrecognizedVMOption {
+
+    /* Create option with very long length(greater than 500 characters) */
+    private static final String VERY_LONG_OPTION = String.format("%500s=10", "unrecognizedoption").replace(" ", "a");
+
+    public static void main(String[] args) throws Exception {
+        OutputAnalyzer output;
+
+        output = new OutputAnalyzer(ProcessTools.createJavaProcessBuilder("-XX:" + VERY_LONG_OPTION, "-version").start());
+        output.shouldHaveExitValue(1);
+        output.shouldContain(String.format("Unrecognized VM option '%s'", VERY_LONG_OPTION));
+    }
+}
--- a/hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java	Thu Jul 09 22:46:16 2015 -0700
@@ -23,12 +23,15 @@
 
 /**
  * @test
- * @library /runtime/testlibrary
  * @library classes
- * @build test.Empty ClassUnloadCommon
+ * @build test.Empty
  * @run main/othervm/timeout=200 FragmentMetaspaceSimple
  */
 
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 
 /**
@@ -47,8 +50,14 @@
     private static void runSimple(long time) {
         long startTime = System.currentTimeMillis();
         ArrayList<ClassLoader> cls = new ArrayList<>();
-        for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
-            ClassLoader ldr = ClassUnloadCommon.newClassLoader();
+        char sep = File.separatorChar;
+        String fileName = "classes" + sep + "test" + sep + "Empty.class";
+        File file = new File(System.getProperty("test.classes",".") + sep + fileName);
+        byte buff[] = read(file);
+
+        int i = 0;
+        for (i = 0; System.currentTimeMillis() < startTime + time; ++i) {
+            ClassLoader ldr = new MyClassLoader(buff);
             if (i % 1000 == 0) {
                 cls.clear();
             }
@@ -59,11 +68,43 @@
             Class<?> c = null;
             try {
                 c = ldr.loadClass("test.Empty");
+                c.getClass().getClassLoader(); // make sure we have a valid class.
             } catch (ClassNotFoundException ex) {
+                System.out.println("i=" + i + ", len" + buff.length);
                 throw new RuntimeException(ex);
             }
             c = null;
         }
         cls = null;
+        System.out.println("Finished " + i + " iterations in " +
+                           (System.currentTimeMillis() - startTime) + " ms");
+    }
+
+    private static byte[] read(File file) {
+        byte buff[] = new byte[(int)(file.length())];
+        try {
+            DataInputStream din = new DataInputStream(new FileInputStream(file));
+            din.readFully(buff);
+            din.close();
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+        return buff;
+    }
+
+    static class MyClassLoader extends ClassLoader {
+        byte buff[];
+        MyClassLoader(byte buff[]) {
+            this.buff = buff;
+        }
+
+        public Class<?> loadClass() throws ClassNotFoundException {
+            String name = "test.Empty";
+            try {
+                return defineClass(name, buff, 0, buff.length);
+            } catch (Throwable e) {
+                throw new ClassNotFoundException(name, e);
+            }
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageAttributeOffsetsTest.java	Thu Jul 09 22:46:16 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.
+ */
+
+/*
+ * Retrieves the array of offsets once with MemoryMapImage enabled once disabled.
+ * @test ImageAttributeOffsetsTest
+ * @summary Unit test for JVM_ImageAttributeOffsets() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageAttributeOffsetsTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageAttributeOffsetsTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageAttributeOffsetsTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageAttributeOffsetsTest {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+        long id = wb.imageOpenImage(imageFile, bigEndian);
+        boolean passed = true;
+        // Get offsets
+        int[] array = wb.imageAttributeOffsets(id);
+        assertNotNull(array, "Could not retrieve offsets of array");
+
+        wb.imageCloseImage(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageCloseTest.java	Thu Jul 09 22:46:16 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.
+ */
+
+/*
+ * Test closing image opened multiple time. Test closing mutiple time an image.
+ * @test ImageCloseTest
+ * @summary Unit test for JVM_ImageClose() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageCloseTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageCloseTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+
+public class ImageCloseTest {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+        long id = 0;
+
+        // too many opens
+        for (int i = 0; i < 100; i++) {
+            id = wb.imageOpenImage(imageFile, bigEndian);
+        }
+        wb.imageCloseImage(id);
+
+        // too many closes
+        id = wb.imageOpenImage(imageFile, bigEndian);
+        for (int i = 0; i < 100; i++) {
+            wb.imageCloseImage(id);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageFileHeaderTest.java	Thu Jul 09 22:46:16 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.
+ */
+
+/*
+ * Test that opening image containing wrong headers fails.
+ * @test ImageFileHeaderTest
+ * @library /testlibrary /../../test/lib
+ * @build ImageFileHeaderTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageFileHeaderTest
+ */
+
+import java.nio.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageFileHeaderTest {
+
+    public static final int MAGIC = 0xCAFEDADA;
+    public static final short MAJOR = 0;
+    public static final short MINOR = 1;
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+    public static ByteBuffer buf;
+
+    public static void main(String... args) throws Exception {
+
+        ByteOrder endian = getEndian();
+
+        // Try to read a non-existing file
+        assertFalse(wb.readImageFile("bogus"));
+
+        // Incomplete header, only include the correct magic
+        buf = ByteBuffer.allocate(100);
+        buf.order(endian);
+        buf.putInt(MAGIC);
+        assertFalse(testImageFile("invalidheader.jimage"));
+
+        // Build a complete header but reverse the endian
+        buf = ByteBuffer.allocate(100);
+        buf.order(endian == ByteOrder.LITTLE_ENDIAN ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+        buf.putInt(MAGIC);
+        buf.putShort(MAJOR);
+        buf.putShort(MINOR);
+        assertFalse(testImageFile("wrongendian.jimage"));
+
+        // Use the wrong magic
+        buf = ByteBuffer.allocate(100);
+        buf.order(endian);
+        buf.putInt(0xBEEFCACE);
+        buf.putShort(MAJOR);
+        buf.putShort(MINOR);
+        assertFalse(testImageFile("wrongmagic.jimage"));
+
+        // Wrong major version (current + 1)
+        buf = ByteBuffer.allocate(100);
+        buf.order(endian);
+        buf.putInt(MAGIC);
+        buf.putShort((short)(MAJOR + 1));
+        buf.putShort((short)MINOR);
+        assertFalse(testImageFile("wrongmajorversion.jimage"));
+
+        // Wrong major version (negative)
+        buf = ByteBuffer.allocate(100);
+        buf.order(endian);
+        buf.putInt(MAGIC);
+        buf.putShort((short) -17);
+        buf.putShort((short)MINOR);
+        assertFalse(testImageFile("negativemajorversion.jimage"));
+
+        // Wrong minor version (current + 1)
+        buf = ByteBuffer.allocate(100);
+        buf.order(endian);
+        buf.putInt(MAGIC);
+        buf.putShort((short)MAJOR);
+        buf.putShort((short)(MINOR + 1));
+        assertFalse(testImageFile("wrongminorversion.jimage"));
+
+        // Wrong minor version (negative)
+        buf = ByteBuffer.allocate(100);
+        buf.order(endian);
+        buf.putInt(MAGIC);
+        buf.putShort((short)MAJOR);
+        buf.putShort((short) -17);
+        assertFalse(testImageFile("negativeminorversion.jimage"));
+    }
+
+    public static boolean testImageFile(String filename) throws Exception {
+        Files.write(Paths.get(filename), buf.array());
+        System.out.println("Calling ReadImageFile on " + filename);
+        return wb.readImageFile(filename);
+    }
+
+    public static ByteOrder getEndian() {
+        String endian = System.getProperty("sun.cpu.endian");
+        if (endian.equalsIgnoreCase("little")) {
+            return ByteOrder.LITTLE_ENDIAN;
+        } else if (endian.equalsIgnoreCase("big")) {
+            return ByteOrder.BIG_ENDIAN;
+        }
+        throw new RuntimeException("Unexpected sun.cpu.endian value: " + endian);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageFindAttributesTest.java	Thu Jul 09 22:46:16 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.
+ */
+
+/*
+ * Find the attributes of existing and invalid classes.
+ * @test ImageFindAttributesTest
+ * @summary Unit test for JVM_ImageFindAttributes() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageFindAttributesTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageFindAttributesTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageFindAttributesTest {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+        long id = wb.imageOpenImage(imageFile, bigEndian);
+
+        // class resource
+        String className = "/java.base/java/lang/String.class";
+        long[] longArr = wb.imageFindAttributes(id, className.getBytes());
+
+        assertNotNull(longArr, "Could not retrieve attributes of class " + className);
+
+        // non-existent resource
+        String neClassName = "/java.base/java/lang/NonExistentClass.class";
+        longArr = wb.imageFindAttributes(id, neClassName.getBytes());
+
+        assertNull(longArr, "Failed. Returned not null for non-existent " + neClassName);
+
+        // garbage byte array
+        byte[] buf = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        longArr = wb.imageFindAttributes(id, buf);
+
+        assertNull(longArr, "Found attributes for garbage class");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetAttributesTest.java	Thu Jul 09 22:46:16 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.
+ */
+
+/*
+ * Test getting all attributes,
+ * @test ImageGetAttributesTest
+ * @summary Unit test for JVM_ImageGetAttributes() method
+ * @library /testlibrary /../../test/lib
+ * @build LocationConstants ImageGetAttributesTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetAttributesTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetAttributesTest implements LocationConstants {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        testImageGetAttributes(imageFile);
+    }
+
+    private static void testImageGetAttributes(String imageFile) {
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+        long id = wb.imageOpenImage(imageFile, bigEndian);
+        try {
+            long stringsSize = wb.imageGetStringsSize(id);
+            assertNE(stringsSize, 0, "strings size is 0");
+
+            int[] array = wb.imageAttributeOffsets(id);
+            assertNotNull(array, "Could not retrieve offsets of array");
+
+            // Get non-null attributes
+            boolean attFound = false;
+            int[] idx = {-1, -1, -1};
+            // first non-null attribute
+            for (int i = 0; i < array.length; i++) {
+                if (array[i] != 0) {
+                    attFound = true;
+                    idx[0] = i;
+                    break;
+                }
+            }
+
+            // middle non-null attribute
+            for (int i = array.length / 2; i < array.length; i++) {
+                if (array[i] != 0) {
+                    attFound = true;
+                    idx[1] = i;
+                    break;
+                }
+            }
+
+            // last non-null attribute
+            for (int i = array.length - 1; i >= 0; i--) {
+                if (array[i] != 0) {
+                    attFound = true;
+                    idx[2] = i;
+                    break;
+                }
+            }
+            assertTrue(attFound, "Failed. No non-null offset attributes");
+                // test cases above
+                for (int i = 0; i < 3; i++) {
+                    if (idx[i] != -1) {
+                        long[] attrs = wb.imageGetAttributes(id, (int) array[idx[i]]);
+                        long module = attrs[LOCATION_ATTRIBUTE_MODULE];
+                        long parent = attrs[LOCATION_ATTRIBUTE_PARENT];
+                        long base = attrs[LOCATION_ATTRIBUTE_BASE];
+                        long ext = attrs[LOCATION_ATTRIBUTE_EXTENSION];
+
+                        if ((module >= 0) && (module < stringsSize)
+                                && (parent >= 0) && (parent < stringsSize)
+                                && (base != 0)
+                                && (ext >= 0) && (ext < stringsSize)) {
+                        } else {
+                            System.out.printf("Failed. Read attribute offset %d (position %d) but wrong offsets\n",
+                                    array[idx[i]], idx[i]);
+                            System.out.printf("    offsets: module = %d parent = %d base = %d extention = %d\n",
+                                    module, parent, base, ext);
+                            throw new RuntimeException("Read attribute offset error");
+                        }
+                    } else {
+                        System.out.printf("Failed. Could not read attribute offset %d (position %d)\n",
+                                array[idx[i]], idx[i]);
+                        throw new RuntimeException("Read attribute offset error");
+                    }
+                }
+        } finally {
+            wb.imageCloseImage(id);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetDataAddressTest.java	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,71 @@
+/*
+ * 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 accessing the data address of a jimage. This only makes sense when the
+ * entire jimage is mapped into memory.
+ * @test ImageGetDataAddressTest
+ * @summary Unit test for JVM_ImageGetDataAddress() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageGetDataAddressTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageGetDataAddressTest +
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageGetDataAddressTest -
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetDataAddressTest {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean isMMap = args[0].equals("+");
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+        long id = wb.imageOpenImage(imageFile, bigEndian);
+
+        // get data for valid id
+        long dataAddr = wb.imageGetDataAddress(id);
+        assertFalse((dataAddr == 0) && isMMap, "Failed. Data address is " + dataAddr + " for valid id\n");
+
+        // get data for invalid id == 0
+        dataAddr = wb.imageGetDataAddress(0);
+        assertTrue(dataAddr == 0, "Failed. Data address is " + dataAddr + " for zero id\n");
+
+        wb.imageCloseImage(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetIndexAddressTest.java	Thu Jul 09 22:46:16 2015 -0700
@@ -0,0 +1,67 @@
+/*
+ * 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 the address of the jimage index.
+ * @test ImageGetIndexAddressTest
+ * @summary Unit test for JVM_ImageGetIndexAddress() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageGetIndexAddressTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetIndexAddressTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetIndexAddressTest {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+        long id = wb.imageOpenImage(imageFile, bigEndian);
+
+        // get index for valid id
+        long indexAddr = wb.imageGetIndexAddress(id);
+        assertFalse(indexAddr == 0, "Failed. Index address is zero for valid id");
+
+        // get index for invalid id == 0
+        indexAddr = wb.imageGetIndexAddress(0);
+        assertTrue(indexAddr == 0, "Failed. Index address is" + indexAddr + " for zero id\n");
+
+        wb.imageCloseImage(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetStringBytesTest.java	Thu Jul 09 22:46:16 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 that the string referenced by an attribute is retrieved.
+ * @test ImageGetStringBytesTest
+ * @summary Unit test for JVM_ImageGetStringBytes() method
+ * @library /testlibrary /../../test/lib
+ * @build LocationConstants ImageGetStringBytesTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetStringBytesTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetStringBytesTest implements LocationConstants {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+        long id = wb.imageOpenImage(imageFile, bigEndian);
+
+        String className = "/java.base/java/lang/String.class";
+        long[] offsetArr = wb.imageFindAttributes(id, className.getBytes());
+
+        // Module
+        assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_MODULE, "Module"));
+
+        // Parent
+        assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_PARENT, "Parent"));
+
+        // Base
+        assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_BASE, "Base"));
+
+        // Extension
+        assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_EXTENSION, "Extension"));
+
+        wb.imageCloseImage(id);
+    }
+
+    private static boolean checkAttribute(long id, long[] offsetArr, int attrId, String attrName) {
+        long offset = offsetArr[attrId];
+        return wb.imageGetStringBytes(id, (int) offset) != null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageOpenTest.java	Thu Jul 09 22:46:16 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.
+ */
+
+/*
+ * Test image opening/closing
+ * @test ImageOpenTest
+ * @summary Unit test for JVM_ImageOpen() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageOpenTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageOpenTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageOpenTest {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String nonexistentImageFile = javaHome + "/lib/modules/nonexistent.jimage";
+        String bootmodulesImageFile = javaHome + File.separator + "lib" + File.separator
+                + "modules" + File.separator + "bootmodules.jimage";
+
+        if (!(new File(bootmodulesImageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+
+        // open nonexistent image
+        long id = wb.imageOpenImage(nonexistentImageFile, bigEndian);
+        assertTrue(id == 0L, "Failed. Get id " + id + "instead of 0 on opening nonexistent file\n");
+        wb.imageCloseImage(id);
+
+        // open bootmodules image
+        id = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+        assertFalse(id == 0, "Failed. Get id 0 on opening bootmodules.jimage");
+        wb.imageCloseImage(id);
+
+        // non-native endian
+        id = wb.imageOpenImage(bootmodulesImageFile, !bigEndian);
+        assertFalse(id == 0, "Failed. Get id 0 on opening bootmodules.jimage with non-native endian");
+        wb.imageCloseImage(id);
+
+        //
+        // open several times
+        //
+        id = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+        long id1 = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+        long id2 = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+        assertTrue((id == id1) && (id == id2), "Failed. Open thee times with ids " + id + " " + id1 + " " + id1);
+
+        wb.imageCloseImage(id);
+        wb.imageCloseImage(id1);
+        wb.imageCloseImage(id2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageReadTest.java	Thu Jul 09 22:46:16 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 reading resource content.
+ * @test ImageReadTest
+ * @summary Unit test for JVM_ImageRead() method
+ * @library /testlibrary /../../test/lib
+ * @build LocationConstants ImageReadTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageReadTest +
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageReadTest -
+ */
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageReadTest implements LocationConstants {
+
+    public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        String javaHome = System.getProperty("java.home");
+        String imageFile = javaHome + File.separator + "lib"
+                + File.separator + "modules" + File.separator
+                + "bootmodules.jimage";
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped.");
+            return;
+        }
+
+        boolean isMMap = args[0].equals("+");
+
+        long id = wb.imageOpenImage(imageFile, isMMap);
+
+        final String mm = isMMap ? "-XX:+MemoryMapImage" : "-XX:-MemoryMapImage";
+        final int magic = 0xCAFEBABE;
+
+        String className = "/java.base/java/lang/String.class";
+        long[] offsetArr = wb.imageFindAttributes(id, className.getBytes());
+        long offset = offsetArr[LOCATION_ATTRIBUTE_OFFSET];
+        long size = offsetArr[LOCATION_ATTRIBUTE_UNCOMPRESSED];
+
+        // positive: read
+        ByteBuffer buf = ByteBuffer.allocateDirect((int) size);
+        assertTrue(wb.imageRead(id, offset, buf, size), "Failed. Read operation returned false, should be true");
+        int m = buf.getInt();
+        assertTrue(m == magic, "Failed. Read operation returned true but wrong magic = " + magic);
+
+        // positive: mmap
+        if (isMMap) {
+            long dataAddr = wb.imageGetDataAddress(id);
+            assertFalse(dataAddr == 0L, "Failed. Did not obtain data address on mmapped test");
+            int data = wb.imageGetIntAtAddress(dataAddr, (int) offset, true);
+            assertTrue(data == magic, "Failed. MMap operation returned true but wrong magic = " + data);
+        }
+
+        // negative: wrong offset
+        boolean success = wb.imageRead(id, -100, buf, size);
+        assertFalse(success, "Failed. Read operation (wrong offset): returned true");
+
+        // negative: too big offset
+        long filesize = new File(imageFile).length();
+        success = wb.imageRead(id, filesize + 1, buf, size);
+        assertFalse(success, "Failed. Read operation (offset > file size) returned true");
+
+        // negative: negative size
+        success = wb.imageRead(id, offset, buf, -100);
+        assertFalse(success, "Failed. Read operation (negative size) returned true");
+
+        wb.imageCloseImage(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/LocationConstants.java	Thu Jul 09 22:46:16 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.
+ */
+
+public interface LocationConstants {
+    // keep this in sync with enum in ImageLocation C++ class in the
+    // hotspot's C++ header file imageFile.hpp
+    public static final int LOCATION_ATTRIBUTE_END = 0;          // End of attribute stream marker
+    public static final int LOCATION_ATTRIBUTE_MODULE = 1;       // String table offset of module name
+    public static final int LOCATION_ATTRIBUTE_PARENT = 2;       // String table offset of resource path parent
+    public static final int LOCATION_ATTRIBUTE_BASE = 3;         // String table offset of resource path base
+    public static final int LOCATION_ATTRIBUTE_EXTENSION = 4;    // String table offset of resource path extension
+    public static final int LOCATION_ATTRIBUTE_OFFSET = 5;       // Container byte offset of resource
+    public static final int LOCATION_ATTRIBUTE_COMPRESSED = 6;   // In image byte size of the compressed resource
+    public static final int LOCATION_ATTRIBUTE_UNCOMPRESSED = 7; // In memory byte size of the uncompressed resource
+    public static final int LOCATION_ATTRIBUTE_COUNT = 8;        // Number of attribute kinds
+}
--- a/hotspot/test/testlibrary/ctw/Makefile	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/testlibrary/ctw/Makefile	Thu Jul 09 22:46:16 2015 -0700
@@ -8,7 +8,7 @@
 #
 # This code is distributed in the hope that it will be useful, but WITHOUT
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.	See the GNU General Public License
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 # version 2 for more details (a copy is included in the LICENSE file that
 # accompanied this code).
 #
--- a/hotspot/test/testlibrary/ctw/README	Wed Jul 05 20:41:30 2017 +0200
+++ b/hotspot/test/testlibrary/ctw/README	Thu Jul 09 22:46:16 2015 -0700
@@ -1,26 +1,26 @@
-#
-# 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.
-#
-#
+
+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.
+
+
 
 DESCRIPTION