changeset 7815:a4f200a81135

Merge
author anoll
date Tue, 03 Feb 2015 09:56:21 +0000
parents 5bfedd3cfd39 5960a65b0f54
children b50281ff91ce
files make/linux/makefiles/build_vm_def.sh test/gc/g1/TestEagerReclaimHumongousRegions2.java test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java test/runtime/7194254/Test7194254.java
diffstat 343 files changed, 11553 insertions(+), 3181 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Feb 03 10:30:16 2015 +0100
+++ b/.hgtags	Tue Feb 03 09:56:21 2015 +0000
@@ -445,3 +445,9 @@
 6b09b3193d731e3288e2a240c504a20d0a06c766 jdk9-b40
 1d29b13e8a515a7ea3b882f140576d5d675bc11f jdk9-b41
 38cb4fbd47e3472bd1b5ebac83bda96fe4869c4f jdk9-b42
+65a9747147b8090037541040ba67156ec914db6a jdk9-b43
+43a44b56dca61a4d766a20f0528fdd8b5ceff873 jdk9-b44
+5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45
+a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46
+3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
+cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48
--- a/agent/make/Makefile	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/make/Makefile	Tue Feb 03 09:56:21 2015 +0000
@@ -58,15 +58,19 @@
 sun.jvm.hotspot.debugger.dummy \
 sun.jvm.hotspot.debugger.linux \
 sun.jvm.hotspot.debugger.linux.amd64 \
+sun.jvm.hotspot.debugger.linux.ppc64 \
 sun.jvm.hotspot.debugger.linux.x86 \
 sun.jvm.hotspot.debugger.posix \
 sun.jvm.hotspot.debugger.posix.elf \
+sun.jvm.hotspot.debugger.ppc64 \
 sun.jvm.hotspot.debugger.proc \
 sun.jvm.hotspot.debugger.proc.amd64 \
+sun.jvm.hotspot.debugger.proc.ppc64 \
 sun.jvm.hotspot.debugger.proc.sparc \
 sun.jvm.hotspot.debugger.proc.x86 \
 sun.jvm.hotspot.debugger.remote \
 sun.jvm.hotspot.debugger.remote.amd64 \
+sun.jvm.hotspot.debugger.remote.ppc64 \
 sun.jvm.hotspot.debugger.remote.sparc \
 sun.jvm.hotspot.debugger.remote.x86 \
 sun.jvm.hotspot.debugger.sparc \
@@ -93,9 +97,11 @@
 sun.jvm.hotspot.runtime.bsd_x86 \
 sun.jvm.hotspot.runtime.linux \
 sun.jvm.hotspot.runtime.linux_amd64 \
+sun.jvm.hotspot.runtime.linux_ppc64 \
 sun.jvm.hotspot.runtime.linux_sparc \
 sun.jvm.hotspot.runtime.linux_x86 \
 sun.jvm.hotspot.runtime.posix \
+sun.jvm.hotspot.runtime.ppc64 \
 sun.jvm.hotspot.runtime.solaris_amd64 \
 sun.jvm.hotspot.runtime.solaris_sparc \
 sun.jvm.hotspot.runtime.solaris_x86 \
@@ -142,15 +148,19 @@
 sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
 sun/jvm/hotspot/debugger/dummy/*.java \
 sun/jvm/hotspot/debugger/linux/*.java \
+sun/jvm/hotspot/debugger/linux/ppc64/*.java \
 sun/jvm/hotspot/debugger/linux/x86/*.java \
 sun/jvm/hotspot/debugger/posix/*.java \
 sun/jvm/hotspot/debugger/posix/elf/*.java \
+sun/jvm/hotspot/debugger/ppc64/*.java \
 sun/jvm/hotspot/debugger/proc/*.java \
 sun/jvm/hotspot/debugger/proc/amd64/*.java \
+sun/jvm/hotspot/debugger/proc/ppc64/*.java \
 sun/jvm/hotspot/debugger/proc/sparc/*.java \
 sun/jvm/hotspot/debugger/proc/x86/*.java \
 sun/jvm/hotspot/debugger/remote/*.java \
 sun/jvm/hotspot/debugger/remote/amd64/*.java \
+sun/jvm/hotspot/debugger/remote/ppc64/*.java \
 sun/jvm/hotspot/debugger/remote/sparc/*.java \
 sun/jvm/hotspot/debugger/remote/x86/*.java \
 sun/jvm/hotspot/debugger/sparc/*.java \
@@ -174,9 +184,11 @@
 sun/jvm/hotspot/runtime/bsd_x86/*.java \
 sun/jvm/hotspot/runtime/linux/*.java \
 sun/jvm/hotspot/runtime/linux_amd64/*.java \
+sun/jvm/hotspot/runtime/linux_ppc64/*.java \
 sun/jvm/hotspot/runtime/linux_sparc/*.java \
 sun/jvm/hotspot/runtime/linux_x86/*.java \
 sun/jvm/hotspot/runtime/posix/*.java \
+sun/jvm/hotspot/runtime/ppc64/*.java \
 sun/jvm/hotspot/runtime/solaris_amd64/*.java \
 sun/jvm/hotspot/runtime/solaris_sparc/*.java \
 sun/jvm/hotspot/runtime/solaris_x86/*.java \
--- a/agent/src/os/linux/LinuxDebuggerLocal.c	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/os/linux/LinuxDebuggerLocal.c	Tue Feb 03 09:56:21 2015 +0000
@@ -49,6 +49,10 @@
 #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
 #endif
 
+#ifdef ppc64
+#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
+#endif
+
 static jfieldID p_ps_prochandle_ID = 0;
 static jfieldID threadList_ID = 0;
 static jfieldID loadObjectList_ID = 0;
@@ -341,7 +345,7 @@
   return (err == PS_OK)? array : 0;
 }
 
-#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9)
+#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64)
 JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
   (JNIEnv *env, jobject this_obj, jint lwp_id) {
 
@@ -366,6 +370,10 @@
 #if defined(sparc) || defined(sparcv9)
 #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
 #endif
+#ifdef ppc64
+#define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG
+#endif
+
 
   array = (*env)->NewLongArray(env, NPRGREG);
   CHECK_EXCEPTION_(0);
@@ -458,6 +466,45 @@
   regs[REG_INDEX(R_O7)]  = gregs.u_regs[14];
 #endif /* sparc */
 
+#ifdef ppc64
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg
+
+  regs[REG_INDEX(LR)] = gregs.link;
+  regs[REG_INDEX(NIP)] = gregs.nip;
+  regs[REG_INDEX(R0)]  = gregs.gpr[0];
+  regs[REG_INDEX(R1)]  = gregs.gpr[1];
+  regs[REG_INDEX(R2)]  = gregs.gpr[2];
+  regs[REG_INDEX(R3)]  = gregs.gpr[3];
+  regs[REG_INDEX(R4)]  = gregs.gpr[4];
+  regs[REG_INDEX(R5)]  = gregs.gpr[5];
+  regs[REG_INDEX(R6)]  = gregs.gpr[6];
+  regs[REG_INDEX(R7)]  = gregs.gpr[7];
+  regs[REG_INDEX(R8)]  = gregs.gpr[8];
+  regs[REG_INDEX(R9)]  = gregs.gpr[9];
+  regs[REG_INDEX(R10)] = gregs.gpr[10];
+  regs[REG_INDEX(R11)] = gregs.gpr[11];
+  regs[REG_INDEX(R12)] = gregs.gpr[12];
+  regs[REG_INDEX(R13)] = gregs.gpr[13];
+  regs[REG_INDEX(R14)] = gregs.gpr[14];
+  regs[REG_INDEX(R15)] = gregs.gpr[15];
+  regs[REG_INDEX(R16)] = gregs.gpr[16];
+  regs[REG_INDEX(R17)] = gregs.gpr[17];
+  regs[REG_INDEX(R18)] = gregs.gpr[18];
+  regs[REG_INDEX(R19)] = gregs.gpr[19];
+  regs[REG_INDEX(R20)] = gregs.gpr[20];
+  regs[REG_INDEX(R21)] = gregs.gpr[21];
+  regs[REG_INDEX(R22)] = gregs.gpr[22];
+  regs[REG_INDEX(R23)] = gregs.gpr[23];
+  regs[REG_INDEX(R24)] = gregs.gpr[24];
+  regs[REG_INDEX(R25)] = gregs.gpr[25];
+  regs[REG_INDEX(R26)] = gregs.gpr[26];
+  regs[REG_INDEX(R27)] = gregs.gpr[27];
+  regs[REG_INDEX(R28)] = gregs.gpr[28];
+  regs[REG_INDEX(R29)] = gregs.gpr[29];
+  regs[REG_INDEX(R30)] = gregs.gpr[30];
+  regs[REG_INDEX(R31)] = gregs.gpr[31];
+
+#endif
 
   (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
   return array;
--- a/agent/src/os/linux/ps_proc.c	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/os/linux/ps_proc.c	Tue Feb 03 09:56:21 2015 +0000
@@ -27,9 +27,11 @@
 #include <string.h>
 #include <signal.h>
 #include <errno.h>
+#include <elf.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/ptrace.h>
+#include <sys/uio.h>
 #include "libproc_impl.h"
 
 #if defined(x86_64) && !defined(amd64)
@@ -138,6 +140,15 @@
    return false;
  }
  return true;
+#elif defined(PTRACE_GETREGSET)
+ struct iovec iov;
+ iov.iov_base = user;
+ iov.iov_len = sizeof(*user);
+ if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void*) &iov) < 0) {
+   print_debug("ptrace(PTRACE_GETREGSET, ...) failed for lwp %d\n", pid);
+   return false;
+ }
+ return true;
 #else
  print_debug("ptrace(PTRACE_GETREGS, ...) not supported\n");
  return false;
--- a/agent/src/os/linux/symtab.c	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/os/linux/symtab.c	Tue Feb 03 09:56:21 2015 +0000
@@ -325,6 +325,12 @@
 
   // Reading of elf header
   struct elf_section *scn_cache = NULL;
+#if defined(ppc64) && !defined(ABI_ELFv2)
+  // Only big endian ppc64 (i.e. ABI_ELFv1) has 'official procedure descriptors' in ELF files
+  // see: http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html
+  struct elf_section *opd_sect = NULL;
+  ELF_SHDR *opd = NULL;
+#endif
   int cnt = 0;
   ELF_SHDR* shbuf = NULL;
   ELF_SHDR* cursct = NULL;
@@ -368,6 +374,14 @@
     cursct++;
   }
 
+#if defined(ppc64) && !defined(ABI_ELFv2)
+  opd_sect = find_section_by_name(".opd", fd, &ehdr, scn_cache);
+  if (opd_sect != NULL && opd_sect->c_data != NULL && opd_sect->c_shdr != NULL) {
+    // plausibility check
+    opd = opd_sect->c_shdr;
+  }
+#endif
+
   for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
     ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
 
@@ -412,6 +426,7 @@
       // copy symbols info our symtab and enter them info the hash table
       for (j = 0; j < n; j++, syms++) {
         ENTRY item, *ret;
+        uintptr_t sym_value;
         char *sym_name = symtab->strs + syms->st_name;
 
         // skip non-object and non-function symbols
@@ -422,9 +437,19 @@
         if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
 
         symtab->symbols[j].name   = sym_name;
-        symtab->symbols[j].offset = syms->st_value - baseaddr;
         symtab->symbols[j].size   = syms->st_size;
+        sym_value = syms->st_value;
 
+#if defined(ppc64) && !defined(ABI_ELFv2)
+        // see hotspot/src/share/vm/utilities/elfFuncDescTable.hpp for a detailed description
+        // of why we have to go this extra way via the '.opd' section on big endian ppc64
+        if (opd != NULL && *sym_name != '.' &&
+            (opd->sh_addr <= sym_value && sym_value <= opd->sh_addr + opd->sh_size)) {
+          sym_value = ((ELF_ADDR*)opd_sect->c_data)[(sym_value - opd->sh_addr) / sizeof(ELF_ADDR*)];
+        }
+#endif
+
+        symtab->symbols[j].offset = sym_value - baseaddr;
         item.key = sym_name;
         item.data = (void *)&(symtab->symbols[j]);
 
@@ -433,9 +458,17 @@
     }
   }
 
+#if defined(ppc64) && !defined(ABI_ELFv2)
+  // On Linux/PPC64 the debuginfo files contain an empty function descriptor
+  // section (i.e. '.opd' section) which makes the resolution of symbols
+  // with the above algorithm impossible (we would need the have both, the
+  // .opd section from the library and the symbol table from the debuginfo
+  // file which doesn't match with the current workflow.)
+  goto quit;
+#endif
+
   // Look for a separate debuginfo file.
   if (try_debuginfo) {
-
     // We prefer a debug symtab to an object's own symtab, so look in
     // the debuginfo file.  We stash a copy of the old symtab in case
     // there is no debuginfo.
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java	Tue Feb 03 09:56:21 2015 +0000
@@ -34,6 +34,6 @@
   }
 
   public boolean isBigEndian() {
-    return true;
+    return "big".equals(System.getProperty("sun.cpu.endian"));
   }
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java	Tue Feb 03 09:56:21 2015 +0000
@@ -26,14 +26,17 @@
 
 import java.io.*;
 import java.util.*;
+
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.debugger.cdbg.*;
 import sun.jvm.hotspot.debugger.x86.*;
 import sun.jvm.hotspot.debugger.amd64.*;
 import sun.jvm.hotspot.debugger.sparc.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
 import sun.jvm.hotspot.debugger.linux.x86.*;
 import sun.jvm.hotspot.debugger.linux.amd64.*;
 import sun.jvm.hotspot.debugger.linux.sparc.*;
+import sun.jvm.hotspot.debugger.linux.ppc64.*;
 import sun.jvm.hotspot.utilities.*;
 
 class LinuxCDebugger implements CDebugger {
@@ -96,7 +99,14 @@
        Address pc  = context.getRegisterAsAddress(SPARCThreadContext.R_O7);
        if (pc == null) return null;
        return new LinuxSPARCCFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
-    } else {
+    }  else if (cpu.equals("ppc64")) {
+        PPC64ThreadContext context = (PPC64ThreadContext) thread.getContext();
+        Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP);
+        if (sp == null) return null;
+        Address pc  = context.getRegisterAsAddress(PPC64ThreadContext.PC);
+        if (pc == null) return null;
+        return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
+     } else {
        // Runtime exception thrown by LinuxThreadContextFactory if unknown cpu
        ThreadContext context = (ThreadContext) thread.getContext();
        return context.getTopFrame(dbg);
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java	Tue Feb 03 09:56:21 2015 +0000
@@ -29,6 +29,7 @@
 import sun.jvm.hotspot.debugger.linux.amd64.*;
 import sun.jvm.hotspot.debugger.linux.ia64.*;
 import sun.jvm.hotspot.debugger.linux.x86.*;
+import sun.jvm.hotspot.debugger.linux.ppc64.*;
 import sun.jvm.hotspot.debugger.linux.sparc.*;
 
 class LinuxThreadContextFactory {
@@ -42,6 +43,8 @@
          return new LinuxIA64ThreadContext(dbg);
       } else if (cpu.equals("sparc")) {
          return new LinuxSPARCThreadContext(dbg);
+      }  else if (cpu.equals("ppc64")) {
+          return new LinuxPPC64ThreadContext(dbg);
       } else  {
         try {
           Class tcc = Class.forName("sun.jvm.hotspot.debugger.linux." +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.linux.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.debugger.linux.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
+import sun.jvm.hotspot.debugger.cdbg.basic.*;
+
+final public class LinuxPPC64CFrame extends BasicCFrame {
+  // package/class internals only
+
+  public LinuxPPC64CFrame(LinuxDebugger dbg, Address sp, Address pc, int address_size) {
+    super(dbg.getCDebugger());
+    this.sp = sp;
+    this.pc = pc;
+    this.dbg = dbg;
+    this.address_size = address_size;
+  }
+
+  // override base class impl to avoid ELF parsing
+  public ClosestSymbol closestSymbolToPC() {
+    // try native lookup in debugger.
+    return dbg.lookup(dbg.getAddressValue(pc()));
+  }
+
+  public Address pc() {
+    return pc;
+  }
+
+  public Address localVariableBase() {
+    return sp;
+  }
+
+  public CFrame sender(ThreadProxy thread) {
+    if (sp == null) {
+      return null;
+    }
+
+    Address nextSP = sp.getAddressAt(0);
+    if (nextSP == null) {
+      return null;
+    }
+    Address nextPC  = sp.getAddressAt(2 * address_size);
+    if (nextPC == null) {
+      return null;
+    }
+    return new LinuxPPC64CFrame(dbg, nextSP, nextPC, address_size);
+  }
+
+  public static int PPC64_STACK_BIAS = 0;
+  private static int address_size;
+  private Address pc;
+  private Address sp;
+  private LinuxDebugger dbg;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.linux.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.debugger.linux.*;
+
+public class LinuxPPC64ThreadContext extends PPC64ThreadContext {
+  private LinuxDebugger debugger;
+
+  public LinuxPPC64ThreadContext(LinuxDebugger debugger) {
+    super();
+    this.debugger = debugger;
+  }
+
+  public void setRegisterAsAddress(int index, Address value) {
+    setRegister(index, debugger.getAddressValue(value));
+  }
+
+  public Address getRegisterAsAddress(int index) {
+    return debugger.newAddress(getRegister(index));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
+
+/** Specifies the thread context on ppc64 platforms; only a sub-portion
+ * of the context is guaranteed to be present on all operating
+ * systems. */
+
+public abstract class PPC64ThreadContext implements ThreadContext {
+
+  // NOTE: The indices for the various registers must be maintained as
+  // listed across various operating systems. However, only a small
+  // subset of the registers' values are guaranteed to be present (and
+  // must be present for the SA's stack walking to work).
+
+  public static final int R31 = 0;
+  public static final int R30 = 1;
+  public static final int R29 = 2;
+  public static final int R28 = 3;
+  public static final int R27 = 4;
+  public static final int R26 = 5;
+  public static final int R25 = 6;
+  public static final int R24 = 7;
+  public static final int R23 = 8;
+  public static final int R22 = 9;
+  public static final int R21 = 10;
+  public static final int R20 = 11;
+  public static final int R19 = 12;
+  public static final int R18 = 13;
+  public static final int R17 = 14;
+  public static final int R16 = 15;
+  public static final int R15 = 16;
+  public static final int R14 = 17;
+  public static final int R13 = 18;
+  public static final int R12 = 19;
+  public static final int R11 = 20;
+  public static final int R10 = 21;
+  public static final int R9 = 22;
+  public static final int R8 = 23;
+  public static final int R7 = 24;
+  public static final int R6 = 25;
+  public static final int R5 = 26;
+  public static final int R4 = 27;
+  public static final int R3 = 28;
+  public static final int R2 = 29;
+  public static final int R1 = 30;
+  public static final int R0 = 31;
+  public static final int NIP = 32;
+  public static final int LR = 33;
+
+  public static final int NPRGREG = 34;
+
+  private static final String[] regNames = {
+    "r31", "r30", "r29", "r28", "r27", "r26", "r25", "r24",
+    "r23", "r22", "r21", "r20", "r19", "r18", "r17", "r16",
+    "r15", "r14", "r13", "r12", "r11", "r10", "r9",  "r8",
+    "r7",  "r6",  "r5",  "r4",  "r3",   "r2", "r1",  "r0",
+    "nip", "link"
+  };
+
+  public static final int PC = NIP;
+  public static final int SP = R1;
+
+  private long[] data;
+
+  public PPC64ThreadContext() {
+    data = new long[NPRGREG];
+  }
+
+  public int getNumRegisters() {
+    return NPRGREG;
+  }
+
+  public String getRegisterName(int index) {
+    return regNames[index];
+  }
+
+  public void setRegister(int index, long value) {
+    data[index] = value;
+  }
+
+  public long getRegister(int index) {
+    return data[index];
+  }
+
+  public CFrame getTopFrame(Debugger dbg) {
+    return null;
+  }
+
+  /** This can't be implemented in this class since we would have to
+   * tie the implementation to, for example, the debugging system */
+  public abstract void setRegisterAsAddress(int index, Address value);
+
+  /** This can't be implemented in this class since we would have to
+   * tie the implementation to, for example, the debugging system */
+  public abstract Address getRegisterAsAddress(int index);
+
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,9 @@
 import sun.jvm.hotspot.debugger.cdbg.*;
 import sun.jvm.hotspot.debugger.proc.amd64.*;
 import sun.jvm.hotspot.debugger.proc.sparc.*;
+import sun.jvm.hotspot.debugger.proc.ppc64.*;
 import sun.jvm.hotspot.debugger.proc.x86.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
 import sun.jvm.hotspot.debugger.amd64.*;
 import sun.jvm.hotspot.debugger.sparc.*;
 import sun.jvm.hotspot.debugger.x86.*;
@@ -86,6 +88,10 @@
             threadFactory = new ProcAMD64ThreadFactory(this);
             pcRegIndex = AMD64ThreadContext.RIP;
             fpRegIndex = AMD64ThreadContext.RBP;
+        } else if (cpu.equals("ppc64")) {
+            threadFactory = new ProcPPC64ThreadFactory(this);
+            pcRegIndex = PPC64ThreadContext.PC;
+            fpRegIndex = PPC64ThreadContext.SP;
         } else {
           try {
             Class tfc = Class.forName("sun.jvm.hotspot.debugger.proc." +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.proc.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.debugger.proc.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class ProcPPC64Thread implements ThreadProxy {
+  private ProcDebugger debugger;
+  private int id;
+
+  public ProcPPC64Thread(ProcDebugger debugger, Address addr) {
+    this.debugger = debugger;
+
+    // FIXME: the size here should be configurable. However, making it
+    // so would produce a dependency on the "types" package from the
+    // debugger package, which is not desired.
+    this.id = (int) addr.getCIntegerAt(0, 4, true);
+  }
+
+  public ProcPPC64Thread(ProcDebugger debugger, long id) {
+    this.debugger = debugger;
+    this.id = (int) id;
+  }
+
+  public ThreadContext getContext() throws IllegalThreadStateException {
+    ProcPPC64ThreadContext context = new ProcPPC64ThreadContext(debugger);
+    long[] regs = debugger.getThreadIntegerRegisterSet(id);
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(regs.length <= PPC64ThreadContext.NPRGREG, "size of register set is greater than " + PPC64ThreadContext.NPRGREG);
+    }
+    for (int i = 0; i < regs.length; i++) {
+      context.setRegister(i, regs[i]);
+    }
+    return context;
+  }
+
+  public boolean canSetContext() throws DebuggerException {
+    return false;
+  }
+
+  public void setContext(ThreadContext context)
+    throws IllegalThreadStateException, DebuggerException {
+    throw new DebuggerException("Unimplemented");
+  }
+
+  public String toString() {
+    return "t@" + id;
+  }
+
+  public boolean equals(Object obj) {
+    if ((obj == null) || !(obj instanceof ProcPPC64Thread)) {
+      return false;
+    }
+
+    return (((ProcPPC64Thread) obj).id == id);
+  }
+
+  public int hashCode() {
+    return id;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.proc.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.debugger.proc.*;
+
+public class ProcPPC64ThreadContext extends PPC64ThreadContext {
+  private ProcDebugger debugger;
+
+  public ProcPPC64ThreadContext(ProcDebugger debugger) {
+    super();
+    this.debugger = debugger;
+  }
+
+  public void setRegisterAsAddress(int index, Address value) {
+    setRegister(index, debugger.getAddressValue(value));
+  }
+
+  public Address getRegisterAsAddress(int index) {
+    return debugger.newAddress(getRegister(index));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.proc.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.proc.*;
+
+public class ProcPPC64ThreadFactory implements ProcThreadFactory {
+  private ProcDebugger debugger;
+
+  public ProcPPC64ThreadFactory(ProcDebugger debugger) {
+    this.debugger = debugger;
+  }
+
+  public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
+    return new ProcPPC64Thread(debugger, threadIdentifierAddr);
+  }
+
+  public ThreadProxy createThreadWrapper(long id) {
+    return new ProcPPC64Thread(debugger, id);
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java	Tue Feb 03 09:56:21 2015 +0000
@@ -33,6 +33,7 @@
 import sun.jvm.hotspot.debugger.remote.sparc.*;
 import sun.jvm.hotspot.debugger.remote.x86.*;
 import sun.jvm.hotspot.debugger.remote.amd64.*;
+import sun.jvm.hotspot.debugger.remote.ppc64.*;
 
 /** An implementation of Debugger which wraps a
     RemoteDebugger, providing remote debugging via RMI.
@@ -70,6 +71,11 @@
         cachePageSize = 4096;
         cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize);
         unalignedAccessesOkay = true;
+      } else if (cpu.equals("ppc64")) {
+        threadFactory = new RemotePPC64ThreadFactory(this);
+        cachePageSize = 4096;
+        cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize);
+        unalignedAccessesOkay = true;
       } else {
         try {
           Class tf = Class.forName("sun.jvm.hotspot.debugger.remote." +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.remote.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.debugger.remote.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class RemotePPC64Thread extends RemoteThread  {
+  public RemotePPC64Thread(RemoteDebuggerClient debugger, Address addr) {
+    super(debugger, addr);
+  }
+
+  public RemotePPC64Thread(RemoteDebuggerClient debugger, long id) {
+    super(debugger, id);
+  }
+
+  public ThreadContext getContext() throws IllegalThreadStateException {
+    RemotePPC64ThreadContext context = new RemotePPC64ThreadContext(debugger);
+    long[] regs = (addr != null)? debugger.getThreadIntegerRegisterSet(addr) :
+                                  debugger.getThreadIntegerRegisterSet(id);
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(regs.length == PPC64ThreadContext.NPRGREG, "size of register set must match");
+    }
+    for (int i = 0; i < regs.length; i++) {
+      context.setRegister(i, regs[i]);
+    }
+    return context;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.remote.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.debugger.remote.*;
+
+public class RemotePPC64ThreadContext extends PPC64ThreadContext {
+  private RemoteDebuggerClient debugger;
+
+  public RemotePPC64ThreadContext(RemoteDebuggerClient debugger) {
+    super();
+    this.debugger = debugger;
+  }
+
+  /** This can't be implemented in this class since we would have to
+      tie the implementation to, for example, the debugging system */
+  public void setRegisterAsAddress(int index, Address value) {
+    setRegister(index, debugger.getAddressValue(value));
+  }
+
+  /** This can't be implemented in this class since we would have to
+      tie the implementation to, for example, the debugging system */
+  public Address getRegisterAsAddress(int index) {
+    return debugger.newAddress(getRegister(index));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.debugger.remote.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.remote.*;
+
+public class RemotePPC64ThreadFactory implements RemoteThreadFactory {
+  private RemoteDebuggerClient debugger;
+
+  public RemotePPC64ThreadFactory(RemoteDebuggerClient debugger) {
+    this.debugger = debugger;
+  }
+
+  public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
+    return new RemotePPC64Thread(debugger, threadIdentifierAddr);
+  }
+
+  public ThreadProxy createThreadWrapper(long id) {
+    return new RemotePPC64Thread(debugger, id);
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java	Tue Feb 03 09:56:21 2015 +0000
@@ -25,6 +25,7 @@
 package sun.jvm.hotspot.runtime;
 
 import java.util.*;
+
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.runtime.solaris_sparc.SolarisSPARCJavaThreadPDAccess;
@@ -34,6 +35,7 @@
 import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess;
 import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess;
 import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess;
+import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess;
 import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess;
 import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess;
 import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess;
@@ -87,6 +89,8 @@
                 access = new LinuxAMD64JavaThreadPDAccess();
             } else if (cpu.equals("sparc")) {
                 access = new LinuxSPARCJavaThreadPDAccess();
+            } else if (cpu.equals("ppc64")) {
+                access = new LinuxPPC64JavaThreadPDAccess();
             } else {
               try {
                 access = (JavaThreadPDAccess)
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Tue Feb 03 10:30:16 2015 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Tue Feb 03 09:56:21 2015 +0000
@@ -78,7 +78,7 @@
         }
 
         if (f.isRuntimeFrame()) {
-          // This is a conversion frame. Skip this frame and try again.
+          // This is a conversion frame or a Stub routine. Skip this frame and try again.
           RegisterMap tempMap = regMap.copy();
           Frame s = f.sender(tempMap);
           return newVFrame(s, tempMap, thread, unsafe, false);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime.linux_ppc64;
+
+import java.io.*;
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.runtime.ppc64.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class LinuxPPC64JavaThreadPDAccess implements JavaThreadPDAccess {
+  private static AddressField  osThreadField;
+
+  // Field from OSThread
+  private static CIntegerField osThreadThreadIDField;
+
+  // This is currently unneeded but is being kept in case we change
+  // the currentFrameGuess algorithm
+  private static final long GUESS_SCAN_RANGE = 128 * 1024;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) {
+    Type type = db.lookupType("JavaThread");
+    osThreadField = type.getAddressField("_osthread");
+
+    Type osThreadType = db.lookupType("OSThread");
+    osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id");
+  }
+
+  public Address getLastJavaFP(Address addr) {
+    return null;
+  }
+
+  public Address getLastJavaPC(Address addr) {
+    return null;
+  }
+
+  public Address getBaseOfStackPointer(Address addr) {
+    return null;
+  }
+
+  public Frame getLastFramePD(JavaThread thread, Address addr) {
+    Address fp = thread.getLastJavaFP();
+    if (fp == null) {
+      return null; // no information
+    }
+    return new PPC64Frame(thread.getLastJavaSP(), fp);
+  }
+
+  public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
+    return new PPC64RegisterMap(thread, updateMap);
+  }
+
+  public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
+    ThreadProxy t = getThreadProxy(addr);
+    PPC64ThreadContext context = (PPC64ThreadContext) t.getContext();
+    PPC64CurrentFrameGuess guesser = new PPC64CurrentFrameGuess(context, thread);
+    if (!guesser.run(GUESS_SCAN_RANGE)) {
+      return null;
+    }
+    if (guesser.getPC() == null) {
+      return new PPC64Frame(guesser.getSP(), guesser.getFP());
+    } else {
+      return new PPC64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
+    }
+  }
+
+  public void printThreadIDOn(Address addr, PrintStream tty) {
+    tty.print(getThreadProxy(addr));
+  }
+
+  public void printInfoOn(Address threadAddr, PrintStream tty) {
+    tty.print("Thread id: ");
+    printThreadIDOn(threadAddr, tty);
+    // tty.println("\nPostJavaState: " + getPostJavaState(threadAddr));
+  }
+
+  public Address getLastSP(Address addr) {
+    ThreadProxy t = getThreadProxy(addr);
+    PPC64ThreadContext context = (PPC64ThreadContext) t.getContext();
+    return context.getRegisterAsAddress(PPC64ThreadContext.SP);
+  }
+
+  public Address getLastFP(Address addr) {
+    return getLastSP(addr).getAddressAt(0);
+  }
+
+  public ThreadProxy getThreadProxy(Address addr) {
+    // Addr is the address of the JavaThread.
+    // Fetch the OSThread (for now and for simplicity, not making a
+    // separate "OSThread" class in this package)
+    Address osThreadAddr = osThreadField.getValue(addr);
+    // Get the address of the _thread_id from the OSThread
+    Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
+
+    JVMDebugger debugger = VM.getVM().getDebugger();
+    return debugger.getThreadForIdentifierAddress(threadIdAddr);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.ppc64.*;
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.interpreter.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.runtime.ppc64.*;
+
+/** <P> Should be able to be used on all ppc64 platforms we support
+    (Linux/ppc64) to implement JavaThread's "currentFrameGuess()"
+    functionality. Input is a PPC64ThreadContext; output is SP, FP,
+    and PC for an PPC64Frame. Instantiation of the PPC64Frame is left
+    to the caller, since we may need to subclass PPC64Frame to support
+    signal handler frames on Unix platforms. </P>
+ */
+
+public class PPC64CurrentFrameGuess {
+  private PPC64ThreadContext context;
+  private JavaThread       thread;
+  private Address          spFound;
+  private Address          fpFound;
+  private Address          pcFound;
+
+  private static final boolean DEBUG;
+  static {
+    DEBUG = System.getProperty("sun.jvm.hotspot.runtime.ppc64.PPC64Frame.DEBUG") != null;
+  }
+
+  public PPC64CurrentFrameGuess(PPC64ThreadContext context,
+                              JavaThread thread) {
+    this.context = context;
+    this.thread  = thread;
+  }
+
+  /** Returns false if not able to find a frame within a reasonable range. */
+  public boolean run(long regionInBytesToSearch) {
+    Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP);
+    Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC);
+    if (sp == null) {
+      // Bail out if no last java frame either
+      if (thread.getLastJavaSP() != null) {
+        Address javaSP = thread.getLastJavaSP();
+        Address javaFP = javaSP.getAddressAt(0);
+        setValues(javaSP, javaFP, null);
+        return true;
+      }
+      return false;
+    }
+    /* There is no frame pointer per se for the ppc64 architecture.  To mirror
+     * the behavior of the VM frame manager, we set fp to be the caller's (i.e., "sender's")
+     * stack pointer, which is the back chain value contained in our sp.
+     */
+    Address fp = sp.getAddressAt(0);
+    setValues(null, null, null); // Assume we're not going to find anything
+
+    VM vm = VM.getVM();
+    if (vm.isJavaPCDbg(pc)) {
+      if (vm.isClientCompiler()) {
+        // Topmost frame is a Java frame.
+        if (DEBUG) {
+          System.out.println("CurrentFrameGuess: choosing compiler frame: sp = " +
+                             sp + ", fp = " + fp + ", pc = " + pc);
+        }
+        setValues(sp, fp, pc);
+        return true;
+      } else {
+        if (vm.getInterpreter().contains(pc)) {
+          if (DEBUG) {
+            System.out.println("CurrentFrameGuess: choosing interpreter frame: sp = " +
+                               sp + ", fp = " + fp + ", pc = " + pc);
+          }
+          setValues(sp, fp, pc);
+          return true;
+        }
+
+        // This algorithm takes the current PC as a given and tries to
+        // find the correct corresponding SP by walking up the stack
+        // and repeatedly performing stackwalks (very inefficient).
+        for (long offset = 0;
+             offset < regionInBytesToSearch;
+             offset += vm.getAddressSize()) {
+          try {
+            Address curSP = sp.addOffsetTo(offset);
+            fp = curSP.getAddressAt(0);
+            Frame frame = new PPC64Frame(curSP, fp, pc);
+            RegisterMap map = thread.newRegisterMap(false);
+            while (frame != null) {
+              if (frame.isEntryFrame() && frame.entryFrameIsFirst()) {
+                // We were able to traverse all the way to the
+                // bottommost Java frame.
+                // This sp looks good. Keep it.
+                if (DEBUG) {
+                  System.out.println("CurrentFrameGuess: Choosing sp = " + curSP + ", pc = " + pc);
+                }
+                setValues(curSP, fp, pc);
+                return true;
+              }
+              frame = frame.sender(map);
+            }
+          } catch (Exception e) {
+            if (DEBUG) {
+              System.out.println("CurrentFrameGuess: Exception " + e + " at offset " + offset);
+            }
+            // Bad SP. Try another.
+          }
+        }
+
+        // Were not able to find a plausible SP to go with this PC.
+        // Bail out.
+        return false;
+
+      }
+    } else {
+      // If the current program counter was not known to us as a Java
+      // PC, we currently assume that we are in the run-time system
+      // and attempt to look to thread-local storage for saved java SP.
+      // Note that if this is null (because we were, in fact,
+      // in Java code, i.e., vtable stubs or similar, and the SA
+      // didn't have enough insight into the target VM to understand
+      // that) then we are going to lose the entire stack trace for
+      // the thread, which is sub-optimal. FIXME.
+
+      if (thread.getLastJavaSP() == null) {
+        if (DEBUG) {
+          System.out.println("CurrentFrameGuess: last java sp is null");
+        }
+        return false; // No known Java frames on stack
+      }
+
+      Address javaSP = thread.getLastJavaSP();
+      Address javaFP = javaSP.getAddressAt(0);
+      Address javaPC = thread.getLastJavaPC();
+      if (DEBUG) {
+        System.out.println("CurrentFrameGuess: choosing last Java frame: sp = " +
+                           javaSP + ", fp = " + javaFP + ", pc = " + javaPC);
+      }
+      setValues(javaSP, javaFP, javaPC);
+      return true;
+    }
+  }
+
+  public Address getSP() { return spFound; }
+  public Address getFP() { return fpFound; }
+  /** May be null if getting values from thread-local storage; take
+      care to call the correct PPC64Frame constructor to recover this if
+      necessary */
+  public Address getPC() { return pcFound; }
+
+  private void setValues(Address sp, Address fp, Address pc) {
+    spFound = sp;
+    fpFound = fp;
+    pcFound = pc;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime.ppc64;
+
+import java.util.*;
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.compiler.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+/** Specialization of and implementation of abstract methods of the
+    Frame class for the ppc64 family of CPUs. */
+
+public class PPC64Frame extends Frame {
+  private static final boolean DEBUG;
+  static {
+    DEBUG = System.getProperty("sun.jvm.hotspot.runtime.ppc64.PPC64Frame.DEBUG") != null;
+  }
+
+  // All frames
+  private static final int SENDER_SP_OFFSET           =  0;
+
+  // Interpreter frames
+  private static final int INTERPRETER_FRAME_MIRROR_OFFSET = -3; // for native calls only
+  private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -4;
+  private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET -1;
+  private static final int INTERPRETER_FRAME_ESP_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_ESP_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_CACHE_OFFSET =INTERPRETER_FRAME_BCX_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_MONITORS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_MONITORS_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; // FIXME: probably wrong, but unused anyway
+  private static final int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
+  private static final int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
+
+  // Entry frames
+  private static int ENTRY_FRAME_CALL_WRAPPER_OFFSET;
+
+  // Native frames
+  private static int NATIVE_FRAME_INITIAL_PARAM_OFFSET;
+
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+      public void update(Observable o, Object data) {
+        initialize(VM.getVM().getTypeDataBase());
+      }
+    });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) {
+    int abi_minframe_size = db.lookupIntConstant("frame::abi_minframe_size").intValue();
+    int entry_frame_locals_size = db.lookupIntConstant("frame::entry_frame_locals_size").intValue();
+    int wordLength = (int) VM.getVM().getAddressSize();
+    NATIVE_FRAME_INITIAL_PARAM_OFFSET = -abi_minframe_size/wordLength;
+    ENTRY_FRAME_CALL_WRAPPER_OFFSET = -entry_frame_locals_size/wordLength;
+  }
+
+
+  // an additional field beyond sp and pc:
+  Address raw_fp; // frame pointer
+  private Address raw_unextendedSP;
+
+  private PPC64Frame() {
+  }
+
+  private void adjustForDeopt() {
+    if ( pc != null) {
+      // Look for a deopt pc and if it is deopted convert to original pc
+      CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
+      if (cb != null && cb.isJavaMethod()) {
+        NMethod nm = (NMethod) cb;
+        if (pc.equals(nm.deoptHandlerBegin())) {
+          if (Assert.ASSERTS_ENABLED) {
+            Assert.that(this.getUnextendedSP() != null, "null SP in Java frame");
+          }
+          // adjust pc if frame is deoptimized.
+          pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
+          deoptimized = true;
+        }
+      }
+    }
+  }
+
+  public PPC64Frame(Address raw_sp, Address raw_fp, Address pc) {
+    this.raw_sp = raw_sp;
+    this.raw_unextendedSP = raw_sp;
+    if (raw_fp == null) {
+      this.raw_fp = raw_sp.getAddressAt(0);
+    } else {
+      this.raw_fp = raw_fp;
+    }
+    if (pc == null) {
+      this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize());
+    } else {
+      this.pc = pc;
+    }
+    adjustUnextendedSP();
+
+    // Frame must be fully constructed before this call
+    adjustForDeopt();
+
+    if (DEBUG) {
+      System.out.println("PPC64Frame(sp, fp, pc): " + this);
+      dumpStack();
+    }
+  }
+
+  public PPC64Frame(Address raw_sp, Address raw_fp) {
+    this.raw_sp = raw_sp;
+    this.raw_unextendedSP = raw_sp;
+    if (raw_fp == null) {
+      this.raw_fp = raw_sp.getAddressAt(0);
+    } else {
+      this.raw_fp = raw_fp;
+    }
+    this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize());
+    adjustUnextendedSP();
+
+    // Frame must be fully constructed before this call
+    adjustForDeopt();
+
+    if (DEBUG) {
+      System.out.println("PPC64Frame(sp, fp): " + this);
+      dumpStack();
+    }
+  }
+
+  public PPC64Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) {
+    this.raw_sp = raw_sp;
+    this.raw_unextendedSP = raw_unextendedSp;
+    if (raw_fp == null) {
+      this.raw_fp = raw_sp.getAddressAt(0);
+    } else {
+      this.raw_fp = raw_fp;
+    }
+    if (pc == null) {
+      this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize());
+    } else {
+      this.pc = pc;
+    }
+    adjustUnextendedSP();
+
+    // Frame must be fully constructed before this call
+    adjustForDeopt();
+
+    if (DEBUG) {
+      System.out.println("PPC64Frame(sp, unextendedSP, fp, pc): " + this);
+      dumpStack();
+    }
+
+  }
+
+  public Object clone() {
+    PPC64Frame frame = new PPC64Frame();
+    frame.raw_sp = raw_sp;
+    frame.raw_unextendedSP = raw_unextendedSP;
+    frame.raw_fp = raw_fp;
+    frame.pc = pc;
+    frame.deoptimized = deoptimized;
+    return frame;
+  }
+
+  public boolean equals(Object arg) {
+    if (arg == null) {
+      return false;
+    }
+
+    if (!(arg instanceof PPC64Frame)) {
+      return false;
+    }
+
+    PPC64Frame other = (PPC64Frame) arg;
+
+    return (AddressOps.equal(getSP(), other.getSP()) &&
+        AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) &&
+        AddressOps.equal(getFP(), other.getFP()) &&
+        AddressOps.equal(getPC(), other.getPC()));
+  }
+
+  public int hashCode() {
+    if (raw_sp == null) {
+      return 0;
+    }
+
+    return raw_sp.hashCode();
+  }
+
+  public String toString() {
+    return "sp: " + (getSP() == null ? "null" : getSP().toString()) +
+        ", unextendedSP: " + (getUnextendedSP() == null ? "null" : getUnextendedSP().toString()) +
+        ", fp: " + (getFP() == null ? "null" : getFP().toString()) +
+        ", pc: " + (pc == null ? "null" : pc.toString());
+  }
+
+  // accessors for the instance variables
+  public Address getFP() { return raw_fp; }
+  public Address getSP() { return raw_sp; }
+  public Address getID() { return raw_sp; }
+
+  // FIXME: not implemented yet (should be done for Solaris/PPC64)
+  public boolean isSignalHandlerFrameDbg() { return false; }
+  public int     getSignalNumberDbg()      { return 0;     }
+  public String  getSignalNameDbg()        { return null;  }
+
+  public boolean isInterpretedFrameValid() {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(isInterpretedFrame(), "Not an interpreted frame");
+    }
+
+    // These are reasonable sanity checks
+    if (getFP() == null || getFP().andWithMask(0x3) != null) {
+      return false;
+    }
+
+    if (getSP() == null || getSP().andWithMask(0x3) != null) {
+      return false;
+    }
+
+    // These are hacks to keep us out of trouble.
+    // The problem with these is that they mask other problems
+    if (getFP().lessThanOrEqual(getSP())) {
+      // this attempts to deal with unsigned comparison above
+      return false;
+    }
+
+    if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) {
+      // stack frames shouldn't be large.
+      return false;
+    }
+
+    return true;
+  }
+
+  // FIXME: not applicable in current system
+  //  void    patch_pc(Thread* thread, address pc);
+
+  public Frame sender(RegisterMap regMap, CodeBlob cb) {
+    PPC64RegisterMap map = (PPC64RegisterMap) regMap;
+
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(map != null, "map must be set");
+    }
+
+    // Default is we done have to follow them. The sender_for_xxx will
+    // update it accordingly
+    map.setIncludeArgumentOops(false);
+
+    if (isEntryFrame()) return senderForEntryFrame(map);
+    if (isInterpretedFrame()) return senderForInterpreterFrame(map);
+
+    if(cb == null) {
+      cb = VM.getVM().getCodeCache().findBlob(getPC());
+    } else {
+      if (Assert.ASSERTS_ENABLED) {
+        Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
+      }
+    }
+
+    if (cb != null) {
+      return senderForCompiledFrame(map, cb);
+    }
+
+    // Must be native-compiled frame, i.e. the marshaling code for native
+    // methods that exists in the core system.
+    return new PPC64Frame(getSenderSP(), getLink(), getSenderPC());
+  }
+
+  private Frame senderForEntryFrame(PPC64RegisterMap map) {
+    if (DEBUG) {
+      System.out.println("senderForEntryFrame");
+    }
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(map != null, "map must be set");
+    }
+    // Java frame called from C; skip all C frames and return top C
+    // frame of that chunk as the sender
+    PPC64JavaCallWrapper jcw = (PPC64JavaCallWrapper) getEntryFrameCallWrapper();
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
+      Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
+    }
+    PPC64Frame fr;
+    if (jcw.getLastJavaPC() != null) {
+      fr = new PPC64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC());
+    } else {
+      fr = new PPC64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP());
+    }
+    map.clear();
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
+    }
+    return fr;
+  }
+
+  //------------------------------------------------------------------------------
+  // frame::adjust_unextended_sp
+  private void adjustUnextendedSP() {
+    raw_unextendedSP = getFP();
+  }
+  private Frame senderForInterpreterFrame(PPC64RegisterMap map) {
+    if (DEBUG) {
+      System.out.println("senderForInterpreterFrame");
+    }
+    Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
+    Address sp = getSenderSP();
+
+    return new PPC64Frame(sp, unextendedSP, getLink(), getSenderPC());
+  }
+
+
+  private Frame senderForCompiledFrame(PPC64RegisterMap map, CodeBlob cb) {
+    if (DEBUG) {
+      System.out.println("senderForCompiledFrame");
+    }
+
+    //
+    // NOTE: some of this code is (unfortunately) duplicated in PPC64CurrentFrameGuess
+    //
+
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(map != null, "map must be set");
+    }
+
+    // frame owned by optimizing compiler
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size");
+    }
+    Address senderSP = getSenderSP();
+
+    Address senderPC = getSenderPC();
+
+    if (map.getUpdateMap()) {
+      // Tell GC to use argument oopmaps for some runtime stubs that need it.
+      // For C1, the runtime stub might not have oop maps, so set this flag
+      // outside of update_register_map.
+      map.setIncludeArgumentOops(cb.callerMustGCArguments());
+
+      if (cb.getOopMaps() != null) {
+        OopMapSet.updateRegisterMap(this, cb, map, true);
+      }
+    }
+
+    return new PPC64Frame(senderSP, getLink(), senderPC);
+  }
+
+  protected boolean hasSenderPD() {
+    // FIXME
+    return true;
+  }
+
+  public long frameSize() {
+    return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
+  }
+
+  public Address getLink() {
+    return getSenderSP().getAddressAt(0);
+  }
+
+  public Address getUnextendedSP() { return raw_unextendedSP; }
+
+  // Return address:
+  public Address getSenderPC()     { return getSenderSP().getAddressAt(2 * VM.getVM().getAddressSize()); }
+
+  // return address of param, zero origin index.
+  // MPJ note:   Appears to be unused.
+  public Address getNativeParamAddr(int idx) {
+    return null;
+    // return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx);
+  }
+
+  public Address getSenderSP()     { return getFP(); }
+  public Address addressOfInterpreterFrameLocals() {
+    return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET);
+  }
+
+  private Address addressOfInterpreterFrameBCX() {
+    return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET);
+  }
+
+  public int getInterpreterFrameBCI() {
+    // FIXME: this is not atomic with respect to GC and is unsuitable
+    // for use in a non-debugging, or reflective, system. Need to
+    // figure out how to express this.
+    Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
+    Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0);
+    Method method = (Method)Metadata.instantiateWrapperFor(methodHandle);
+    return bcpToBci(bcp, method);
+  }
+
+  public Address addressOfInterpreterFrameMDX() {
+    return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET);
+  }
+
+  // FIXME
+  //inline int frame::interpreter_frame_monitor_size() {
+  //  return BasicObjectLock::size();
+  //}
+
+  // expression stack
+  // (the max_stack arguments are used by the GC; see class FrameClosure)
+
+  public Address addressOfInterpreterFrameExpressionStack() {
+    Address monitorEnd = interpreterFrameMonitorEnd().address();
+    return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize());
+  }
+
+  public int getInterpreterFrameExpressionStackDirection() { return -1; }
+
+  // top of expression stack
+  public Address addressOfInterpreterFrameTOS() {
+    return getSP();
+  }
+
+  /** Expression stack from top down */
+  public Address addressOfInterpreterFrameTOSAt(int slot) {
+    return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
+  }
+
+  public Address getInterpreterFrameSenderSP() {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(isInterpretedFrame(), "interpreted frame expected");
+    }
+    return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
+  }
+
+  // Monitors
+  public BasicObjectLock interpreterFrameMonitorBegin() {
+    return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET));
+  }
+
+  public BasicObjectLock interpreterFrameMonitorEnd() {
+    Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
+    if (Assert.ASSERTS_ENABLED) {
+      // make sure the pointer points inside the frame
+      Assert.that(AddressOps.gt(getFP(), result), "result must <  than frame pointer");
+      Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer");
+    }
+    return new BasicObjectLock(result);
+  }
+
+  public int interpreterFrameMonitorSize() {
+    return BasicObjectLock.size();
+  }
+
+  // Method
+  public Address addressOfInterpreterFrameMethod() {
+    return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET);
+  }
+
+  // Constant pool cache
+  public Address addressOfInterpreterFrameCPCache() {
+    return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET);
+  }
+
+  // Entry frames
+  public JavaCallWrapper getEntryFrameCallWrapper() {
+    return new PPC64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0));
+  }
+
+  protected Address addressOfSavedOopResult() {
+    // offset is 2 for compiler2 and 3 for compiler1
+    return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) *
+        VM.getVM().getAddressSize());
+  }
+
+  protected Address addressOfSavedReceiver() {
+    return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
+  }
+
+  private void dumpStack() {
+    if (getFP() != null) {
+      for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
+          AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize()));
+          addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
+        System.out.println(addr + ": " + addr.getAddressAt(0));
+      }
+    } else {
+      for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
+          AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize()));
+          addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
+        System.out.println(addr + ": " + addr.getAddressAt(0));
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime.ppc64;
+
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+
+public class PPC64JavaCallWrapper extends JavaCallWrapper {
+
+  public PPC64JavaCallWrapper(Address addr) {
+    super(addr);
+  }
+
+  public Address getLastJavaFP() {
+    return null;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 20014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime.ppc64;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+
+public class PPC64RegisterMap extends RegisterMap {
+
+  /** This is the only public constructor */
+  public PPC64RegisterMap(JavaThread thread, boolean updateMap) {
+    super(thread, updateMap);
+  }
+
+  protected PPC64RegisterMap(RegisterMap map) {
+    super(map);
+  }
+
+  public Object clone() {
+    PPC64RegisterMap retval = new PPC64RegisterMap(this);
+    return retval;
+  }
+
+  // no PD state to clear or copy:
+  protected void clearPD() {}
+  protected void initializePD() {}
+  protected void initializeFromPD(RegisterMap map) {}
+  protected Address getLocationPD(VMReg reg) { return null; }
+}
--- a/make/aix/Makefile	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/aix/Makefile	Tue Feb 03 09:56:21 2015 +0000
@@ -246,8 +246,7 @@
 XSLT_CHECK	= $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(REMOTE) $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/make/aix/makefiles/mapfile-vers-debug	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/aix/makefiles/mapfile-vers-debug	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -132,6 +132,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameters;
                 JVM_GetMethodTypeAnnotations;
+                JVM_GetNanoTimeAdjustment;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
--- a/make/aix/makefiles/mapfile-vers-product	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/aix/makefiles/mapfile-vers-product	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -130,6 +130,7 @@
                 JVM_GetMethodIxNameUTF;
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameters;
+                JVM_GetNanoTimeAdjustment;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
--- a/make/aix/makefiles/ppc64.make	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/aix/makefiles/ppc64.make	Tue Feb 03 09:56:21 2015 +0000
@@ -46,7 +46,9 @@
 #  - 1540-1090 (I) The destructor of "..." might not be called.
 #  - 1500-010: (W) WARNING in ...: Infinite loop.  Program may not stop.
 #    There are several infinite loops in the vm, suppress.
-CFLAGS += -qsuppress=1540-1090 -qsuppress=1500-010
+#  - 1540-1639 (I) The behavior of long type bit fields has changed ...
+#                  ... long type bit fields now default to long, not int.
+CFLAGS += -qsuppress=1540-1090 -qsuppress=1500-010 -qsuppress=1540-1639
 
 # Suppress 
 #  - 540-1088 (W) The exception specification is being ignored.
--- a/make/aix/makefiles/xlc.make	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/aix/makefiles/xlc.make	Tue Feb 03 09:56:21 2015 +0000
@@ -74,6 +74,12 @@
 # no xlc counterpart for -fcheck-new
 # CFLAGS += -fcheck-new
 
+# We need to define this on the command line if we want to use the the
+# predefined format specifiers from "inttypes.h". Otherwise system headrs
+# can indirectly include inttypes.h before we define __STDC_FORMAT_MACROS
+# in globalDefinitions.hpp
+CFLAGS += -D__STDC_FORMAT_MACROS
+
 ARCHFLAG = -q64
 
 CFLAGS     += $(ARCHFLAG)
@@ -124,7 +130,7 @@
 # MAPFLAG = -Xlinker --version-script=FILENAME
 
 # Build shared library
-SHARED_FLAG = -q64 -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath
+SHARED_FLAG = -q64 -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath -bernotok
 
 #------------------------------------------------------------------------
 # Debug flags
--- a/make/bsd/Makefile	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/bsd/Makefile	Tue Feb 03 09:56:21 2015 +0000
@@ -240,8 +240,7 @@
 XSLT_CHECK	= $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(REMOTE) $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/make/bsd/makefiles/dtrace.make	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/bsd/makefiles/dtrace.make	Tue Feb 03 09:56:21 2015 +0000
@@ -179,23 +179,23 @@
 # $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
 $(JVMOFFS).h: $(GENOFFS)
 	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -header > $@.tmp; touch $@; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; \
-	else rm -f $@.tmp; \
+	if diff $@.tmp $@ > /dev/null 2>&1 ; \
+	then rm -f $@.tmp; \
+	else rm -f $@; mv $@.tmp $@; \
 	fi
 
 $(JVMOFFS)Index.h: $(GENOFFS)
 	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -index > $@.tmp; touch $@; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; \
-	else rm -f $@.tmp; \
+	if diff $@.tmp $@ > /dev/null 2>&1 ; \
+	then rm -f $@.tmp; \
+	else rm -f $@; mv $@.tmp $@; \
 	fi
 
 $(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
 	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -table > $@.tmp; touch $@; \
-	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
-	then rm -f $@; mv $@.tmp $@; \
-	else rm -f $@.tmp; \
+	if diff $@.tmp $@ > /dev/null 2>&1; \
+	then rm -f $@.tmp; \
+	else rm -f $@; mv $@.tmp $@; \
 	fi
 
 $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp 
--- a/make/bsd/makefiles/mapfile-vers-darwin-debug	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/bsd/makefiles/mapfile-vers-darwin-debug	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -130,6 +130,7 @@
                 _JVM_GetMethodIxSignatureUTF
                 _JVM_GetMethodParameters
                 _JVM_GetMethodTypeAnnotations
+                _JVM_GetNanoTimeAdjustment
                 _JVM_GetPrimitiveArrayElement
                 _JVM_GetProtectionDomain
                 _JVM_GetStackAccessControlContext
--- a/make/bsd/makefiles/mapfile-vers-darwin-product	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/bsd/makefiles/mapfile-vers-darwin-product	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -130,6 +130,7 @@
                 _JVM_GetMethodIxSignatureUTF
                 _JVM_GetMethodParameters
                 _JVM_GetMethodTypeAnnotations
+                _JVM_GetNanoTimeAdjustment
                 _JVM_GetPrimitiveArrayElement
                 _JVM_GetProtectionDomain
                 _JVM_GetStackAccessControlContext
--- a/make/bsd/makefiles/mapfile-vers-debug	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/bsd/makefiles/mapfile-vers-debug	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -132,6 +132,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameters;
                 JVM_GetMethodTypeAnnotations;
+                JVM_GetNanoTimeAdjustment;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
--- a/make/bsd/makefiles/mapfile-vers-product	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/bsd/makefiles/mapfile-vers-product	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -132,6 +132,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameters;
                 JVM_GetMethodTypeAnnotations;
+                JVM_GetNanoTimeAdjustment;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
--- a/make/bsd/makefiles/universal.gmk	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/bsd/makefiles/universal.gmk	Tue Feb 03 09:56:21 2015 +0000
@@ -59,7 +59,7 @@
 
 # Package built libraries in a universal binary
 $(UNIVERSAL_LIPO_LIST):
-	BUILT_LIPO_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`"; \
+	BUILT_LIPO_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`" || test $$? = "1"; \
 	if [ -n "$${BUILT_LIPO_FILES}" ]; then \
 	  $(MKDIR) -p $(shell dirname $@); \
 	  lipo -create -output $@ $${BUILT_LIPO_FILES}; \
@@ -70,7 +70,7 @@
 # - copies directories; including empty dirs
 # - copies files, symlinks, other non-directory files
 $(UNIVERSAL_COPY_LIST):
-	BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) -prune 2>/dev/null`"; \
+	BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) -prune 2>/dev/null`" || test $$? = "1"; \
 	if [ -n "$${BUILT_COPY_FILES}" ]; then \
 	  for i in $${BUILT_COPY_FILES}; do \
 	    $(MKDIR) -p $(shell dirname $@); \
--- a/make/linux/Makefile	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/linux/Makefile	Tue Feb 03 09:56:21 2015 +0000
@@ -246,8 +246,7 @@
 XSLT_CHECK	= $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(REMOTE) $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/make/linux/makefiles/build_vm_def.sh	Tue Feb 03 10:30:16 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-# If we're cross compiling use that path for nm
-if [ "$CROSS_COMPILE_ARCH" != "" ]; then 
-NM=$ALT_COMPILER_PATH/nm
-else
-NM=nm
-fi
-
-$NM --defined-only $* \
-    | awk '{
-              if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";"
-              if ($3 ~ /^UseSharedSpaces$/) print "\t" $3 ";"
-              if ($3 ~ /^_ZN9Arguments17SharedArchivePathE$/) print "\t" $3 ";"
-          }' \
-    | sort -u
--- a/make/linux/makefiles/mapfile-vers-debug	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/linux/makefiles/mapfile-vers-debug	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -132,6 +132,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameters;
                 JVM_GetMethodTypeAnnotations;
+                JVM_GetNanoTimeAdjustment;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
--- a/make/linux/makefiles/mapfile-vers-product	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/linux/makefiles/mapfile-vers-product	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -132,6 +132,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameters;
                 JVM_GetMethodTypeAnnotations;
+                JVM_GetNanoTimeAdjustment;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
--- a/make/linux/makefiles/sa.make	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/linux/makefiles/sa.make	Tue Feb 03 09:56:21 2015 +0000
@@ -109,6 +109,7 @@
 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext
+	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.ppc64.PPC64ThreadContext
 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.asm.Disassembler
 
 clean:
--- a/make/linux/makefiles/vm.make	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/linux/makefiles/vm.make	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -239,8 +239,14 @@
 	rm -f $@
 	cat $^ > $@
 
+VMDEF_PAT  = ^_ZTV
+VMDEF_PAT := ^gHotSpotVM|$(VMDEF_PAT)
+VMDEF_PAT := ^UseSharedSpaces$$|$(VMDEF_PAT)
+VMDEF_PAT := ^_ZN9Arguments17SharedArchivePathE$$|$(VMDEF_PAT)
+
 vm.def: $(Res_Files) $(Obj_Files)
-	sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
+	$(QUIETLY) $(NM) --defined-only $(Obj_Files) | sort -k3 -u | \
+	awk '$$3 ~ /$(VMDEF_PAT)/ { print "\t" $$3 ";" }' > $@
 
 mapfile_ext:
 	rm -f $@
@@ -334,10 +340,8 @@
 	    rm -f $@.1; ln -s $@ $@.1;                                  \
             if [ \"$(CROSS_COMPILE_ARCH)\" = \"\" ] ; then                    \
 	      if [ -x /usr/sbin/selinuxenabled ] ; then                 \
-	        /usr/sbin/selinuxenabled;                               \
-                if [ $$? = 0 ] ; then					\
-		  /usr/bin/chcon -t textrel_shlib_t $@;                 \
-		  if [ $$? != 0 ]; then                                 \
+                if /usr/sbin/selinuxenabled; then			\
+		  if ! /usr/bin/chcon -t textrel_shlib_t $@; then       \
 		    echo "ERROR: Cannot chcon $@";			\
 		  fi							\
 	        fi							\
--- a/make/sa.files	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/sa.files	Tue Feb 03 09:56:21 2015 +0000
@@ -39,6 +39,7 @@
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/ci/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/classfile/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \
@@ -49,24 +50,31 @@
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ia64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ia64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/elf/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/coff/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/ia64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windows/x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windows/amd64/*.java \
@@ -90,12 +98,16 @@
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_amd64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_sparc/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/posix/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_amd64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_x86/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/sparc/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/x86/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_amd64/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_x86/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/ppc64/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/jcore/*.java \
 $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/soql/*.java \
--- a/make/solaris/Makefile	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/solaris/Makefile	Tue Feb 03 09:56:21 2015 +0000
@@ -190,8 +190,7 @@
 XSLT_CHECK	= $(RUN.JAVAP) javax.xml.transform.TransformerFactory
 # If not found then fail fast.
 check_j2se_version:
-	$(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
-	if [ $$? -ne 0 ]; then \
+	$(QUIETLY) if ! $(XSLT_CHECK) > /dev/null 2>&1; then \
 	  $(RUN.JAVA) -version; \
 	  echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
 	  "to bootstrap this build" 1>&2; \
--- a/make/solaris/makefiles/dtrace.make	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/solaris/makefiles/dtrace.make	Tue Feb 03 09:56:21 2015 +0000
@@ -171,11 +171,11 @@
 		./lib$(GENOFFS).so
 
 CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \
-	cmp -s $@ $@.tmp; \
-	case $$? in \
-	0) rm -f $@.tmp;; \
-	*) rm -f $@ && mv $@.tmp $@ && echo Updated $@;; \
-	esac
+	if cmp -s $@ $@.tmp; then \
+	  rm -f $@.tmp; \
+	else \
+	  rm -f $@ && mv $@.tmp $@ && echo Updated $@; \
+	fi
 
 # $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
 $(JVMOFFS).h: $(GENOFFS)
--- a/make/solaris/makefiles/mapfile-vers	Tue Feb 03 10:30:16 2015 +0100
+++ b/make/solaris/makefiles/mapfile-vers	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2000, 2014, 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
@@ -132,6 +132,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameters;
                 JVM_GetMethodTypeAnnotations;
+                JVM_GetNanoTimeAdjustment;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
--- a/src/cpu/ppc/vm/assembler_ppc.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/assembler_ppc.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -284,19 +284,20 @@
     MTCTR_OPCODE  = (MTSPR_OPCODE | 9 << SPR_0_4_SHIFT),
     MFCTR_OPCODE  = (MFSPR_OPCODE | 9 << SPR_0_4_SHIFT),
 
-    MTTFHAR_OPCODE   = (MTSPR_OPCODE | 128 << SPR_0_4_SHIFT),
-    MFTFHAR_OPCODE   = (MFSPR_OPCODE | 128 << SPR_0_4_SHIFT),
-    MTTFIAR_OPCODE   = (MTSPR_OPCODE | 129 << SPR_0_4_SHIFT),
-    MFTFIAR_OPCODE   = (MFSPR_OPCODE | 129 << SPR_0_4_SHIFT),
-    MTTEXASR_OPCODE  = (MTSPR_OPCODE | 130 << SPR_0_4_SHIFT),
-    MFTEXASR_OPCODE  = (MFSPR_OPCODE | 130 << SPR_0_4_SHIFT),
-    MTTEXASRU_OPCODE = (MTSPR_OPCODE | 131 << SPR_0_4_SHIFT),
-    MFTEXASRU_OPCODE = (MFSPR_OPCODE | 131 << SPR_0_4_SHIFT),
+    // Attention: Higher and lower half are inserted in reversed order.
+    MTTFHAR_OPCODE   = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
+    MFTFHAR_OPCODE   = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
+    MTTFIAR_OPCODE   = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 1 << SPR_0_4_SHIFT),
+    MFTFIAR_OPCODE   = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 1 << SPR_0_4_SHIFT),
+    MTTEXASR_OPCODE  = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 2 << SPR_0_4_SHIFT),
+    MFTEXASR_OPCODE  = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 2 << SPR_0_4_SHIFT),
+    MTTEXASRU_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 3 << SPR_0_4_SHIFT),
+    MFTEXASRU_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 3 << SPR_0_4_SHIFT),
 
-    MTVRSAVE_OPCODE  = (MTSPR_OPCODE | 256 << SPR_0_4_SHIFT),
-    MFVRSAVE_OPCODE  = (MFSPR_OPCODE | 256 << SPR_0_4_SHIFT),
+    MTVRSAVE_OPCODE  = (MTSPR_OPCODE | 8 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
+    MFVRSAVE_OPCODE  = (MFSPR_OPCODE | 8 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
 
-    MFTB_OPCODE   = (MFSPR_OPCODE | 268 << SPR_0_4_SHIFT),
+    MFTB_OPCODE   = (MFSPR_OPCODE | 8 << SPR_5_9_SHIFT | 12 << SPR_0_4_SHIFT),
 
     MTCRF_OPCODE  = (31u << OPCODE_SHIFT | 144u << 1),
     MFCR_OPCODE   = (31u << OPCODE_SHIFT | 19u << 1),
@@ -1494,6 +1495,26 @@
   inline void mftexasr(Register d);
   inline void mftexasru(Register d);
 
+  // TEXASR bit description
+  enum transaction_failure_reason {
+    // Upper half (TEXASRU):
+    tm_failure_persistent =  7, // The failure is likely to recur on each execution.
+    tm_disallowed         =  8, // The instruction is not permitted.
+    tm_nesting_of         =  9, // The maximum transaction level was exceeded.
+    tm_footprint_of       = 10, // The tracking limit for transactional storage accesses was exceeded.
+    tm_self_induced_cf    = 11, // A self-induced conflict occurred in Suspended state.
+    tm_non_trans_cf       = 12, // A conflict occurred with a non-transactional access by another processor.
+    tm_trans_cf           = 13, // A conflict occurred with another transaction.
+    tm_translation_cf     = 14, // A conflict occurred with a TLB invalidation.
+    tm_inst_fetch_cf      = 16, // An instruction fetch was performed from a block that was previously written transactionally.
+    tm_tabort             = 31, // Termination was caused by the execution of an abort instruction.
+    // Lower half:
+    tm_suspended          = 32, // Failure was recorded in Suspended state.
+    tm_failure_summary    = 36, // Failure has been detected and recorded.
+    tm_tfiar_exact        = 37, // Value in the TFIAR is exact.
+    tm_rot                = 38, // Rollback-only transaction.
+  };
+
   // PPC 1, section 2.4.1 Branch Instructions
   inline void b(  address a, relocInfo::relocType rt = relocInfo::none);
   inline void b(  Label& L);
@@ -1581,6 +1602,7 @@
   inline void bnectrl(ConditionRegister crx, relocInfo::relocType rt = relocInfo::none);
 
   // condition register logic instructions
+  // NOTE: There's a preferred form: d and s2 should point into the same condition register.
   inline void crand( int d, int s1, int s2);
   inline void crnand(int d, int s1, int s2);
   inline void cror(  int d, int s1, int s2);
@@ -1590,6 +1612,19 @@
   inline void crandc(int d, int s1, int s2);
   inline void crorc( int d, int s1, int s2);
 
+  // More convenient version.
+  int condition_register_bit(ConditionRegister cr, Condition c) {
+    return 4 * (int)(intptr_t)cr + c;
+  }
+  void crand( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+  void crnand(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+  void cror(  ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+  void crxor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+  void crnor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+  void creqv( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+  void crandc(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+  void crorc( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+
   // icache and dcache related instructions
   inline void icbi(  Register s1, Register s2);
   //inline void dcba(Register s1, Register s2); // Instruction for embedded processor only.
@@ -1673,6 +1708,10 @@
   inline void smt_prio_low();
   inline void smt_prio_medium_low();
   inline void smt_prio_medium();
+  // >= Power7
+  inline void smt_yield();
+  inline void smt_mdoio();
+  inline void smt_mdoom();
 
   // trap instructions
   inline void twi_0(Register a); // for load with acquire semantics use load+twi_0+isync (trap can't occur)
@@ -1958,6 +1997,7 @@
   inline void tbeginrot_(); // R=1 Rollback-Only Transaction
   inline void tend_();    // A=0
   inline void tendall_(); // A=1
+  inline void tabort_();
   inline void tabort_(Register a);
   inline void tabortwc_(int t, Register a, Register b);
   inline void tabortwci_(int t, Register a, int si);
@@ -1967,6 +2007,10 @@
   inline void tresume_();  // tsr with L=1
   inline void tcheck(int f);
 
+  static bool is_tbegin(int x) {
+    return TBEGIN_OPCODE == (x & (0x3f << OPCODE_SHIFT | 0x3ff << 1));
+  }
+
   // The following encoders use r0 as second operand. These instructions
   // read r0 as '0'.
   inline void lwzx( Register d, Register s2);
--- a/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -453,6 +453,48 @@
 inline void Assembler::crandc(int d, int s1, int s2) { emit_int32(CRANDC_OPCODE | bt(d) | ba(s1) | bb(s2)); }
 inline void Assembler::crorc( int d, int s1, int s2) { emit_int32(CRORC_OPCODE  | bt(d) | ba(s1) | bb(s2)); }
 
+// More convenient version.
+inline void Assembler::crand( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  crand(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crnand(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  crnand(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::cror(  ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  cror(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crxor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  crxor(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crnor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  crnor(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::creqv( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  creqv(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crandc(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  crandc(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crorc( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+  int dst_bit = condition_register_bit(crdst, cdst),
+      src_bit = condition_register_bit(crsrc, csrc);
+  crorc(dst_bit, src_bit, dst_bit);
+}
+
 // Conditional move (>= Power7)
 inline void Assembler::isel(Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b) {
   if (b == noreg) {
@@ -516,6 +558,10 @@
 inline void Assembler::smt_prio_medium()      { Assembler::or_unchecked(R2,  R2,  R2); }
 inline void Assembler::smt_prio_medium_high() { Assembler::or_unchecked(R5,  R5,  R5); }
 inline void Assembler::smt_prio_high()        { Assembler::or_unchecked(R3,  R3,  R3); }
+// >= Power7
+inline void Assembler::smt_yield()            { Assembler::or_unchecked(R27, R27, R27); }
+inline void Assembler::smt_mdoio()            { Assembler::or_unchecked(R29, R29, R29); }
+inline void Assembler::smt_mdoom()            { Assembler::or_unchecked(R30, R30, R30); }
 
 inline void Assembler::twi_0(Register a)      { twi_unchecked(0, a, 0);}
 
@@ -778,7 +824,8 @@
 inline void Assembler::tbeginrot_()                             { emit_int32( TBEGIN_OPCODE | /*R=1*/ 1u << (31-10) | rc(1)); }
 inline void Assembler::tend_()                                  { emit_int32( TEND_OPCODE | rc(1)); }
 inline void Assembler::tendall_()                               { emit_int32( TEND_OPCODE | /*A=1*/ 1u << (31-6) | rc(1)); }
-inline void Assembler::tabort_(Register a)                      { emit_int32( TABORT_OPCODE | ra(a) | rc(1)); }
+inline void Assembler::tabort_()                                { emit_int32( TABORT_OPCODE | rc(1)); }
+inline void Assembler::tabort_(Register a)                      { assert(a != R0, "r0 not allowed"); emit_int32( TABORT_OPCODE | ra(a) | rc(1)); }
 inline void Assembler::tabortwc_(int t, Register a, Register b) { emit_int32( TABORTWC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
 inline void Assembler::tabortwci_(int t, Register a, int si)    { emit_int32( TABORTWCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); }
 inline void Assembler::tabortdc_(int t, Register a, Register b) { emit_int32( TABORTDC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
--- a/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -1712,7 +1712,7 @@
   andi_(R0, klass, TypeEntries::type_unknown);
   // Already unknown. Nothing to do anymore.
   //bne(CCR0, do_nothing);
-  crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2); // cr0 eq = cr1 eq or cr0 ne
+  crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne
   beq(CCR0, do_nothing);
 
   clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask));
@@ -1826,9 +1826,9 @@
       lbz(tmp2, Method::intrinsic_id_offset_in_bytes(), R19_method);
       cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic);
       cmpwi(CCR1, tmp1, Bytecodes::_invokehandle);
-      cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+      cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
       cmpwi(CCR1, tmp2, vmIntrinsics::_compiledLambdaForm);
-      cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+      cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
       bne(CCR0, profile_continue);
     }
 
--- a/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -567,16 +567,21 @@
   inline void load_with_trap_null_check(Register d, int si16, Register s1);
 
   // Load heap oop and decompress. Loaded oop may not be null.
-  inline void load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1 = noreg);
+  // Specify tmp to save one cycle.
+  inline void load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1 = noreg,
+                                     Register tmp = noreg);
+  // Store heap oop and decompress.  Decompressed oop may not be null.
+  // Specify tmp register if d should not be changed.
   inline void store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1,
-                                      /*specify if d must stay uncompressed*/ Register tmp = noreg);
+                                      Register tmp = noreg);
 
   // Null allowed.
   inline void load_heap_oop(Register d, RegisterOrConstant offs, Register s1 = noreg);
 
   // Encode/decode heap oop. Oop may not be null, else en/decoding goes wrong.
+  // src == d allowed.
   inline Register encode_heap_oop_not_null(Register d, Register src = noreg);
-  inline void decode_heap_oop_not_null(Register d);
+  inline Register decode_heap_oop_not_null(Register d, Register src = noreg);
 
   // Null allowed.
   inline void decode_heap_oop(Register d);
--- a/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -311,11 +311,14 @@
   ld(d, si16, s1);
 }
 
-inline void MacroAssembler::load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1) {
+inline void MacroAssembler::load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
   if (UseCompressedOops) {
-    lwz(d, offs, s1);
+    // In disjoint mode decoding can save a cycle if src != dst.
+    Register narrowOop = (tmp != noreg && Universe::narrow_oop_base_disjoint()) ? tmp : d;
+    lwz(narrowOop, offs, s1);
     // Attention: no null check here!
-    decode_heap_oop_not_null(d);
+    Register res = decode_heap_oop_not_null(d, narrowOop);
+    assert(res == d, "caller will not consume loaded value");
   } else {
     ld(d, offs, s1);
   }
@@ -340,26 +343,36 @@
 }
 
 inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register src) {
-  Register current = (src!=noreg) ? src : d; // Compressed oop is in d if no src provided.
-  if (Universe::narrow_oop_base() != NULL) {
+  Register current = (src != noreg) ? src : d; // Oop to be compressed is in d if no src provided.
+  if (Universe::narrow_oop_base_overlaps()) {
     sub(d, current, R30);
     current = d;
   }
   if (Universe::narrow_oop_shift() != 0) {
-    srdi(d, current, LogMinObjAlignmentInBytes);
+    rldicl(d, current, 64-Universe::narrow_oop_shift(), 32);  // Clears the upper bits.
     current = d;
   }
   return current; // Encoded oop is in this register.
 }
 
-inline void MacroAssembler::decode_heap_oop_not_null(Register d) {
+inline Register MacroAssembler::decode_heap_oop_not_null(Register d, Register src) {
+  if (Universe::narrow_oop_base_disjoint() && src != noreg && src != d &&
+      Universe::narrow_oop_shift() != 0) {
+    mr(d, R30);
+    rldimi(d, src, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
+    return d;
+  }
+
+  Register current = (src != noreg) ? src : d; // Compressed oop is in d if no src provided.
   if (Universe::narrow_oop_shift() != 0) {
-    assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
-    sldi(d, d, LogMinObjAlignmentInBytes);
+    sldi(d, current, Universe::narrow_oop_shift());
+    current = d;
   }
   if (Universe::narrow_oop_base() != NULL) {
-    add(d, d, R30);
+    add(d, current, R30);
+    current = d;
   }
+  return current; // Decoded oop is in this register.
 }
 
 inline void MacroAssembler::decode_heap_oop(Register d) {
@@ -368,13 +381,7 @@
     cmpwi(CCR0, d, 0);
     beq(CCR0, isNull);
   }
-  if (Universe::narrow_oop_shift() != 0) {
-    assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
-    sldi(d, d, LogMinObjAlignmentInBytes);
-  }
-  if (Universe::narrow_oop_base() != NULL) {
-    add(d, d, R30);
-  }
+  decode_heap_oop_not_null(d);
   bind(isNull);
 }
 
--- a/src/cpu/ppc/vm/methodHandles_ppc.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/methodHandles_ppc.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -172,15 +172,15 @@
 
   // Load the invoker, as MH -> MH.form -> LF.vmentry
   __ verify_oop(recv);
-  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv);
+  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv, temp2);
   __ verify_oop(method_temp);
-  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp);
+  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp, temp2);
   __ verify_oop(method_temp);
-  // the following assumes that a Method* is normally compressed in the vmtarget field:
+  // The following assumes that a Method* is normally compressed in the vmtarget field:
   __ ld(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), method_temp);
 
   if (VerifyMethodHandles && !for_compiler_entry) {
-    // make sure recv is already on stack
+    // Make sure recv is already on stack.
     __ ld(temp2, in_bytes(Method::const_offset()), method_temp);
     __ load_sized_value(temp2, in_bytes(ConstMethod::size_of_parameters_offset()), temp2,
                         sizeof(u2), /*is_signed*/ false);
@@ -259,8 +259,9 @@
   }
 
   if (TraceMethodHandles) {
-    if (tmp_mh != noreg)
+    if (tmp_mh != noreg) {
       __ mr(R23_method_handle, tmp_mh);  // make stub happy
+    }
     trace_method_handle_interpreter_entry(_masm, iid);
   }
 
@@ -332,7 +333,7 @@
       if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
         Label L_ok;
         Register temp2_defc = temp2;
-        __ load_heap_oop_not_null(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg);
+        __ load_heap_oop_not_null(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg, temp3);
         load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
         __ verify_klass_ptr(temp2_defc);
         __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, L_ok);
@@ -407,7 +408,7 @@
       }
 
       Register temp2_intf = temp2;
-      __ load_heap_oop_not_null(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg);
+      __ load_heap_oop_not_null(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg, temp3);
       load_klass_from_Class(_masm, temp2_intf, temp3, temp4);
       __ verify_klass_ptr(temp2_intf);
 
@@ -464,7 +465,7 @@
                  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,
-                adaptername, mh_reg_name, (intptr_t) mh, (intptr_t) entry_sp);
+                adaptername, mh_reg_name, (intptr_t) mh, entry_sp);
 
   if (Verbose) {
     tty->print_cr("Registers:");
@@ -535,23 +536,22 @@
 
   BLOCK_COMMENT("trace_method_handle {");
 
-  int nbytes_save = 10 * 8;             // 10 volatile gprs
-  __ save_LR_CR(R0);
-  __ mr(R0, R1_SP);                     // saved_sp
-  assert(Assembler::is_simm(-nbytes_save, 16), "Overwriting R0");
-  // Push_frame_reg_args only uses R0 if nbytes_save is wider than 16 bit.
-  __ push_frame_reg_args(nbytes_save, R0);
-  __ save_volatile_gprs(R1_SP, frame::abi_reg_args_size); // Except R0.
+  const Register tmp = R11; // Will be preserved.
+  const int nbytes_save = 11*8; // volatile gprs except R0
+  __ save_volatile_gprs(R1_SP, -nbytes_save); // except R0
+  __ save_LR_CR(tmp); // save in old frame
 
-  __ load_const(R3_ARG1, (address)adaptername);
+  __ mr(R5_ARG3, R1_SP);     // saved_sp
+  __ push_frame_reg_args(nbytes_save, tmp);
+
+  __ load_const_optimized(R3_ARG1, (address)adaptername, tmp);
   __ mr(R4_ARG2, R23_method_handle);
-  __ mr(R5_ARG3, R0);        // saved_sp
   __ mr(R6_ARG4, R1_SP);
   __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub));
 
-  __ restore_volatile_gprs(R1_SP, 112); // Except R0.
   __ pop_frame();
-  __ restore_LR_CR(R0);
+  __ restore_LR_CR(tmp);
+  __ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0
 
   BLOCK_COMMENT("} trace_method_handle");
 }
--- a/src/cpu/ppc/vm/ppc.ad	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/ppc.ad	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 //
-// Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
-// Copyright 2012, 2014 SAP AG. All rights reserved.
+// Copyright (c) 2011, 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
@@ -2698,7 +2698,7 @@
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else if (constant_reloc == relocInfo::metadata_type) {
-        AddressLiteral a = __ allocate_metadata_address((Metadata *)val);
+        AddressLiteral a = __ constant_metadata_address((Metadata *)val);
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else {
@@ -2727,7 +2727,7 @@
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else if (constant_reloc == relocInfo::metadata_type) {
-        AddressLiteral a = __ allocate_metadata_address((Metadata *)val);
+        AddressLiteral a = __ constant_metadata_address((Metadata *)val);
         const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
         __ relocate(a.rspec());
       } else {  // non-oop pointers, e.g. card mark base, heap top
@@ -6029,6 +6029,20 @@
   ins_pipe(pipe_class_default);
 %}
 
+// Optimize DecodeN for disjoint base.
+// Load base of compressed oops into a register
+instruct loadBase(iRegLdst dst) %{
+  effect(DEF dst);
+
+  format %{ "MR      $dst, r30_heapbase" %}
+  size(4);
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_or);
+    __ mr($dst$$Register, R30);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 // Loading ConN must be postalloc expanded so that edges between
 // the nodes are safe. They may not interfere with a safepoint.
 // GL TODO: This needs three instructions: better put this into the constant pool.
@@ -6724,13 +6738,12 @@
   ins_pipe(pipe_class_default);
 %}
 
-// base != 0
-// 32G aligned narrow oop base.
-instruct encodeP_32GAligned(iRegNdst dst, iRegPsrc src) %{
+// Disjoint narrow oop base.
+instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
   match(Set dst (EncodeP src));
-  predicate(false /* TODO: PPC port Universe::narrow_oop_base_disjoint()*/);
-
-  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
+  predicate(Universe::narrow_oop_base_disjoint());
+
+  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
   size(4);
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
@@ -6745,7 +6758,7 @@
   effect(TEMP crx);
   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
             Universe::narrow_oop_shift() != 0 &&
-            true /* TODO: PPC port Universe::narrow_oop_base_overlaps()*/);
+            Universe::narrow_oop_base_overlaps());
 
   format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
   postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
@@ -6756,7 +6769,7 @@
   match(Set dst (EncodeP src));
   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
             Universe::narrow_oop_shift() != 0 &&
-            true /* TODO: PPC port Universe::narrow_oop_base_overlaps()*/);
+            Universe::narrow_oop_base_overlaps());
 
   format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
   postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
@@ -6876,6 +6889,7 @@
              n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
             Universe::narrow_oop_shift() != 0 &&
             Universe::narrow_oop_base() != 0);
+  ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
   effect(TEMP crx);
 
   format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
@@ -6897,6 +6911,106 @@
   ins_pipe(pipe_class_default);
 %}
 
+// Optimize DecodeN for disjoint base.
+// Shift narrow oop and or it into register that already contains the heap base.
+// Base == dst must hold, and is assured by construction in postaloc_expand.
+instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
+  match(Set dst (DecodeN src));
+  effect(TEMP base);
+  predicate(false);
+
+  format %{ "RLDIMI  $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
+  size(4);
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
+    __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Optimize DecodeN for disjoint base.
+// This node requires only one cycle on the critical path.
+// We must postalloc_expand as we can not express use_def effects where
+// the used register is L and the def'ed register P.
+instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
+  match(Set dst (DecodeN src));
+  effect(TEMP_DEF dst);
+  predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
+             n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
+            Universe::narrow_oop_base_disjoint());
+  ins_cost(DEFAULT_COST);
+
+  format %{ "MOV     $dst, R30 \t\n"
+            "RLDIMI  $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
+  postalloc_expand %{
+    loadBaseNode *n1 = new loadBaseNode();
+    n1->add_req(NULL);
+    n1->_opnds[0] = op_dst;
+
+    decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
+    n2->add_req(n_region, n_src, n1);
+    n2->_opnds[0] = op_dst;
+    n2->_opnds[1] = op_src;
+    n2->_opnds[2] = op_dst;
+    n2->_bottom_type = _bottom_type;
+
+    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+
+    nodes->push(n1);
+    nodes->push(n2);
+  %}
+%}
+
+instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
+  match(Set dst (DecodeN src));
+  effect(TEMP_DEF dst, TEMP crx);
+  predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
+             n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
+            Universe::narrow_oop_base_disjoint() && VM_Version::has_isel());
+  ins_cost(3 * DEFAULT_COST);
+
+  format %{ "DecodeN  $dst, $src \t// decode with disjoint base using isel" %}
+  postalloc_expand %{
+    loadBaseNode *n1 = new loadBaseNode();
+    n1->add_req(NULL);
+    n1->_opnds[0] = op_dst;
+
+    cmpN_reg_imm0Node *n_compare  = new cmpN_reg_imm0Node();
+    n_compare->add_req(n_region, n_src);
+    n_compare->_opnds[0] = op_crx;
+    n_compare->_opnds[1] = op_src;
+    n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
+    
+    decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
+    n2->add_req(n_region, n_src, n1);
+    n2->_opnds[0] = op_dst;
+    n2->_opnds[1] = op_src;
+    n2->_opnds[2] = op_dst;
+    n2->_bottom_type = _bottom_type;
+
+    cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
+    n_cond_set->add_req(n_region, n_compare, n2);
+    n_cond_set->_opnds[0] = op_dst;
+    n_cond_set->_opnds[1] = op_crx;
+    n_cond_set->_opnds[2] = op_dst;
+    n_cond_set->_bottom_type = _bottom_type;
+
+    assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
+    ra_->set_oop(n_cond_set, true);
+    
+    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+    ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
+    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+    ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+
+    nodes->push(n1);
+    nodes->push(n_compare);
+    nodes->push(n2);
+    nodes->push(n_cond_set);
+  %}
+%}
+
 // src != 0, shift != 0, base != 0
 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
   match(Set dst (DecodeN src));
@@ -6904,6 +7018,7 @@
              n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
             Universe::narrow_oop_shift() != 0 &&
             Universe::narrow_oop_base() != 0);
+  ins_cost(2 * DEFAULT_COST);
 
   format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %}
   postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
@@ -6973,13 +7088,12 @@
   ins_pipe(pipe_class_default);
 %}
 
-// base != 0
-// 32G aligned narrow oop base.
-instruct encodePKlass_32GAligned(iRegNdst dst, iRegPsrc src) %{
+// Disjoint narrow oop base.
+instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
   match(Set dst (EncodePKlass src));
   predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/);
 
-  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with 32G aligned base" %}
+  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
   size(4);
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
@@ -7486,7 +7600,7 @@
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
-                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
                 noreg, NULL, true);
   %}
   ins_pipe(pipe_class_default);
@@ -10476,7 +10590,7 @@
   match(Set crx (CmpN src1 src2));
 
   size(4);
-  ins_cost(DEFAULT_COST);
+  ins_cost(2);
   format %{ "CMPLW   $crx, $src1, $src2 \t// compressed ptr" %}
   ins_encode %{
     // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
@@ -10488,7 +10602,7 @@
 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
   match(Set crx (CmpN src1 src2));
   // Make this more expensive than zeroCheckN_iReg_imm0.
-  ins_cost(DEFAULT_COST);
+  ins_cost(2);
 
   format %{ "CMPLWI  $crx, $src1, $src2 \t// compressed ptr" %}
   size(4);
@@ -10508,6 +10622,7 @@
             _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
             _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
             Matcher::branches_to_uncommon_trap(_leaf));
+  ins_cost(1); // Should not be cheaper than zeroCheckN.
 
   ins_is_TrapBasedCheckNode(true);
 
@@ -10889,7 +11004,7 @@
 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
                              iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
   match(Set result (PartialSubtypeCheck subklass superklass));
-  effect(TEMP result, TEMP tmp_klass, TEMP tmp_arrayptr);
+  effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
   ins_cost(DEFAULT_COST*10);
 
   format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
@@ -11000,7 +11115,7 @@
   predicate(SpecialStringIndexOf);  // type check implicit by parameter type, See Matcher::match_rule_supported
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
 
-  effect(TEMP result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
 
   ins_cost(150);
   format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
@@ -11037,7 +11152,7 @@
                              iRegIdst tmp1, iRegIdst tmp2,
                              flagsRegCR0 cr0, flagsRegCR1 cr1) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
-  effect(USE_KILL needle, /* TDEF needle, */ TEMP result,
+  effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
          TEMP tmp1, TEMP tmp2);
   // Required for EA: check if it is still a type_array.
   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
@@ -11084,7 +11199,7 @@
                             iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
                             flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
-  effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP result,
+  effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
   // Required for EA: check if it is still a type_array.
   predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
@@ -11118,7 +11233,7 @@
                         flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6) %{
   match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
   effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
-         TEMP result,
+         TEMP_DEF result,
          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
   predicate(SpecialStringIndexOf);  // See Matcher::match_rule_supported.
   ins_cost(300);
@@ -11142,7 +11257,7 @@
                            iRegPdst tmp1, iRegPdst tmp2,
                            flagsRegCR0 cr0, flagsRegCR6 cr6, regCTR ctr) %{
   match(Set result (StrEquals (Binary str1 str2) cntImm));
-  effect(TEMP result, TEMP tmp1, TEMP tmp2,
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2,
          KILL cr0, KILL cr6, KILL ctr);
   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
   ins_cost(250);
@@ -11165,7 +11280,7 @@
                        iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3, iRegPdst tmp4, iRegPdst tmp5,
                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
   match(Set result (StrEquals (Binary str1 str2) cnt));
-  effect(TEMP result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
+  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
          KILL cr0, KILL cr1, KILL cr6, KILL ctr);
   predicate(SpecialStringEquals);  // See Matcher::match_rule_supported.
   ins_cost(300);
@@ -11188,7 +11303,7 @@
 instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
                         iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{
   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
-  effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP result, TEMP tmp, KILL cr0, KILL ctr);
+  effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP_DEF result, TEMP tmp, KILL cr0, KILL ctr);
   ins_cost(300);
 
   ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
--- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1079,7 +1079,7 @@
     __ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes
     __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
     __ cmpld(CCR1, tmp1, tmp2);
-    __ crand(/*CCR0 lt*/0, /*CCR1 lt*/4+0, /*CCR0 lt*/0);
+    __ crand(CCR0, Assembler::less, CCR1, Assembler::less);
     __ blt(CCR0, l_overlap); // Src before dst and distance smaller than size.
 
     // need to copy forwards
--- a/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -264,11 +264,11 @@
       __ cmpdi(CCR0, Rmdo, 0);
       __ beq(CCR0, no_mdo);
 
-      // Increment backedge counter in the MDO.
-      const int mdo_bc_offs = in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
-      __ lwz(Rscratch2, mdo_bc_offs, Rmdo);
+      // Increment invocation counter in the MDO.
+      const int mdo_ic_offs = in_bytes(MethodData::invocation_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+      __ lwz(Rscratch2, mdo_ic_offs, Rmdo);
       __ addi(Rscratch2, Rscratch2, increment);
-      __ stw(Rscratch2, mdo_bc_offs, Rmdo);
+      __ stw(Rscratch2, mdo_ic_offs, Rmdo);
       __ load_const_optimized(Rscratch1, mask, R0);
       __ and_(Rscratch1, Rscratch2, Rscratch1);
       __ bne(CCR0, done);
@@ -276,12 +276,12 @@
     }
 
     // Increment counter in MethodCounters*.
-    const int mo_bc_offs = in_bytes(MethodCounters::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+    const int mo_ic_offs = in_bytes(MethodCounters::invocation_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
     __ bind(no_mdo);
     __ get_method_counters(R19_method, R3_counters, done);
-    __ lwz(Rscratch2, mo_bc_offs, R3_counters);
+    __ lwz(Rscratch2, mo_ic_offs, R3_counters);
     __ addi(Rscratch2, Rscratch2, increment);
-    __ stw(Rscratch2, mo_bc_offs, R3_counters);
+    __ stw(Rscratch2, mo_ic_offs, R3_counters);
     __ load_const_optimized(Rscratch1, mask, R0);
     __ and_(Rscratch1, Rscratch2, Rscratch1);
     __ beq(CCR0, *overflow);
--- a/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 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
@@ -335,11 +335,11 @@
 
   __ cmpwi(CCR0, Rscratch2, JVM_CONSTANT_UnresolvedClass); // Unresolved class?
   __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_UnresolvedClassInError); // Unresolved class in error state?
-  __ cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+  __ cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
 
   // Resolved class - need to call vm to get java mirror of the class.
   __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_Class);
-  __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // Neither resolved class nor unresolved case from above?
+  __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal); // Neither resolved class nor unresolved case from above?
   __ beq(CCR0, notClass);
 
   __ li(R4, wide ? 1 : 0);
@@ -2611,7 +2611,7 @@
           __ cmpwi(CCR0, Rflags, ltos);
           __ cmpwi(CCR1, Rflags, dtos);
           __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(1));
-          __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+          __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal);
           __ beq(CCR0, is_one_slot);
           __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(2));
           __ bind(is_one_slot);
@@ -3563,7 +3563,7 @@
     // Make sure klass does not have has_finalizer, or is abstract, or interface or java/lang/Class.
     __ andi_(R0, Rinstance_size, Klass::_lh_instance_slow_path_bit); // slow path bit equals 0?
 
-    __ crnand(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // slow path bit set or not fully initialized?
+    __ crnand(CCR0, Assembler::equal, CCR1, Assembler::equal); // slow path bit set or not fully initialized?
     __ beq(CCR0, Lslow_case);
 
     // --------------------------------------------------------------------------
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -483,15 +483,6 @@
 
 }
 
-jbyte* G1PostBarrierStub::_byte_map_base = NULL;
-
-jbyte* G1PostBarrierStub::byte_map_base_slow() {
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  assert(bs->is_a(BarrierSet::G1SATBCTLogging),
-         "Must be if we're using this.");
-  return ((G1SATBCardTableModRefBS*)bs)->byte_map_base;
-}
-
 void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
 
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1374,6 +1374,7 @@
 }
 
 void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocation_count,
+                                                                Register method_counters,
                                                                 Register Rtmp,
                                                                 Label &profile_continue) {
   assert(ProfileInterpreter, "must be profiling interpreter");
@@ -1386,9 +1387,8 @@
   br_notnull_short(ImethodDataPtr, Assembler::pn, done);
 
   // Test to see if we should create a method data oop
-  AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
-  sethi(profile_limit, Rtmp);
-  ld(Rtmp, profile_limit.low10(), Rtmp);
+  Address profile_limit(method_counters, MethodCounters::interpreter_profile_limit_offset());
+  ld(profile_limit, Rtmp);
   cmp(invocation_count, Rtmp);
   // Use long branches because call_VM() code and following code generated by
   // test_backedge_count_for_osr() is large in debug VM.
@@ -2375,6 +2375,7 @@
 
 #ifndef CC_INTERP
 void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_count,
+                                                             Register method_counters,
                                                              Register branch_bcp,
                                                              Register Rtmp ) {
   Label did_not_overflow;
@@ -2382,8 +2383,8 @@
   assert_different_registers(backedge_count, Rtmp, branch_bcp);
   assert(UseOnStackReplacement,"Must UseOnStackReplacement to test_backedge_count_for_osr");
 
-  AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit);
-  load_contents(limit, Rtmp);
+  Address limit(method_counters, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset()));
+  ld(limit, Rtmp);
   cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow);
 
   // When ProfileInterpreter is on, the backedge_count comes from the
@@ -2500,17 +2501,13 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask_addr,
                                                         Register scratch1, Register scratch2,
                                                         Condition cond, Label *where) {
   ld(counter_addr, scratch1);
   add(scratch1, increment, scratch1);
-  if (is_simm13(mask)) {
-    andcc(scratch1, mask, G0);
-  } else {
-    set(mask, scratch2);
-    andcc(scratch1, scratch2,  G0);
-  }
+  ld(mask_addr, scratch2);
+  andcc(scratch1, scratch2,  G0);
   br(cond, false, Assembler::pn, *where);
   delayed()->st(scratch1, counter_addr);
 }
--- a/src/cpu/sparc/vm/interp_masm_sparc.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -267,7 +267,7 @@
   void increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
   void increment_backedge_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
 #ifndef CC_INTERP
-  void test_backedge_count_for_osr( Register backedge_count, Register branch_bcp, Register Rtmp );
+  void test_backedge_count_for_osr(Register backedge_count, Register method_counters, Register branch_bcp, Register Rtmp );
 
 #endif /* CC_INTERP */
   // Object locking
@@ -280,7 +280,7 @@
   void set_method_data_pointer_for_bcp();
   void test_method_data_pointer(Label& zero_continue);
   void verify_method_data_pointer();
-  void test_invocation_counter_for_mdp(Register invocation_count, Register Rtmp, Label &profile_continue);
+  void test_invocation_counter_for_mdp(Register invocation_count, Register method_counters, Register Rtmp, Label &profile_continue);
 
   void set_mdp_data_at(int constant, Register value);
   void increment_mdp_data_at(Address counter, Register bumped_count,
@@ -291,7 +291,7 @@
                              Register bumped_count, Register scratch2,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask_addr,
                                Register scratch1, Register scratch2,
                                Condition cond, Label *where);
   void set_mdp_flag_at(int flag_constant, Register scratch);
--- a/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -630,7 +630,12 @@
 
 inline void MacroAssembler::ldf(FloatRegisterImpl::Width w, const Address& a, FloatRegister d, int offset) {
   relocate(a.rspec(offset));
-  ldf(w, a.base(), a.disp() + offset, d);
+  if (a.has_index()) {
+    assert(offset == 0, "");
+    ldf(w, a.base(), a.index(), d);
+  } else {
+    ldf(w, a.base(), a.disp() + offset, d);
+  }
 }
 
 // returns if membar generates anything, obviously this code should mirror
--- a/src/cpu/sparc/vm/sparc.ad	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/sparc/vm/sparc.ad	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -2996,7 +2996,7 @@
   %}
 
 enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
-    Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
+    Label Lchar, Lchar_loop, Ldone;
     MacroAssembler _masm(&cbuf);
 
     Register   str1_reg = reg_to_register_object($str1$$reg);
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -282,12 +282,11 @@
 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
   // Note: In tiered we increment either counters in MethodCounters* or in
   // MDO depending if we're profiling or not.
-  const Register Rcounters = G3_scratch;
+  const Register G3_method_counters = G3_scratch;
   Label done;
 
   if (TieredCompilation) {
     const int increment = InvocationCounter::count_increment;
-    const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // If no method data exists, go to profile_continue.
@@ -297,6 +296,7 @@
       Address mdo_invocation_counter(G4_scratch,
                                      in_bytes(MethodData::invocation_counter_offset()) +
                                      in_bytes(InvocationCounter::counter_offset()));
+      Address mask(G4_scratch, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask,
                                  G3_scratch, Lscratch,
                                  Assembler::zero, overflow);
@@ -305,20 +305,21 @@
 
     // Increment counter in MethodCounters*
     __ bind(no_mdo);
-    Address invocation_counter(Rcounters,
+    Address invocation_counter(G3_method_counters,
             in_bytes(MethodCounters::invocation_counter_offset()) +
             in_bytes(InvocationCounter::counter_offset()));
-    __ get_method_counters(Lmethod, Rcounters, done);
+    __ get_method_counters(Lmethod, G3_method_counters, done);
+    Address mask(G3_method_counters, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask,
                                G4_scratch, Lscratch,
                                Assembler::zero, overflow);
     __ bind(done);
-  } else {
+  } else { // not TieredCompilation
     // Update standard invocation counters
-    __ get_method_counters(Lmethod, Rcounters, done);
-    __ increment_invocation_counter(Rcounters, O0, G4_scratch);
+    __ get_method_counters(Lmethod, G3_method_counters, done);
+    __ increment_invocation_counter(G3_method_counters, O0, G4_scratch);
     if (ProfileInterpreter) {
-      Address interpreter_invocation_counter(Rcounters,
+      Address interpreter_invocation_counter(G3_method_counters,
             in_bytes(MethodCounters::interpreter_invocation_counter_offset()));
       __ ld(interpreter_invocation_counter, G4_scratch);
       __ inc(G4_scratch);
@@ -327,16 +328,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit);
-      __ load_contents(profile_limit, G3_scratch);
-      __ cmp_and_br_short(O0, G3_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
+      Address profile_limit(G3_method_counters, in_bytes(MethodCounters::interpreter_profile_limit_offset()));
+      __ ld(profile_limit, G1_scratch);
+      __ cmp_and_br_short(O0, G1_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(*profile_method);
     }
 
-    AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit);
-    __ load_contents(invocation_limit, G3_scratch);
+    Address invocation_limit(G3_method_counters, in_bytes(MethodCounters::interpreter_invocation_limit_offset()));
+    __ ld(invocation_limit, G3_scratch);
     __ cmp(O0, G3_scratch);
     __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance
     __ delayed()->nop();
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1599,13 +1599,12 @@
     // Bump bytecode pointer by displacement (take the branch)
     __ delayed()->add( O1_disp, Lbcp, Lbcp );     // add to bc addr
 
-    const Register Rcounters = G3_scratch;
-    __ get_method_counters(Lmethod, Rcounters, Lforward);
+    const Register G3_method_counters = G3_scratch;
+    __ get_method_counters(Lmethod, G3_method_counters, Lforward);
 
     if (TieredCompilation) {
       Label Lno_mdo, Loverflow;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // If no method data exists, go to profile_continue.
         __ ld_ptr(Lmethod, Method::method_data_offset(), G4_scratch);
@@ -1614,6 +1613,7 @@
         // Increment backedge counter in the MDO
         Address mdo_backedge_counter(G4_scratch, in_bytes(MethodData::backedge_counter_offset()) +
                                                  in_bytes(InvocationCounter::counter_offset()));
+        Address mask(G4_scratch, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, O0,
                                    Assembler::notZero, &Lforward);
         __ ba_short(Loverflow);
@@ -1621,9 +1621,10 @@
 
       // If there's no MDO, increment counter in MethodCounters*
       __ bind(Lno_mdo);
-      Address backedge_counter(Rcounters,
+      Address backedge_counter(G3_method_counters,
               in_bytes(MethodCounters::backedge_counter_offset()) +
               in_bytes(InvocationCounter::counter_offset()));
+      Address mask(G3_method_counters, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(backedge_counter, increment, mask, G4_scratch, O0,
                                  Assembler::notZero, &Lforward);
       __ bind(Loverflow);
@@ -1663,18 +1664,19 @@
       __ jmp(O2, G0);
       __ delayed()->nop();
 
-    } else {
+    } else { // not TieredCompilation
       // Update Backedge branch separately from invocations
       const Register G4_invoke_ctr = G4;
-      __ increment_backedge_counter(Rcounters, G4_invoke_ctr, G1_scratch);
+      __ increment_backedge_counter(G3_method_counters, G4_invoke_ctr, G1_scratch);
       if (ProfileInterpreter) {
-        __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_scratch, Lforward);
+        __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_method_counters, G1_scratch, Lforward);
         if (UseOnStackReplacement) {
-          __ test_backedge_count_for_osr(O2_bumped_count, l_cur_bcp, G3_scratch);
+
+          __ test_backedge_count_for_osr(O2_bumped_count, G3_method_counters, l_cur_bcp, G1_scratch);
         }
       } else {
         if (UseOnStackReplacement) {
-          __ test_backedge_count_for_osr(G4_invoke_ctr, l_cur_bcp, G3_scratch);
+          __ test_backedge_count_for_osr(G4_invoke_ctr, G3_method_counters, l_cur_bcp, G1_scratch);
         }
       }
     }
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -541,15 +541,6 @@
 
 }
 
-jbyte* G1PostBarrierStub::_byte_map_base = NULL;
-
-jbyte* G1PostBarrierStub::byte_map_base_slow() {
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  assert(bs->is_a(BarrierSet::G1SATBCTLogging),
-         "Must be if we're using this.");
-  return ((G1SATBCardTableModRefBS*)bs)->byte_map_base;
-}
-
 void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
   assert(addr()->is_register(), "Precondition.");
--- a/src/cpu/x86/vm/interp_masm_x86_32.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1360,7 +1360,7 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask,
                                                         Register scratch, bool preloaded,
                                                         Condition cond, Label* where) {
   if (!preloaded) {
--- a/src/cpu/x86/vm/interp_masm_x86_32.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -182,7 +182,7 @@
   void increment_mdp_data_at(Register mdp_in, Register reg, int constant,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask,
                                Register scratch, bool preloaded,
                                Condition cond, Label* where);
   void set_mdp_flag_at(Register mdp_in, int flag_constant);
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1426,7 +1426,7 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask,
                                                         Register scratch, bool preloaded,
                                                         Condition cond, Label* where) {
   if (!preloaded) {
--- a/src/cpu/x86/vm/interp_masm_x86_64.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -191,7 +191,7 @@
   void increment_mdp_data_at(Register mdp_in, Register reg, int constant,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask,
                                Register scratch, bool preloaded,
                                Condition cond, Label* where);
   void set_mdp_flag_at(Register mdp_in, int flag_constant);
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -3184,7 +3184,24 @@
     jmp(done);
   } else {
     // Stack: X Y
-    Label x_negative, y_odd;
+    Label x_negative, y_not_2;
+
+    static double two = 2.0;
+    ExternalAddress two_addr((address)&two);
+
+    // constant maybe too far on 64 bit
+    lea(tmp2, two_addr);
+    fld_d(Address(tmp2, 0));    // Stack: 2 X Y
+    fcmp(tmp, 2, true, false);  // Stack: X Y
+    jcc(Assembler::parity, y_not_2);
+    jcc(Assembler::notEqual, y_not_2);
+
+    fxch(); fpop();             // Stack: X
+    fmul(0);                    // Stack: X*X
+
+    jmp(done);
+
+    bind(y_not_2);
 
     fldz();                     // Stack: 0 X Y
     fcmp(tmp, 1, true, false);  // Stack: X Y
@@ -6177,7 +6194,7 @@
   ShortBranchVerifier sbv(this);
   assert(UseSSE42Intrinsics, "SSE4.2 is required");
 
-  // This method uses pcmpestri inxtruction with bound registers
+  // This method uses pcmpestri instruction with bound registers
   //   inputs:
   //     xmm - substring
   //     rax - substring length (elements count)
@@ -6338,7 +6355,7 @@
   //
   assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < 8), "should be != 0");
 
-  // This method uses pcmpestri inxtruction with bound registers
+  // This method uses pcmpestri instruction with bound registers
   //   inputs:
   //     xmm - substring
   //     rax - substring length (elements count)
@@ -6627,7 +6644,6 @@
     // start from first character again because it has aligned address.
     int stride2 = 16;
     int adr_stride  = stride  << scale;
-    int adr_stride2 = stride2 << scale;
 
     assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri");
     // rax and rdx are used by pcmpestri as elements counters
@@ -6726,7 +6742,7 @@
     //   inputs:
     //     vec1- substring
     //     rax - negative string length (elements count)
-    //     mem - scaned string
+    //     mem - scanned string
     //     rdx - string length (elements count)
     //     pcmpmask - cmp mode: 11000 (string compare with negated result)
     //               + 00 (unsigned bytes) or  + 01 (unsigned shorts)
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -346,7 +346,6 @@
   // depending if we're profiling or not.
   if (TieredCompilation) {
     int increment = InvocationCounter::count_increment;
-    int mask = ((1 << Tier0InvokeNotifyFreqLog)  - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // Are we profiling?
@@ -356,6 +355,7 @@
       // Increment counter in the MDO
       const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+      const Address mask(rax, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
       __ jmp(done);
     }
@@ -366,11 +366,12 @@
                   InvocationCounter::counter_offset());
 
     __ get_method_counters(rbx, rax, done);
+    const Address mask(rax, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask,
                                rcx, false, Assembler::zero, overflow);
     __ bind(done);
-  } else {
-    const Address backedge_counter  (rax,
+  } else { // not TieredCompilation
+    const Address backedge_counter(rax,
                   MethodCounters::backedge_counter_offset() +
                   InvocationCounter::counter_offset());
     const Address invocation_counter(rax,
@@ -400,16 +401,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      __ cmp32(rcx,
-               ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit));
+      __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+      __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
       __ jcc(Assembler::less, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(rax, *profile_method);
     }
 
-    __ cmp32(rcx,
-             ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
+    __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+    __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_invocation_limit_offset())));
     __ jcc(Assembler::aboveEqual, *overflow);
     __ bind(done);
   }
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -299,7 +299,6 @@
   // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not.
   if (TieredCompilation) {
     int increment = InvocationCounter::count_increment;
-    int mask = ((1 << Tier0InvokeNotifyFreqLog)  - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // Are we profiling?
@@ -309,6 +308,7 @@
       // Increment counter in the MDO
       const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+      const Address mask(rax, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
       __ jmp(done);
     }
@@ -318,10 +318,11 @@
                   MethodCounters::invocation_counter_offset() +
                   InvocationCounter::counter_offset());
     __ get_method_counters(rbx, rax, done);
+    const Address mask(rax, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask, rcx,
                                false, Assembler::zero, overflow);
     __ bind(done);
-  } else {
+  } else { // not TieredCompilation
     const Address backedge_counter(rax,
                   MethodCounters::backedge_counter_offset() +
                   InvocationCounter::counter_offset());
@@ -350,14 +351,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit));
+      __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+      __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
       __ jcc(Assembler::less, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(rax, *profile_method);
     }
 
-    __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
+    __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+    __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_invocation_limit_offset())));
     __ jcc(Assembler::aboveEqual, *overflow);
     __ bind(done);
   }
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1621,7 +1621,6 @@
     if (TieredCompilation) {
       Label no_mdo;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // Are we profiling?
         __ movptr(rbx, Address(rcx, in_bytes(Method::method_data_offset())));
@@ -1630,6 +1629,7 @@
         // Increment the MDO backedge counter
         const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+        const Address mask(rbx, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
                                    rax, false, Assembler::zero, &backedge_counter_overflow);
         __ jmp(dispatch);
@@ -1637,9 +1637,10 @@
       __ bind(no_mdo);
       // Increment backedge counter in MethodCounters*
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
+      const Address mask(rcx, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
                                  rax, false, Assembler::zero, &backedge_counter_overflow);
-    } else {
+    } else { // not TieredCompilation
       // increment counter
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
       __ movl(rax, Address(rcx, be_offset));        // load backedge counter
@@ -1653,8 +1654,7 @@
 
       if (ProfileInterpreter) {
         // Test to see if we should create a method data oop
-        __ cmp32(rax,
-                 ExternalAddress((address) &InvocationCounter::InterpreterProfileLimit));
+        __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
         __ jcc(Assembler::less, dispatch);
 
         // if no method data exists, go to profile method
@@ -1662,8 +1662,7 @@
 
         if (UseOnStackReplacement) {
           // check for overflow against rbx, which is the MDO taken count
-          __ cmp32(rbx,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rbx, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::below, dispatch);
 
           // When ProfileInterpreter is on, the backedge_count comes from the
@@ -1678,8 +1677,7 @@
       } else {
         if (UseOnStackReplacement) {
           // check for overflow against rax, which is the sum of the counters
-          __ cmp32(rax,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
 
         }
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1642,7 +1642,6 @@
     if (TieredCompilation) {
       Label no_mdo;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // Are we profiling?
         __ movptr(rbx, Address(rcx, in_bytes(Method::method_data_offset())));
@@ -1651,6 +1650,7 @@
         // Increment the MDO backedge counter
         const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) +
                                            in_bytes(InvocationCounter::counter_offset()));
+        const Address mask(rbx, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
                                    rax, false, Assembler::zero, &backedge_counter_overflow);
         __ jmp(dispatch);
@@ -1658,9 +1658,10 @@
       __ bind(no_mdo);
       // Increment backedge counter in MethodCounters*
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
+         const Address mask(rcx, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
                                  rax, false, Assembler::zero, &backedge_counter_overflow);
-    } else {
+    } else { // not TieredCompilation
       // increment counter
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
       __ movl(rax, Address(rcx, be_offset));        // load backedge counter
@@ -1674,8 +1675,7 @@
 
       if (ProfileInterpreter) {
         // Test to see if we should create a method data oop
-        __ cmp32(rax,
-                 ExternalAddress((address) &InvocationCounter::InterpreterProfileLimit));
+        __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
         __ jcc(Assembler::less, dispatch);
 
         // if no method data exists, go to profile method
@@ -1683,8 +1683,7 @@
 
         if (UseOnStackReplacement) {
           // check for overflow against ebx which is the MDO taken count
-          __ cmp32(rbx,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rbx, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::below, dispatch);
 
           // When ProfileInterpreter is on, the backedge_count comes
@@ -1702,8 +1701,7 @@
         if (UseOnStackReplacement) {
           // check for overflow against eax, which is the sum of the
           // counters
-          __ cmp32(rax,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
 
         }
--- a/src/os/aix/vm/os_aix.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/aix/vm/os_aix.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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.
  * Copyright 2012, 2014 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1115,6 +1115,15 @@
   return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
 }
 
+void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
+  timeval time;
+  int status = gettimeofday(&time, NULL);
+  assert(status != -1, "aix error at gettimeofday()");
+  seconds = jlong(time.tv_sec);
+  nanos = jlong(time.tv_usec) * 1000;
+}
+
+
 // We need to manually declare mread_real_time,
 // because IBM didn't provide a prototype in time.h.
 // (they probably only ever tested in C, not C++)
--- a/src/os/aix/vm/perfMemory_aix.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/aix/vm/perfMemory_aix.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -31,6 +31,7 @@
 #include "os_aix.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/perfMemory.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
 
 // put OS-includes here
@@ -196,12 +197,37 @@
   return pid;
 }
 
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+static bool is_statbuf_secure(struct stat *statp) {
+  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+    // The path represents a link or some non-directory file type,
+    // which is not what we expected. Declare it insecure.
+    //
+    return false;
+  }
+  // We have an existing directory, check if the permissions are safe.
+  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+    // The directory is open for writing and could be subjected
+    // to a symlink or a hard link attack. Declare it insecure.
+    return false;
+  }
+  // See if the uid of the directory matches the effective uid of the process.
+  //
+  if (statp->st_uid != geteuid()) {
+    // The directory was not created by this user, declare it insecure.
+    return false;
+  }
+  return true;
+}
 
-// check if the given path is considered a secure directory for
+
+// Check if the given path is considered a secure directory for
 // the backing store files. Returns true if the directory exists
 // and is considered a secure location. Returns false if the path
 // is a symbolic link or if an error occurred.
-//
 static bool is_directory_secure(const char* path) {
   struct stat statbuf;
   int result = 0;
@@ -211,38 +237,276 @@
     return false;
   }
 
-  // the path exists, now check it's mode
-  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
-    // the path represents a link or some non-directory file type,
-    // which is not what we expected. declare it insecure.
-    //
+  // The path exists, see if it is secure.
+  return is_statbuf_secure(&statbuf);
+}
+
+// (Taken over from Solaris to support the O_NOFOLLOW case on AIX.)
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+static bool is_dirfd_secure(int dir_fd) {
+  struct stat statbuf;
+  int result = 0;
+
+  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+  if (result == OS_ERR) {
     return false;
   }
-  else {
-    // we have an existing directory, check if the permissions are safe.
-    //
-    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
-      // the directory is open for writing and could be subjected
-      // to a symlnk attack. declare it insecure.
-      //
-      return false;
+
+  // The path exists, now check its mode.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+static bool is_same_fsobject(int fd1, int fd2) {
+  struct stat statbuf1;
+  struct stat statbuf2;
+  int result = 0;
+
+  RESTARTABLE(::fstat(fd1, &statbuf1), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+  RESTARTABLE(::fstat(fd2, &statbuf2), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+
+  if ((statbuf1.st_ino == statbuf2.st_ino) &&
+      (statbuf1.st_dev == statbuf2.st_dev)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+// Helper functions for open without O_NOFOLLOW which is not present on AIX 5.3/6.1.
+// We use the jdk6 implementation here.
+#ifndef O_NOFOLLOW
+// The O_NOFOLLOW oflag doesn't exist before solaris 5.10, this is to simulate that behaviour
+// was done in jdk 5/6 hotspot by Oracle this way
+static int open_o_nofollow_impl(const char* path, int oflag, mode_t mode, bool use_mode) {
+  struct stat orig_st;
+  struct stat new_st;
+  bool create;
+  int error;
+  int fd;
+
+  create = false;
+
+  if (lstat(path, &orig_st) != 0) {
+    if (errno == ENOENT && (oflag & O_CREAT) != 0) {
+      // File doesn't exist, but_we want to create it, add O_EXCL flag
+      // to make sure no-one creates it (or a symlink) before us
+      // This works as we expect with symlinks, from posix man page:
+      // 'If O_EXCL  and  O_CREAT  are set, and path names a symbolic
+      // link, open() shall fail and set errno to [EEXIST]'.
+      oflag |= O_EXCL;
+      create = true;
+    } else {
+      // File doesn't exist, and we are not creating it.
+      return OS_ERR;
     }
+  } else {
+    // Lstat success, check if existing file is a link.
+    if ((orig_st.st_mode & S_IFMT) == S_IFLNK)  {
+      // File is a symlink.
+      errno = ELOOP;
+      return OS_ERR;
+    }
+  }
+
+  if (use_mode == true) {
+    fd = open(path, oflag, mode);
+  } else {
+    fd = open(path, oflag);
+  }
+
+  if (fd == OS_ERR) {
+    return fd;
+  }
+
+  // Can't do inode checks on before/after if we created the file.
+  if (create == false) {
+    if (fstat(fd, &new_st) != 0) {
+      // Keep errno from fstat, in case close also fails.
+      error = errno;
+      ::close(fd);
+      errno = error;
+      return OS_ERR;
+    }
+
+    if (orig_st.st_dev != new_st.st_dev || orig_st.st_ino != new_st.st_ino) {
+      // File was tampered with during race window.
+      ::close(fd);
+      errno = EEXIST;
+      if (PrintMiscellaneous && Verbose) {
+        warning("possible file tampering attempt detected when opening %s", path);
+      }
+      return OS_ERR;
+    }
+  }
+
+  return fd;
+}
+
+static int open_o_nofollow(const char* path, int oflag, mode_t mode) {
+  return open_o_nofollow_impl(path, oflag, mode, true);
+}
+
+static int open_o_nofollow(const char* path, int oflag) {
+  return open_o_nofollow_impl(path, oflag, 0, false);
+}
+#endif
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+static DIR *open_directory_secure(const char* dirname) {
+  // Open the directory using open() so that it can be verified
+  // to be secure by calling is_dirfd_secure(), opendir() and then check
+  // to see if they are the same file system object.  This method does not
+  // introduce a window of opportunity for the directory to be attacked that
+  // calling opendir() and is_directory_secure() does.
+  int result;
+  DIR *dirp = NULL;
+
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open;
+  // so provide a workaround in this case.
+#ifdef O_NOFOLLOW
+  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+#else
+  // workaround (jdk6 coding)
+  RESTARTABLE(::open_o_nofollow(dirname, O_RDONLY), result);
+#endif
+
+  if (result == OS_ERR) {
+    // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
+    if (PrintMiscellaneous && Verbose) {
+      if (errno == ELOOP) {
+        warning("directory %s is a symlink and is not secure\n", dirname);
+      } else {
+        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+      }
+    }
+    return dirp;
+  }
+  int fd = result;
+
+  // Determine if the open directory is secure.
+  if (!is_dirfd_secure(fd)) {
+    // The directory is not a secure directory.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Open the directory.
+  dirp = ::opendir(dirname);
+  if (dirp == NULL) {
+    // The directory doesn't exist, close fd and return.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Check to make sure fd and dirp are referencing the same file system object.
+  if (!is_same_fsobject(fd, dirp->dd_fd)) {
+    // The directory is not secure.
+    os::close(fd);
+    os::closedir(dirp);
+    dirp = NULL;
+    return dirp;
+  }
+
+  // Close initial open now that we know directory is secure
+  os::close(fd);
+
+  return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions.  Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+  // Open the directory.
+  DIR* dirp = open_directory_secure(dirname);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+    return dirp;
+  }
+  int fd = dirp->dd_fd;
+
+  // Open a fd to the cwd and save it off.
+  int result;
+  RESTARTABLE(::open(".", O_RDONLY), result);
+  if (result == OS_ERR) {
+    *saved_cwd_fd = -1;
+  } else {
+    *saved_cwd_fd = result;
+  }
+
+  // Set the current directory to dirname by using the fd of the directory.
+  result = fchdir(fd);
+
+  return dirp;
+}
+
+// Close the directory and restore the current working directory.
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+  int result;
+  // If we have a saved cwd change back to it and close the fd.
+  if (saved_cwd_fd != -1) {
+    result = fchdir(saved_cwd_fd);
+    ::close(saved_cwd_fd);
+  }
+
+  // Close the directory.
+  os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+static bool is_file_secure(int fd, const char *filename) {
+
+  int result;
+  struct stat statbuf;
+
+  // Determine if the file is secure.
+  RESTARTABLE(::fstat(fd, &statbuf), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+    }
+    return false;
+  }
+  if (statbuf.st_nlink > 1) {
+    // A file with multiple links is not expected.
+    if (PrintMiscellaneous && Verbose) {
+      warning("file %s has multiple links\n", filename);
+    }
+    return false;
   }
   return true;
 }
 
-
-// return the user name for the given user id
+// Return the user name for the given user id.
 //
-// the caller is expected to free the allocated memory.
-//
+// The caller is expected to free the allocated memory.
 static char* get_user_name(uid_t uid) {
 
   struct passwd pwent;
 
-  // determine the max pwbuf size from sysconf, and hardcode
+  // Determine the max pwbuf size from sysconf, and hardcode
   // a default if this not available through sysconf.
-  //
   long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
   if (bufsize == -1)
     bufsize = 1024;
@@ -344,7 +608,8 @@
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
 
-    DIR* subdirp = os::opendir(usrdir_name);
+    // Open the user directory.
+    DIR* subdirp = open_directory_secure(usrdir_name);
 
     if (subdirp == NULL) {
       FREE_C_HEAP_ARRAY(char, usrdir_name);
@@ -464,28 +729,7 @@
   }
 }
 
-
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
-  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
-  strcpy(path, dirname);
-  strcat(path, "/");
-  strcat(path, filename);
-
-  remove_file(path);
-
-  FREE_C_HEAP_ARRAY(char, path);
-}
-
-
-// cleanup stale shared memory resources
+// Cleanup stale shared memory resources
 //
 // This method attempts to remove all stale shared memory files in
 // the named user temporary directory. It scans the named directory
@@ -493,33 +737,26 @@
 // process id is extracted from the file name and a test is run to
 // determine if the process is alive. If the process is not alive,
 // any stale file resources are removed.
-//
 static void cleanup_sharedmem_resources(const char* dirname) {
 
-  // open the user temp directory
-  DIR* dirp = os::opendir(dirname);
-
+  int saved_cwd_fd;
+  // Open the directory.
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   if (dirp == NULL) {
-    // directory doesn't exist, so there is nothing to cleanup
+     // Directory doesn't exist or is insecure, so there is nothing to cleanup.
     return;
   }
 
-  if (!is_directory_secure(dirname)) {
-    // the directory is not a secure directory
-    os::closedir(dirp);
-    return;
-  }
-
-  // for each entry in the directory that matches the expected file
+  // For each entry in the directory that matches the expected file
   // name pattern, determine if the file resources are stale and if
   // so, remove the file resources. Note, instrumented HotSpot processes
   // for this user may start and/or terminate during this search and
   // remove or create new files in this directory. The behavior of this
   // loop under these conditions is dependent upon the implementation of
   // opendir/readdir.
-  //
   struct dirent* entry;
   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -529,56 +766,55 @@
 
       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 
-        // attempt to remove all unexpected files, except "." and ".."
-        remove_file(dirname, entry->d_name);
+        // Attempt to remove all unexpected files, except "." and "..".
+        unlink(entry->d_name);
       }
 
       errno = 0;
       continue;
     }
 
-    // we now have a file name that converts to a valid integer
+    // We now have a file name that converts to a valid integer
     // that could represent a process id . if this process id
     // matches the current process id or the process is not running,
     // then remove the stale file resources.
     //
-    // process liveness is detected by sending signal number 0 to
+    // Process liveness is detected by sending signal number 0 to
     // the process id (see kill(2)). if kill determines that the
     // process does not exist, then the file resources are removed.
     // if kill determines that that we don't have permission to
     // signal the process, then the file resources are assumed to
     // be stale and are removed because the resources for such a
     // process should be in a different user specific directory.
-    //
     if ((pid == os::current_process_id()) ||
         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
     }
     errno = 0;
   }
-  os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf);
+
+  // Close the directory and reset the current working directory.
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
+
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 }
 
-// make the user specific temporary directory. Returns true if
+// Make the user specific temporary directory. Returns true if
 // the directory exists and is secure upon return. Returns false
 // if the directory exists but is either a symlink, is otherwise
 // insecure, or if an error occurred.
-//
 static bool make_user_tmp_dir(const char* dirname) {
 
-  // create the directory with 0755 permissions. note that the directory
+  // Create the directory with 0755 permissions. note that the directory
   // will be owned by euid::egid, which may not be the same as uid::gid.
-  //
   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
     if (errno == EEXIST) {
       // The directory already exists and was probably created by another
       // JVM instance. However, this could also be the result of a
       // deliberate symlink. Verify that the existing directory is safe.
-      //
       if (!is_directory_secure(dirname)) {
-        // directory is not secure
+        // Directory is not secure.
         if (PrintMiscellaneous && Verbose) {
           warning("%s directory is insecure\n", dirname);
         }
@@ -614,19 +850,63 @@
     return -1;
   }
 
+  int saved_cwd_fd;
+  // Open the directory and set the current working directory to it.
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so cannot create shared
+    // memory file.
+    return -1;
+  }
+
+  // Open the filename in the current directory.
+  // Cannot use O_TRUNC here; truncation of an existing file has to happen
+  // after the is_file_secure() check below.
   int result;
 
-  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open;
+  // so provide a workaround in this case.
+#ifdef O_NOFOLLOW
+  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
+#else
+  // workaround function (jdk6 code)
+  RESTARTABLE(::open_o_nofollow(filename, O_RDWR|O_CREAT, S_IREAD|S_IWRITE), result);
+#endif
+
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not create file %s: %s\n", filename, strerror(errno));
+      if (errno == ELOOP) {
+        warning("file %s is a symlink and is not secure\n", filename);
+      } else {
+        warning("could not create file %s: %s\n", filename, strerror(errno));
+      }
     }
+    // Close the directory and reset the current working directory.
+    close_directory_secure_cwd(dirp, saved_cwd_fd);
+
     return -1;
   }
+  // Close the directory and reset the current working directory.
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
 
   // save the file descriptor
   int fd = result;
 
+  // Check to see if the file is secure.
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  // Truncate the file to get rid of any existing data.
+  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not truncate shared memory file: %s\n", strerror(errno));
+    }
+    ::close(fd);
+    return -1;
+  }
   // set the file size
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
@@ -648,7 +928,14 @@
 
   // open the file
   int result;
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open;
+  // so provide a workaround in this case
+#ifdef O_NOFOLLOW
   RESTARTABLE(::open(filename, oflags), result);
+#else
+  RESTARTABLE(::open_o_nofollow(filename, oflags), result);
+#endif
+
   if (result == OS_ERR) {
     if (errno == ENOENT) {
       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
@@ -662,8 +949,15 @@
       THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
     }
   }
+  int fd = result;
 
-  return result;
+  // Check to see if the file is secure.
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  return fd;
 }
 
 // create a named shared memory region. returns the address of the
@@ -695,13 +989,21 @@
   char* dirname = get_user_tmp_dir(user_name);
   char* filename = get_sharedmem_filename(dirname, vmid);
 
+  // Get the short filename.
+  char* short_filename = strrchr(filename, '/');
+  if (short_filename == NULL) {
+    short_filename = filename;
+  } else {
+    short_filename++;
+  }
+
   // cleanup any stale shared memory files
   cleanup_sharedmem_resources(dirname);
 
   assert(((size > 0) && (size % os::vm_page_size() == 0)),
          "unexpected PerfMemory region size");
 
-  fd = create_sharedmem_resources(dirname, filename, size);
+  fd = create_sharedmem_resources(dirname, short_filename, size);
 
   FREE_C_HEAP_ARRAY(char, user_name);
   FREE_C_HEAP_ARRAY(char, dirname);
@@ -733,6 +1035,9 @@
   // clear the shared memory region
   (void)::memset((void*) mapAddress, 0, size);
 
+  // It does not go through os api, the operation has to record from here.
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
+
   return mapAddress;
 }
 
@@ -807,7 +1112,7 @@
   char* mapAddress;
   int result;
   int fd;
-  size_t size;
+  size_t size = 0;
   const char* luser = NULL;
 
   int mmap_prot;
@@ -819,12 +1124,18 @@
   // constructs for the file and the shared memory mapping.
   if (mode == PerfMemory::PERF_MODE_RO) {
     mmap_prot = PROT_READ;
+
+  // No O_NOFOLLOW defined at buildtime, and it is not documented for open.
+#ifdef O_NOFOLLOW
+    file_flags = O_RDONLY | O_NOFOLLOW;
+#else
     file_flags = O_RDONLY;
+#endif
   }
   else if (mode == PerfMemory::PERF_MODE_RW) {
 #ifdef LATER
     mmap_prot = PROT_READ | PROT_WRITE;
-    file_flags = O_RDWR;
+    file_flags = O_RDWR | O_NOFOLLOW;
 #else
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Unsupported access mode");
@@ -853,9 +1164,9 @@
   // store file, we don't follow them when attaching either.
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname);
+    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
     if (luser != user) {
-      FREE_C_HEAP_ARRAY(char, luser);
+      FREE_C_HEAP_ARRAY(char, luser, mtInternal);
     }
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
@@ -901,6 +1212,9 @@
               "Could not map PerfMemory");
   }
 
+  // It does not go through os api, the operation has to record from here.
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
+
   *addr = mapAddress;
   *sizep = size;
 
--- a/src/os/bsd/vm/os_bsd.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/bsd/vm/os_bsd.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -984,6 +984,14 @@
   return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
 }
 
+void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
+  timeval time;
+  int status = gettimeofday(&time, NULL);
+  assert(status != -1, "bsd error");
+  seconds = jlong(time.tv_sec);
+  nanos = jlong(time.tv_usec) * 1000;
+}
+
 #ifndef __APPLE__
   #ifndef CLOCK_MONOTONIC
     #define CLOCK_MONOTONIC (1)
--- a/src/os/bsd/vm/perfMemory_bsd.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/bsd/vm/perfMemory_bsd.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -197,7 +197,38 @@
 }
 
 
-// check if the given path is considered a secure directory for
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+//
+static bool is_statbuf_secure(struct stat *statp) {
+  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+    // The path represents a link or some non-directory file type,
+    // which is not what we expected. Declare it insecure.
+    //
+    return false;
+  }
+  // We have an existing directory, check if the permissions are safe.
+  //
+  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+    // The directory is open for writing and could be subjected
+    // to a symlink or a hard link attack. Declare it insecure.
+    //
+    return false;
+  }
+  // See if the uid of the directory matches the effective uid of the process.
+  //
+  if (statp->st_uid != geteuid()) {
+    // The directory was not created by this user, declare it insecure.
+    //
+    return false;
+  }
+  return true;
+}
+
+
+// Check if the given path is considered a secure directory for
 // the backing store files. Returns true if the directory exists
 // and is considered a secure location. Returns false if the path
 // is a symbolic link or if an error occurred.
@@ -211,27 +242,185 @@
     return false;
   }
 
-  // the path exists, now check it's mode
-  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
-    // the path represents a link or some non-directory file type,
-    // which is not what we expected. declare it insecure.
-    //
+  // The path exists, see if it is secure.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+//
+static bool is_dirfd_secure(int dir_fd) {
+  struct stat statbuf;
+  int result = 0;
+
+  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+  if (result == OS_ERR) {
     return false;
   }
-  else {
-    // we have an existing directory, check if the permissions are safe.
-    //
-    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
-      // the directory is open for writing and could be subjected
-      // to a symlnk attack. declare it insecure.
-      //
-      return false;
+
+  // The path exists, now check its mode.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+//
+static bool is_same_fsobject(int fd1, int fd2) {
+  struct stat statbuf1;
+  struct stat statbuf2;
+  int result = 0;
+
+  RESTARTABLE(::fstat(fd1, &statbuf1), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+  RESTARTABLE(::fstat(fd2, &statbuf2), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+
+  if ((statbuf1.st_ino == statbuf2.st_ino) &&
+      (statbuf1.st_dev == statbuf2.st_dev)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+//
+static DIR *open_directory_secure(const char* dirname) {
+  // Open the directory using open() so that it can be verified
+  // to be secure by calling is_dirfd_secure(), opendir() and then check
+  // to see if they are the same file system object.  This method does not
+  // introduce a window of opportunity for the directory to be attacked that
+  // calling opendir() and is_directory_secure() does.
+  int result;
+  DIR *dirp = NULL;
+  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+  if (result == OS_ERR) {
+    // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
+    if (PrintMiscellaneous && Verbose) {
+      if (errno == ELOOP) {
+        warning("directory %s is a symlink and is not secure\n", dirname);
+      } else {
+        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+      }
     }
+    return dirp;
+  }
+  int fd = result;
+
+  // Determine if the open directory is secure.
+  if (!is_dirfd_secure(fd)) {
+    // The directory is not a secure directory.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Open the directory.
+  dirp = ::opendir(dirname);
+  if (dirp == NULL) {
+    // The directory doesn't exist, close fd and return.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Check to make sure fd and dirp are referencing the same file system object.
+  if (!is_same_fsobject(fd, dirfd(dirp))) {
+    // The directory is not secure.
+    os::close(fd);
+    os::closedir(dirp);
+    dirp = NULL;
+    return dirp;
+  }
+
+  // Close initial open now that we know directory is secure
+  os::close(fd);
+
+  return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions.  Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+  // Open the directory.
+  DIR* dirp = open_directory_secure(dirname);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+    return dirp;
+  }
+  int fd = dirfd(dirp);
+
+  // Open a fd to the cwd and save it off.
+  int result;
+  RESTARTABLE(::open(".", O_RDONLY), result);
+  if (result == OS_ERR) {
+    *saved_cwd_fd = -1;
+  } else {
+    *saved_cwd_fd = result;
+  }
+
+  // Set the current directory to dirname by using the fd of the directory.
+  result = fchdir(fd);
+
+  return dirp;
+}
+
+// Close the directory and restore the current working directory.
+//
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+  int result;
+  // If we have a saved cwd change back to it and close the fd.
+  if (saved_cwd_fd != -1) {
+    result = fchdir(saved_cwd_fd);
+    ::close(saved_cwd_fd);
+  }
+
+  // Close the directory.
+  os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+//
+static bool is_file_secure(int fd, const char *filename) {
+
+  int result;
+  struct stat statbuf;
+
+  // Determine if the file is secure.
+  RESTARTABLE(::fstat(fd, &statbuf), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+    }
+    return false;
+  }
+  if (statbuf.st_nlink > 1) {
+    // A file with multiple links is not expected.
+    if (PrintMiscellaneous && Verbose) {
+      warning("file %s has multiple links\n", filename);
+    }
+    return false;
   }
   return true;
 }
 
-
 // return the user name for the given user id
 //
 // the caller is expected to free the allocated memory.
@@ -317,9 +506,11 @@
 
   const char* tmpdirname = os::get_temp_directory();
 
+  // open the temp directory
   DIR* tmpdirp = os::opendir(tmpdirname);
 
   if (tmpdirp == NULL) {
+    // Cannot open the directory to get the user name, return.
     return NULL;
   }
 
@@ -344,25 +535,14 @@
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
 
-    DIR* subdirp = os::opendir(usrdir_name);
+    // open the user directory
+    DIR* subdirp = open_directory_secure(usrdir_name);
 
     if (subdirp == NULL) {
       FREE_C_HEAP_ARRAY(char, usrdir_name);
       continue;
     }
 
-    // Since we don't create the backing store files in directories
-    // pointed to by symbolic links, we also don't follow them when
-    // looking for the files. We check for a symbolic link after the
-    // call to opendir in order to eliminate a small window where the
-    // symlink can be exploited.
-    //
-    if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
-      os::closedir(subdirp);
-      continue;
-    }
-
     struct dirent* udentry;
     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
     errno = 0;
@@ -465,26 +645,6 @@
 }
 
 
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
-  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
-  strcpy(path, dirname);
-  strcat(path, "/");
-  strcat(path, filename);
-
-  remove_file(path);
-
-  FREE_C_HEAP_ARRAY(char, path);
-}
-
-
 // cleanup stale shared memory resources
 //
 // This method attempts to remove all stale shared memory files in
@@ -496,17 +656,11 @@
 //
 static void cleanup_sharedmem_resources(const char* dirname) {
 
-  // open the user temp directory
-  DIR* dirp = os::opendir(dirname);
-
+  int saved_cwd_fd;
+  // open the directory and set the current working directory to it
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   if (dirp == NULL) {
-    // directory doesn't exist, so there is nothing to cleanup
-    return;
-  }
-
-  if (!is_directory_secure(dirname)) {
-    // the directory is not a secure directory
-    os::closedir(dirp);
+    // directory doesn't exist or is insecure, so there is nothing to cleanup
     return;
   }
 
@@ -520,6 +674,7 @@
   //
   struct dirent* entry;
   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -530,7 +685,7 @@
       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 
         // attempt to remove all unexpected files, except "." and ".."
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
       }
 
       errno = 0;
@@ -553,11 +708,14 @@
     if ((pid == os::current_process_id()) ||
         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
     }
     errno = 0;
   }
-  os::closedir(dirp);
+
+  // close the directory and reset the current working directory
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
+
   FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
@@ -614,19 +772,54 @@
     return -1;
   }
 
+  int saved_cwd_fd;
+  // open the directory and set the current working directory to it
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so cannot create shared
+    // memory file.
+    return -1;
+  }
+
+  // Open the filename in the current directory.
+  // Cannot use O_TRUNC here; truncation of an existing file has to happen
+  // after the is_file_secure() check below.
   int result;
-
-  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not create file %s: %s\n", filename, strerror(errno));
+      if (errno == ELOOP) {
+        warning("file %s is a symlink and is not secure\n", filename);
+      } else {
+        warning("could not create file %s: %s\n", filename, strerror(errno));
+      }
     }
+    // close the directory and reset the current working directory
+    close_directory_secure_cwd(dirp, saved_cwd_fd);
+
     return -1;
   }
+  // close the directory and reset the current working directory
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
 
   // save the file descriptor
   int fd = result;
 
+  // check to see if the file is secure
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  // truncate the file to get rid of any existing data
+  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not truncate shared memory file: %s\n", strerror(errno));
+    }
+    ::close(fd);
+    return -1;
+  }
   // set the file size
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
@@ -684,8 +877,15 @@
       THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
     }
   }
+  int fd = result;
 
-  return result;
+  // check to see if the file is secure
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  return fd;
 }
 
 // create a named shared memory region. returns the address of the
@@ -717,13 +917,21 @@
   char* dirname = get_user_tmp_dir(user_name);
   char* filename = get_sharedmem_filename(dirname, vmid);
 
+  // get the short filename
+  char* short_filename = strrchr(filename, '/');
+  if (short_filename == NULL) {
+    short_filename = filename;
+  } else {
+    short_filename++;
+  }
+
   // cleanup any stale shared memory files
   cleanup_sharedmem_resources(dirname);
 
   assert(((size > 0) && (size % os::vm_page_size() == 0)),
          "unexpected PerfMemory region size");
 
-  fd = create_sharedmem_resources(dirname, filename, size);
+  fd = create_sharedmem_resources(dirname, short_filename, size);
 
   FREE_C_HEAP_ARRAY(char, user_name);
   FREE_C_HEAP_ARRAY(char, dirname);
@@ -838,12 +1046,12 @@
   // constructs for the file and the shared memory mapping.
   if (mode == PerfMemory::PERF_MODE_RO) {
     mmap_prot = PROT_READ;
-    file_flags = O_RDONLY;
+    file_flags = O_RDONLY | O_NOFOLLOW;
   }
   else if (mode == PerfMemory::PERF_MODE_RW) {
 #ifdef LATER
     mmap_prot = PROT_READ | PROT_WRITE;
-    file_flags = O_RDWR;
+    file_flags = O_RDWR | O_NOFOLLOW;
 #else
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Unsupported access mode");
--- a/src/os/linux/vm/os_linux.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/linux/vm/os_linux.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -1322,6 +1322,15 @@
   return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
 }
 
+void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
+  timeval time;
+  int status = gettimeofday(&time, NULL);
+  assert(status != -1, "linux error");
+  seconds = jlong(time.tv_sec);
+  nanos = jlong(time.tv_usec) * 1000;
+}
+
+
 #ifndef CLOCK_MONOTONIC
   #define CLOCK_MONOTONIC (1)
 #endif
--- a/src/os/linux/vm/perfMemory_linux.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/linux/vm/perfMemory_linux.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -197,7 +197,38 @@
 }
 
 
-// check if the given path is considered a secure directory for
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+//
+static bool is_statbuf_secure(struct stat *statp) {
+  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+    // The path represents a link or some non-directory file type,
+    // which is not what we expected. Declare it insecure.
+    //
+    return false;
+  }
+  // We have an existing directory, check if the permissions are safe.
+  //
+  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+    // The directory is open for writing and could be subjected
+    // to a symlink or a hard link attack. Declare it insecure.
+    //
+    return false;
+  }
+  // See if the uid of the directory matches the effective uid of the process.
+  //
+  if (statp->st_uid != geteuid()) {
+    // The directory was not created by this user, declare it insecure.
+    //
+    return false;
+  }
+  return true;
+}
+
+
+// Check if the given path is considered a secure directory for
 // the backing store files. Returns true if the directory exists
 // and is considered a secure location. Returns false if the path
 // is a symbolic link or if an error occurred.
@@ -211,22 +242,180 @@
     return false;
   }
 
-  // the path exists, now check it's mode
-  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
-    // the path represents a link or some non-directory file type,
-    // which is not what we expected. declare it insecure.
-    //
+  // The path exists, see if it is secure.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+//
+static bool is_dirfd_secure(int dir_fd) {
+  struct stat statbuf;
+  int result = 0;
+
+  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+  if (result == OS_ERR) {
     return false;
   }
-  else {
-    // we have an existing directory, check if the permissions are safe.
-    //
-    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
-      // the directory is open for writing and could be subjected
-      // to a symlnk attack. declare it insecure.
-      //
-      return false;
+
+  // The path exists, now check its mode.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+//
+static bool is_same_fsobject(int fd1, int fd2) {
+  struct stat statbuf1;
+  struct stat statbuf2;
+  int result = 0;
+
+  RESTARTABLE(::fstat(fd1, &statbuf1), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+  RESTARTABLE(::fstat(fd2, &statbuf2), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+
+  if ((statbuf1.st_ino == statbuf2.st_ino) &&
+      (statbuf1.st_dev == statbuf2.st_dev)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+//
+static DIR *open_directory_secure(const char* dirname) {
+  // Open the directory using open() so that it can be verified
+  // to be secure by calling is_dirfd_secure(), opendir() and then check
+  // to see if they are the same file system object.  This method does not
+  // introduce a window of opportunity for the directory to be attacked that
+  // calling opendir() and is_directory_secure() does.
+  int result;
+  DIR *dirp = NULL;
+  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      if (errno == ELOOP) {
+        warning("directory %s is a symlink and is not secure\n", dirname);
+      } else {
+        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+      }
     }
+    return dirp;
+  }
+  int fd = result;
+
+  // Determine if the open directory is secure.
+  if (!is_dirfd_secure(fd)) {
+    // The directory is not a secure directory.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Open the directory.
+  dirp = ::opendir(dirname);
+  if (dirp == NULL) {
+    // The directory doesn't exist, close fd and return.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Check to make sure fd and dirp are referencing the same file system object.
+  if (!is_same_fsobject(fd, dirfd(dirp))) {
+    // The directory is not secure.
+    os::close(fd);
+    os::closedir(dirp);
+    dirp = NULL;
+    return dirp;
+  }
+
+  // Close initial open now that we know directory is secure
+  os::close(fd);
+
+  return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions.  Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+  // Open the directory.
+  DIR* dirp = open_directory_secure(dirname);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+    return dirp;
+  }
+  int fd = dirfd(dirp);
+
+  // Open a fd to the cwd and save it off.
+  int result;
+  RESTARTABLE(::open(".", O_RDONLY), result);
+  if (result == OS_ERR) {
+    *saved_cwd_fd = -1;
+  } else {
+    *saved_cwd_fd = result;
+  }
+
+  // Set the current directory to dirname by using the fd of the directory.
+  result = fchdir(fd);
+
+  return dirp;
+}
+
+// Close the directory and restore the current working directory.
+//
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+  int result;
+  // If we have a saved cwd change back to it and close the fd.
+  if (saved_cwd_fd != -1) {
+    result = fchdir(saved_cwd_fd);
+    ::close(saved_cwd_fd);
+  }
+
+  // Close the directory.
+  os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+//
+static bool is_file_secure(int fd, const char *filename) {
+
+  int result;
+  struct stat statbuf;
+
+  // Determine if the file is secure.
+  RESTARTABLE(::fstat(fd, &statbuf), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+    }
+    return false;
+  }
+  if (statbuf.st_nlink > 1) {
+    // A file with multiple links is not expected.
+    if (PrintMiscellaneous && Verbose) {
+      warning("file %s has multiple links\n", filename);
+    }
+    return false;
   }
   return true;
 }
@@ -317,9 +506,11 @@
 
   const char* tmpdirname = os::get_temp_directory();
 
+  // open the temp directory
   DIR* tmpdirp = os::opendir(tmpdirname);
 
   if (tmpdirp == NULL) {
+    // Cannot open the directory to get the user name, return.
     return NULL;
   }
 
@@ -344,7 +535,8 @@
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
 
-    DIR* subdirp = os::opendir(usrdir_name);
+    // open the user directory
+    DIR* subdirp = open_directory_secure(usrdir_name);
 
     if (subdirp == NULL) {
       FREE_C_HEAP_ARRAY(char, usrdir_name);
@@ -465,26 +657,6 @@
 }
 
 
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
-  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
-  strcpy(path, dirname);
-  strcat(path, "/");
-  strcat(path, filename);
-
-  remove_file(path);
-
-  FREE_C_HEAP_ARRAY(char, path);
-}
-
-
 // cleanup stale shared memory resources
 //
 // This method attempts to remove all stale shared memory files in
@@ -496,17 +668,11 @@
 //
 static void cleanup_sharedmem_resources(const char* dirname) {
 
-  // open the user temp directory
-  DIR* dirp = os::opendir(dirname);
-
+  int saved_cwd_fd;
+  // open the directory
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   if (dirp == NULL) {
-    // directory doesn't exist, so there is nothing to cleanup
-    return;
-  }
-
-  if (!is_directory_secure(dirname)) {
-    // the directory is not a secure directory
-    os::closedir(dirp);
+    // directory doesn't exist or is insecure, so there is nothing to cleanup
     return;
   }
 
@@ -520,6 +686,7 @@
   //
   struct dirent* entry;
   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -528,9 +695,8 @@
     if (pid == 0) {
 
       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
-
         // attempt to remove all unexpected files, except "." and ".."
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
       }
 
       errno = 0;
@@ -552,12 +718,14 @@
     //
     if ((pid == os::current_process_id()) ||
         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
-
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
     }
     errno = 0;
   }
-  os::closedir(dirp);
+
+  // close the directory and reset the current working directory
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
+
   FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
@@ -614,19 +782,54 @@
     return -1;
   }
 
+  int saved_cwd_fd;
+  // open the directory and set the current working directory to it
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so cannot create shared
+    // memory file.
+    return -1;
+  }
+
+  // Open the filename in the current directory.
+  // Cannot use O_TRUNC here; truncation of an existing file has to happen
+  // after the is_file_secure() check below.
   int result;
-
-  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not create file %s: %s\n", filename, strerror(errno));
+      if (errno == ELOOP) {
+        warning("file %s is a symlink and is not secure\n", filename);
+      } else {
+        warning("could not create file %s: %s\n", filename, strerror(errno));
+      }
     }
+    // close the directory and reset the current working directory
+    close_directory_secure_cwd(dirp, saved_cwd_fd);
+
     return -1;
   }
+  // close the directory and reset the current working directory
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
 
   // save the file descriptor
   int fd = result;
 
+  // check to see if the file is secure
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  // truncate the file to get rid of any existing data
+  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not truncate shared memory file: %s\n", strerror(errno));
+    }
+    ::close(fd);
+    return -1;
+  }
   // set the file size
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
@@ -684,8 +887,15 @@
       THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
     }
   }
+  int fd = result;
 
-  return result;
+  // check to see if the file is secure
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  return fd;
 }
 
 // create a named shared memory region. returns the address of the
@@ -716,6 +926,13 @@
 
   char* dirname = get_user_tmp_dir(user_name);
   char* filename = get_sharedmem_filename(dirname, vmid);
+  // get the short filename
+  char* short_filename = strrchr(filename, '/');
+  if (short_filename == NULL) {
+    short_filename = filename;
+  } else {
+    short_filename++;
+  }
 
   // cleanup any stale shared memory files
   cleanup_sharedmem_resources(dirname);
@@ -723,7 +940,7 @@
   assert(((size > 0) && (size % os::vm_page_size() == 0)),
          "unexpected PerfMemory region size");
 
-  fd = create_sharedmem_resources(dirname, filename, size);
+  fd = create_sharedmem_resources(dirname, short_filename, size);
 
   FREE_C_HEAP_ARRAY(char, user_name);
   FREE_C_HEAP_ARRAY(char, dirname);
@@ -838,12 +1055,12 @@
   // constructs for the file and the shared memory mapping.
   if (mode == PerfMemory::PERF_MODE_RO) {
     mmap_prot = PROT_READ;
-    file_flags = O_RDONLY;
+    file_flags = O_RDONLY | O_NOFOLLOW;
   }
   else if (mode == PerfMemory::PERF_MODE_RW) {
 #ifdef LATER
     mmap_prot = PROT_READ | PROT_WRITE;
-    file_flags = O_RDWR;
+    file_flags = O_RDWR | O_NOFOLLOW;
 #else
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Unsupported access mode");
--- a/src/os/solaris/vm/os_solaris.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/solaris/vm/os_solaris.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -1475,6 +1475,16 @@
   return jlong(t.tv_sec) * 1000  +  jlong(t.tv_usec) / 1000;
 }
 
+void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
+  timeval t;
+  if (gettimeofday(&t, NULL) == -1) {
+    fatal(err_msg("os::javaTimeSystemUTC: gettimeofday (%s)", strerror(errno)));
+  }
+  seconds = jlong(t.tv_sec);
+  nanos = jlong(t.tv_usec) * 1000;
+}
+
+
 jlong os::javaTimeNanos() {
   return (jlong)getTimeNanos();
 }
--- a/src/os/solaris/vm/perfMemory_solaris.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/solaris/vm/perfMemory_solaris.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -199,7 +199,38 @@
 }
 
 
-// check if the given path is considered a secure directory for
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+//
+static bool is_statbuf_secure(struct stat *statp) {
+  if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+    // The path represents a link or some non-directory file type,
+    // which is not what we expected. Declare it insecure.
+    //
+    return false;
+  }
+  // We have an existing directory, check if the permissions are safe.
+  //
+  if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+    // The directory is open for writing and could be subjected
+    // to a symlink or a hard link attack. Declare it insecure.
+    //
+    return false;
+  }
+  // See if the uid of the directory matches the effective uid of the process.
+  //
+  if (statp->st_uid != geteuid()) {
+    // The directory was not created by this user, declare it insecure.
+    //
+    return false;
+  }
+  return true;
+}
+
+
+// Check if the given path is considered a secure directory for
 // the backing store files. Returns true if the directory exists
 // and is considered a secure location. Returns false if the path
 // is a symbolic link or if an error occurred.
@@ -213,27 +244,185 @@
     return false;
   }
 
-  // the path exists, now check it's mode
-  if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
-    // the path represents a link or some non-directory file type,
-    // which is not what we expected. declare it insecure.
-    //
+  // The path exists, see if it is secure.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+//
+static bool is_dirfd_secure(int dir_fd) {
+  struct stat statbuf;
+  int result = 0;
+
+  RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+  if (result == OS_ERR) {
     return false;
   }
-  else {
-    // we have an existing directory, check if the permissions are safe.
-    //
-    if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
-      // the directory is open for writing and could be subjected
-      // to a symlnk attack. declare it insecure.
-      //
-      return false;
+
+  // The path exists, now check its mode.
+  return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+//
+static bool is_same_fsobject(int fd1, int fd2) {
+  struct stat statbuf1;
+  struct stat statbuf2;
+  int result = 0;
+
+  RESTARTABLE(::fstat(fd1, &statbuf1), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+  RESTARTABLE(::fstat(fd2, &statbuf2), result);
+  if (result == OS_ERR) {
+    return false;
+  }
+
+  if ((statbuf1.st_ino == statbuf2.st_ino) &&
+      (statbuf1.st_dev == statbuf2.st_dev)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+//
+static DIR *open_directory_secure(const char* dirname) {
+  // Open the directory using open() so that it can be verified
+  // to be secure by calling is_dirfd_secure(), opendir() and then check
+  // to see if they are the same file system object.  This method does not
+  // introduce a window of opportunity for the directory to be attacked that
+  // calling opendir() and is_directory_secure() does.
+  int result;
+  DIR *dirp = NULL;
+  RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+  if (result == OS_ERR) {
+    // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
+    if (PrintMiscellaneous && Verbose) {
+      if (errno == ELOOP) {
+        warning("directory %s is a symlink and is not secure\n", dirname);
+      } else {
+        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+      }
     }
+    return dirp;
+  }
+  int fd = result;
+
+  // Determine if the open directory is secure.
+  if (!is_dirfd_secure(fd)) {
+    // The directory is not a secure directory.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Open the directory.
+  dirp = ::opendir(dirname);
+  if (dirp == NULL) {
+    // The directory doesn't exist, close fd and return.
+    os::close(fd);
+    return dirp;
+  }
+
+  // Check to make sure fd and dirp are referencing the same file system object.
+  if (!is_same_fsobject(fd, dirp->dd_fd)) {
+    // The directory is not secure.
+    os::close(fd);
+    os::closedir(dirp);
+    dirp = NULL;
+    return dirp;
+  }
+
+  // Close initial open now that we know directory is secure
+  os::close(fd);
+
+  return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions.  Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+  // Open the directory.
+  DIR* dirp = open_directory_secure(dirname);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+    return dirp;
+  }
+  int fd = dirp->dd_fd;
+
+  // Open a fd to the cwd and save it off.
+  int result;
+  RESTARTABLE(::open(".", O_RDONLY), result);
+  if (result == OS_ERR) {
+    *saved_cwd_fd = -1;
+  } else {
+    *saved_cwd_fd = result;
+  }
+
+  // Set the current directory to dirname by using the fd of the directory.
+  result = fchdir(fd);
+
+  return dirp;
+}
+
+// Close the directory and restore the current working directory.
+//
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+  int result;
+  // If we have a saved cwd change back to it and close the fd.
+  if (saved_cwd_fd != -1) {
+    result = fchdir(saved_cwd_fd);
+    ::close(saved_cwd_fd);
+  }
+
+  // Close the directory.
+  os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+//
+static bool is_file_secure(int fd, const char *filename) {
+
+  int result;
+  struct stat statbuf;
+
+  // Determine if the file is secure.
+  RESTARTABLE(::fstat(fd, &statbuf), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+    }
+    return false;
+  }
+  if (statbuf.st_nlink > 1) {
+    // A file with multiple links is not expected.
+    if (PrintMiscellaneous && Verbose) {
+      warning("file %s has multiple links\n", filename);
+    }
+    return false;
   }
   return true;
 }
 
-
 // return the user name for the given user id
 //
 // the caller is expected to free the allocated memory.
@@ -308,9 +497,11 @@
 
   const char* tmpdirname = os::get_temp_directory();
 
+  // open the temp directory
   DIR* tmpdirp = os::opendir(tmpdirname);
 
   if (tmpdirp == NULL) {
+    // Cannot open the directory to get the user name, return.
     return NULL;
   }
 
@@ -335,7 +526,8 @@
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
 
-    DIR* subdirp = os::opendir(usrdir_name);
+    // open the user directory
+    DIR* subdirp = open_directory_secure(usrdir_name);
 
     if (subdirp == NULL) {
       FREE_C_HEAP_ARRAY(char, usrdir_name);
@@ -504,26 +696,6 @@
 }
 
 
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
-  size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
-  strcpy(path, dirname);
-  strcat(path, "/");
-  strcat(path, filename);
-
-  remove_file(path);
-
-  FREE_C_HEAP_ARRAY(char, path);
-}
-
-
 // cleanup stale shared memory resources
 //
 // This method attempts to remove all stale shared memory files in
@@ -535,17 +707,11 @@
 //
 static void cleanup_sharedmem_resources(const char* dirname) {
 
-  // open the user temp directory
-  DIR* dirp = os::opendir(dirname);
-
+  int saved_cwd_fd;
+  // open the directory
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
   if (dirp == NULL) {
-    // directory doesn't exist, so there is nothing to cleanup
-    return;
-  }
-
-  if (!is_directory_secure(dirname)) {
-    // the directory is not a secure directory
-    os::closedir(dirp);
+    // directory doesn't exist or is insecure, so there is nothing to cleanup
     return;
   }
 
@@ -559,6 +725,7 @@
   //
   struct dirent* entry;
   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -569,7 +736,7 @@
       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 
         // attempt to remove all unexpected files, except "." and ".."
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
       }
 
       errno = 0;
@@ -592,11 +759,14 @@
     if ((pid == os::current_process_id()) ||
         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 
-        remove_file(dirname, entry->d_name);
+        unlink(entry->d_name);
     }
     errno = 0;
   }
-  os::closedir(dirp);
+
+  // close the directory and reset the current working directory
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
+
   FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
@@ -653,19 +823,54 @@
     return -1;
   }
 
+  int saved_cwd_fd;
+  // open the directory and set the current working directory to it
+  DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+  if (dirp == NULL) {
+    // Directory doesn't exist or is insecure, so cannot create shared
+    // memory file.
+    return -1;
+  }
+
+  // Open the filename in the current directory.
+  // Cannot use O_TRUNC here; truncation of an existing file has to happen
+  // after the is_file_secure() check below.
   int result;
-
-  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+  RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not create file %s: %s\n", filename, strerror(errno));
+      if (errno == ELOOP) {
+        warning("file %s is a symlink and is not secure\n", filename);
+      } else {
+        warning("could not create file %s: %s\n", filename, strerror(errno));
+      }
     }
+    // close the directory and reset the current working directory
+    close_directory_secure_cwd(dirp, saved_cwd_fd);
+
     return -1;
   }
+  // close the directory and reset the current working directory
+  close_directory_secure_cwd(dirp, saved_cwd_fd);
 
   // save the file descriptor
   int fd = result;
 
+  // check to see if the file is secure
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  // truncate the file to get rid of any existing data
+  RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not truncate shared memory file: %s\n", strerror(errno));
+    }
+    ::close(fd);
+    return -1;
+  }
   // set the file size
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
@@ -701,8 +906,15 @@
       THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
     }
   }
+  int fd = result;
 
-  return result;
+  // check to see if the file is secure
+  if (!is_file_secure(fd, filename)) {
+    ::close(fd);
+    return -1;
+  }
+
+  return fd;
 }
 
 // create a named shared memory region. returns the address of the
@@ -734,13 +946,21 @@
   char* dirname = get_user_tmp_dir(user_name);
   char* filename = get_sharedmem_filename(dirname, vmid);
 
+  // get the short filename
+  char* short_filename = strrchr(filename, '/');
+  if (short_filename == NULL) {
+    short_filename = filename;
+  } else {
+    short_filename++;
+  }
+
   // cleanup any stale shared memory files
   cleanup_sharedmem_resources(dirname);
 
   assert(((size > 0) && (size % os::vm_page_size() == 0)),
          "unexpected PerfMemory region size");
 
-  fd = create_sharedmem_resources(dirname, filename, size);
+  fd = create_sharedmem_resources(dirname, short_filename, size);
 
   FREE_C_HEAP_ARRAY(char, user_name);
   FREE_C_HEAP_ARRAY(char, dirname);
@@ -856,12 +1076,12 @@
   // constructs for the file and the shared memory mapping.
   if (mode == PerfMemory::PERF_MODE_RO) {
     mmap_prot = PROT_READ;
-    file_flags = O_RDONLY;
+    file_flags = O_RDONLY | O_NOFOLLOW;
   }
   else if (mode == PerfMemory::PERF_MODE_RW) {
 #ifdef LATER
     mmap_prot = PROT_READ | PROT_WRITE;
-    file_flags = O_RDWR;
+    file_flags = O_RDWR | O_NOFOLLOW;
 #else
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Unsupported access mode");
--- a/src/os/windows/vm/os_windows.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os/windows/vm/os_windows.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -428,9 +428,9 @@
   }
 
   // Diagnostic code to investigate JDK-6573254
-  int res = 50115;  // non-java thread
+  int res = 30115;  // non-java thread
   if (thread->is_Java_thread()) {
-    res = 40115;    // java thread
+    res = 20115;    // java thread
   }
 
   // Install a win32 structured exception handler around every thread created
@@ -839,6 +839,12 @@
   return (a - offset()) / 10000;
 }
 
+// Returns time ticks in (10th of micro seconds)
+jlong windows_to_time_ticks(FILETIME wt) {
+  jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
+  return (a - offset());
+}
+
 FILETIME java_to_windows_time(jlong l) {
   jlong a = (l * 10000) + offset();
   FILETIME result;
@@ -874,6 +880,15 @@
   }
 }
 
+void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
+  FILETIME wt;
+  GetSystemTimeAsFileTime(&wt);
+  jlong ticks = windows_to_time_ticks(wt); // 10th of micros
+  jlong secs = jlong(ticks / 10000000); // 10000 * 1000
+  seconds = secs;
+  nanos = jlong(ticks - (secs*10000000)) * 100;
+}
+
 jlong os::javaTimeNanos() {
   if (!win32::_has_performance_count) {
     return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
@@ -1693,7 +1708,7 @@
     }
     break;
 
-  case 6004:
+  case 10000:
     if (is_workstation) {
       st->print("10");
     } else {
@@ -3791,6 +3806,7 @@
 
     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
     static CRITICAL_SECTION crit_sect;
+    static volatile jint process_exiting = 0;
     int i, j;
     DWORD res;
     HANDLE hproc, hthr;
@@ -3798,10 +3814,10 @@
     // The first thread that reached this point, initializes the critical section.
     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
-    } else {
+    } else if (OrderAccess::load_acquire(&process_exiting) == 0) {
       EnterCriticalSection(&crit_sect);
 
-      if (what == EPT_THREAD) {
+      if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
         // Remove from the array those handles of the threads that have completed exiting.
         for (i = 0, j = 0; i < handle_count; ++i) {
           res = WaitForSingleObject(handles[i], 0 /* don't wait */);
@@ -3856,7 +3872,7 @@
         // The current exiting thread has stored its handle in the array, and now
         // should leave the critical section before calling _endthreadex().
 
-      } else { // what != EPT_THREAD
+      } else if (what != EPT_THREAD) {
         if (handle_count > 0) {
           // Before ending the process, make sure all the threads that had called
           // _endthreadex() completed.
@@ -3882,24 +3898,28 @@
           handle_count = 0;
         }
 
-        // End the process, not leaving critical section.
-        // This makes sure no other thread executes exit-related code at the same
-        // time, thus a race is avoided.
-        if (what == EPT_PROCESS) {
-          ::exit(exit_code);
-        } else {
-          _exit(exit_code);
-        }
+        OrderAccess::release_store(&process_exiting, 1);
       }
 
       LeaveCriticalSection(&crit_sect);
     }
+
+    if (what == EPT_THREAD) {
+      while (OrderAccess::load_acquire(&process_exiting) != 0) {
+        // Some other thread is about to call exit(), so we
+        // don't let the current thread proceed to _endthreadex()
+        SuspendThread(GetCurrentThread());
+        // Avoid busy-wait loop, if SuspendThread() failed.
+        Sleep(EXIT_TIMEOUT);
+      }
+    }
   }
 
   // We are here if either
   // - there's no 'race at exit' bug on this OS release;
   // - initialization of the critical section failed (unlikely);
-  // - the current thread has stored its handle and left the critical section.
+  // - the current thread has stored its handle and left the critical section;
+  // - the process-exiting thread has raised the flag and left the critical section.
   if (what == EPT_THREAD) {
     _endthreadex((unsigned)exit_code);
   } else if (what == EPT_PROCESS) {
--- a/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2011 Red Hat, Inc.
+ * Copyright 2007, 2008, 2011, 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
@@ -237,7 +237,13 @@
   // operation.  Note that some platforms only support this with the
   // limitation that the only valid value to store is the immediate
   // constant 1.  There is a test for this in JNI_CreateJavaVM().
-  return __sync_lock_test_and_set (dest, exchange_value);
+  jint result = __sync_lock_test_and_set (dest, exchange_value);
+  // All atomic operations are expected to be full memory barriers
+  // (see atomic.hpp). However, __sync_lock_test_and_set is not
+  // a full memory barrier, but an acquire barrier. Hence, this added
+  // barrier.
+  __sync_synchronize();
+  return result;
 #endif // M68K
 #endif // ARM
 }
@@ -250,7 +256,9 @@
 #ifdef M68K
   return m68k_lock_test_and_set(dest, exchange_value);
 #else
-  return __sync_lock_test_and_set (dest, exchange_value);
+  intptr_t result = __sync_lock_test_and_set (dest, exchange_value);
+  __sync_synchronize();
+  return result;
 #endif // M68K
 #endif // ARM
 }
--- a/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2011 Red Hat, Inc.
+ * Copyright 2007, 2008, 2011, 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
@@ -231,7 +231,13 @@
   // operation.  Note that some platforms only support this with the
   // limitation that the only valid value to store is the immediate
   // constant 1.  There is a test for this in JNI_CreateJavaVM().
-  return __sync_lock_test_and_set (dest, exchange_value);
+  jint result = __sync_lock_test_and_set (dest, exchange_value);
+  // All atomic operations are expected to be full memory barriers
+  // (see atomic.hpp). However, __sync_lock_test_and_set is not
+  // a full memory barrier, but an acquire barrier. Hence, this added
+  // barrier.
+  __sync_synchronize();
+  return result;
 #endif // M68K
 #endif // ARM
 }
@@ -244,7 +250,9 @@
 #ifdef M68K
   return m68k_lock_test_and_set(dest, exchange_value);
 #else
-  return __sync_lock_test_and_set (dest, exchange_value);
+  intptr_t result = __sync_lock_test_and_set (dest, exchange_value);
+  __sync_synchronize();
+  return result;
 #endif // M68K
 #endif // ARM
 }
--- a/src/share/vm/c1/c1_CodeStubs.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/c1/c1_CodeStubs.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -601,15 +601,6 @@
   LIR_Opr _addr;
   LIR_Opr _new_val;
 
-  static jbyte* _byte_map_base;
-  static jbyte* byte_map_base_slow();
-  static jbyte* byte_map_base() {
-    if (_byte_map_base == NULL) {
-      _byte_map_base = byte_map_base_slow();
-    }
-    return _byte_map_base;
-  }
-
  public:
   // addr (the address of the object head) and new_val must be registers.
   G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { }
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -32,6 +32,7 @@
 #include "ci/ciArrayKlass.hpp"
 #include "ci/ciInstance.hpp"
 #include "ci/ciObjArray.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/vm_version.hpp"
@@ -3351,7 +3352,12 @@
   if (!x->inlinee()->is_accessor()) {
     CodeEmitInfo* info = state_for(x, x->state(), true);
     // Notify the runtime very infrequently only to take care of counter overflows
-    increment_event_counter_impl(info, x->inlinee(), (1 << Tier23InlineeNotifyFreqLog) - 1, InvocationEntryBci, false, true);
+    int freq_log = Tier23InlineeNotifyFreqLog;
+    double scale;
+    if (_method->has_option_value("CompileThresholdScaling", scale)) {
+      freq_log = Arguments::scaled_freq_log(freq_log, scale);
+    }
+    increment_event_counter_impl(info, x->inlinee(), right_n_bits(freq_log), InvocationEntryBci, false, true);
   }
 }
 
@@ -3366,7 +3372,11 @@
     ShouldNotReachHere();
   }
   // Increment the appropriate invocation/backedge counter and notify the runtime.
-  increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true);
+  double scale;
+  if (_method->has_option_value("CompileThresholdScaling", scale)) {
+    freq_log = Arguments::scaled_freq_log(freq_log, scale);
+  }
+  increment_event_counter_impl(info, info->scope()->method(), right_n_bits(freq_log), bci, backedge, true);
 }
 
 void LIRGenerator::decrement_age(CodeEmitInfo* info) {
--- a/src/share/vm/ci/bcEscapeAnalyzer.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -89,8 +89,8 @@
 public:
   ArgumentMap *_vars;
   ArgumentMap *_stack;
-  short _stack_height;
-  short _max_stack;
+  int _stack_height;
+  int _max_stack;
   bool _initialized;
   ArgumentMap empty_map;
 
--- a/src/share/vm/ci/ciMethod.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/ci/ciMethod.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -70,7 +70,8 @@
 // Loaded method.
 ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) :
   ciMetadata(h_m()),
-  _holder(holder)
+  _holder(holder),
+  _has_injected_profile(false)
 {
   assert(h_m() != NULL, "no null method");
 
@@ -168,7 +169,8 @@
   _liveness(               NULL),
   _can_be_statically_bound(false),
   _method_blocks(          NULL),
-  _method_data(            NULL)
+  _method_data(            NULL),
+  _has_injected_profile(   false)
 #if defined(COMPILER2) || defined(SHARK)
   ,
   _flow(                   NULL),
--- a/src/share/vm/ci/ciMethod.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/ci/ciMethod.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -79,6 +79,7 @@
   bool _is_c1_compilable;
   bool _is_c2_compilable;
   bool _can_be_statically_bound;
+  bool _has_injected_profile;
 
   // Lazy fields, filled in on demand
   address              _code;
@@ -286,6 +287,9 @@
   int instructions_size();
   int scale_count(int count, float prof_factor = 1.);  // make MDO count commensurate with IIC
 
+  bool has_injected_profile() const { return _has_injected_profile;     }
+  void set_injected_profile(bool x) {        _has_injected_profile = x; }
+
   // Stack walking support
   bool is_ignored_by_security_stack_walk() const;
 
--- a/src/share/vm/classfile/classLoaderData.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/classLoaderData.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -786,17 +786,12 @@
   MetadataOnStackMark md_on_stack(has_redefined_a_class);
 
   if (has_redefined_a_class) {
-    // purge_previous_versions also cleans weak method links. Because
-    // one method's MDO can reference another method from another
-    // class loader, we need to first clean weak method links for all
-    // class loaders here. Below, we can then free redefined methods
-    // for all class loaders.
     for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
       data->classes_do(InstanceKlass::purge_previous_versions);
     }
   }
 
-  // Need to purge the previous version before deallocating.
+  // Should purge the previous version before deallocating.
   free_deallocate_lists();
 }
 
@@ -834,8 +829,6 @@
 
 void ClassLoaderDataGraph::free_deallocate_lists() {
   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
-    // We need to keep this data until InstanceKlass::purge_previous_version has been
-    // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces.
     cld->free_deallocate_list();
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/classfile/compactHashtable.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,441 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 "classfile/javaClasses.hpp"
+#include "memory/metaspaceShared.hpp"
+#include "utilities/numberSeq.hpp"
+#include <sys/stat.h>
+
+/////////////////////////////////////////////////////
+//
+// The compact hash table writer implementations
+//
+CompactHashtableWriter::CompactHashtableWriter(const char* table_name,
+                                               int num_entries,
+                                               CompactHashtableStats* stats) {
+  assert(DumpSharedSpaces, "dump-time only");
+  _table_name = table_name;
+  _num_entries = num_entries;
+  _num_buckets = number_of_buckets(_num_entries);
+  _buckets = NEW_C_HEAP_ARRAY(Entry*, _num_buckets, mtSymbol);
+  memset(_buckets, 0, sizeof(Entry*) * _num_buckets);
+
+  /* bucket sizes table */
+  _bucket_sizes = NEW_C_HEAP_ARRAY(juint, _num_buckets, mtSymbol);
+  memset(_bucket_sizes, 0, sizeof(juint) * _num_buckets);
+
+  stats->hashentry_count = _num_entries;
+  // Compact buckets' entries will have only the 4-byte offset, but
+  // we don't know how many there will be at this point. So use a
+  // conservative estimate here. The size is adjusted later when we
+  // write out the buckets.
+  stats->hashentry_bytes = _num_entries * 8;
+  stats->bucket_count    = _num_buckets;
+  stats->bucket_bytes    = (_num_buckets + 1) * (sizeof(juint));
+  _stats = stats;
+
+  // See compactHashtable.hpp for table layout
+  _required_bytes = sizeof(juint) * 2; // _base_address, written as 2 juints
+  _required_bytes+= sizeof(juint) +    // num_entries
+                    sizeof(juint) +    // num_buckets
+                    stats->hashentry_bytes +
+                    stats->bucket_bytes;
+}
+
+CompactHashtableWriter::~CompactHashtableWriter() {
+  for (int index = 0; index < _num_buckets; index++) {
+    Entry* next = NULL;
+    for (Entry* tent = _buckets[index]; tent; tent = next) {
+      next = tent->next();
+      delete tent;
+    }
+  }
+
+  FREE_C_HEAP_ARRAY(juint, _bucket_sizes);
+  FREE_C_HEAP_ARRAY(Entry*, _buckets);
+}
+
+// Calculate the number of buckets in the temporary hash table
+int CompactHashtableWriter::number_of_buckets(int num_entries) {
+  const int buksize = (int)SharedSymbolTableBucketSize;
+  int num_buckets = (num_entries + buksize - 1) / buksize;
+  num_buckets = (num_buckets + 1) & (~0x01);
+
+  return num_buckets;
+}
+
+// Add a symbol entry to the temporary hash table
+void CompactHashtableWriter::add(unsigned int hash, Entry* entry) {
+  int index = hash % _num_buckets;
+  entry->set_next(_buckets[index]);
+  _buckets[index] = entry;
+  _bucket_sizes[index] ++;
+}
+
+// Write the compact table's bucket infos
+juint* CompactHashtableWriter::dump_table(juint* p, juint** first_bucket,
+                                          NumberSeq* summary) {
+  int index;
+  juint* compact_table = p;
+  // Find the start of the buckets, skip the compact_bucket_infos table
+  // and the table end offset.
+  juint offset = _num_buckets + 1;
+  *first_bucket = compact_table + offset;
+
+  for (index = 0; index < _num_buckets; index++) {
+    int bucket_size = _bucket_sizes[index];
+    if (bucket_size == 1) {
+      // bucket with one entry is compacted and only has the symbol offset
+      compact_table[index] = BUCKET_INFO(offset, COMPACT_BUCKET_TYPE);
+      offset += bucket_size; // each entry contains symbol offset only
+    } else {
+      // regular bucket, each entry is a symbol (hash, offset) pair
+      compact_table[index] = BUCKET_INFO(offset, REGULAR_BUCKET_TYPE);
+      offset += bucket_size * 2; // each hash entry is 2 juints
+    }
+    if (offset & ~BUCKET_OFFSET_MASK) {
+      vm_exit_during_initialization("CompactHashtableWriter::dump_table: Overflow! "
+                                    "Too many symbols.");
+    }
+    summary->add(bucket_size);
+  }
+  // Mark the end of the table
+  compact_table[_num_buckets] = BUCKET_INFO(offset, TABLEEND_BUCKET_TYPE);
+
+  return compact_table;
+}
+
+// Write the compact table's entries
+juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p,
+                                            NumberSeq* summary) {
+  uintx base_address = uintx(MetaspaceShared::shared_rs()->base());
+  uintx max_delta    = uintx(MetaspaceShared::shared_rs()->size());
+  assert(max_delta <= 0x7fffffff, "range check");
+  int num_compact_buckets = 0;
+
+  assert(p != NULL, "sanity");
+  for (int index = 0; index < _num_buckets; index++) {
+    juint count = 0;
+    int bucket_size = _bucket_sizes[index];
+    int bucket_type = BUCKET_TYPE(compact_table[index]);
+
+    if (bucket_size == 1) {
+      assert(bucket_type == COMPACT_BUCKET_TYPE, "Bad bucket type");
+      num_compact_buckets ++;
+    }
+    for (Entry* tent = _buckets[index]; tent;
+         tent = tent->next()) {
+      if (bucket_type == REGULAR_BUCKET_TYPE) {
+        *p++ = juint(tent->hash()); // write symbol hash
+      }
+      uintx deltax = uintx(tent->value()) - base_address;
+      assert(deltax < max_delta, "range check");
+      juint delta = juint(deltax);
+      *p++ = delta; // write symbol offset
+      count ++;
+    }
+    assert(count == _bucket_sizes[index], "sanity");
+  }
+
+  // Adjust the hashentry_bytes in CompactHashtableStats. Each compact
+  // bucket saves 4-byte.
+  _stats->hashentry_bytes -= num_compact_buckets * 4;
+
+  return p;
+}
+
+// Write the compact table
+void CompactHashtableWriter::dump(char** top, char* end) {
+  NumberSeq summary;
+  char* old_top = *top;
+  juint* p = (juint*)(*top);
+
+  uintx base_address = uintx(MetaspaceShared::shared_rs()->base());
+
+  *p++ = high(base_address);
+  *p++ = low (base_address); // base address
+  *p++ = _num_entries;  // number of entries in the table
+  *p++ = _num_buckets;  // number of buckets in the table
+
+  juint* first_bucket = NULL;
+  juint* compact_table = dump_table(p, &first_bucket, &summary);
+  juint* bucket_end = dump_buckets(compact_table, first_bucket, &summary);
+
+  assert(bucket_end <= (juint*)end, "cannot write past end");
+  *top = (char*)bucket_end;
+
+  if (PrintSharedSpaces) {
+    double avg_cost = 0.0;
+    if (_num_entries > 0) {
+      avg_cost = double(_required_bytes)/double(_num_entries);
+    }
+    tty->print_cr("Shared %s table stats -------- base: " PTR_FORMAT, _table_name, (intptr_t)base_address);
+    tty->print_cr("Number of entries       : %9d", _num_entries);
+    tty->print_cr("Total bytes used        : %9d", (int)((*top) - old_top));
+    tty->print_cr("Average bytes per entry : %9.3f", avg_cost);
+    tty->print_cr("Average bucket size     : %9.3f", summary.avg());
+    tty->print_cr("Variance of bucket size : %9.3f", summary.variance());
+    tty->print_cr("Std. dev. of bucket size: %9.3f", summary.sd());
+    tty->print_cr("Maximum bucket size     : %9d", (int)summary.maximum());
+  }
+}
+
+/////////////////////////////////////////////////////////////
+//
+// The CompactHashtable implementation
+//
+template <class T, class N> const char* CompactHashtable<T, N>::init(const char* buffer) {
+  assert(!DumpSharedSpaces, "run-time only");
+  juint*p = (juint*)buffer;
+  juint upper = *p++;
+  juint lower = *p++;
+  _base_address = uintx(jlong_from(upper, lower));
+  _entry_count = *p++;
+  _bucket_count = *p++;
+  _buckets = p;
+  _table_end_offset = BUCKET_OFFSET(p[_bucket_count]); // located at the end of the bucket_info table
+
+  juint *end = _buckets + _table_end_offset;
+  return (const char*)end;
+}
+
+template <class T, class N> void CompactHashtable<T, N>::symbols_do(SymbolClosure *cl) {
+  assert(!DumpSharedSpaces, "run-time only");
+  for (juint i = 0; i < _bucket_count; i ++) {
+    juint bucket_info = _buckets[i];
+    juint bucket_offset = BUCKET_OFFSET(bucket_info);
+    int   bucket_type = BUCKET_TYPE(bucket_info);
+    juint* bucket = _buckets + bucket_offset;
+    juint* bucket_end = _buckets;
+
+    Symbol* sym;
+    if (bucket_type == COMPACT_BUCKET_TYPE) {
+      sym = (Symbol*)((void*)(_base_address + bucket[0]));
+      cl->do_symbol(&sym);
+    } else {
+      bucket_end += BUCKET_OFFSET(_buckets[i + 1]);
+      while (bucket < bucket_end) {
+        sym = (Symbol*)((void*)(_base_address + bucket[1]));
+        cl->do_symbol(&sym);
+        bucket += 2;
+      }
+    }
+  }
+}
+
+// Explicitly instantiate these types
+template class CompactHashtable<Symbol*, char>;
+
+#ifndef O_BINARY       // if defined (Win32) use binary files.
+#define O_BINARY 0     // otherwise do nothing.
+#endif
+
+////////////////////////////////////////////////////////
+//
+// HashtableTextDump
+//
+HashtableTextDump::HashtableTextDump(const char* filename) : _fd(-1) {
+  struct stat st;
+  if (os::stat(filename, &st) != 0) {
+    quit("Unable to get hashtable dump file size", filename);
+  }
+  _size = st.st_size;
+  _fd = open(filename, O_RDONLY | O_BINARY, 0);
+  if (_fd < 0) {
+    quit("Unable to open hashtable dump file", filename);
+  }
+  _base = os::map_memory(_fd, filename, 0, NULL, _size, true, false);
+  if (_base == NULL) {
+    quit("Unable to map hashtable dump file", filename);
+  }
+  _p = _base;
+  _end = _base + st.st_size;
+  _filename = filename;
+}
+
+HashtableTextDump::~HashtableTextDump() {
+  os::unmap_memory((char*)_base, _size);
+  if (_fd >= 0) {
+    close(_fd);
+  }
+}
+
+void HashtableTextDump::quit(const char* err, const char* msg) {
+  vm_exit_during_initialization(err, msg);
+}
+
+void HashtableTextDump::corrupted(const char *p) {
+  char info[60];
+  sprintf(info, "corrupted at pos %d", (int)(p - _base));
+  quit(info, _filename);
+}
+
+bool HashtableTextDump::skip_newline() {
+  if (_p[0] == '\r' && _p[1] == '\n') {
+    _p += 2;
+  } else if (_p[0] == '\n') {
+    _p += 1;
+  } else {
+    corrupted(_p);
+  }
+  return true;
+}
+
+int HashtableTextDump::skip(char must_be_char) {
+  corrupted_if(remain() < 1);
+  corrupted_if(*_p++ != must_be_char);
+  return 0;
+}
+
+void HashtableTextDump::skip_past(char c) {
+  for (;;) {
+    corrupted_if(remain() < 1);
+    if (*_p++ == c) {
+      return;
+    }
+  }
+}
+
+void HashtableTextDump::check_version(const char* ver) {
+  int len = (int)strlen(ver);
+  corrupted_if(remain() < len);
+  if (strncmp(_p, ver, len) != 0) {
+    quit("wrong version of hashtable dump file", _filename);
+  }
+  _p += len;
+  skip_newline();
+}
+
+
+int HashtableTextDump::scan_prefix() {
+  // Expect /[0-9]+: /
+  int utf8_length = get_num(':');
+  if (*_p != ' ') {
+    corrupted(_p);
+  }
+  _p++;
+  return utf8_length;
+}
+
+int HashtableTextDump::scan_prefix2() {
+  // Expect /[0-9]+ (-|)[0-9]+: /
+  int utf8_length = get_num(' ');
+  if (*_p == '-') {
+    _p++;
+  }
+  (void)get_num(':');
+  if (*_p != ' ') {
+    corrupted(_p);
+  }
+  _p++;
+  return utf8_length;
+}
+
+jchar HashtableTextDump::unescape(const char* from, const char* end, int count) {
+  jchar value = 0;
+
+  corrupted_if(from + count > end);
+
+  for (int i=0; i<count; i++) {
+    char c = *from++;
+    switch (c) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      value = (value << 4) + c - '0';
+      break;
+    case 'a': case 'b': case 'c':
+    case 'd': case 'e': case 'f':
+      value = (value << 4) + 10 + c - 'a';
+      break;
+    case 'A': case 'B': case 'C':
+    case 'D': case 'E': case 'F':
+      value = (value << 4) + 10 + c - 'A';
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+  }
+  return value;
+}
+
+void HashtableTextDump::get_utf8(char* utf8_buffer, int utf8_length) {
+  // cache in local vars
+  const char* from = _p;
+  const char* end = _end;
+  char* to = utf8_buffer;
+  int n = utf8_length;
+
+  for (; n > 0 && from < end; n--) {
+    if (*from != '\\') {
+      *to++ = *from++;
+    } else {
+      corrupted_if(from + 2 > end);
+      char c = from[1];
+      from += 2;
+      switch (c) {
+      case 'x':
+        {
+          jchar value = unescape(from, end, 2);
+          from += 2;
+          assert(value <= 0xff, "sanity");
+          *to++ = (char)(value & 0xff);
+        }
+        break;
+      case 't':  *to++ = '\t'; break;
+      case 'n':  *to++ = '\n'; break;
+      case 'r':  *to++ = '\r'; break;
+      case '\\': *to++ = '\\'; break;
+      default:
+        ShouldNotReachHere();
+      }
+    }
+  }
+  corrupted_if(n > 0); // expected more chars but file has ended
+  _p = from;
+  skip_newline();
+}
+
+// NOTE: the content is NOT the same as
+// UTF8::as_quoted_ascii(const char* utf8_str, int utf8_length, char* buf, int buflen).
+// We want to escape \r\n\t so that output [1] is more readable; [2] can be more easily
+// parsed by scripts; [3] quickly processed by HashtableTextDump::get_utf8()
+void HashtableTextDump::put_utf8(outputStream* st, const char* utf8_string, int utf8_length) {
+  const char *c = utf8_string;
+  const char *end = c + utf8_length;
+  for (; c < end; c++) {
+    switch (*c) {
+    case '\t': st->print("\\t"); break;
+    case '\r': st->print("\\r"); break;
+    case '\n': st->print("\\n"); break;
+    case '\\': st->print("\\\\"); break;
+    default:
+      if (isprint(*c)) {
+        st->print("%c", *c);
+      } else {
+        st->print("\\x%02x", ((unsigned int)*c) & 0xff);
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/classfile/compactHashtable.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -0,0 +1,408 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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_COMPACTHASHTABLE_HPP
+#define SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP
+
+#include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
+#include "memory/allocation.inline.hpp"
+#include "oops/symbol.hpp"
+#include "services/diagnosticCommand.hpp"
+#include "utilities/hashtable.hpp"
+
+class NumberSeq;
+
+// Stats for symbol tables in the CDS archive
+class CompactHashtableStats VALUE_OBJ_CLASS_SPEC {
+public:
+  int hashentry_count;
+  int hashentry_bytes;
+  int bucket_count;
+  int bucket_bytes;
+};
+
+/////////////////////////////////////////////////////////////////////////
+//
+// The compact hash table writer. Used at dump time for writing out
+// the compact table to the shared archive.
+//
+// At dump time, the CompactHashtableWriter obtains all entries from the
+// symbol table and adds them to a new temporary hash table. The hash
+// table size (number of buckets) is calculated using
+// '(num_entries + bucket_size - 1) / bucket_size'. The default bucket
+// size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option.
+// 4 is chosen because it produces smaller sized bucket on average for
+// faster lookup. It also has relatively small number of empty buckets and
+// good distribution of the entries.
+//
+// We use a simple hash function (symbol_hash % num_bucket) for the table.
+// The new table is compacted when written out. Please see comments
+// above the CompactHashtable class for the table layout detail. The bucket
+// offsets are written to the archive as part of the compact table. The
+// bucket offset is encoded in the low 30-bit (0-29) and the bucket type
+// (regular or compact) are encoded in bit[31, 30]. For buckets with more
+// than one entry, both symbol hash and symbol offset are written to the
+// table. For buckets with only one entry, only the symbol offset is written
+// to the table and the buckets are tagged as compact in their type bits.
+// Buckets without entry are skipped from the table. Their offsets are
+// still written out for faster lookup.
+//
+class CompactHashtableWriter: public StackObj {
+public:
+  class Entry: public CHeapObj<mtSymbol> {
+    Entry* _next;
+    unsigned int _hash;
+    void* _literal;
+
+  public:
+    Entry(unsigned int hash, Symbol *symbol) : _next(NULL), _hash(hash), _literal(symbol) {}
+
+    void *value() {
+      return _literal;
+    }
+    Symbol *symbol() {
+      return (Symbol*)_literal;
+    }
+    unsigned int hash() {
+      return _hash;
+    }
+    Entry *next()           {return _next;}
+    void set_next(Entry *p) {_next = p;}
+  }; // class CompactHashtableWriter::Entry
+
+private:
+  static int number_of_buckets(int num_entries);
+
+  const char* _table_name;
+  int _num_entries;
+  int _num_buckets;
+  juint* _bucket_sizes;
+  Entry** _buckets;
+  int _required_bytes;
+  CompactHashtableStats* _stats;
+
+public:
+  // This is called at dump-time only
+  CompactHashtableWriter(const char* table_name, int num_entries, CompactHashtableStats* stats);
+  ~CompactHashtableWriter();
+
+  int get_required_bytes() {
+    return _required_bytes;
+  }
+
+  void add(unsigned int hash, Symbol* symbol) {
+    add(hash, new Entry(hash, symbol));
+  }
+
+private:
+  void add(unsigned int hash, Entry* entry);
+  juint* dump_table(juint* p, juint** first_bucket, NumberSeq* summary);
+  juint* dump_buckets(juint* table, juint* p, NumberSeq* summary);
+
+public:
+  void dump(char** top, char* end);
+};
+
+#define REGULAR_BUCKET_TYPE       0
+#define COMPACT_BUCKET_TYPE       1
+#define TABLEEND_BUCKET_TYPE      3
+#define BUCKET_OFFSET_MASK        0x3FFFFFFF
+#define BUCKET_OFFSET(info)       ((info) & BUCKET_OFFSET_MASK)
+#define BUCKET_TYPE_SHIFT         30
+#define BUCKET_TYPE(info)         (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT)
+#define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK))
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// CompactHashtable is used to stored the CDS archive's symbol table. Used
+// at runtime only to access the compact table from the archive.
+//
+// Because these tables are read-only (no entries can be added/deleted) at run-time
+// and tend to have large number of entries, we try to minimize the footprint
+// cost per entry.
+//
+// Layout of compact symbol table in the shared archive:
+//
+//   uintx base_address;
+//   juint num_symbols;
+//   juint num_buckets;
+//   juint bucket_infos[num_buckets+1]; // bit[31,30]: type; bit[29-0]: offset
+//   juint table[]
+//
+// -----------------------------------
+// | base_address  | num_symbols     |
+// |---------------------------------|
+// | num_buckets   | bucket_info0    |
+// |---------------------------------|
+// | bucket_info1  | bucket_info2    |
+// | bucket_info3    ...             |
+// | ....          | table_end_info  |
+// |---------------------------------|
+// | entry0                          |
+// | entry1                          |
+// | entry2                          |
+// |                                 |
+// | ...                             |
+// -----------------------------------
+//
+// The size of the bucket_info table is 'num_buckets + 1'. Each entry of the
+// bucket_info table is a 32-bit encoding of the bucket type and bucket offset,
+// with the type in the left-most 2-bit and offset in the remaining 30-bit.
+// The last entry is a special type. It contains the offset of the last
+// bucket end. We use that information when traversing the compact table.
+//
+// There are two types of buckets, regular buckets and compact buckets. The
+// compact buckets have '01' in their highest 2-bit, and regular buckets have
+// '00' in their highest 2-bit.
+//
+// For normal buckets, each symbol's entry is 8 bytes in the table[]:
+//   juint hash;    /* symbol hash */
+//   juint offset;  /* Symbol* sym = (Symbol*)(base_address + offset) */
+//
+// For compact buckets, each entry has only the 4-byte 'offset' in the table[].
+//
+// See CompactHashtable::lookup() for how the table is searched at runtime.
+// See CompactHashtableWriter::dump() for how the table is written at CDS
+// dump time.
+//
+template <class T, class N> class CompactHashtable VALUE_OBJ_CLASS_SPEC {
+  uintx  _base_address;
+  juint  _entry_count;
+  juint  _bucket_count;
+  juint  _table_end_offset;
+  juint* _buckets;
+
+  inline bool equals(T entry, const char* name, int len) {
+    if (entry->equals(name, len)) {
+      assert(entry->refcount() == -1, "must be shared");
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+public:
+  CompactHashtable() {
+    _entry_count = 0;
+    _bucket_count = 0;
+    _table_end_offset = 0;
+    _buckets = 0;
+  }
+  const char* init(const char *buffer);
+
+  // Lookup an entry from the compact table
+  inline T lookup(const N* name, unsigned int hash, int len) {
+    if (_entry_count > 0) {
+      assert(!DumpSharedSpaces, "run-time only");
+      int index = hash % _bucket_count;
+      juint bucket_info = _buckets[index];
+      juint bucket_offset = BUCKET_OFFSET(bucket_info);
+      int   bucket_type = BUCKET_TYPE(bucket_info);
+      juint* bucket = _buckets + bucket_offset;
+      juint* bucket_end = _buckets;
+
+      if (bucket_type == COMPACT_BUCKET_TYPE) {
+        // the compact bucket has one entry with symbol offset only
+        T entry = (T)((void*)(_base_address + bucket[0]));
+        if (equals(entry, name, len)) {
+          return entry;
+        }
+      } else {
+        // This is a regular bucket, which has more than one
+        // entries. Each entry is a pair of symbol (hash, offset).
+        // Seek until the end of the bucket.
+        bucket_end += BUCKET_OFFSET(_buckets[index + 1]);
+        while (bucket < bucket_end) {
+          unsigned int h = (unsigned int)(bucket[0]);
+          if (h == hash) {
+            juint offset = bucket[1];
+            T entry = (T)((void*)(_base_address + offset));
+            if (equals(entry, name, len)) {
+              return entry;
+            }
+          }
+          bucket += 2;
+        }
+      }
+    }
+    return NULL;
+  }
+
+  // iterate over symbols
+  void symbols_do(SymbolClosure *cl);
+};
+
+////////////////////////////////////////////////////////////////////////
+//
+// Read/Write the contents of a hashtable textual dump (created by
+// SymbolTable::dump).
+// Because the dump file may be big (hundred of MB in extreme cases),
+// we use mmap for fast access when reading it.
+//
+class HashtableTextDump VALUE_OBJ_CLASS_SPEC {
+  int _fd;
+  const char* _base;
+  const char* _p;
+  const char* _end;
+  const char* _filename;
+  size_t      _size;
+public:
+  HashtableTextDump(const char* filename);
+  ~HashtableTextDump();
+
+  void quit(const char* err, const char* msg);
+
+  inline int remain() {
+    return (int)(_end - _p);
+  }
+
+  void corrupted(const char *p);
+
+  inline void corrupted_if(bool cond) {
+    if (cond) {
+      corrupted(_p);
+    }
+  }
+
+  bool skip_newline();
+  int skip(char must_be_char);
+  void skip_past(char c);
+  void check_version(const char* ver);
+
+  inline int get_num(char delim) {
+    const char* p   = _p;
+    const char* end = _end;
+    int num = 0;
+
+    while (p < end) {
+      char c = *p ++;
+      if ('0' <= c && c <= '9') {
+        num = num * 10 + (c - '0');
+      } else if (c == delim) {
+        _p = p;
+        return num;
+      } else {
+        corrupted(p-1);
+      }
+    }
+    corrupted(_end);
+    ShouldNotReachHere();
+    return 0;
+  }
+
+  int scan_prefix();
+  int scan_prefix2();
+
+  jchar unescape(const char* from, const char* end, int count);
+  void get_utf8(char* utf8_buffer, int utf8_length);
+  static void put_utf8(outputStream* st, const char* utf8_string, int utf8_length);
+};
+
+///////////////////////////////////////////////////////////////////////
+//
+// jcmd command support for symbol table and string table dumping:
+//   VM.symboltable -verbose: for dumping the symbol table
+//   VM.stringtable -verbose: for dumping the string table
+//
+class VM_DumpHashtable : public VM_Operation {
+private:
+  outputStream* _out;
+  int _which;
+  bool _verbose;
+public:
+  enum {
+    DumpSymbols = 1 << 0,
+    DumpStrings = 1 << 1,
+    DumpSysDict = 1 << 2  // not implemented yet
+  };
+  VM_DumpHashtable(outputStream* out, int which, bool verbose) {
+    _out = out;
+    _which = which;
+    _verbose = verbose;
+  }
+
+  virtual VMOp_Type type() const { return VMOp_DumpHashtable; }
+
+  virtual void doit() {
+    switch (_which) {
+    case DumpSymbols:
+      SymbolTable::dump(_out, _verbose);
+      break;
+    case DumpStrings:
+      StringTable::dump(_out, _verbose);
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+  }
+};
+
+class SymboltableDCmd : public DCmdWithParser {
+protected:
+  DCmdArgument<bool> _verbose;
+public:
+  SymboltableDCmd(outputStream* output, bool heap);
+  static const char* name() {
+    return "VM.symboltable";
+  }
+  static const char* description() {
+    return "Dump symbol table.";
+  }
+  static const char* impact() {
+    return "Medium: Depends on Java content.";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments();
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
+class StringtableDCmd : public DCmdWithParser {
+protected:
+  DCmdArgument<bool> _verbose;
+public:
+  StringtableDCmd(outputStream* output, bool heap);
+  static const char* name() {
+    return "VM.stringtable";
+  }
+  static const char* description() {
+    return "Dump string table.";
+  }
+  static const char* impact() {
+    return "Medium: Depends on Java content.";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments();
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
+#endif // SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP
--- a/src/share/vm/classfile/stringTable.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/stringTable.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/altHashing.hpp"
+#include "classfile/compactHashtable.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -379,8 +380,36 @@
   }
 }
 
-void StringTable::dump(outputStream* st) {
-  the_table()->dump_table(st, "StringTable");
+void StringTable::dump(outputStream* st, bool verbose) {
+  if (!verbose) {
+    the_table()->dump_table(st, "StringTable");
+  } else {
+    Thread* THREAD = Thread::current();
+    st->print_cr("VERSION: 1.1");
+    for (int i = 0; i < the_table()->table_size(); ++i) {
+      HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
+      for ( ; p != NULL; p = p->next()) {
+        oop s = p->literal();
+        typeArrayOop value  = java_lang_String::value(s);
+        int          offset = java_lang_String::offset(s);
+        int          length = java_lang_String::length(s);
+
+        if (length <= 0) {
+          st->print("%d: ", length);
+        } else {
+          ResourceMark rm(THREAD);
+          jchar* chars = (jchar*)value->char_at_addr(offset);
+          int utf8_length = UNICODE::utf8_length(chars, length);
+          char* utf8_string = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
+          UNICODE::convert_to_utf8(chars, length, utf8_string);
+
+          st->print("%d: ", utf8_length);
+          HashtableTextDump::put_utf8(st, utf8_string, utf8_length);
+        }
+        st->cr();
+      }
+    }
+  }
 }
 
 StringTable::VerifyRetTypes StringTable::compare_entries(
@@ -558,3 +587,28 @@
   _needs_rehashing = false;
   _the_table = new_table;
 }
+
+// Utility for dumping strings
+StringtableDCmd::StringtableDCmd(outputStream* output, bool heap) :
+                                 DCmdWithParser(output, heap),
+  _verbose("-verbose", "Dump the content of each string in the table",
+           "BOOLEAN", false, "false") {
+  _dcmdparser.add_dcmd_option(&_verbose);
+}
+
+void StringtableDCmd::execute(DCmdSource source, TRAPS) {
+  VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpStrings,
+                         _verbose.value());
+  VMThread::execute(&dumper);
+}
+
+int StringtableDCmd::num_arguments() {
+  ResourceMark rm;
+  StringtableDCmd* dcmd = new StringtableDCmd(NULL, false);
+  if (dcmd != NULL) {
+    DCmdMark mark(dcmd);
+    return dcmd->_dcmdparser.num_arguments();
+  } else {
+    return 0;
+  }
+}
--- a/src/share/vm/classfile/stringTable.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/stringTable.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -118,7 +118,7 @@
 
   // Debugging
   static void verify();
-  static void dump(outputStream* st);
+  static void dump(outputStream* st, bool verbose=false);
 
   enum VerifyMesgModes {
     _verify_quietly    = 0,
--- a/src/share/vm/classfile/symbolTable.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/symbolTable.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/altHashing.hpp"
+#include "classfile/compactHashtable.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -47,6 +48,9 @@
 // Static arena for symbols that are not deallocated
 Arena* SymbolTable::_arena = NULL;
 bool SymbolTable::_needs_rehashing = false;
+bool SymbolTable::_lookup_shared_first = false;
+
+CompactHashtable<Symbol*, char> SymbolTable::_shared_table;
 
 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
   assert (len <= Symbol::max_length(), "should be checked by caller");
@@ -78,6 +82,10 @@
 
 // Call function for all symbols in the symbol table.
 void SymbolTable::symbols_do(SymbolClosure *cl) {
+  // all symbols from shared table
+  _shared_table.symbols_do(cl);
+
+  // all symbols from the dynamic table
   const int n = the_table()->table_size();
   for (int i = 0; i < n; i++) {
     for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
@@ -186,8 +194,8 @@
 
 // Lookup a symbol in a bucket.
 
-Symbol* SymbolTable::lookup(int index, const char* name,
-                              int len, unsigned int hash) {
+Symbol* SymbolTable::lookup_dynamic(int index, const char* name,
+                                    int len, unsigned int hash) {
   int count = 0;
   for (HashtableEntry<Symbol*, mtSymbol>* e = bucket(index); e != NULL; e = e->next()) {
     count++;  // count all entries in this bucket, not just ones with same hash
@@ -207,6 +215,34 @@
   return NULL;
 }
 
+Symbol* SymbolTable::lookup_shared(const char* name,
+                                   int len, unsigned int hash) {
+  return _shared_table.lookup(name, hash, len);
+}
+
+Symbol* SymbolTable::lookup(int index, const char* name,
+                            int len, unsigned int hash) {
+  Symbol* sym;
+  if (_lookup_shared_first) {
+    sym = lookup_shared(name, len, hash);
+    if (sym != NULL) {
+      return sym;
+    }
+    _lookup_shared_first = false;
+    return lookup_dynamic(index, name, len, hash);
+  } else {
+    sym = lookup_dynamic(index, name, len, hash);
+    if (sym != NULL) {
+      return sym;
+    }
+    sym = lookup_shared(name, len, hash);
+    if (sym != NULL) {
+      _lookup_shared_first = true;
+    }
+    return sym;
+  }
+}
+
 // Pick hashing algorithm.
 unsigned int SymbolTable::hash_symbol(const char* s, int len) {
   return use_alternate_hashcode() ?
@@ -483,10 +519,56 @@
   }
 }
 
-void SymbolTable::dump(outputStream* st) {
-  the_table()->dump_table(st, "SymbolTable");
+void SymbolTable::dump(outputStream* st, bool verbose) {
+  if (!verbose) {
+    the_table()->dump_table(st, "SymbolTable");
+  } else {
+    st->print_cr("VERSION: 1.0");
+    for (int i = 0; i < the_table()->table_size(); ++i) {
+      HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
+      for ( ; p != NULL; p = p->next()) {
+        Symbol* s = (Symbol*)(p->literal());
+        const char* utf8_string = (const char*)s->bytes();
+        int utf8_length = s->utf8_length();
+        st->print("%d %d: ", utf8_length, s->refcount());
+        HashtableTextDump::put_utf8(st, utf8_string, utf8_length);
+        st->cr();
+      }
+    }
+  }
 }
 
+bool SymbolTable::copy_compact_table(char** top, char*end) {
+#if INCLUDE_CDS
+  CompactHashtableWriter ch_table("symbol", the_table()->number_of_entries(),
+                                  &MetaspaceShared::stats()->symbol);
+  if (*top + ch_table.get_required_bytes() > end) {
+    // not enough space left
+    return false;
+  }
+
+  for (int i = 0; i < the_table()->table_size(); ++i) {
+    HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
+    for ( ; p != NULL; p = p->next()) {
+      Symbol* s = (Symbol*)(p->literal());
+      unsigned int fixed_hash = hash_symbol((char*)s->bytes(), s->utf8_length());
+      assert(fixed_hash == p->hash(), "must not rehash during dumping");
+      ch_table.add(fixed_hash, s);
+    }
+  }
+
+  char* old_top = *top;
+  ch_table.dump(top, end);
+
+  *top = (char*)align_pointer_up(*top, sizeof(void*));
+#endif
+  return true;
+}
+
+const char* SymbolTable::init_shared_table(const char* buffer) {
+  const char* end = _shared_table.init(buffer);
+  return (const char*)align_pointer_up(end, sizeof(void*));
+}
 
 //---------------------------------------------------------------------------
 // Non-product code
@@ -574,3 +656,29 @@
   }
 }
 #endif // PRODUCT
+
+
+// Utility for dumping symbols
+SymboltableDCmd::SymboltableDCmd(outputStream* output, bool heap) :
+                                 DCmdWithParser(output, heap),
+  _verbose("-verbose", "Dump the content of each symbol in the table",
+           "BOOLEAN", false, "false") {
+  _dcmdparser.add_dcmd_option(&_verbose);
+}
+
+void SymboltableDCmd::execute(DCmdSource source, TRAPS) {
+  VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpSymbols,
+                         _verbose.value());
+  VMThread::execute(&dumper);
+}
+
+int SymboltableDCmd::num_arguments() {
+  ResourceMark rm;
+  SymboltableDCmd* dcmd = new SymboltableDCmd(NULL, false);
+  if (dcmd != NULL) {
+    DCmdMark mark(dcmd);
+    return dcmd->_dcmdparser.num_arguments();
+  } else {
+    return 0;
+  }
+}
--- a/src/share/vm/classfile/symbolTable.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/symbolTable.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -73,6 +73,8 @@
   operator Symbol*()                             { return _temp; }
 };
 
+template <class T, class N> class CompactHashtable;
+
 class SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> {
   friend class VMStructs;
   friend class ClassFileParser;
@@ -83,11 +85,15 @@
 
   // Set if one bucket is out of balance due to hash algorithm deficiency
   static bool _needs_rehashing;
+  static bool _lookup_shared_first;
 
   // For statistics
   static int _symbols_removed;
   static int _symbols_counted;
 
+  // shared symbol table.
+  static CompactHashtable<Symbol*, char> _shared_table;
+
   Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
 
   // Adding elements
@@ -106,6 +112,8 @@
     add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
   }
 
+  static Symbol* lookup_shared(const char* name, int len, unsigned int hash);
+  Symbol* lookup_dynamic(int index, const char* name, int len, unsigned int hash);
   Symbol* lookup(int index, const char* name, int len, unsigned int hash);
 
   SymbolTable()
@@ -144,20 +152,6 @@
     initialize_symbols(symbol_alloc_arena_size);
   }
 
-  static void create_table(HashtableBucket<mtSymbol>* t, int length,
-                           int number_of_entries) {
-    assert(_the_table == NULL, "One symbol table allowed.");
-
-    // If CDS archive used a different symbol table size, use that size instead
-    // which is better than giving an error.
-    SymbolTableSize = length/bucket_size();
-
-    _the_table = new SymbolTable(t, number_of_entries);
-    // if CDS give symbol table a default arena size since most symbols
-    // are already allocated in the shared misc section.
-    initialize_symbols();
-  }
-
   static unsigned int hash_symbol(const char* s, int len);
 
   static Symbol* lookup(const char* name, int len, TRAPS);
@@ -230,18 +224,12 @@
 
   // Debugging
   static void verify();
-  static void dump(outputStream* st);
+  static void dump(outputStream* st, bool verbose=false);
+  static void read(const char* filename, TRAPS);
 
   // Sharing
-  static void copy_buckets(char** top, char*end) {
-    the_table()->Hashtable<Symbol*, mtSymbol>::copy_buckets(top, end);
-  }
-  static void copy_table(char** top, char*end) {
-    the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end);
-  }
-  static void reverse(void* boundary = NULL) {
-    the_table()->Hashtable<Symbol*, mtSymbol>::reverse(boundary);
-  }
+  static bool copy_compact_table(char** top, char* end);
+  static const char* init_shared_table(const char* buffer);
 
   // Rehash the symbol table if it gets out of balance
   static void rehash_table();
--- a/src/share/vm/classfile/systemDictionary.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/systemDictionary.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -32,6 +32,7 @@
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "code/codeCache.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/bytecodeStream.hpp"
 #include "interpreter/interpreter.hpp"
@@ -1627,7 +1628,7 @@
   // Note: must be done *after* linking k into the hierarchy (was bug 12/9/97)
   // Also, first reinitialize vtable because it may have gotten out of synch
   // while the new class wasn't connected to the class hierarchy.
-  Universe::flush_dependents_on(k);
+  CodeCache::flush_dependents_on(k);
 }
 
 // ----------------------------------------------------------------------------
@@ -1904,11 +1905,12 @@
   InstanceKlass::cast(WK_KLASS(Reference_klass))->set_reference_type(REF_OTHER);
   InstanceRefKlass::update_nonstatic_oop_maps(WK_KLASS(Reference_klass));
 
-  initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(PhantomReference_klass), scan, CHECK);
+  initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Cleaner_klass), scan, CHECK);
   InstanceKlass::cast(WK_KLASS(SoftReference_klass))->set_reference_type(REF_SOFT);
   InstanceKlass::cast(WK_KLASS(WeakReference_klass))->set_reference_type(REF_WEAK);
   InstanceKlass::cast(WK_KLASS(FinalReference_klass))->set_reference_type(REF_FINAL);
   InstanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
+  InstanceKlass::cast(WK_KLASS(Cleaner_klass))->set_reference_type(REF_CLEANER);
 
   // JSR 292 classes
   WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
--- a/src/share/vm/classfile/systemDictionary.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -128,6 +128,7 @@
   do_klass(WeakReference_klass,                         java_lang_ref_WeakReference,               Pre                 ) \
   do_klass(FinalReference_klass,                        java_lang_ref_FinalReference,              Pre                 ) \
   do_klass(PhantomReference_klass,                      java_lang_ref_PhantomReference,            Pre                 ) \
+  do_klass(Cleaner_klass,                               sun_misc_Cleaner,                          Pre                 ) \
   do_klass(Finalizer_klass,                             java_lang_ref_Finalizer,                   Pre                 ) \
                                                                                                                          \
   do_klass(Thread_klass,                                java_lang_Thread,                          Pre                 ) \
--- a/src/share/vm/classfile/verifier.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/verifier.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -1546,23 +1546,28 @@
           no_control_flow = true; break;
         case Bytecodes::_getstatic :
         case Bytecodes::_putstatic :
+          // pass TRUE, operand can be an array type for getstatic/putstatic.
+          verify_field_instructions(
+            &bcs, &current_frame, cp, true, CHECK_VERIFY(this));
+          no_control_flow = false; break;
         case Bytecodes::_getfield :
         case Bytecodes::_putfield :
+          // pass FALSE, operand can't be an array type for getfield/putfield.
           verify_field_instructions(
-            &bcs, &current_frame, cp, CHECK_VERIFY(this));
+            &bcs, &current_frame, cp, false, CHECK_VERIFY(this));
           no_control_flow = false; break;
         case Bytecodes::_invokevirtual :
         case Bytecodes::_invokespecial :
         case Bytecodes::_invokestatic :
           verify_invoke_instructions(
-            &bcs, code_length, &current_frame,
-            &this_uninit, return_type, cp, CHECK_VERIFY(this));
+            &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max),
+            &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this));
           no_control_flow = false; break;
         case Bytecodes::_invokeinterface :
         case Bytecodes::_invokedynamic :
           verify_invoke_instructions(
-            &bcs, code_length, &current_frame,
-            &this_uninit, return_type, cp, CHECK_VERIFY(this));
+            &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max),
+            &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this));
           no_control_flow = false; break;
         case Bytecodes::_new :
         {
@@ -1945,7 +1950,7 @@
   InstanceKlass* target_instance = InstanceKlass::cast(target_class);
   fieldDescriptor fd;
   if (is_method) {
-    Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::normal);
+    Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::find_overpass);
     if (m != NULL && m->is_protected()) {
       if (!this_class->is_same_class_package(m->method_holder())) {
         return true;
@@ -2107,6 +2112,7 @@
 void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
                                               StackMapFrame* current_frame,
                                               constantPoolHandle cp,
+                                              bool allow_arrays,
                                               TRAPS) {
   u2 index = bcs->get_index_u2();
   verify_cp_type(bcs->bci(), index, cp,
@@ -2126,8 +2132,8 @@
   // Get referenced class type
   VerificationType ref_class_type = cp_ref_index_to_type(
     index, cp, CHECK_VERIFY(this));
-  if (!ref_class_type.is_object()) {
-    /* Unreachable?  Class file parser verifies Fieldref contents */
+  if (!ref_class_type.is_object() &&
+    (!allow_arrays || !ref_class_type.is_array())) {
     verify_error(ErrorContext::bad_type(bcs->bci(),
         TypeOrigin::cp(index, ref_class_type)),
         "Expecting reference to class in class %s at constant pool index %d",
@@ -2406,8 +2412,9 @@
 
 void ClassVerifier::verify_invoke_init(
     RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
-    StackMapFrame* current_frame, u4 code_length, bool *this_uninit,
-    constantPoolHandle cp, TRAPS) {
+    StackMapFrame* current_frame, u4 code_length, bool in_try_block,
+    bool *this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
+    TRAPS) {
   u2 bci = bcs->bci();
   VerificationType type = current_frame->pop_stack(
     VerificationType::reference_check(), CHECK_VERIFY(this));
@@ -2423,28 +2430,36 @@
       return;
     }
 
-    // Check if this call is done from inside of a TRY block.  If so, make
-    // sure that all catch clause paths end in a throw.  Otherwise, this
-    // can result in returning an incomplete object.
-    ExceptionTable exhandlers(_method());
-    int exlength = exhandlers.length();
-    for(int i = 0; i < exlength; i++) {
-      u2 start_pc = exhandlers.start_pc(i);
-      u2 end_pc = exhandlers.end_pc(i);
+    // If this invokespecial call is done from inside of a TRY block then make
+    // sure that all catch clause paths end in a throw.  Otherwise, this can
+    // result in returning an incomplete object.
+    if (in_try_block) {
+      ExceptionTable exhandlers(_method());
+      int exlength = exhandlers.length();
+      for(int i = 0; i < exlength; i++) {
+        u2 start_pc = exhandlers.start_pc(i);
+        u2 end_pc = exhandlers.end_pc(i);
 
-      if (bci >= start_pc && bci < end_pc) {
-        if (!ends_in_athrow(exhandlers.handler_pc(i))) {
-          verify_error(ErrorContext::bad_code(bci),
-            "Bad <init> method call from after the start of a try block");
-          return;
-        } else if (VerboseVerification) {
-          ResourceMark rm;
-          tty->print_cr(
-            "Survived call to ends_in_athrow(): %s",
-                        current_class()->name()->as_C_string());
+        if (bci >= start_pc && bci < end_pc) {
+          if (!ends_in_athrow(exhandlers.handler_pc(i))) {
+            verify_error(ErrorContext::bad_code(bci),
+              "Bad <init> method call from after the start of a try block");
+            return;
+          } else if (VerboseVerification) {
+            ResourceMark rm;
+            tty->print_cr(
+              "Survived call to ends_in_athrow(): %s",
+              current_class()->name()->as_C_string());
+          }
         }
       }
-    }
+
+      // Check the exception handler target stackmaps with the locals from the
+      // incoming stackmap (before initialize_object() changes them to outgoing
+      // state).
+      verify_exception_handler_targets(bci, true, current_frame,
+                                       stackmap_table, CHECK_VERIFY(this));
+    } // in_try_block
 
     current_frame->initialize_object(type, current_type());
     *this_uninit = true;
@@ -2477,12 +2492,11 @@
     // of the current class.
     VerificationType objectref_type = new_class_type;
     if (name_in_supers(ref_class_type.name(), current_class())) {
-      Klass* ref_klass = load_class(
-        ref_class_type.name(), CHECK_VERIFY(this));
+      Klass* ref_klass = load_class(ref_class_type.name(), CHECK);
       Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method(
         vmSymbols::object_initializer_name(),
         cp->signature_ref_at(bcs->get_index_u2()),
-        Klass::normal);
+        Klass::find_overpass);
       // Do nothing if method is not found.  Let resolution detect the error.
       if (m != NULL) {
         instanceKlassHandle mh(THREAD, m->method_holder());
@@ -2499,6 +2513,13 @@
         }
       }
     }
+    // Check the exception handler target stackmaps with the locals from the
+    // incoming stackmap (before initialize_object() changes them to outgoing
+    // state).
+    if (in_try_block) {
+      verify_exception_handler_targets(bci, *this_uninit, current_frame,
+                                       stackmap_table, CHECK_VERIFY(this));
+    }
     current_frame->initialize_object(type, new_class_type);
   } else {
     verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx()),
@@ -2527,8 +2548,8 @@
 
 void ClassVerifier::verify_invoke_instructions(
     RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
-    bool *this_uninit, VerificationType return_type,
-    constantPoolHandle cp, TRAPS) {
+    bool in_try_block, bool *this_uninit, VerificationType return_type,
+    constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS) {
   // Make sure the constant pool item is the right type
   u2 index = bcs->get_index_u2();
   Bytecodes::Code opcode = bcs->raw_code();
@@ -2694,7 +2715,8 @@
       opcode != Bytecodes::_invokedynamic) {
     if (method_name == vmSymbols::object_initializer_name()) {  // <init> method
       verify_invoke_init(bcs, index, ref_class_type, current_frame,
-        code_length, this_uninit, cp, CHECK_VERIFY(this));
+        code_length, in_try_block, this_uninit, cp, stackmap_table,
+        CHECK_VERIFY(this));
     } else {   // other methods
       // Ensures that target class is assignable to method class.
       if (opcode == Bytecodes::_invokespecial) {
--- a/src/share/vm/classfile/verifier.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/verifier.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -297,12 +297,13 @@
 
   void verify_field_instructions(
     RawBytecodeStream* bcs, StackMapFrame* current_frame,
-    constantPoolHandle cp, TRAPS);
+    constantPoolHandle cp, bool allow_arrays, TRAPS);
 
   void verify_invoke_init(
     RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
-    StackMapFrame* current_frame, u4 code_length, bool* this_uninit,
-    constantPoolHandle cp, TRAPS);
+    StackMapFrame* current_frame, u4 code_length, bool in_try_block,
+    bool* this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
+    TRAPS);
 
   // Used by ends_in_athrow() to push all handlers that contain bci onto
   // the handler_stack, if the handler is not already on the stack.
@@ -316,8 +317,8 @@
 
   void verify_invoke_instructions(
     RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
-    bool* this_uninit, VerificationType return_type,
-    constantPoolHandle cp, TRAPS);
+    bool in_try_block, bool* this_uninit, VerificationType return_type,
+    constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS);
 
   VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
   void verify_anewarray(u2 bci, u2 index, constantPoolHandle cp,
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -79,6 +79,7 @@
   template(java_lang_ref_WeakReference,               "java/lang/ref/WeakReference")              \
   template(java_lang_ref_FinalReference,              "java/lang/ref/FinalReference")             \
   template(java_lang_ref_PhantomReference,            "java/lang/ref/PhantomReference")           \
+  template(sun_misc_Cleaner,                          "sun/misc/Cleaner")                         \
   template(java_lang_ref_Finalizer,                   "java/lang/ref/Finalizer")                  \
   template(java_lang_reflect_AccessibleObject,        "java/lang/reflect/AccessibleObject")       \
   template(java_lang_reflect_Method,                  "java/lang/reflect/Method")                 \
@@ -242,7 +243,6 @@
   template(returnType_name,                           "returnType")                               \
   template(signature_name,                            "signature")                                \
   template(slot_name,                                 "slot")                                     \
-  template(selectAlternative_name,                    "selectAlternative")                        \
                                                                                                   \
   /* Support for annotations (JDK 1.5 and above) */                                               \
                                                                                                   \
@@ -294,8 +294,7 @@
   template(setTarget_signature,                       "(Ljava/lang/invoke/MethodHandle;)V")       \
   NOT_LP64(  do_alias(intptr_signature,               int_signature)  )                           \
   LP64_ONLY( do_alias(intptr_signature,               long_signature) )                           \
-  template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
-                                                                      \
+                                                                                                  \
   /* common method and field names */                                                             \
   template(object_initializer_name,                   "<init>")                                   \
   template(class_initializer_name,                    "<clinit>")                                 \
@@ -867,6 +866,12 @@
    do_name(     fullFence_name,                                  "fullFence")                                           \
    do_alias(    fullFence_signature,                              void_method_signature)                                \
                                                                                                                         \
+  /* Custom branch frequencies profiling support for JSR292 */                                                          \
+  do_class(java_lang_invoke_MethodHandleImpl,               "java/lang/invoke/MethodHandleImpl")                        \
+  do_intrinsic(_profileBoolean, java_lang_invoke_MethodHandleImpl, profileBoolean_name, profileBoolean_signature,    F_S)  \
+   do_name(     profileBoolean_name,                               "profileBoolean")                                     \
+   do_signature(profileBoolean_signature,                           "(Z[I)Z")                                            \
+                                                                                                                        \
   /* unsafe memory references (there are a lot of them...) */                                                           \
   do_signature(getObject_signature,       "(Ljava/lang/Object;J)Ljava/lang/Object;")                                    \
   do_signature(putObject_signature,       "(Ljava/lang/Object;JLjava/lang/Object;)V")                                   \
--- a/src/share/vm/code/codeCache.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/code/codeCache.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -199,15 +199,10 @@
   }
   guarantee(NonProfiledCodeHeapSize + ProfiledCodeHeapSize + NonNMethodCodeHeapSize <= ReservedCodeCacheSize, "Size check");
 
-  // Align reserved sizes of CodeHeaps
-  size_t non_method_size   = ReservedCodeSpace::allocation_align_size_up(NonNMethodCodeHeapSize);
-  size_t profiled_size     = ReservedCodeSpace::allocation_align_size_up(ProfiledCodeHeapSize);
-  size_t non_profiled_size = ReservedCodeSpace::allocation_align_size_up(NonProfiledCodeHeapSize);
-
-  // Compute initial sizes of CodeHeaps
-  size_t init_non_method_size   = MIN2(InitialCodeCacheSize, non_method_size);
-  size_t init_profiled_size     = MIN2(InitialCodeCacheSize, profiled_size);
-  size_t init_non_profiled_size = MIN2(InitialCodeCacheSize, non_profiled_size);
+  // Align CodeHeaps
+  size_t alignment = heap_alignment();
+  size_t non_method_size = align_size_up(NonNMethodCodeHeapSize, alignment);
+  size_t profiled_size   = align_size_down(ProfiledCodeHeapSize, alignment);
 
   // Reserve one continuous chunk of memory for CodeHeaps and split it into
   // parts for the individual heaps. The memory layout looks like this:
@@ -216,25 +211,34 @@
   //      Profiled nmethods
   //         Non-nmethods
   // ---------- low ------------
-  ReservedCodeSpace rs = reserve_heap_memory(non_profiled_size + profiled_size + non_method_size);
+  ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
   ReservedSpace non_method_space    = rs.first_part(non_method_size);
   ReservedSpace rest                = rs.last_part(non_method_size);
   ReservedSpace profiled_space      = rest.first_part(profiled_size);
   ReservedSpace non_profiled_space  = rest.last_part(profiled_size);
 
   // Non-nmethods (stubs, adapters, ...)
-  add_heap(non_method_space, "CodeHeap 'non-nmethods'", init_non_method_size, CodeBlobType::NonNMethod);
+  add_heap(non_method_space, "CodeHeap 'non-nmethods'", CodeBlobType::NonNMethod);
   // Tier 2 and tier 3 (profiled) methods
-  add_heap(profiled_space, "CodeHeap 'profiled nmethods'", init_profiled_size, CodeBlobType::MethodProfiled);
+  add_heap(profiled_space, "CodeHeap 'profiled nmethods'", CodeBlobType::MethodProfiled);
   // Tier 1 and tier 4 (non-profiled) methods and native methods
-  add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", init_non_profiled_size, CodeBlobType::MethodNonProfiled);
+  add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", CodeBlobType::MethodNonProfiled);
+}
+
+size_t CodeCache::heap_alignment() {
+  // If large page support is enabled, align code heaps according to large
+  // page size to make sure that code cache is covered by large pages.
+  const size_t page_size = os::can_execute_large_page_memory() ?
+             os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8) :
+             os::vm_page_size();
+  return MAX2(page_size, (size_t) os::vm_allocation_granularity());
 }
 
 ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
   // Determine alignment
   const size_t page_size = os::can_execute_large_page_memory() ?
-          MIN2(os::page_size_for_region(InitialCodeCacheSize, 8),
-               os::page_size_for_region(size, 8)) :
+          MIN2(os::page_size_for_region_aligned(InitialCodeCacheSize, 8),
+               os::page_size_for_region_aligned(size, 8)) :
           os::vm_page_size();
   const size_t granularity = os::vm_allocation_granularity();
   const size_t r_align = MAX2(page_size, granularity);
@@ -284,7 +288,7 @@
   return NULL;
 }
 
-void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type) {
+void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) {
   // Check if heap is needed
   if (!heap_available(code_blob_type)) {
     return;
@@ -295,8 +299,8 @@
   _heaps->append(heap);
 
   // Reserve Space
+  size_t size_initial = MIN2(InitialCodeCacheSize, rs.size());
   size_initial = round_to(size_initial, os::vm_page_size());
-
   if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) {
     vm_exit_during_initialization("Could not reserve enough space for code cache");
   }
@@ -840,7 +844,7 @@
   } else {
     // Use a single code heap
     ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
-    add_heap(rs, "CodeCache", InitialCodeCacheSize, CodeBlobType::All);
+    add_heap(rs, "CodeCache", CodeBlobType::All);
   }
 
   // Initialize ICache flush mechanism
@@ -1005,6 +1009,117 @@
   }
 }
 
+// Flushes compiled methods dependent on dependee.
+void CodeCache::flush_dependents_on(instanceKlassHandle dependee) {
+  assert_lock_strong(Compile_lock);
+
+  if (number_of_nmethods_with_dependencies() == 0) return;
+
+  // CodeCache can only be updated by a thread_in_VM and they will all be
+  // stopped during the safepoint so CodeCache will be safe to update without
+  // holding the CodeCache_lock.
+
+  KlassDepChange changes(dependee);
+
+  // Compute the dependent nmethods
+  if (mark_for_deoptimization(changes) > 0) {
+    // At least one nmethod has been marked for deoptimization
+    VM_Deoptimize op;
+    VMThread::execute(&op);
+  }
+}
+
+// Flushes compiled methods dependent on a particular CallSite
+// instance when its target is different than the given MethodHandle.
+void CodeCache::flush_dependents_on(Handle call_site, Handle method_handle) {
+  assert_lock_strong(Compile_lock);
+
+  if (number_of_nmethods_with_dependencies() == 0) return;
+
+  // CodeCache can only be updated by a thread_in_VM and they will all be
+  // stopped during the safepoint so CodeCache will be safe to update without
+  // holding the CodeCache_lock.
+
+  CallSiteDepChange changes(call_site(), method_handle());
+
+  // Compute the dependent nmethods that have a reference to a
+  // CallSite object.  We use InstanceKlass::mark_dependent_nmethod
+  // directly instead of CodeCache::mark_for_deoptimization because we
+  // want dependents on the call site class only not all classes in
+  // the ContextStream.
+  int marked = 0;
+  {
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    InstanceKlass* call_site_klass = InstanceKlass::cast(call_site->klass());
+    marked = call_site_klass->mark_dependent_nmethods(changes);
+  }
+  if (marked > 0) {
+    // At least one nmethod has been marked for deoptimization
+    VM_Deoptimize op;
+    VMThread::execute(&op);
+  }
+}
+
+#ifdef HOTSWAP
+// Flushes compiled methods dependent on dependee in the evolutionary sense
+void CodeCache::flush_evol_dependents_on(instanceKlassHandle ev_k_h) {
+  // --- Compile_lock is not held. However we are at a safepoint.
+  assert_locked_or_safepoint(Compile_lock);
+  if (number_of_nmethods_with_dependencies() == 0) return;
+
+  // CodeCache can only be updated by a thread_in_VM and they will all be
+  // stopped during the safepoint so CodeCache will be safe to update without
+  // holding the CodeCache_lock.
+
+  // Compute the dependent nmethods
+  if (mark_for_evol_deoptimization(ev_k_h) > 0) {
+    // At least one nmethod has been marked for deoptimization
+
+    // All this already happens inside a VM_Operation, so we'll do all the work here.
+    // Stuff copied from VM_Deoptimize and modified slightly.
+
+    // We do not want any GCs to happen while we are in the middle of this VM operation
+    ResourceMark rm;
+    DeoptimizationMarker dm;
+
+    // Deoptimize all activations depending on marked nmethods
+    Deoptimization::deoptimize_dependents();
+
+    // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies)
+    make_marked_nmethods_not_entrant();
+  }
+}
+#endif // HOTSWAP
+
+
+// Flushes compiled methods dependent on dependee
+void CodeCache::flush_dependents_on_method(methodHandle m_h) {
+  // --- Compile_lock is not held. However we are at a safepoint.
+  assert_locked_or_safepoint(Compile_lock);
+
+  // CodeCache can only be updated by a thread_in_VM and they will all be
+  // stopped dring the safepoint so CodeCache will be safe to update without
+  // holding the CodeCache_lock.
+
+  // Compute the dependent nmethods
+  if (mark_for_deoptimization(m_h()) > 0) {
+    // At least one nmethod has been marked for deoptimization
+
+    // All this already happens inside a VM_Operation, so we'll do all the work here.
+    // Stuff copied from VM_Deoptimize and modified slightly.
+
+    // We do not want any GCs to happen while we are in the middle of this VM operation
+    ResourceMark rm;
+    DeoptimizationMarker dm;
+
+    // Deoptimize all activations depending on marked nmethods
+    Deoptimization::deoptimize_dependents();
+
+    // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies)
+    make_marked_nmethods_not_entrant();
+  }
+}
+
 void CodeCache::verify() {
   assert_locked_or_safepoint(CodeCache_lock);
   FOR_ALL_HEAPS(heap) {
--- a/src/share/vm/code/codeCache.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/code/codeCache.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -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
@@ -98,12 +98,13 @@
   // CodeHeap management
   static void initialize_heaps();                             // Initializes the CodeHeaps
   // Creates a new heap with the given name and size, containing CodeBlobs of the given type
-  static void add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type);
+  static void add_heap(ReservedSpace rs, const char* name, int code_blob_type);
   static CodeHeap* get_code_heap(const CodeBlob* cb);         // Returns the CodeHeap for the given CodeBlob
   static CodeHeap* get_code_heap(int code_blob_type);         // Returns the CodeHeap for the given CodeBlobType
   // Returns the name of the VM option to set the size of the corresponding CodeHeap
   static const char* get_code_heap_flag_name(int code_blob_type);
   static bool heap_available(int code_blob_type);             // Returns true if an own CodeHeap for the given CodeBlobType is available
+  static size_t heap_alignment();                             // Returns the alignment of the CodeHeaps in bytes
   static ReservedCodeSpace reserve_heap_memory(size_t size);  // Reserves one continuous chunk of memory for the CodeHeaps
 
   // Iteration
@@ -209,16 +210,28 @@
   static void verify_icholder_relocations();
 
   // Deoptimization
+ private:
   static int  mark_for_deoptimization(DepChange& changes);
 #ifdef HOTSWAP
   static int  mark_for_evol_deoptimization(instanceKlassHandle dependee);
 #endif // HOTSWAP
 
+ public:
   static void mark_all_nmethods_for_deoptimization();
   static int  mark_for_deoptimization(Method* dependee);
   static void make_marked_nmethods_zombies();
   static void make_marked_nmethods_not_entrant();
 
+  // Flushing and deoptimization
+  static void flush_dependents_on(instanceKlassHandle dependee);
+  static void flush_dependents_on(Handle call_site, Handle method_handle);
+#ifdef HOTSWAP
+  // Flushing and deoptimization in case of evolution
+  static void flush_evol_dependents_on(instanceKlassHandle dependee);
+#endif // HOTSWAP
+  // Support for fullspeed debugging
+  static void flush_dependents_on_method(methodHandle dependee);
+
   // tells how many nmethods have dependencies
   static int number_of_nmethods_with_dependencies();
 
--- a/src/share/vm/code/dependencies.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/code/dependencies.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -560,7 +560,7 @@
       put_star = !Dependencies::is_concrete_klass((Klass*)arg.metadata_value());
     } else if (arg.is_method()) {
       what = "method ";
-      put_star = !Dependencies::is_concrete_method((Method*)arg.metadata_value());
+      put_star = !Dependencies::is_concrete_method((Method*)arg.metadata_value(), NULL);
     } else if (arg.is_klass()) {
       what = "class  ";
     } else {
@@ -878,8 +878,8 @@
         // Static methods don't override non-static so punt
         return true;
       }
-      if (   !Dependencies::is_concrete_method(lm)
-          && !Dependencies::is_concrete_method(m)
+      if (   !Dependencies::is_concrete_method(lm, k)
+          && !Dependencies::is_concrete_method(m, ctxk)
           && lm->method_holder()->is_subtype_of(m->method_holder()))
         // Method m is overridden by lm, but both are non-concrete.
         return true;
@@ -915,8 +915,17 @@
     } else if (!k->oop_is_instance()) {
       return false; // no methods to find in an array type
     } else {
-      Method* m = InstanceKlass::cast(k)->find_method(_name, _signature);
-      if (m == NULL || !Dependencies::is_concrete_method(m))  return false;
+      // Search class hierarchy first.
+      Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature);
+      if (!Dependencies::is_concrete_method(m, k)) {
+        // Check interface defaults also, if any exist.
+        Array<Method*>* default_methods = InstanceKlass::cast(k)->default_methods();
+        if (default_methods == NULL)
+            return false;
+        m = InstanceKlass::cast(k)->find_method(default_methods, _name, _signature);
+        if (!Dependencies::is_concrete_method(m, NULL))
+            return false;
+      }
       _found_methods[_num_participants] = m;
       // Note:  If add_participant(k) is called,
       // the method m will already be memoized for it.
@@ -1209,15 +1218,17 @@
   return true;
 }
 
-bool Dependencies::is_concrete_method(Method* m) {
-  // Statics are irrelevant to virtual call sites.
-  if (m->is_static())  return false;
-
-  // We could also return false if m does not yet appear to be
-  // executed, if the VM version supports this distinction also.
-  // Default methods are considered "concrete" as well.
-  return !m->is_abstract() &&
-         !m->is_overpass(); // error functions aren't concrete
+bool Dependencies::is_concrete_method(Method* m, Klass * k) {
+  // NULL is not a concrete method,
+  // statics are irrelevant to virtual call sites,
+  // abstract methods are not concrete,
+  // overpass (error) methods are not concrete if k is abstract
+  //
+  // note "true" is conservative answer --
+  //     overpass clause is false if k == NULL, implies return true if
+  //     answer depends on overpass clause.
+  return ! ( m == NULL || m -> is_static() || m -> is_abstract() ||
+             m->is_overpass() && k != NULL && k -> is_abstract() );
 }
 
 
@@ -1242,16 +1253,6 @@
   return true;
 }
 
-bool Dependencies::is_concrete_method(ciMethod* m) {
-  // Statics are irrelevant to virtual call sites.
-  if (m->is_static())  return false;
-
-  // We could also return false if m does not yet appear to be
-  // executed, if the VM version supports this distinction also.
-  return !m->is_abstract();
-}
-
-
 bool Dependencies::has_finalizable_subclass(ciInstanceKlass* k) {
   return k->has_finalizable_subclass();
 }
@@ -1469,7 +1470,7 @@
   Klass* wit = wf.find_witness_definer(ctxk);
   if (wit != NULL)  return NULL;  // Too many witnesses.
   Method* fm = wf.found_method(0);  // Will be NULL if num_parts == 0.
-  if (Dependencies::is_concrete_method(m)) {
+  if (Dependencies::is_concrete_method(m, ctxk)) {
     if (fm == NULL) {
       // It turns out that m was always the only implementation.
       fm = m;
@@ -1499,61 +1500,6 @@
   return wf.find_witness_definer(ctxk, changes);
 }
 
-// Find the set of all non-abstract methods under ctxk that match m[0].
-// (The method m[0] must be defined or inherited in ctxk.)
-// Include m itself in the set, unless it is abstract.
-// Fill the given array m[0..(mlen-1)] with this set, and return the length.
-// (The length may be zero if no concrete methods are found anywhere.)
-// If there are too many concrete methods to fit in marray, return -1.
-int Dependencies::find_exclusive_concrete_methods(Klass* ctxk,
-                                                  int mlen,
-                                                  Method* marray[]) {
-  Method* m0 = marray[0];
-  ClassHierarchyWalker wf(m0);
-  assert(wf.check_method_context(ctxk, m0), "proper context");
-  wf.record_witnesses(mlen);
-  bool participants_hide_witnesses = true;
-  Klass* wit = wf.find_witness_definer(ctxk);
-  if (wit != NULL)  return -1;  // Too many witnesses.
-  int num = wf.num_participants();
-  assert(num <= mlen, "oob");
-  // Keep track of whether m is also part of the result set.
-  int mfill = 0;
-  assert(marray[mfill] == m0, "sanity");
-  if (Dependencies::is_concrete_method(m0))
-    mfill++;  // keep m0 as marray[0], the first result
-  for (int i = 0; i < num; i++) {
-    Method* fm = wf.found_method(i);
-    if (fm == m0)  continue;  // Already put this guy in the list.
-    if (mfill == mlen) {
-      return -1;              // Oops.  Too many methods after all!
-    }
-    marray[mfill++] = fm;
-  }
-#ifndef PRODUCT
-  // Make sure the dependency mechanism will pass this discovery:
-  if (VerifyDependencies) {
-    // Turn off dependency tracing while actually testing deps.
-    FlagSetting fs(TraceDependencies, false);
-    switch (mfill) {
-    case 1:
-      guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]),
-                "verify dep.");
-      break;
-    case 2:
-      guarantee(NULL == (void *)
-                check_exclusive_concrete_methods(ctxk, marray[0], marray[1]),
-                "verify dep.");
-      break;
-    default:
-      ShouldNotReachHere();  // mlen > 2 yet supported
-    }
-  }
-#endif //PRODUCT
-  return mfill;
-}
-
-
 Klass* Dependencies::check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes) {
   Klass* search_at = ctxk;
   if (changes != NULL)
@@ -1561,7 +1507,6 @@
   return find_finalizable_subclass(search_at);
 }
 
-
 Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
   assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "sanity");
   assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
--- a/src/share/vm/code/dependencies.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/code/dependencies.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -288,7 +288,7 @@
   // In that case, there would be a middle ground between concrete
   // and abstract (as defined by the Java language and VM).
   static bool is_concrete_klass(Klass* k);    // k is instantiable
-  static bool is_concrete_method(Method* m);  // m is invocable
+  static bool is_concrete_method(Method* m, Klass* k);  // m is invocable
   static Klass* find_finalizable_subclass(Klass* k);
 
   // These versions of the concreteness queries work through the CI.
@@ -302,7 +302,6 @@
   // not go back into the VM to get their value; they must cache the
   // bit in the CI, either eagerly or lazily.)
   static bool is_concrete_klass(ciInstanceKlass* k); // k appears instantiable
-  static bool is_concrete_method(ciMethod* m);       // m appears invocable
   static bool has_finalizable_subclass(ciInstanceKlass* k);
 
   // As a general rule, it is OK to compile under the assumption that
@@ -349,7 +348,6 @@
   static Klass*    find_unique_concrete_subtype(Klass* ctxk);
   static Method*   find_unique_concrete_method(Klass* ctxk, Method* m);
   static int       find_exclusive_concrete_subtypes(Klass* ctxk, int klen, Klass* k[]);
-  static int       find_exclusive_concrete_methods(Klass* ctxk, int mlen, Method* m[]);
 
   // Create the encoding which will be stored in an nmethod.
   void encode_content_bytes();
--- a/src/share/vm/code/nmethod.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/code/nmethod.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -2310,17 +2310,6 @@
 #endif // !SHARK
 }
 
-
-oop nmethod::embeddedOop_at(u_char* p) {
-  RelocIterator iter(this, p, p + 1);
-  while (iter.next())
-    if (iter.type() == relocInfo::oop_type) {
-      return iter.oop_reloc()->oop_value();
-    }
-  return NULL;
-}
-
-
 inline bool includes(void* p, void* from, void* to) {
   return from <= p && p < to;
 }
--- a/src/share/vm/code/nmethod.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/code/nmethod.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -730,11 +730,6 @@
   int  compile_id() const                         { return _compile_id; }
   const char* compile_kind() const;
 
-  // For debugging
-  // CompiledIC*    IC_at(char* p) const;
-  // PrimitiveIC*   primitiveIC_at(char* p) const;
-  oop embeddedOop_at(address p);
-
   // tells if any of this method's dependencies have been invalidated
   // (this is expensive!)
   static void check_all_dependencies(DepChange& changes);
--- a/src/share/vm/compiler/compileBroker.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/compiler/compileBroker.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -252,7 +252,7 @@
   } else {
     task = new CompileTask();
     DEBUG_ONLY(_num_allocated_tasks++;)
-    assert (_num_allocated_tasks < 10000, "Leaking compilation tasks?");
+    assert (WhiteBoxAPI || _num_allocated_tasks < 10000, "Leaking compilation tasks?");
     task->set_next(NULL);
     task->set_is_free(true);
   }
@@ -1470,7 +1470,9 @@
 
   // The method may be explicitly excluded by the user.
   bool quietly;
-  if (CompilerOracle::should_exclude(method, quietly)) {
+  double scale;
+  if (CompilerOracle::should_exclude(method, quietly)
+      || (CompilerOracle::has_option_value(method, "CompileThresholdScaling", scale) && scale == 0)) {
     if (!quietly) {
       // This does not happen quietly...
       ResourceMark rm;
--- a/src/share/vm/compiler/compilerOracle.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/compiler/compilerOracle.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -105,7 +105,6 @@
     tty->print(".");
     print_symbol(method_name(), _method_mode);
     if (signature() != NULL) {
-      tty->print(" ");
       signature()->print_symbol_on(tty);
     }
   }
@@ -467,43 +466,85 @@
   return UnknownCommand;
 }
 
+static void usage() {
+  tty->cr();
+  tty->print_cr("The CompileCommand option enables the user of the JVM to control specific");
+  tty->print_cr("behavior of the dynamic compilers. Many commands require a pattern that defines");
+  tty->print_cr("the set of methods the command shall be applied to. The CompileCommand");
+  tty->print_cr("option provides the following commands:");
+  tty->cr();
+  tty->print_cr("  break,<pattern>       - debug breakpoint in compiler and in generated code");
+  tty->print_cr("  print,<pattern>       - print assembly");
+  tty->print_cr("  exclude,<pattern>     - don't compile or inline");
+  tty->print_cr("  inline,<pattern>      - always inline");
+  tty->print_cr("  dontinline,<pattern>  - don't inline");
+  tty->print_cr("  compileonly,<pattern> - compile only");
+  tty->print_cr("  log,<pattern>         - log compilation");
+  tty->print_cr("  option,<pattern>,<option type>,<option name>,<value>");
+  tty->print_cr("                        - set value of custom option");
+  tty->print_cr("  option,<pattern>,<bool option name>");
+  tty->print_cr("                        - shorthand for setting boolean flag");
+  tty->print_cr("  quiet                 - silence the compile command output");
+  tty->print_cr("  help                  - print this text");
+  tty->cr();
+  tty->print_cr("The preferred format for the method matching pattern is:");
+  tty->print_cr("  package/Class.method()");
+  tty->cr();
+  tty->print_cr("For backward compatibility this form is also allowed:");
+  tty->print_cr("  package.Class::method()");
+  tty->cr();
+  tty->print_cr("The signature can be separated by an optional whitespace or comma:");
+  tty->print_cr("  package/Class.method ()");
+  tty->cr();
+  tty->print_cr("The class and method identifier can be used together with leading or");
+  tty->print_cr("trailing *'s for a small amount of wildcarding:");
+  tty->print_cr("  *ackage/Clas*.*etho*()");
+  tty->cr();
+  tty->print_cr("It is possible to use more than one CompileCommand on the command line:");
+  tty->print_cr("  -XX:CompileCommand=exclude,java/*.* -XX:CompileCommand=log,java*.*");
+  tty->cr();
+  tty->print_cr("The CompileCommands can be loaded from a file with the flag");
+  tty->print_cr("-XX:CompileCommandFile=<file> or be added to the file '.hotspot_compiler'");
+  tty->print_cr("Use the same format in the file as the argument to the CompileCommand flag.");
+  tty->print_cr("Add one command on each line.");
+  tty->print_cr("  exclude java/*.*");
+  tty->print_cr("  option java/*.* ReplayInline");
+  tty->cr();
+  tty->print_cr("The following commands have conflicting behavior: 'exclude', 'inline', 'dontinline',");
+  tty->print_cr("and 'compileonly'. There is no priority of commands. Applying (a subset of) these");
+  tty->print_cr("commands to the same method results in undefined behavior.");
+  tty->cr();
+};
 
-static void usage() {
-  tty->print_cr("  CompileCommand and the CompilerOracle allows simple control over");
-  tty->print_cr("  what's allowed to be compiled.  The standard supported directives");
-  tty->print_cr("  are exclude and compileonly.  The exclude directive stops a method");
-  tty->print_cr("  from being compiled and compileonly excludes all methods except for");
-  tty->print_cr("  the ones mentioned by compileonly directives.  The basic form of");
-  tty->print_cr("  all commands is a command name followed by the name of the method");
-  tty->print_cr("  in one of two forms: the standard class file format as in");
-  tty->print_cr("  class/name.methodName or the PrintCompilation format");
-  tty->print_cr("  class.name::methodName.  The method name can optionally be followed");
-  tty->print_cr("  by a space then the signature of the method in the class file");
-  tty->print_cr("  format.  Otherwise the directive applies to all methods with the");
-  tty->print_cr("  same name and class regardless of signature.  Leading and trailing");
-  tty->print_cr("  *'s in the class and/or method name allows a small amount of");
-  tty->print_cr("  wildcarding.  ");
-  tty->cr();
-  tty->print_cr("  Examples:");
-  tty->cr();
-  tty->print_cr("  exclude java/lang/StringBuffer.append");
-  tty->print_cr("  compileonly java/lang/StringBuffer.toString ()Ljava/lang/String;");
-  tty->print_cr("  exclude java/lang/String*.*");
-  tty->print_cr("  exclude *.toString");
-}
+// The JVM specification defines the allowed characters.
+// Tokens that are disallowed by the JVM specification can have
+// a meaning to the parser so we need to include them here.
+// The parser does not enforce all rules of the JVMS - a successful parse
+// does not mean that it is an allowed name. Illegal names will
+// be ignored since they never can match a class or method.
+//
+// '\0' and 0xf0-0xff are disallowed in constant string values
+// 0x20 ' ', 0x09 '\t' and, 0x2c ',' are used in the matching
+// 0x5b '[' and 0x5d ']' can not be used because of the matcher
+// 0x28 '(' and 0x29 ')' are used for the signature
+// 0x2e '.' is always replaced before the matching
+// 0x2f '/' is only used in the class name as package separator
 
-
-// The characters allowed in a class or method name.  All characters > 0x7f
-// are allowed in order to handle obfuscated class files (e.g. Volano)
-#define RANGEBASE "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_<>" \
-        "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \
-        "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \
-        "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \
-        "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \
-        "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \
-        "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \
-        "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" \
-        "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+#define RANGEBASE "\x1\x2\x3\x4\x5\x6\x7\x8\xa\xb\xc\xd\xe\xf" \
+    "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \
+    "\x21\x22\x23\x24\x25\x26\x27\x2a\x2b\x2c\x2d" \
+    "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \
+    "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \
+    "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5c\x5e\x5f" \
+    "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \
+    "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \
+    "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \
+    "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \
+    "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
 
 #define RANGE0 "[*" RANGEBASE "]"
 #define RANGESLASH "[*" RANGEBASE "/]"
@@ -512,7 +553,8 @@
   int match = MethodMatcher::Exact;
   while (name[0] == '*') {
     match |= MethodMatcher::Suffix;
-    strcpy(name, name + 1);
+    // Copy remaining string plus NUL to the beginning
+    memmove(name, name + 1, strlen(name + 1) + 1);
   }
 
   if (strcmp(name, "*") == 0) return MethodMatcher::Any;
@@ -648,6 +690,13 @@
   return NULL;
 }
 
+int skip_whitespace(char* line) {
+  // Skip any leading spaces
+  int whitespace_read = 0;
+  sscanf(line, "%*[ \t]%n", &whitespace_read);
+  return whitespace_read;
+}
+
 void CompilerOracle::parse_from_line(char* line) {
   if (line[0] == '\0') return;
   if (line[0] == '#')  return;
@@ -681,8 +730,9 @@
 
   if (command == UnknownCommand) {
     ttyLocker ttyl;
-    tty->print_cr("CompilerOracle: unrecognized line");
+    tty->print_cr("CompileCommand: unrecognized command");
     tty->print_cr("  \"%s\"", original_line);
+    CompilerOracle::print_tip();
     return;
   }
 
@@ -712,9 +762,11 @@
     Symbol* signature = NULL;
 
     line += bytes_read;
+
     // there might be a signature following the method.
     // signatures always begin with ( so match that by hand
-    if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
+    line += skip_whitespace(line);
+    if (1 == sscanf(line, "(%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
       sig[0] = '(';
       line += bytes_read;
       signature = SymbolTable::new_symbol(sig, CHECK);
@@ -736,11 +788,13 @@
       //
       // For future extensions: extend scan_flag_and_value()
       char option[256]; // stores flag for Type (1) and type of Type (2)
-      while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
+
+      line += skip_whitespace(line);
+      while (sscanf(line, "%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
         if (match != NULL && !_quiet) {
           // Print out the last match added
           ttyLocker ttyl;
-          tty->print("CompilerOracle: %s ", command_names[command]);
+          tty->print("CompileCommand: %s ", command_names[command]);
           match->print();
         }
         line += bytes_read;
@@ -766,6 +820,7 @@
           // Type (1) option
           match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true);
         }
+        line += skip_whitespace(line);
       } // while(
     } else {
       match = add_predicate(command, c_name, c_match, m_name, m_match, signature);
@@ -775,26 +830,36 @@
   ttyLocker ttyl;
   if (error_msg != NULL) {
     // an error has happened
-    tty->print_cr("CompilerOracle: unrecognized line");
+    tty->print_cr("CompileCommand: An error occured during parsing");
     tty->print_cr("  \"%s\"", original_line);
     if (error_msg != NULL) {
       tty->print_cr("%s", error_msg);
     }
+    CompilerOracle::print_tip();
+
   } else {
     // check for remaining characters
     bytes_read = 0;
     sscanf(line, "%*[ \t]%n", &bytes_read);
     if (line[bytes_read] != '\0') {
-      tty->print_cr("CompilerOracle: unrecognized line");
+      tty->print_cr("CompileCommand: Bad pattern");
       tty->print_cr("  \"%s\"", original_line);
       tty->print_cr("  Unrecognized text %s after command ", line);
+      CompilerOracle::print_tip();
     } else if (match != NULL && !_quiet) {
-      tty->print("CompilerOracle: %s ", command_names[command]);
+      tty->print("CompileCommand: %s ", command_names[command]);
       match->print();
     }
   }
 }
 
+void CompilerOracle::print_tip() {
+  tty->cr();
+  tty->print_cr("Usage: '-XX:CompileCommand=command,\"package/Class.method()\"'");
+  tty->print_cr("Use:   '-XX:CompileCommand=help' for more information.");
+  tty->cr();
+}
+
 static const char* default_cc_file = ".hotspot_compiler";
 
 static const char* cc_file() {
--- a/src/share/vm/compiler/compilerOracle.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/compiler/compilerOracle.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -34,6 +34,7 @@
 class CompilerOracle : AllStatic {
  private:
   static bool _quiet;
+  static void print_tip();
 
  public:
 
--- a/src/share/vm/compiler/disassembler.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/compiler/disassembler.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -345,21 +345,6 @@
       if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr);
       return;
     }
-
-    oop obj;
-    if (_nm != NULL
-        && (obj = _nm->embeddedOop_at(cur_insn())) != NULL
-        && (address) obj == adr
-        && Universe::heap()->is_in(obj)
-        && Universe::heap()->is_in(obj->klass())) {
-      julong c = st->count();
-      obj->print_value_on(st);
-      if (st->count() == c) {
-        // No output.  (Can happen in product builds.)
-        st->print("(a %s)", obj->klass()->external_name());
-      }
-      return;
-    }
   }
 
   // Fall through to a simple (hexadecimal) numeral.
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -2560,12 +2560,12 @@
      x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,   \
      x }
 
-// Initialize with default setting of CMSParPromoteBlocksToClaim, _not_
-// OldPLABSize, whose static default is different; if overridden at the
+// Initialize with default setting for CMS, _not_
+// generic OldPLABSize, whose static default is different; if overridden at the
 // command-line, this will get reinitialized via a call to
 // modify_initialization() below.
 AdaptiveWeightedAverage CFLS_LAB::_blocks_to_claim[]    =
-  VECTOR_257(AdaptiveWeightedAverage(OldPLABWeight, (float)CMSParPromoteBlocksToClaim));
+  VECTOR_257(AdaptiveWeightedAverage(OldPLABWeight, (float)CFLS_LAB::_default_dynamic_old_plab_size));
 size_t CFLS_LAB::_global_num_blocks[]  = VECTOR_257(0);
 uint   CFLS_LAB::_global_num_workers[] = VECTOR_257(0);
 
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -690,6 +690,9 @@
   void get_from_global_pool(size_t word_sz, AdaptiveFreeList<FreeChunk>* fl);
 
 public:
+  static const int _default_dynamic_old_plab_size = 16;
+  static const int _default_static_old_plab_size  = 50;
+
   CFLS_LAB(CompactibleFreeListSpace* cfls);
 
   // Allocate and return a block of the given size, or else return NULL.
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -645,7 +645,7 @@
   // Support for parallelizing survivor space rescan
   if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
     const size_t max_plab_samples =
-      ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
+      ((DefNewGeneration*)_young_gen)->max_survivor_size() / plab_sample_minimum_size();
 
     _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC);
     _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC);
@@ -703,6 +703,12 @@
   _inter_sweep_timer.start();  // start of time
 }
 
+size_t CMSCollector::plab_sample_minimum_size() {
+  // The default value of MinTLABSize is 2k, but there is
+  // no way to get the default value if the flag has been overridden.
+  return MAX2(ThreadLocalAllocBuffer::min_size() * HeapWordSize, 2 * K);
+}
+
 const char* ConcurrentMarkSweepGeneration::name() const {
   return "concurrent mark-sweep generation";
 }
@@ -1611,14 +1617,15 @@
 
   // If the collection is being acquired from the background
   // collector, there may be references on the discovered
-  // references lists that have NULL referents (being those
-  // that were concurrently cleared by a mutator) or
-  // that are no longer active (having been enqueued concurrently
-  // by the mutator).
-  // Scrub the list of those references because Mark-Sweep-Compact
-  // code assumes referents are not NULL and that all discovered
-  // Reference objects are active.
-  ref_processor()->clean_up_discovered_references();
+  // references lists.  Abandon those references, since some
+  // of them may have become unreachable after concurrent
+  // discovery; the STW compacting collector will redo discovery
+  // more precisely, without being subject to floating garbage.
+  // Leaving otherwise unreachable references in the discovered
+  // lists would require special handling.
+  ref_processor()->disable_discovery();
+  ref_processor()->abandon_partial_discovery();
+  ref_processor()->verify_no_references_recorded();
 
   if (first_state > Idling) {
     save_heap_summary();
@@ -1684,7 +1691,7 @@
   ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
 
   ref_processor()->set_enqueuing_is_done(false);
-  ref_processor()->enable_discovery(false /*verify_disabled*/, false /*check_no_refs*/);
+  ref_processor()->enable_discovery();
   ref_processor()->setup_policy(clear_all_soft_refs);
   // If an asynchronous collection finishes, the _modUnionTable is
   // all clear.  If we are assuming the collection from an asynchronous
@@ -3001,7 +3008,7 @@
                     Mutex::_no_safepoint_check_flag);
     checkpointRootsInitialWork();
     // enable ("weak") refs discovery
-    rp->enable_discovery(true /*verify_disabled*/, true /*check_no_refs*/);
+    rp->enable_discovery();
     _collectorState = Marking;
   }
   SpecializationStats::print();
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -737,6 +737,10 @@
   size_t*    _cursor;
   ChunkArray* _survivor_plab_array;
 
+  // A bounded minimum size of PLABs, should not return too small values since
+  // this will affect the size of the data structures used for parallel young gen rescan
+  size_t plab_sample_minimum_size();
+
   // Support for marking stack overflow handling
   bool take_from_overflow_list(size_t num, CMSMarkStack* to_stack);
   bool par_take_from_overflow_list(size_t num,
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -971,7 +971,7 @@
   // Start Concurrent Marking weak-reference discovery.
   ReferenceProcessor* rp = g1h->ref_processor_cm();
   // enable ("weak") refs discovery
-  rp->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+  rp->enable_discovery();
   rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
 
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
@@ -1910,7 +1910,6 @@
   }
 
   void work(uint worker_id) {
-    double start = os::elapsedTime();
     FreeRegionList local_cleanup_list("Local Cleanup List");
     HRRSCleanupTask hrrs_cleanup_task;
     G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list,
--- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,13 @@
     // active field set to true.
     PtrQueue(qset_, perm, true /* active */) { }
 
+  // Flush before destroying; queue may be used to capture pending work while
+  // doing something else, with auto-flush on completion.
+  ~DirtyCardQueue() { if (!is_permanent()) flush(); }
+
+  // Process queue entries and release resources.
+  void flush() { flush_impl(); }
+
   // Apply the closure to all elements, and reset the index to make the
   // buffer empty.  If a closure application returns "false", return
   // "false" immediately, halting the iteration.  If "consume" is true,
--- a/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -254,25 +254,23 @@
 HeapRegion* SurvivorGCAllocRegion::allocate_new_region(size_t word_size,
                                                        bool force) {
   assert(!force, "not supported for GC alloc regions");
-  return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForSurvived);
+  return _g1h->new_gc_alloc_region(word_size, count(), InCSetState::Young);
 }
 
 void SurvivorGCAllocRegion::retire_region(HeapRegion* alloc_region,
                                           size_t allocated_bytes) {
-  _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
-                               GCAllocForSurvived);
+  _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, InCSetState::Young);
 }
 
 HeapRegion* OldGCAllocRegion::allocate_new_region(size_t word_size,
                                                   bool force) {
   assert(!force, "not supported for GC alloc regions");
-  return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForTenured);
+  return _g1h->new_gc_alloc_region(word_size, count(), InCSetState::Old);
 }
 
 void OldGCAllocRegion::retire_region(HeapRegion* alloc_region,
                                      size_t allocated_bytes) {
-  _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
-                               GCAllocForTenured);
+  _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, InCSetState::Old);
 }
 
 HeapRegion* OldGCAllocRegion::release() {
--- a/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Tue Feb 03 09:56:21 2015 +0000
@@ -99,8 +99,8 @@
   }
 
   if (ResizePLAB) {
-    _g1h->_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
-    _g1h->_old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
+    _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);
   }
 }
 
@@ -113,15 +113,16 @@
 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
   ParGCAllocBuffer(gclab_word_size), _retired(true) { }
 
-HeapWord* G1ParGCAllocator::allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) {
-  HeapWord* obj = NULL;
-  size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
+HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest,
+                                                        size_t word_sz,
+                                                        AllocationContext_t context) {
+  size_t gclab_word_size = _g1h->desired_plab_sz(dest);
   if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
-    G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose, context);
+    G1ParGCAllocBuffer* alloc_buf = alloc_buffer(dest, context);
     add_to_alloc_buffer_waste(alloc_buf->words_remaining());
     alloc_buf->retire(false /* end_of_gc */, false /* retain */);
 
-    HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size, context);
+    HeapWord* buf = _g1h->par_allocate_during_gc(dest, gclab_word_size, context);
     if (buf == NULL) {
       return NULL; // Let caller handle allocation failure.
     }
@@ -129,30 +130,33 @@
     alloc_buf->set_word_size(gclab_word_size);
     alloc_buf->set_buf(buf);
 
-    obj = alloc_buf->allocate(word_sz);
+    HeapWord* const obj = alloc_buf->allocate(word_sz);
     assert(obj != NULL, "buffer was definitely big enough...");
+    return obj;
   } else {
-    obj = _g1h->par_allocate_during_gc(purpose, word_sz, context);
+    return _g1h->par_allocate_during_gc(dest, word_sz, context);
   }
-  return obj;
 }
 
 G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) :
-            G1ParGCAllocator(g1h),
-            _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)),
-            _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)) {
-
-  _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer;
-  _alloc_buffers[GCAllocForTenured]  = &_tenured_alloc_buffer;
-
+  G1ParGCAllocator(g1h),
+  _surviving_alloc_buffer(g1h->desired_plab_sz(InCSetState::Young)),
+  _tenured_alloc_buffer(g1h->desired_plab_sz(InCSetState::Old)) {
+  for (uint state = 0; state < InCSetState::Num; state++) {
+    _alloc_buffers[state] = NULL;
+  }
+  _alloc_buffers[InCSetState::Young] = &_surviving_alloc_buffer;
+  _alloc_buffers[InCSetState::Old]  = &_tenured_alloc_buffer;
 }
 
 void G1DefaultParGCAllocator::retire_alloc_buffers() {
-  for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
-    size_t waste = _alloc_buffers[ap]->words_remaining();
-    add_to_alloc_buffer_waste(waste);
-    _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
-                                               true /* end_of_gc */,
-                                               false /* retain */);
+  for (uint state = 0; state < InCSetState::Num; state++) {
+    G1ParGCAllocBuffer* const buf = _alloc_buffers[state];
+    if (buf != NULL) {
+      add_to_alloc_buffer_waste(buf->words_remaining());
+      buf->flush_stats_and_retire(_g1h->alloc_buffer_stats(state),
+                                  true /* end_of_gc */,
+                                  false /* retain */);
+    }
   }
 }
--- a/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Tue Feb 03 10:30:16 2015 +0100
+++ b/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Tue Feb 03 09:56:21 2015 +0000
@@ -27,14 +27,9 @@
 
 #include "gc_implementation/g1/g1AllocationContext.hpp"
 #include "gc_implementation/g1/g1AllocRegion.hpp"
+#include "gc_implementation/g1/g1InCSetState.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
 
-enum GCAllocPurpose {
-  GCAllocForTenured,
-  GCAllocForSurvived,
-  GCAllocPurposeCount
-};
-
 // Base class for G1 allocators.
 class G1Allocator : public CHeapObj<mtGC> {
   friend class VMStructs;
@@ -178,20 +173,40 @@
 protected:
   G1CollectedHeap* _g1h;
 
+  // The survivor alignment in effect in bytes.
+  // == 0 : don't align survivors
+  // != 0 : align survivors to that alignment
+  // These values were chosen to favor the non-alignment case since some
+  // architectures have a special compare against zero instructions.
+  const uint _survivor_alignment_bytes;
+
   size_t _alloc_buffer_waste;
   size_t _undo_waste;
 
   void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
   void add_to_undo_waste(size_t waste)         { _undo_waste += waste; }
 
-  HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context);
+  virtual void retire_alloc_buffers() = 0;
+  virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
 
-  virtual void retire_alloc_buffers() = 0;
-  virtual G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, AllocationContext_t context) = 0;
+  // Calculate the survivor space object alignment in bytes. Returns that or 0 if
+  // there are no restrictions on survivor alignment.
+  static uint calc_survivor_alignment_bytes() {
+    assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity");
+    if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) {
+      // No need to align objects in the survivors differently, return 0
+      // which means "survivor alignment is not used".
+      return 0;
+    } else {
+      assert(SurvivorAlignmentInBytes > 0, "sanity");
+      return SurvivorAlignmentInBytes;
+    }
+  }
 
 public:
   G1ParGCAllocator(G1CollectedHeap* g1h) :
-    _g1h(g1h), _alloc_buffer_waste(0), _undo_waste(0) {
+    _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()),
+    _alloc_buffer_waste(0), _undo_waste(0) {
   }
 
   static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
@@ -199,24 +214,40 @@
   size_t alloc_buffer_waste() { return _alloc_buffer_waste; }
   size_t undo_waste() {return _undo_waste; }
 
-  HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) {
-    HeapWord* obj = NULL;
-    if (purpose == GCAllocForSurvived) {
-      obj = alloc_buffer(purpose, context)->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
+  // Allocate word_sz words in dest, either directly into the regions or by
+  // allocating a new PLAB. Returns the address of the allocated memory, NULL if