changeset 23566:ac9a68124ba9

Merge
author asaha
date Tue, 05 Jan 2016 08:40:50 -0800
parents c3091ebd2811 (diff) 451dda77f6c2 (current diff)
children 2a2720daacaa
files .hgtags
diffstat 71 files changed, 853 insertions(+), 852 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Dec 22 12:28:01 2015 -0800
+++ b/.hgtags	Tue Jan 05 08:40:50 2016 -0800
@@ -795,3 +795,6 @@
 a8e4754b89aecc388623394a20f6d43d4c58f083 jdk8u72-b13
 dc2fdd4e0b8105268b8231040f761f27ab4523f2 jdk8u72-b14
 d6670c5d49ba381405ec9f69a78ccc5b8b0c8473 jdk8u72-b15
+d7b01fb81aa8a5437cb03bc36afe15cf0e55fb89 jdk8u76-b00
+c1679cc87ba045219169cabb6b9b378c2b5cc578 jdk8u76-b01
+218483967e52b419d885d34af4488a81c5133804 jdk8u76-b02
--- a/agent/src/os/linux/LinuxDebuggerLocal.c	Tue Dec 22 12:28:01 2015 -0800
+++ b/agent/src/os/linux/LinuxDebuggerLocal.c	Tue Jan 05 08:40:50 2016 -0800
@@ -209,9 +209,12 @@
   verifyBitness(env, (char *) &buf);
   CHECK_EXCEPTION;
 
+  char err_buf[200];
   struct ps_prochandle* ph;
-  if ( (ph = Pgrab(jpid)) == NULL) {
-    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
+  if ( (ph = Pgrab(jpid, err_buf, sizeof(err_buf))) == NULL) {
+    char msg[230];
+    snprintf(msg, sizeof(msg), "Can't attach to the process: %s", err_buf);
+    THROW_NEW_DEBUGGER_EXCEPTION(msg);
   }
   (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
   fillThreadsAndLoadObjects(env, this_obj, ph);
--- a/agent/src/os/linux/libproc.h	Tue Dec 22 12:28:01 2015 -0800
+++ b/agent/src/os/linux/libproc.h	Tue Jan 05 08:40:50 2016 -0800
@@ -69,6 +69,7 @@
 
 
 #if defined(sparc) || defined(sparcv9) || defined(ppc64)
+#include <asm/ptrace.h>
 #define user_regs_struct  pt_regs
 #endif
 
@@ -82,7 +83,7 @@
 struct ps_prochandle;
 
 // attach to a process
-struct ps_prochandle* Pgrab(pid_t pid);
+struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len);
 
 // attach to a core dump
 struct ps_prochandle* Pgrab_core(const char* execfile, const char* corefile);
--- a/agent/src/os/linux/ps_proc.c	Tue Dec 22 12:28:01 2015 -0800
+++ b/agent/src/os/linux/ps_proc.c	Tue Jan 05 08:40:50 2016 -0800
@@ -215,9 +215,12 @@
 }
 
 // attach to a process/thread specified by "pid"
-static bool ptrace_attach(pid_t pid) {
+static bool ptrace_attach(pid_t pid, char* err_buf, size_t err_buf_len) {
   if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
-    print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
+    char buf[200];
+    char* msg = strerror_r(errno, buf, sizeof(buf));
+    snprintf(err_buf, err_buf_len, "ptrace(PTRACE_ATTACH, ..) failed for %d: %s", pid, msg);
+    print_debug("%s\n", err_buf);
     return false;
   } else {
     return ptrace_waitpid(pid);
@@ -339,16 +342,17 @@
 };
 
 // attach to the process. One and only one exposed stuff
-struct ps_prochandle* Pgrab(pid_t pid) {
+struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len) {
   struct ps_prochandle* ph = NULL;
   thread_info* thr = NULL;
 
   if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
-     print_debug("can't allocate memory for ps_prochandle\n");
+     snprintf(err_buf, err_buf_len, "can't allocate memory for ps_prochandle");
+     print_debug("%s\n", err_buf);
      return NULL;
   }
 
-  if (ptrace_attach(pid) != true) {
+  if (ptrace_attach(pid, err_buf, err_buf_len) != true) {
      free(ph);
      return NULL;
   }
@@ -371,7 +375,7 @@
   thr = ph->threads;
   while (thr) {
      // don't attach to the main thread again
-     if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id) != true) {
+    if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) {
         // even if one attach fails, we get return NULL
         Prelease(ph);
         return NULL;
--- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Tue Dec 22 12:28:01 2015 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Tue Jan 05 08:40:50 2016 -0800
@@ -1446,7 +1446,7 @@
                 if (type.equals("threads")) {
                     Threads threads = VM.getVM().getThreads();
                     for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
-                        Address base = thread.getBaseOfStackPointer();
+                        Address base = thread.getStackBase();
                         Address end = thread.getLastJavaSP();
                         if (end == null) continue;
                         if (end.lessThan(base)) {
@@ -1454,11 +1454,13 @@
                             base = end;
                             end = tmp;
                         }
-                        out.println("Searching " + base + " " + end);
+                        //out.println("Searching " + base + " " + end);
                         while (base != null && base.lessThan(end)) {
                             Address val = base.getAddressAt(0);
                             if (AddressOps.equal(val, value)) {
-                                out.println(base);
+                                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                                thread.printThreadIDOn(new PrintStream(bos));
+                                out.println("found on the stack of thread " + bos.toString() + " at " + base);
                             }
                             base = base.addOffsetTo(stride);
                         }
@@ -1601,6 +1603,8 @@
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
                             out.println("Thread " + bos.toString() + " Address " + thread.getAddress());
+                            thread.printInfoOn(out);
+                            out.println(" ");
                             if (!all) return;
                         }
                     }
@@ -1618,6 +1622,8 @@
                     for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
                         thread.printThreadIDOn(out);
                         out.println(" " + thread.getThreadName());
+                        thread.printInfoOn(out);
+                        out.println("\n...");
                     }
                 }
             }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Tue Dec 22 12:28:01 2015 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Tue Jan 05 08:40:50 2016 -0800
@@ -415,7 +415,7 @@
     } else {
       tty.println("No Java frames present");
     }
-    tty.println("Base of Stack: " + getBaseOfStackPointer());
+    tty.println("Base of Stack: " + getStackBase());
     tty.println("Last_Java_SP: " + getLastJavaSP());
     tty.println("Last_Java_FP: " + getLastJavaFP());
     tty.println("Last_Java_PC: " + getLastJavaPC());
--- a/make/linux/Makefile	Tue Dec 22 12:28:01 2015 -0800
+++ b/make/linux/Makefile	Tue Jan 05 08:40:50 2016 -0800
@@ -67,8 +67,12 @@
   endif
 endif
 # C1 is not ported on ppc64, so we cannot build a tiered VM:
-ifeq ($(ARCH),ppc64)
-  FORCE_TIERED=0
+# Notice: after 8046471 ARCH will be 'ppc' for top-level ppc64 builds but
+# 'ppc64' for HotSpot-only ppc64 builds. Need to detect both variants here!
+ifneq (,$(findstring $(ARCH), ppc ppc64))
+  ifeq ($(ARCH_DATA_MODEL), 64)
+    FORCE_TIERED=0
+  endif
 endif
 
 ifdef LP64
--- a/make/linux/makefiles/defs.make	Tue Dec 22 12:28:01 2015 -0800
+++ b/make/linux/makefiles/defs.make	Tue Jan 05 08:40:50 2016 -0800
@@ -69,7 +69,7 @@
 endif
 
 # sparc
-ifeq ($(ARCH), sparc64)
+ifneq (,$(findstring $(ARCH), sparc))
   ifeq ($(ARCH_DATA_MODEL), 64)
     ARCH_DATA_MODEL  = 64
     MAKE_ARGS        += LP64=1
@@ -83,39 +83,35 @@
   HS_ARCH            = sparc
 endif
 
-# amd64/x86_64
-ifneq (,$(findstring $(ARCH), amd64 x86_64))
+# i686/i586 and amd64/x86_64
+ifneq (,$(findstring $(ARCH), amd64 x86_64 i686 i586))
   ifeq ($(ARCH_DATA_MODEL), 64)
     ARCH_DATA_MODEL = 64
     MAKE_ARGS       += LP64=1
     PLATFORM        = linux-amd64
     VM_PLATFORM     = linux_amd64
-    HS_ARCH         = x86
   else
     ARCH_DATA_MODEL = 32
     PLATFORM        = linux-i586
     VM_PLATFORM     = linux_i486
-    HS_ARCH         = x86
-    # We have to reset ARCH to i686 since SRCARCH relies on it
-    ARCH            = i686
   endif
+  HS_ARCH           = x86
 endif
 
-# i686/i586 ie 32-bit x86
-ifneq (,$(findstring $(ARCH), i686 i586))
-  ARCH_DATA_MODEL  = 32
-  PLATFORM         = linux-i586
-  VM_PLATFORM      = linux_i486
-  HS_ARCH          = x86
-endif
-
-# PPC64
-ifeq ($(ARCH), ppc64)
-  ARCH_DATA_MODEL  = 64
-  MAKE_ARGS        += LP64=1
-  PLATFORM         = linux-ppc64
-  VM_PLATFORM      = linux_ppc64
-  HS_ARCH          = ppc
+# PPC
+# Notice: after 8046471 ARCH will be 'ppc' for top-level ppc64 builds but
+# 'ppc64' for HotSpot-only ppc64 builds. Need to detect both variants here!
+ifneq (,$(findstring $(ARCH), ppc ppc64))
+  ifeq ($(ARCH_DATA_MODEL), 64)
+    MAKE_ARGS        += LP64=1
+    PLATFORM         = linux-ppc64
+    VM_PLATFORM      = linux_ppc64
+  else
+    ARCH_DATA_MODEL  = 32
+    PLATFORM         = linux-ppc
+    VM_PLATFORM      = linux_ppc
+  endif
+  HS_ARCH = ppc
 endif
 
 # On 32 bit linux we build server and client, on 64 bit just server.
--- a/src/cpu/ppc/vm/interpreter_ppc.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/ppc/vm/interpreter_ppc.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -296,8 +296,16 @@
   __ bind(do_float);
   __ lfs(floatSlot, 0, arg_java);
 #if defined(LINUX)
+  // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float
+  // in the least significant word of an argument slot.
+#if defined(VM_LITTLE_ENDIAN)
+  __ stfs(floatSlot, 0, arg_c);
+#else
   __ stfs(floatSlot, 4, arg_c);
+#endif
 #elif defined(AIX)
+  // Although AIX runs on big endian CPU, float is in most significant
+  // word of an argument slot.
   __ stfs(floatSlot, 0, arg_c);
 #else
 #error "unknown OS"
--- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -592,13 +592,6 @@
            "can't identify emitted call");
   } else {
     // variant 1:
-#if defined(ABI_ELFv2)
-    nop();
-    calculate_address_from_global_toc(R12, dest, true, true, false);
-    mtctr(R12);
-    nop();
-    nop();
-#else
     mr(R0, R11);  // spill R11 -> R0.
 
     // Load the destination address into CTR,
@@ -608,7 +601,6 @@
     mtctr(R11);
     mr(R11, R0);  // spill R11 <- R0.
     nop();
-#endif
 
     // do the call/jump
     if (link) {
--- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -766,6 +766,21 @@
     // in farg_reg[j] if argument i is the j-th float argument of this call.
     //
     case T_FLOAT:
+#if defined(LINUX)
+      // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float
+      // in the least significant word of an argument slot.
+#if defined(VM_LITTLE_ENDIAN)
+#define FLOAT_WORD_OFFSET_IN_SLOT 0
+#else
+#define FLOAT_WORD_OFFSET_IN_SLOT 1
+#endif
+#elif defined(AIX)
+      // Although AIX runs on big endian CPU, float is in the most
+      // significant word of an argument slot.
+#define FLOAT_WORD_OFFSET_IN_SLOT 0
+#else
+#error "unknown OS"
+#endif
       if (freg < Argument::n_float_register_parameters_c) {
         // Put float in register ...
         reg = farg_reg[freg];
@@ -779,14 +794,14 @@
         if (arg >= Argument::n_regs_not_on_stack_c) {
           // ... and on the stack.
           guarantee(regs2 != NULL, "must pass float in register and stack slot");
-          VMReg reg2 = VMRegImpl::stack2reg(stk LINUX_ONLY(+1));
+          VMReg reg2 = VMRegImpl::stack2reg(stk + FLOAT_WORD_OFFSET_IN_SLOT);
           regs2[i].set1(reg2);
           stk += inc_stk_for_intfloat;
         }
 
       } else {
         // Put float on stack.
-        reg = VMRegImpl::stack2reg(stk LINUX_ONLY(+1));
+        reg = VMRegImpl::stack2reg(stk + FLOAT_WORD_OFFSET_IN_SLOT);
         stk += inc_stk_for_intfloat;
       }
       regs[i].set1(reg);
--- a/src/cpu/sparc/vm/frame_sparc.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/sparc/vm/frame_sparc.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -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
@@ -447,32 +447,6 @@
 }
 #endif // CC_INTERP
 
-
-#ifdef ASSERT
-// Debugging aid
-static frame nth_sender(int n) {
-  frame f = JavaThread::current()->last_frame();
-
-  for(int i = 0; i < n; ++i)
-    f = f.sender((RegisterMap*)NULL);
-
-  printf("first frame %d\n",          f.is_first_frame()       ? 1 : 0);
-  printf("interpreted frame %d\n",    f.is_interpreted_frame() ? 1 : 0);
-  printf("java frame %d\n",           f.is_java_frame()        ? 1 : 0);
-  printf("entry frame %d\n",          f.is_entry_frame()       ? 1 : 0);
-  printf("native frame %d\n",         f.is_native_frame()      ? 1 : 0);
-  if (f.is_compiled_frame()) {
-    if (f.is_deoptimized_frame())
-      printf("deoptimized frame 1\n");
-    else
-      printf("compiled frame 1\n");
-  }
-
-  return f;
-}
-#endif
-
-
 frame frame::sender_for_entry_frame(RegisterMap *map) const {
   assert(map != NULL, "map must be set");
   // Java frame called from C; skip all C frames and return top C
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -6143,7 +6143,9 @@
     // Save caller's stack pointer into RBP if the frame pointer is preserved.
     if (PreserveFramePointer) {
       movptr(rbp, rsp);
-      addptr(rbp, framesize + wordSize);
+      if (framesize > 0) {
+        addptr(rbp, framesize);
+      }
     }
   }
 
--- a/src/cpu/x86/vm/x86_32.ad	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/x86/vm/x86_32.ad	Tue Jan 05 08:40:50 2016 -0800
@@ -566,7 +566,11 @@
     st->print("MOV    [ESP + #%d], EBP\t# Save EBP",framesize);
     if (PreserveFramePointer) {
       st->print("\n\t");
-      st->print("MOV    EBP, [ESP + #%d]\t# Save the caller's SP into EBP", (framesize + wordSize));
+      st->print("MOV    EBP, ESP\t# Save the caller's SP into EBP");
+      if (framesize > 0) {
+        st->print("\n\t");
+        st->print("ADD    EBP, #%d", framesize);
+      }
     }
   }
 
--- a/src/cpu/x86/vm/x86_64.ad	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/x86/vm/x86_64.ad	Tue Jan 05 08:40:50 2016 -0800
@@ -863,7 +863,11 @@
     st->print("movq    [rsp + #%d], rbp\t# Save rbp",framesize);    
     if (PreserveFramePointer) {
       st->print("\n\t");
-      st->print("movq    rbp, [rsp + #%d]\t# Save the caller's SP into rbp", (framesize + wordSize));
+      st->print("movq    rbp, rsp\t# Save the caller's SP into rbp");
+      if (framesize > 0) {
+        st->print("\n\t");
+        st->print("addq    rbp, #%d", framesize);
+      }      
     }
   }
 
--- a/src/cpu/zero/vm/frame_zero.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/cpu/zero/vm/frame_zero.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -216,7 +216,7 @@
     valuebuf[buflen - 1] = '\0';
 
     // Print the result
-    st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf);
+    st->print_cr(" " PTR_FORMAT ": %-21s = %s", p2i(addr), fieldbuf, valuebuf);
   }
 }
 
--- a/src/os/aix/vm/perfMemory_aix.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os/aix/vm/perfMemory_aix.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2013 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -454,13 +454,27 @@
     *saved_cwd_fd = result;
   }
 
-  // Set the current directory to dirname by using the fd of the directory.
+  // Set the current directory to dirname by using the fd of the directory and
+  // handle errors, otherwise shared memory files will be created in cwd.
   result = fchdir(fd);
-
-  return dirp;
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not change to directory %s", dirname);
+    }
+    if (*saved_cwd_fd != -1) {
+      ::close(*saved_cwd_fd);
+      *saved_cwd_fd = -1;
+    }
+    // Close the directory.
+    os::closedir(dirp);
+    return NULL;
+  } else {
+    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;
--- a/src/os/bsd/dtrace/hotspot.d	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os/bsd/dtrace/hotspot.d	Tue Jan 05 08:40:50 2016 -0800
@@ -47,8 +47,8 @@
   probe mem__pool__gc__end(
     char*, uintptr_t, char*, uintptr_t, 
     uintptr_t, uintptr_t, uintptr_t, uintptr_t);
-  probe thread__probe__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
-  probe thread__probe__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+  probe thread__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+  probe thread__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
   probe thread__sleep__begin(long long);
   probe thread__sleep__end(int);
   probe thread__yield();
@@ -68,7 +68,7 @@
   probe monitor__contended__entered(uintptr_t, uintptr_t, char*, uintptr_t);
   probe monitor__contended__exit(uintptr_t, uintptr_t, char*, uintptr_t);
   probe monitor__wait(uintptr_t, uintptr_t, char*, uintptr_t, uintptr_t);
-  probe monitor__probe__waited(uintptr_t, uintptr_t, char*, uintptr_t);
+  probe monitor__waited(uintptr_t, uintptr_t, char*, uintptr_t);
   probe monitor__notify(uintptr_t, uintptr_t, char*, uintptr_t);
   probe monitor__notifyAll(uintptr_t, uintptr_t, char*, uintptr_t);
 
--- a/src/os/bsd/vm/perfMemory_bsd.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os/bsd/vm/perfMemory_bsd.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -375,10 +375,23 @@
     *saved_cwd_fd = result;
   }
 
-  // Set the current directory to dirname by using the fd of the directory.
+  // Set the current directory to dirname by using the fd of the directory and
+  // handle errors, otherwise shared memory files will be created in cwd.
   result = fchdir(fd);
-
-  return dirp;
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not change to directory %s", dirname);
+    }
+    if (*saved_cwd_fd != -1) {
+      ::close(*saved_cwd_fd);
+      *saved_cwd_fd = -1;
+    }
+    // Close the directory.
+    os::closedir(dirp);
+    return NULL;
+  } else {
+    return dirp;
+  }
 }
 
 // Close the directory and restore the current working directory.
--- a/src/os/linux/vm/perfMemory_linux.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os/linux/vm/perfMemory_linux.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -374,10 +374,23 @@
     *saved_cwd_fd = result;
   }
 
-  // Set the current directory to dirname by using the fd of the directory.
+  // Set the current directory to dirname by using the fd of the directory and
+  // handle errors, otherwise shared memory files will be created in cwd.
   result = fchdir(fd);
-
-  return dirp;
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not change to directory %s", dirname);
+    }
+    if (*saved_cwd_fd != -1) {
+      ::close(*saved_cwd_fd);
+      *saved_cwd_fd = -1;
+    }
+    // Close the directory.
+    os::closedir(dirp);
+    return NULL;
+  } else {
+    return dirp;
+  }
 }
 
 // Close the directory and restore the current working directory.
--- a/src/os/solaris/vm/os_solaris.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -178,75 +178,6 @@
 
 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
 
-// Thread Local Storage
-// This is common to all Solaris platforms so it is defined here,
-// in this common file.
-// The declarations are in the os_cpu threadLS*.hpp files.
-//
-// Static member initialization for TLS
-Thread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL};
-
-#ifndef PRODUCT
-#define _PCT(n,d)       ((100.0*(double)(n))/(double)(d))
-
-int ThreadLocalStorage::_tcacheHit = 0;
-int ThreadLocalStorage::_tcacheMiss = 0;
-
-void ThreadLocalStorage::print_statistics() {
-  int total = _tcacheMiss+_tcacheHit;
-  tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n",
-                _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total));
-}
-#undef _PCT
-#endif // PRODUCT
-
-Thread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id,
-                                                        int index) {
-  Thread *thread = get_thread_slow();
-  if (thread != NULL) {
-    address sp = os::current_stack_pointer();
-    guarantee(thread->_stack_base == NULL ||
-              (sp <= thread->_stack_base &&
-                 sp >= thread->_stack_base - thread->_stack_size) ||
-               is_error_reported(),
-              "sp must be inside of selected thread stack");
-
-    thread->set_self_raw_id(raw_id);  // mark for quick retrieval
-    _get_thread_cache[ index ] = thread;
-  }
-  return thread;
-}
-
-
-static const double all_zero[ sizeof(Thread) / sizeof(double) + 1 ] = {0};
-#define NO_CACHED_THREAD ((Thread*)all_zero)
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-
-  // Store the new value before updating the cache to prevent a race
-  // between get_thread_via_cache_slowly() and this store operation.
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-
-  // Update thread cache with new thread if setting on thread create,
-  // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit.
-  uintptr_t raw = pd_raw_thread_id();
-  int ix = pd_cache_index(raw);
-  _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread;
-}
-
-void ThreadLocalStorage::pd_init() {
-  for (int i = 0; i < _pd_cache_size; i++) {
-    _get_thread_cache[i] = NO_CACHED_THREAD;
-  }
-}
-
-// Invalidate all the caches (happens to be the same as pd_init).
-void ThreadLocalStorage::pd_invalidate_all() { pd_init(); }
-
-#undef NO_CACHED_THREAD
-
-// END Thread Local Storage
-
 static inline size_t adjust_stack_size(address base, size_t size) {
   if ((ssize_t)size < 0) {
     // 4759953: Compensate for ridiculous stack size.
@@ -1473,64 +1404,6 @@
   return (int)(_initial_pid ? _initial_pid : getpid());
 }
 
-int os::allocate_thread_local_storage() {
-  // %%%       in Win32 this allocates a memory segment pointed to by a
-  //           register.  Dan Stein can implement a similar feature in
-  //           Solaris.  Alternatively, the VM can do the same thing
-  //           explicitly: malloc some storage and keep the pointer in a
-  //           register (which is part of the thread's context) (or keep it
-  //           in TLS).
-  // %%%       In current versions of Solaris, thr_self and TSD can
-  //           be accessed via short sequences of displaced indirections.
-  //           The value of thr_self is available as %g7(36).
-  //           The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4),
-  //           assuming that the current thread already has a value bound to k.
-  //           It may be worth experimenting with such access patterns,
-  //           and later having the parameters formally exported from a Solaris
-  //           interface.  I think, however, that it will be faster to
-  //           maintain the invariant that %g2 always contains the
-  //           JavaThread in Java code, and have stubs simply
-  //           treat %g2 as a caller-save register, preserving it in a %lN.
-  thread_key_t tk;
-  if (thr_keycreate( &tk, NULL ) )
-    fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed "
-                  "(%s)", strerror(errno)));
-  return int(tk);
-}
-
-void os::free_thread_local_storage(int index) {
-  // %%% don't think we need anything here
-  // if ( pthread_key_delete((pthread_key_t) tk) )
-  //   fatal("os::free_thread_local_storage: pthread_key_delete failed");
-}
-
-#define SMALLINT 32   // libthread allocate for tsd_common is a version specific
-                      // small number - point is NO swap space available
-void os::thread_local_storage_at_put(int index, void* value) {
-  // %%% this is used only in threadLocalStorage.cpp
-  if (thr_setspecific((thread_key_t)index, value)) {
-    if (errno == ENOMEM) {
-       vm_exit_out_of_memory(SMALLINT, OOM_MALLOC_ERROR,
-                             "thr_setspecific: out of swap space");
-    } else {
-      fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed "
-                    "(%s)", strerror(errno)));
-    }
-  } else {
-      ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ;
-  }
-}
-
-// This function could be called before TLS is initialized, for example, when
-// VM receives an async signal or when VM causes a fatal error during
-// initialization. Return NULL if thr_getspecific() fails.
-void* os::thread_local_storage_at(int index) {
-  // %%% this is used only in threadLocalStorage.cpp
-  void* r = NULL;
-  return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
-}
-
-
 // gethrtime() should be monotonic according to the documentation,
 // but some virtualized platforms are known to break this guarantee.
 // getTimeNanos() must be guaranteed not to move backwards, so we
--- a/src/os/solaris/vm/perfMemory_solaris.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os/solaris/vm/perfMemory_solaris.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -377,10 +377,23 @@
     *saved_cwd_fd = result;
   }
 
-  // Set the current directory to dirname by using the fd of the directory.
+  // Set the current directory to dirname by using the fd of the directory and
+  // handle errors, otherwise shared memory files will be created in cwd.
   result = fchdir(fd);
-
-  return dirp;
+  if (result == OS_ERR) {
+    if (PrintMiscellaneous && Verbose) {
+      warning("could not change to directory %s", dirname);
+    }
+    if (*saved_cwd_fd != -1) {
+      ::close(*saved_cwd_fd);
+      *saved_cwd_fd = -1;
+    }
+    // Close the directory.
+    os::closedir(dirp);
+    return NULL;
+  } else {
+    return dirp;
+  }
 }
 
 // Close the directory and restore the current working directory.
--- a/src/os/solaris/vm/thread_solaris.inline.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os/solaris/vm/thread_solaris.inline.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, 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
@@ -40,19 +40,12 @@
 // For SPARC, to avoid excessive register window spill-fill faults,
 // we aggressively inline these routines.
 
-inline Thread* ThreadLocalStorage::thread()  {
-  // don't use specialized code if +UseMallocOnly -- may confuse Purify et al.
-  debug_only(if (UseMallocOnly) return get_thread_slow(););
+inline void ThreadLocalStorage::set_thread(Thread* thread) {
+  _thr_current = thread;
+}
 
-  uintptr_t raw = pd_raw_thread_id();
-  int ix = pd_cache_index(raw);
-  Thread* candidate = ThreadLocalStorage::_get_thread_cache[ix];
-  if (candidate->self_raw_id() == raw) {
-    // hit
-    return candidate;
-  } else {
-    return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix);
-  }
+inline Thread* ThreadLocalStorage::thread()  {
+  return _thr_current;
 }
 
 #endif // OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
--- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -55,8 +55,8 @@
 #include "utilities/vmError.hpp"
 
 address os::current_stack_pointer() {
-  address dummy = (address) &dummy;
-  return dummy;
+  // return the address of the current function
+  return (address)__builtin_frame_address(0);
 }
 
 frame os::get_sender_for_C_frame(frame* fr) {
--- a/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,19 +26,26 @@
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadLocalStorage.hpp"
 
-// Provides an entry point we can link against and
-// a buffer we can emit code into. The buffer is
-// filled by ThreadLocalStorage::generate_code_for_get_thread
-// and called from ThreadLocalStorage::thread()
+// True thread-local variable
+__thread Thread * ThreadLocalStorage::_thr_current = NULL;
+
+// Implementations needed to support the shared API
 
-#include <sys/systeminfo.h>
+void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
 
-// The portable TLS mechanism (get_thread_via_cache) is enough on SPARC.
-// There is no need for hand-assembling a special function.
-void ThreadLocalStorage::generate_code_for_get_thread() {
+bool ThreadLocalStorage::_initialized = false;
+
+void ThreadLocalStorage::init() {
+  _initialized = true;
 }
 
-void ThreadLocalStorage::set_thread_in_slot (Thread * self) {}
+bool ThreadLocalStorage::is_initialized() {
+  return _initialized;
+}
+
+Thread* ThreadLocalStorage::get_thread_slow() {
+    return thread();
+}
 
 extern "C" Thread* get_thread() {
   return ThreadLocalStorage::thread();
--- a/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,47 +25,15 @@
 #ifndef OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
 #define OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
 
-public:
-  // Java Thread  - force inlining
-  static inline Thread* thread() ;
+// Solaris specific implementation involves simple, direct use
+// of a compiler-based thread-local variable
 
 private:
-  static Thread* _get_thread_cache[];  // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size]
-  static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index);
+  static __thread Thread * _thr_current;
 
-  NOT_PRODUCT(static int _tcacheHit;)
-  NOT_PRODUCT(static int _tcacheMiss;)
+  static bool _initialized;  // needed for shared API
 
 public:
-
-  // Print cache hit/miss statistics
-  static void print_statistics() PRODUCT_RETURN;
-
-  enum Constants {
-    _pd_cache_size         =  256*2  // projected typical # of threads * 2
-  };
-
-  static void set_thread_in_slot (Thread *) ;
-
-  static uintptr_t pd_raw_thread_id() {
-    return _raw_thread_id();
-  }
-
-  static int pd_cache_index(uintptr_t raw_id) {
-    // Hash function: From email from Dave:
-    // The hash function deserves an explanation.  %g7 points to libthread's
-    // "thread" structure.  On T1 the thread structure is allocated on the
-    // user's stack (yes, really!) so the ">>20" handles T1 where the JVM's
-    // stack size is usually >= 1Mb.  The ">>9" is for T2 where Roger allocates
-    // globs of thread blocks contiguously.  The "9" has to do with the
-    // expected size of the T2 thread structure.  If these constants are wrong
-    // the worst thing that'll happen is that the hit rate for heavily threaded
-    // apps won't be as good as it could be.  If you want to burn another
-    // shift+xor you could mix together _all of the %g7 bits to form the hash,
-    // but I think that's excessive.  Making the change above changed the
-    // T$ miss rate on SpecJBB (on a 16X system) from about 3% to imperceptible.
-    uintptr_t ix = (int) (((raw_id >> 9) ^ (raw_id >> 20)) % _pd_cache_size);
-    return ix;
-  }
+  static inline Thread* thread();
 
 #endif // OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
--- a/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, 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
@@ -23,11 +23,10 @@
  */
 
 #include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "runtime/os.hpp"
 #include "runtime/threadLocalStorage.hpp"
-
+#include "runtime/thread.inline.hpp"
 
 void MacroAssembler::int3() {
   push(rax);
@@ -39,98 +38,32 @@
   pop(rax);
 }
 
-#define __  _masm->
-#ifndef _LP64
-static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) {
-
-  // slow call to of thr_getspecific
-  // int thr_getspecific(thread_key_t key, void **value);
-  // Consider using pthread_getspecific instead.
-
-__  push(0);                                                            // allocate space for return value
-  if (thread != rax) __ push(rax);                                      // save rax, if caller still wants it
-__  push(rcx);                                                          // save caller save
-__  push(rdx);                                                          // save caller save
+// This is simply a call to ThreadLocalStorage::thread()
+void MacroAssembler::get_thread(Register thread) {
   if (thread != rax) {
-__    lea(thread, Address(rsp, 3 * sizeof(int)));                       // address of return value
-  } else {
-__    lea(thread, Address(rsp, 2 * sizeof(int)));                       // address of return value
+    push(rax);
   }
-__  push(thread);                                                       // and pass the address
-__  push(ThreadLocalStorage::thread_index());                           // the key
-__  call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific)));
-__  increment(rsp, 2 * wordSize);
-__  pop(rdx);
-__  pop(rcx);
-  if (thread != rax) __ pop(rax);
-__  pop(thread);
-
-}
-#else
-static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) {
-  // slow call to of thr_getspecific
-  // int thr_getspecific(thread_key_t key, void **value);
-  // Consider using pthread_getspecific instead.
+  push(rdi);
+  push(rsi);
+  push(rdx);
+  push(rcx);
+  push(r8);
+  push(r9);
+  push(r10);
+  push(r11);
 
+  call(RuntimeAddress(CAST_FROM_FN_PTR(address, ThreadLocalStorage::thread)));
+
+  pop(r11);
+  pop(r10);
+  pop(r9);
+  pop(r8);
+  pop(rcx);
+  pop(rdx);
+  pop(rsi);
+  pop(rdi);
   if (thread != rax) {
-__    push(rax);
-  }
-__  push(0); // space for return value
-__  push(rdi);
-__  push(rsi);
-__  lea(rsi, Address(rsp, 16)); // pass return value address
-__  push(rdx);
-__  push(rcx);
-__  push(r8);
-__  push(r9);
-__  push(r10);
-  // XXX
-__  mov(r10, rsp);
-__  andptr(rsp, -16);
-__  push(r10);
-__  push(r11);
-
-__  movl(rdi, ThreadLocalStorage::thread_index());
-__  call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific)));
-
-__  pop(r11);
-__  pop(rsp);
-__  pop(r10);
-__  pop(r9);
-__  pop(r8);
-__  pop(rcx);
-__  pop(rdx);
-__  pop(rsi);
-__  pop(rdi);
-__  pop(thread); // load return value
-  if (thread != rax) {
-__    pop(rax);
+    movl(thread, rax);
+    pop(rax);
   }
 }
-#endif //LP64
-
-void MacroAssembler::get_thread(Register thread) {
-
-  int segment = NOT_LP64(Assembler::GS_segment) LP64_ONLY(Assembler::FS_segment);
-  // Try to emit a Solaris-specific fast TSD/TLS accessor.
-  ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode ();
-  if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) {            // T1
-     // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset]
-     emit_int8 (segment);
-     // ExternalAddress doesn't work because it can't take NULL
-     AddressLiteral null(0, relocInfo::none);
-     movptr (thread, null);
-     movptr(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ;
-     return ;
-  } else
-  if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) {              // T2
-     // mov r, gs:[tlsOffset]
-     emit_int8 (segment);
-     AddressLiteral tls_off((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none);
-     movptr (thread, tls_off);
-     return ;
-  }
-
-  slow_call_thr_specific(this, thread);
-
-}
--- a/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,167 +26,27 @@
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadLocalStorage.hpp"
 
-#ifdef AMD64
-extern "C" Thread*  fs_load(ptrdiff_t tlsOffset);
-extern "C" intptr_t fs_thread();
-#else
-// From solaris_i486.s
-extern "C" Thread*  gs_load(ptrdiff_t tlsOffset);
-extern "C" intptr_t gs_thread();
-#endif // AMD64
+// True thread-local variable
+__thread Thread * ThreadLocalStorage::_thr_current = NULL;
+
+// Implementations needed to support the shared API
 
-// tlsMode encoding:
-//
-// pd_tlsAccessUndefined : uninitialized
-// pd_tlsAccessSlow      : not available
-// pd_tlsAccessIndirect  :
-//   old-style indirect access - present in "T1" libthread.
-//   use thr_slot_sync_allocate() to attempt to allocate a slot.
-// pd_tlsAccessDirect    :
-//   new-style direct access - present in late-model "T2" libthread.
-//   Allocate the offset (slot) via _thr_slot_offset() or by
-//   defining an IE- or LE-mode TLS/TSD slot in the launcher and then passing
-//   that offset into libjvm.so.
-//   See http://sac.eng/Archives/CaseLog/arc/PSARC/2003/159/.
-//
-// Note that we have a capability gap - some early model T2 forms
-// (e.g., unpatched S9) have neither _thr_slot_sync_allocate() nor
-// _thr_slot_offset().  In that case we revert to the usual
-// thr_getspecific accessor.
-//
+void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
 
-static ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_tlsAccessUndefined ;
-static ptrdiff_t tlsOffset = 0 ;
-static thread_key_t tlsKey ;
-
-typedef int (*TSSA_Entry) (ptrdiff_t *, int, int) ;
-typedef ptrdiff_t (*TSO_Entry) (int) ;
+bool ThreadLocalStorage::_initialized = false;
 
-ThreadLocalStorage::pd_tlsAccessMode ThreadLocalStorage::pd_getTlsAccessMode ()
-{
-   guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ;
-   return tlsMode ;
-}
-
-ptrdiff_t ThreadLocalStorage::pd_getTlsOffset () {
-   guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ;
-   return tlsOffset ;
+void ThreadLocalStorage::init() {
+  _initialized = true;
 }
 
-// TODO: Consider the following improvements:
-//
-// 1.   Convert from thr_*specific* to pthread_*specific*.
-//      The pthread_ forms are slightly faster.  Also, the
-//      pthread_ forms have a pthread_key_delete() API which
-//      would aid in clean JVM shutdown and the eventual goal
-//      of permitting a JVM to reinstantiate itself withing a process.
-//
-// 2.   See ThreadLocalStorage::init().  We end up allocating
-//      two TLS keys during VM startup.  That's benign, but we could collapse
-//      down to one key without too much trouble.
-//
-// 3.   MacroAssembler::get_thread() currently emits calls to thr_getspecific().
-//      Modify get_thread() to call Thread::current() instead.
-//
-// 4.   Thread::current() currently uses a cache keyed by %gs:[0].
-//      (The JVM has PSARC permission to use %g7/%gs:[0]
-//      as an opaque temporally unique thread identifier).
-//      For C++ access to a thread's reflexive "self" pointer we
-//      should consider using one of the following:
-//      a. a radix tree keyed by %esp - as in EVM.
-//         This requires two loads (the 2nd dependent on the 1st), but
-//         is easily inlined and doesn't require a "miss" slow path.
-//      b. a fast TLS/TSD slot allocated by _thr_slot_offset
-//         or _thr_slot_sync_allocate.
-//
-// 5.   'generate_code_for_get_thread' is a misnomer.
-//      We should change it to something more general like
-//      pd_ThreadSelf_Init(), for instance.
-//
-
-static void AllocateTLSOffset ()
-{
-   int rslt ;
-   TSSA_Entry tssa ;
-   TSO_Entry  tso ;
-   ptrdiff_t off ;
-
-   guarantee (tlsMode == ThreadLocalStorage::pd_tlsAccessUndefined, "tlsMode not set") ;
-   tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ;
-   tlsOffset = 0 ;
-#ifndef AMD64
-
-   tssa = (TSSA_Entry) dlsym (RTLD_DEFAULT, "thr_slot_sync_allocate") ;
-   if (tssa != NULL) {
-        off = -1 ;
-        rslt = (*tssa)(&off, NULL, NULL) ;                // (off,dtor,darg)
-        if (off != -1) {
-           tlsOffset = off ;
-           tlsMode = ThreadLocalStorage::pd_tlsAccessIndirect ;
-           return ;
-        }
-    }
-
-    rslt = thr_keycreate (&tlsKey, NULL) ;
-    if (rslt != 0) {
-        tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ;   // revert to slow mode
-        return ;
-    }
-
-    tso = (TSO_Entry) dlsym (RTLD_DEFAULT, "_thr_slot_offset") ;
-    if (tso != NULL) {
-        off = (*tso)(tlsKey) ;
-        if (off >= 0) {
-           tlsOffset = off ;
-           tlsMode = ThreadLocalStorage::pd_tlsAccessDirect ;
-           return ;
-        }
-    }
-
-    // Failure: Too bad ... we've allocated a TLS slot we don't need and there's
-    // no provision in the ABI for returning the slot.
-    //
-    // If we didn't find a slot then then:
-    // 1. We might be on liblwp.
-    // 2. We might be on T2 libthread, but all "fast" slots are already
-    //    consumed
-    // 3. We might be on T1, and all TSD (thr_slot_sync_allocate) slots are
-    //    consumed.
-    // 4. We might be on T2 libthread, but it's be re-architected
-    //    so that fast slots are no longer g7-relative.
-    //
-
-    tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ;
-    return ;
-#endif // AMD64
+bool ThreadLocalStorage::is_initialized() {
+  return _initialized;
 }
 
-void ThreadLocalStorage::generate_code_for_get_thread() {
-    AllocateTLSOffset() ;
+Thread* ThreadLocalStorage::get_thread_slow() {
+    return thread();
 }
 
-void ThreadLocalStorage::set_thread_in_slot(Thread *thread) {
-  guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ;
-  if (tlsMode == pd_tlsAccessIndirect) {
-#ifdef AMD64
-        intptr_t tbase = fs_thread();
-#else
-        intptr_t tbase = gs_thread();
-#endif // AMD64
-        *((Thread**) (tbase + tlsOffset)) = thread ;
-  } else
-  if (tlsMode == pd_tlsAccessDirect) {
-        thr_setspecific (tlsKey, (void *) thread) ;
-        // set with thr_setspecific and then readback with gs_load to validate.
-#ifdef AMD64
-        guarantee (thread == fs_load(tlsOffset), "tls readback failure") ;
-#else
-        guarantee (thread == gs_load(tlsOffset), "tls readback failure") ;
-#endif // AMD64
-  }
-}
-
-
 extern "C" Thread* get_thread() {
   return ThreadLocalStorage::thread();
 }
--- a/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,61 +25,15 @@
 #ifndef OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
 #define OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
 
-// Processor dependent parts of ThreadLocalStorage
+// Solaris specific implementation involves simple, direct use
+// of a compiler-based thread-local variable
 
 private:
-  static Thread* _get_thread_cache[];  // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size]
-  static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index);
+  static __thread Thread * _thr_current;
 
-  NOT_PRODUCT(static int _tcacheHit;)
-  NOT_PRODUCT(static int _tcacheMiss;)
+  static bool _initialized;  // needed for shared API
 
 public:
-  // Cache hit/miss statistics
-  static void print_statistics() PRODUCT_RETURN;
-
-  enum Constants {
-#ifdef AMD64
-    _pd_cache_size         =  256*2   // projected typical # of threads * 2
-#else
-    _pd_cache_size         =  128*2   // projected typical # of threads * 2
-#endif // AMD64
-  };
-
-  enum pd_tlsAccessMode {
-     pd_tlsAccessUndefined      = -1,
-     pd_tlsAccessSlow           = 0,
-     pd_tlsAccessIndirect       = 1,
-     pd_tlsAccessDirect         = 2
-  } ;
-
-  static void set_thread_in_slot (Thread *) ;
-
-  static pd_tlsAccessMode pd_getTlsAccessMode () ;
-  static ptrdiff_t pd_getTlsOffset () ;
-
-  static uintptr_t pd_raw_thread_id() {
-#ifdef _GNU_SOURCE
-#ifdef AMD64
-    uintptr_t rv;
-    __asm__ __volatile__ ("movq %%fs:0, %0" : "=r"(rv));
-    return rv;
-#else
-    return gs_thread();
-#endif // AMD64
-#else  //_GNU_SOURCE
-    return _raw_thread_id();
-#endif //_GNU_SOURCE
-  }
-
-  static int pd_cache_index(uintptr_t raw_id) {
-    // Copied from the sparc version. Dave said it should also work fine
-    // for solx86.
-    int ix = (int) (((raw_id >> 9) ^ (raw_id >> 20)) % _pd_cache_size);
-    return ix;
-  }
-
-  // Java Thread
   static inline Thread* thread();
 
 #endif // OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
--- a/src/share/vm/c1/c1_ValueType.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/c1/c1_ValueType.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -153,7 +153,19 @@
     case T_FLOAT  : return new FloatConstant (value.as_float ());
     case T_DOUBLE : return new DoubleConstant(value.as_double());
     case T_ARRAY  : // fall through (ciConstant doesn't have an array accessor)
-    case T_OBJECT : return new ObjectConstant(value.as_object());
+    case T_OBJECT : {
+      // TODO: Common the code with GraphBuilder::load_constant?
+      ciObject* obj = value.as_object();
+      if (obj->is_null_object())
+        return objectNull;
+      if (obj->is_loaded()) {
+        if (obj->is_array())
+          return new ArrayConstant(obj->as_array());
+        else if (obj->is_instance())
+          return new InstanceConstant(obj->as_instance());
+      }
+      return new ObjectConstant(obj);
+    }
   }
   ShouldNotReachHere();
   return illegalType;
--- a/src/share/vm/ci/ciField.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/ci/ciField.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -187,6 +187,14 @@
   // Even if general trusting is disabled, trust system-built closures in these packages.
   if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke"))
     return true;
+  // Trust Atomic*FieldUpdaters: they are very important for performance, and make up one
+  // more reason not to use Unsafe, if their final fields are trusted. See more in JDK-8140483.
+  if (holder->name() == ciSymbol::java_util_concurrent_atomic_AtomicIntegerFieldUpdater_Impl() ||
+      holder->name() == ciSymbol::java_util_concurrent_atomic_AtomicLongFieldUpdater_CASUpdater() ||
+      holder->name() == ciSymbol::java_util_concurrent_atomic_AtomicLongFieldUpdater_LockedUpdater() ||
+      holder->name() == ciSymbol::java_util_concurrent_atomic_AtomicReferenceFieldUpdater_Impl()) {
+    return true;
+  }
   return TrustFinalNonStaticFields;
 }
 
--- a/src/share/vm/classfile/classLoader.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/classfile/classLoader.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -414,30 +414,30 @@
 }
 #endif
 
-void ClassLoader::trace_class_path(const char* msg, const char* name) {
+void ClassLoader::trace_class_path(outputStream* out, const char* msg, const char* name) {
   if (!TraceClassPaths) {
     return;
   }
 
   if (msg) {
-    tty->print("%s", msg);
+    out->print("%s", msg);
   }
   if (name) {
     if (strlen(name) < 256) {
-      tty->print("%s", name);
+      out->print("%s", name);
     } else {
       // For very long paths, we need to print each character separately,
       // as print_cr() has a length limit
       while (name[0] != '\0') {
-        tty->print("%c", name[0]);
+        out->print("%c", name[0]);
         name++;
       }
     }
   }
   if (msg && msg[0] == '[') {
-    tty->print_cr("]");
+    out->print_cr("]");
   } else {
-    tty->cr();
+    out->cr();
   }
 }
 
@@ -583,7 +583,7 @@
     // Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
     // the same as the bootcp of the shared archive.
   } else {
-    trace_class_path("[Bootstrap loader class path=", sys_class_path);
+    trace_class_path(tty, "[Bootstrap loader class path=", sys_class_path);
   }
 #if INCLUDE_CDS
   if (DumpSharedSpaces) {
--- a/src/share/vm/classfile/classLoader.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/classfile/classLoader.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -346,7 +346,7 @@
   static void  exit_with_path_failure(const char* error, const char* message);
 #endif
 
-  static void  trace_class_path(const char* msg, const char* name = NULL);
+  static void  trace_class_path(outputStream* out, const char* msg, const char* name = NULL);
 
   // VM monitoring and management support
   static jlong classloader_time_ms();
--- a/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,7 @@
 }
 
 bool SharedPathsMiscInfo::fail(const char* msg, const char* name) {
-  ClassLoader::trace_class_path(msg, name);
+  ClassLoader::trace_class_path(tty, msg, name);
   MetaspaceShared::set_archive_loading_failed();
   return false;
 }
--- a/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,7 @@
   bool read(void* ptr, size_t size);
 
   static void trace_class_path(const char* msg, const char* name = NULL) {
-    ClassLoader::trace_class_path(msg, name);
+    ClassLoader::trace_class_path(tty, msg, name);
   }
 protected:
   static bool fail(const char* msg, const char* name = NULL);
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -203,7 +203,11 @@
   template(java_lang_StackTraceElement,               "java/lang/StackTraceElement")              \
                                                                                                   \
   /* Concurrency support */                                                                       \
-  template(java_util_concurrent_locks_AbstractOwnableSynchronizer,   "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
+  template(java_util_concurrent_locks_AbstractOwnableSynchronizer,           "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
+  template(java_util_concurrent_atomic_AtomicIntegerFieldUpdater_Impl,       "java/util/concurrent/atomic/AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl") \
+  template(java_util_concurrent_atomic_AtomicLongFieldUpdater_CASUpdater,    "java/util/concurrent/atomic/AtomicLongFieldUpdater$CASUpdater") \
+  template(java_util_concurrent_atomic_AtomicLongFieldUpdater_LockedUpdater, "java/util/concurrent/atomic/AtomicLongFieldUpdater$LockedUpdater") \
+  template(java_util_concurrent_atomic_AtomicReferenceFieldUpdater_Impl,     "java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl") \
   template(sun_misc_Contended_signature,              "Lsun/misc/Contended;")                     \
                                                                                                   \
   /* class symbols needed by intrinsics */                                                        \
--- a/src/share/vm/code/nmethod.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/code/nmethod.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1619,7 +1619,11 @@
       // During GC the is_alive closure is non-NULL, and is used to
       // determine liveness of dependees that need to be updated.
       if (is_alive == NULL || klass->is_loader_alive(is_alive)) {
-        InstanceKlass::cast(klass)->remove_dependent_nmethod(this);
+        // The GC defers deletion of this entry, since there might be multiple threads
+        // iterating over the _dependencies graph. Other call paths are single-threaded
+        // and may delete it immediately.
+        bool delete_immediately = is_alive == NULL;
+        InstanceKlass::cast(klass)->remove_dependent_nmethod(this, delete_immediately);
       }
     }
   }
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -2331,6 +2331,7 @@
     case GCCause::_java_lang_system_gc:     return ExplicitGCInvokesConcurrent;
     case GCCause::_g1_humongous_allocation: return true;
     case GCCause::_update_allocation_context_stats_inc: return true;
+    case GCCause::_wb_conc_mark:            return true;
     default:                                return false;
   }
 }
@@ -5045,12 +5046,8 @@
 public:
 
   void clean_klass(InstanceKlass* ik) {
-    ik->clean_implementors_list(_is_alive);
-    ik->clean_method_data(_is_alive);
-
-    // G1 specific cleanup work that has
-    // been moved here to be done in parallel.
-    ik->clean_dependent_nmethods();
+    ik->clean_weak_instanceklass_links(_is_alive);
+
     if (JvmtiExport::has_redefined_a_class()) {
       InstanceKlass::purge_previous_versions(ik);
     }
--- a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -90,12 +90,8 @@
 
 void VM_G1IncCollectionPause::doit() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  assert(!_should_initiate_conc_mark ||
-  ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
-   (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
-    _gc_cause == GCCause::_g1_humongous_allocation ||
-    _gc_cause == GCCause::_update_allocation_context_stats_inc),
-      "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle");
+  assert(!_should_initiate_conc_mark || g1h->should_do_concurrent_full_gc(_gc_cause),
+      "only a GC locker, a System.gc(), stats update, whitebox, or a hum allocation induced GC should start a cycle");
 
   if (_word_size > 0) {
     // An allocation has been requested. So, try to do that first.
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -348,7 +348,7 @@
     HeapWord*            _partial_obj_addr;
     region_sz_t          _partial_obj_size;
     region_sz_t volatile _dc_and_los;
-    bool                 _blocks_filled;
+    bool        volatile _blocks_filled;
 
 #ifdef ASSERT
     size_t               _blocks_filled_count;   // Number of block table fills.
@@ -499,7 +499,9 @@
 inline bool
 ParallelCompactData::RegionData::blocks_filled() const
 {
-  return _blocks_filled;
+  bool result = _blocks_filled;
+  OrderAccess::acquire();
+  return result;
 }
 
 #ifdef ASSERT
@@ -513,6 +515,7 @@
 inline void
 ParallelCompactData::RegionData::set_blocks_filled()
 {
+  OrderAccess::release();
   _blocks_filled = true;
   // Debug builds count the number of times the table was filled.
   DEBUG_ONLY(Atomic::inc_ptr(&_blocks_filled_count));
--- a/src/share/vm/gc_interface/gcCause.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/gc_interface/gcCause.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -54,6 +54,9 @@
     case _wb_young_gc:
       return "WhiteBox Initiated Young GC";
 
+    case _wb_conc_mark:
+      return "WhiteBox Initiated Concurrent Mark";
+
     case _update_allocation_context_stats_inc:
     case _update_allocation_context_stats_full:
       return "Update Allocation Context Stats";
--- a/src/share/vm/gc_interface/gcCause.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/gc_interface/gcCause.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -47,6 +47,7 @@
     _heap_inspection,
     _heap_dump,
     _wb_young_gc,
+    _wb_conc_mark,
     _update_allocation_context_stats_inc,
     _update_allocation_context_stats_full,
 
--- a/src/share/vm/memory/universe.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/memory/universe.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -847,12 +847,6 @@
     // See needs_explicit_null_check.
     // Only set the heap base for compressed oops because it indicates
     // compressed oops for pstack code.
-    bool verbose = PrintCompressedOopsMode || (PrintMiscellaneous && Verbose);
-    if (verbose) {
-      tty->cr();
-      tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
-                 Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
-    }
     if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax)) {
       // Can't reserve heap below 32Gb.
       // keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
@@ -862,16 +856,8 @@
       // are decoded so that NULL is preserved, so this page will not be accessed.
       Universe::set_narrow_oop_use_implicit_null_checks(false);
 #endif
-      if (verbose) {
-        tty->print(", %s: "PTR_FORMAT,
-            narrow_oop_mode_to_string(HeapBasedNarrowOop),
-            Universe::narrow_oop_base());
-      }
     } else {
       Universe::set_narrow_oop_base(0);
-      if (verbose) {
-        tty->print(", %s", narrow_oop_mode_to_string(ZeroBasedNarrowOop));
-      }
 #ifdef _WIN64
       if (!Universe::narrow_oop_use_implicit_null_checks()) {
         // Don't need guard page for implicit checks in indexed addressing
@@ -884,17 +870,14 @@
         Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
       } else {
         Universe::set_narrow_oop_shift(0);
-        if (verbose) {
-          tty->print(", %s", narrow_oop_mode_to_string(UnscaledNarrowOop));
-        }
       }
     }
 
-    if (verbose) {
-      tty->cr();
-      tty->cr();
+    Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
+
+    if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
+      Universe::print_compressed_oops_mode();
     }
-    Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
   }
   // Universe::narrow_oop_base() is one page below the heap.
   assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() -
@@ -915,6 +898,24 @@
   return JNI_OK;
 }
 
+void Universe::print_compressed_oops_mode() {
+  tty->cr();
+  tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
+              Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
+
+  tty->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode()));
+
+  if (Universe::narrow_oop_base() != 0) {
+    tty->print(":" PTR_FORMAT, Universe::narrow_oop_base());
+  }
+
+  if (Universe::narrow_oop_shift() != 0) {
+    tty->print(", Oop shift amount: %d", Universe::narrow_oop_shift());
+  }
+
+  tty->cr();
+  tty->cr();
+}
 
 // Reserve the Java heap, which is now the same for all GCs.
 ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
@@ -984,11 +985,11 @@
 const char* Universe::narrow_oop_mode_to_string(Universe::NARROW_OOP_MODE mode) {
   switch (mode) {
     case UnscaledNarrowOop:
-      return "32-bits Oops";
+      return "32-bit";
     case ZeroBasedNarrowOop:
-      return "zero based Compressed Oops";
+      return "Zero based";
     case HeapBasedNarrowOop:
-      return "Compressed Oops with base";
+      return "Non-zero based";
   }
 
   ShouldNotReachHere();
--- a/src/share/vm/memory/universe.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/memory/universe.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -376,6 +376,8 @@
   static void     set_narrow_ptrs_base(address a)         { _narrow_ptrs_base = a; }
   static address  narrow_ptrs_base()                      { return _narrow_ptrs_base; }
 
+  static void     print_compressed_oops_mode();
+
   // this is set in vm_version on sparc (and then reset in universe afaict)
   static void     set_narrow_oop_shift(int shift)         {
     _narrow_oop._shift   = shift;
--- a/src/share/vm/oops/instanceKlass.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/oops/instanceKlass.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1969,7 +1969,7 @@
 // find a corresponding bucket otherwise there's a bug in the
 // recording of dependecies.
 //
-void InstanceKlass::remove_dependent_nmethod(nmethod* nm) {
+void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) {
   assert_locked_or_safepoint(CodeCache_lock);
   nmethodBucket* b = _dependencies;
   nmethodBucket* last = NULL;
@@ -1978,7 +1978,17 @@
       int val = b->decrement();
       guarantee(val >= 0, err_msg("Underflow: %d", val));
       if (val == 0) {
-        set_has_unloaded_dependent(true);
+        if (delete_immediately) {
+          if (last == NULL) {
+            _dependencies = b->next();
+          } else {
+            last->set_next(b->next());
+          }
+          delete b;
+        } else {
+          // The deletion of this entry is deferred until a later, potentially parallel GC phase.
+          set_has_unloaded_dependent(true);
+        }
       }
       return;
     }
@@ -2318,6 +2328,13 @@
 
 #endif // INCLUDE_ALL_GCS
 
+void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) {
+  clean_implementors_list(is_alive);
+  clean_method_data(is_alive);
+
+  clean_dependent_nmethods();
+}
+
 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
   assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
   if (is_interface()) {
--- a/src/share/vm/oops/instanceKlass.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/oops/instanceKlass.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -785,7 +785,7 @@
   // maintenance of deoptimization dependencies
   int mark_dependent_nmethods(DepChange& changes);
   void add_dependent_nmethod(nmethod* nm);
-  void remove_dependent_nmethod(nmethod* nm);
+  void remove_dependent_nmethod(nmethod* nm, bool delete_immediately);
 
   // On-stack replacement support
   nmethod* osr_nmethods_head() const         { return _osr_nmethods_head; };
@@ -974,6 +974,7 @@
   void oop_follow_contents(oop obj);
   int  oop_adjust_pointers(oop obj);
 
+  void clean_weak_instanceklass_links(BoolObjectClosure* is_alive);
   void clean_implementors_list(BoolObjectClosure* is_alive);
   void clean_method_data(BoolObjectClosure* is_alive);
   void clean_dependent_nmethods();
--- a/src/share/vm/oops/klass.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/oops/klass.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -454,8 +454,7 @@
     // Clean the implementors list and method data.
     if (clean_alive_klasses && current->oop_is_instance()) {
       InstanceKlass* ik = InstanceKlass::cast(current);
-      ik->clean_implementors_list(is_alive);
-      ik->clean_method_data(is_alive);
+      ik->clean_weak_instanceklass_links(is_alive);
     }
   }
 }
--- a/src/share/vm/opto/c2_globals.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/c2_globals.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -205,6 +205,9 @@
   notproduct(bool, TraceProfileTripCount, false,                            \
           "Trace profile loop trip count information")                      \
                                                                             \
+  product(bool, UseCountedLoopSafepoints, false,                            \
+          "Force counted loops to keep a safepoint")                        \
+                                                                            \
   product(bool, UseLoopPredicate, true,                                     \
           "Generate a predicate to select fast/slow loop versions")         \
                                                                             \
@@ -669,6 +672,9 @@
   product_pd(bool, TrapBasedRangeChecks,                                    \
           "Generate code for range checks that uses a cmp and trap "        \
           "instruction raising SIGTRAP. Used on PPC64.")                    \
+                                                                            \
+  develop(bool, RenumberLiveNodes, true,                                    \
+          "Renumber live nodes")                                            \
 
 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
 
--- a/src/share/vm/opto/compile.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/compile.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -2093,6 +2093,20 @@
   // so keep only the actual candidates for optimizations.
   cleanup_expensive_nodes(igvn);
 
+  if (!failing() && RenumberLiveNodes && live_nodes() + NodeLimitFudgeFactor < unique()) {
+    NOT_PRODUCT(Compile::TracePhase t2("", &_t_renumberLive, TimeCompiler);)
+    initial_gvn()->replace_with(&igvn);
+    for_igvn()->clear();
+    Unique_Node_List new_worklist(C->comp_arena());
+    {
+      ResourceMark rm;
+      PhaseRenumberLive prl = PhaseRenumberLive(initial_gvn(), for_igvn(), &new_worklist);
+    }
+    set_for_igvn(&new_worklist);
+    igvn = PhaseIterGVN(initial_gvn());
+    igvn.optimize();
+  }
+
   // Perform escape analysis
   if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
     if (has_loops()) {
--- a/src/share/vm/opto/loopnode.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/loopnode.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -685,14 +685,16 @@
 
   } // LoopLimitCheck
 
-  // Check for SafePoint on backedge and remove
-  Node *sfpt = x->in(LoopNode::LoopBackControl);
-  if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
-    lazy_replace( sfpt, iftrue );
-    if (loop->_safepts != NULL) {
-      loop->_safepts->yank(sfpt);
+  if (!UseCountedLoopSafepoints) {
+    // Check for SafePoint on backedge and remove
+    Node *sfpt = x->in(LoopNode::LoopBackControl);
+    if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
+      lazy_replace( sfpt, iftrue );
+      if (loop->_safepts != NULL) {
+        loop->_safepts->yank(sfpt);
+      }
+      loop->_tail = iftrue;
     }
-    loop->_tail = iftrue;
   }
 
   // Build a canonical trip test.
@@ -781,12 +783,14 @@
   lazy_replace( x, l );
   set_idom(l, init_control, dom_depth(x));
 
-  // Check for immediately preceding SafePoint and remove
-  Node *sfpt2 = le->in(0);
-  if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) {
-    lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
-    if (loop->_safepts != NULL) {
-      loop->_safepts->yank(sfpt2);
+  if (!UseCountedLoopSafepoints) {
+    // Check for immediately preceding SafePoint and remove
+    Node *sfpt2 = le->in(0);
+    if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) {
+      lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
+      if (loop->_safepts != NULL) {
+        loop->_safepts->yank(sfpt2);
+      }
     }
   }
 
@@ -1806,6 +1810,37 @@
   }
 }
 
+void IdealLoopTree::remove_safepoints(PhaseIdealLoop* phase, bool keep_one) {
+  Node* keep = NULL;
+  if (keep_one) {
+    // Look for a safepoint on the idom-path.
+    for (Node* i = tail(); i != _head; i = phase->idom(i)) {
+      if (i->Opcode() == Op_SafePoint && phase->get_loop(i) == this) {
+        keep = i;
+        break; // Found one
+      }
+    }
+  }
+
+  // Don't remove any safepoints if it is requested to keep a single safepoint and
+  // no safepoint was found on idom-path. It is not safe to remove any safepoint
+  // in this case since there's no safepoint dominating all paths in the loop body.
+  bool prune = !keep_one || keep != NULL;
+
+  // Delete other safepoints in this loop.
+  Node_List* sfpts = _safepts;
+  if (prune && sfpts != NULL) {
+    assert(keep == NULL || keep->Opcode() == Op_SafePoint, "not safepoint");
+    for (uint i = 0; i < sfpts->size(); i++) {
+      Node* n = sfpts->at(i);
+      assert(phase->get_loop(n) == this, "");
+      if (n != keep && phase->is_deleteable_safept(n)) {
+        phase->lazy_replace(n, n->in(TypeFunc::Control));
+      }
+    }
+  }
+}
+
 //------------------------------counted_loop-----------------------------------
 // Convert to counted loops where possible
 void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) {
@@ -1817,42 +1852,23 @@
 
   if (_head->is_CountedLoop() ||
       phase->is_counted_loop(_head, this)) {
-    _has_sfpt = 1;              // Indicate we do not need a safepoint here
-
-    // Look for safepoints to remove.
-    Node_List* sfpts = _safepts;
-    if (sfpts != NULL) {
-      for (uint i = 0; i < sfpts->size(); i++) {
-        Node* n = sfpts->at(i);
-        assert(phase->get_loop(n) == this, "");
-        if (phase->is_deleteable_safept(n)) {
-          phase->lazy_replace(n, n->in(TypeFunc::Control));
-        }
-      }
+
+    if (!UseCountedLoopSafepoints) {
+      // Indicate we do not need a safepoint here
+      _has_sfpt = 1;
     }
 
+    // Remove safepoints
+    bool keep_one_sfpt = !(_has_call || _has_sfpt);
+    remove_safepoints(phase, keep_one_sfpt);
+
     // Look for induction variables
     phase->replace_parallel_iv(this);
 
   } else if (_parent != NULL && !_irreducible) {
-    // Not a counted loop.
-    // Look for a safepoint on the idom-path.
-    Node* sfpt = tail();
-    for (; sfpt != _head; sfpt = phase->idom(sfpt)) {
-      if (sfpt->Opcode() == Op_SafePoint && phase->get_loop(sfpt) == this)
-        break; // Found one
-    }
-    // Delete other safepoints in this loop.
-    Node_List* sfpts = _safepts;
-    if (sfpts != NULL && sfpt != _head && sfpt->Opcode() == Op_SafePoint) {
-      for (uint i = 0; i < sfpts->size(); i++) {
-        Node* n = sfpts->at(i);
-        assert(phase->get_loop(n) == this, "");
-        if (n != sfpt && phase->is_deleteable_safept(n)) {
-          phase->lazy_replace(n, n->in(TypeFunc::Control));
-        }
-      }
-    }
+    // Not a counted loop. Keep one safepoint.
+    bool keep_one_sfpt = true;
+    remove_safepoints(phase, keep_one_sfpt);
   }
 
   // Recursively
@@ -1906,6 +1922,15 @@
     if (cl->is_main_loop()) tty->print(" main");
     if (cl->is_post_loop()) tty->print(" post");
   }
+  if (_has_call) tty->print(" has_call");
+  if (_has_sfpt) tty->print(" has_sfpt");
+  if (_rce_candidate) tty->print(" rce");
+  if (_safepts != NULL && _safepts->size() > 0) {
+    tty->print(" sfpts={"); _safepts->dump_simple(); tty->print(" }");
+  }
+  if (_required_safept != NULL && _required_safept->size() > 0) {
+    tty->print(" req={"); _required_safept->dump_simple(); tty->print(" }");
+  }
   tty->cr();
 }
 
--- a/src/share/vm/opto/loopnode.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/loopnode.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -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
@@ -403,6 +403,9 @@
   // encountered.
   void allpaths_check_safepts(VectorSet &visited, Node_List &stack);
 
+  // Remove safepoints from loop. Optionally keeping one.
+  void remove_safepoints(PhaseIdealLoop* phase, bool keep_one);
+
   // Convert to counted loops where possible
   void counted_loop( PhaseIdealLoop *phase );
 
--- a/src/share/vm/opto/node.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/node.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -325,6 +325,9 @@
 // Create a Node, with a given number of required edges.
 Node::Node(uint req)
   : _idx(IDX_INIT(req))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   assert( req < Compile::current()->max_node_limit() - NodeLimitFudgeFactor, "Input limit exceeded" );
   debug_only( verify_construction() );
@@ -344,6 +347,9 @@
 //------------------------------Node-------------------------------------------
 Node::Node(Node *n0)
   : _idx(IDX_INIT(1))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
@@ -356,6 +362,9 @@
 //------------------------------Node-------------------------------------------
 Node::Node(Node *n0, Node *n1)
   : _idx(IDX_INIT(2))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
@@ -370,6 +379,9 @@
 //------------------------------Node-------------------------------------------
 Node::Node(Node *n0, Node *n1, Node *n2)
   : _idx(IDX_INIT(3))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
@@ -386,6 +398,9 @@
 //------------------------------Node-------------------------------------------
 Node::Node(Node *n0, Node *n1, Node *n2, Node *n3)
   : _idx(IDX_INIT(4))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
@@ -404,6 +419,9 @@
 //------------------------------Node-------------------------------------------
 Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4)
   : _idx(IDX_INIT(5))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
@@ -425,6 +443,9 @@
 Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
                      Node *n4, Node *n5)
   : _idx(IDX_INIT(6))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
@@ -448,6 +469,9 @@
 Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
                      Node *n4, Node *n5, Node *n6)
   : _idx(IDX_INIT(7))
+#ifdef ASSERT
+  , _parse_idx(_idx)
+#endif
 {
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
@@ -2083,6 +2107,17 @@
 #endif
 }
 
+void Node_List::dump_simple() const {
+#ifndef PRODUCT
+  for( uint i = 0; i < _cnt; i++ )
+    if( _nodes[i] ) {
+      tty->print(" %d", _nodes[i]->_idx);
+    } else {
+      tty->print(" NULL");
+    }
+#endif
+}
+
 //=============================================================================
 //------------------------------remove-----------------------------------------
 void Unique_Node_List::remove( Node *n ) {
--- a/src/share/vm/opto/node.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/node.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -294,10 +294,16 @@
 
  public:
   // Each Node is assigned a unique small/dense number.  This number is used
-  // to index into auxiliary arrays of data and bitvectors.
-  // It is declared const to defend against inadvertant assignment,
-  // since it is used by clients as a naked field.
+  // to index into auxiliary arrays of data and bit vectors.
+  // The field _idx is declared constant to defend against inadvertent assignments,
+  // since it is used by clients as a naked field. However, the field's value can be
+  // changed using the set_idx() method.
+  //
+  // The PhaseRenumberLive phase renumbers nodes based on liveness information.
+  // Therefore, it updates the value of the _idx field. The parse-time _idx is
+  // preserved in _parse_idx.
   const node_idx_t _idx;
+  DEBUG_ONLY(const node_idx_t _parse_idx;)
 
   // Get the (read-only) number of input edges
   uint req() const { return _cnt; }
@@ -1368,6 +1374,7 @@
   void clear() { _cnt = 0; Node_Array::clear(); } // retain storage
   uint size() const { return _cnt; }
   void dump() const;
+  void dump_simple() const;
 };
 
 //------------------------------Unique_Node_List-------------------------------
--- a/src/share/vm/opto/phase.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/phase.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -67,6 +67,8 @@
 elapsedTimer   Phase::_t_iterGVN;
 elapsedTimer   Phase::_t_iterGVN2;
 elapsedTimer   Phase::_t_incrInline;
+elapsedTimer   Phase::_t_renumberLive;
+
 
 // Subtimers for _t_registerAllocation
 elapsedTimer   Phase::_t_ctorChaitin;
@@ -115,13 +117,14 @@
     }
     tty->print_cr ("      iterGVN        : %3.3f sec", Phase::_t_iterGVN.seconds());
     tty->print_cr ("      incrInline     : %3.3f sec", Phase::_t_incrInline.seconds());
+    tty->print_cr ("      renumberLive   : %3.3f sec", Phase::_t_renumberLive.seconds());
     tty->print_cr ("      idealLoop      : %3.3f sec", Phase::_t_idealLoop.seconds());
     tty->print_cr ("      idealLoopVerify: %3.3f sec", Phase::_t_idealLoopVerify.seconds());
     tty->print_cr ("      ccp            : %3.3f sec", Phase::_t_ccp.seconds());
     tty->print_cr ("      iterGVN2       : %3.3f sec", Phase::_t_iterGVN2.seconds());
     tty->print_cr ("      macroExpand    : %3.3f sec", Phase::_t_macroExpand.seconds());
     tty->print_cr ("      graphReshape   : %3.3f sec", Phase::_t_graphReshaping.seconds());
-    double optimizer_subtotal = Phase::_t_iterGVN.seconds() + Phase::_t_iterGVN2.seconds() +
+    double optimizer_subtotal = Phase::_t_iterGVN.seconds() + Phase::_t_iterGVN2.seconds() + Phase::_t_renumberLive.seconds() +
       Phase::_t_escapeAnalysis.seconds() + Phase::_t_macroEliminate.seconds() +
       Phase::_t_idealLoop.seconds() + Phase::_t_ccp.seconds() +
       Phase::_t_macroExpand.seconds() + Phase::_t_graphReshaping.seconds();
--- a/src/share/vm/opto/phase.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/phase.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -40,22 +40,23 @@
 class Phase : public StackObj {
 public:
   enum PhaseNumber {
-    Compiler,                   // Top-level compiler phase
-    Parser,                     // Parse bytecodes
-    Remove_Useless,             // Remove useless nodes
-    Optimistic,                 // Optimistic analysis phase
-    GVN,                        // Pessimistic global value numbering phase
-    Ins_Select,                 // Instruction selection phase
-    CFG,                        // Build a CFG
-    BlockLayout,                // Linear ordering of blocks
-    Register_Allocation,        // Register allocation, duh
-    LIVE,                       // Dragon-book LIVE range problem
-    StringOpts,                 // StringBuilder related optimizations
-    Interference_Graph,         // Building the IFG
-    Coalesce,                   // Coalescing copies
-    Ideal_Loop,                 // Find idealized trip-counted loops
-    Macro_Expand,               // Expand macro nodes
-    Peephole,                   // Apply peephole optimizations
+    Compiler,                         // Top-level compiler phase
+    Parser,                           // Parse bytecodes
+    Remove_Useless,                   // Remove useless nodes
+    Remove_Useless_And_Renumber_Live, // First, remove useless nodes from the graph. Then, renumber live nodes.
+    Optimistic,                       // Optimistic analysis phase
+    GVN,                              // Pessimistic global value numbering phase
+    Ins_Select,                       // Instruction selection phase
+    CFG,                              // Build a CFG
+    BlockLayout,                      // Linear ordering of blocks
+    Register_Allocation,              // Register allocation, duh
+    LIVE,                             // Dragon-book LIVE range problem
+    StringOpts,                       // StringBuilder related optimizations
+    Interference_Graph,               // Building the IFG
+    Coalesce,                         // Coalescing copies
+    Ideal_Loop,                       // Find idealized trip-counted loops
+    Macro_Expand,                     // Expand macro nodes
+    Peephole,                         // Apply peephole optimizations
     last_phase
   };
 protected:
@@ -102,6 +103,7 @@
   static elapsedTimer   _t_iterGVN;
   static elapsedTimer   _t_iterGVN2;
   static elapsedTimer   _t_incrInline;
+  static elapsedTimer   _t_renumberLive;
 
 // Subtimers for _t_registerAllocation
   static elapsedTimer   _t_ctorChaitin;
--- a/src/share/vm/opto/phaseX.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/phaseX.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -398,7 +398,7 @@
 //=============================================================================
 //------------------------------PhaseRemoveUseless-----------------------------
 // 1) Use a breadthfirst walk to collect useful nodes reachable from root.
-PhaseRemoveUseless::PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist ) : Phase(Remove_Useless),
+PhaseRemoveUseless::PhaseRemoveUseless(PhaseGVN *gvn, Unique_Node_List *worklist, PhaseNumber phase_num) : Phase(phase_num),
   _useful(Thread::current()->resource_area()) {
 
   // Implementation requires 'UseLoopSafepoints == true' and an edge from root
@@ -435,6 +435,82 @@
   }
 }
 
+//=============================================================================
+//------------------------------PhaseRenumberLive------------------------------
+// First, remove useless nodes (equivalent to identifying live nodes).
+// Then, renumber live nodes.
+//
+// The set of live nodes is returned by PhaseRemoveUseless in the _useful structure.
+// If the number of live nodes is 'x' (where 'x' == _useful.size()), then the
+// PhaseRenumberLive updates the node ID of each node (the _idx field) with a unique
+// value in the range [0, x).
+//
+// At the end of the PhaseRenumberLive phase, the compiler's count of unique nodes is
+// updated to 'x' and the list of dead nodes is reset (as there are no dead nodes).
+//
+// The PhaseRenumberLive phase updates two data structures with the new node IDs.
+// (1) The worklist is used by the PhaseIterGVN phase to identify nodes that must be
+// processed. A new worklist (with the updated node IDs) is returned in 'new_worklist'.
+// (2) Type information (the field PhaseGVN::_types) maps type information to each
+// node ID. The mapping is updated to use the new node IDs as well. Updated type
+// information is returned in PhaseGVN::_types.
+//
+// The PhaseRenumberLive phase does not preserve the order of elements in the worklist.
+//
+// Other data structures used by the compiler are not updated. The hash table for value
+// numbering (the field PhaseGVN::_table) is not updated because computing the hash
+// values is not based on node IDs. The field PhaseGVN::_nodes is not updated either
+// because it is empty wherever PhaseRenumberLive is used.
+PhaseRenumberLive::PhaseRenumberLive(PhaseGVN* gvn,
+                                     Unique_Node_List* worklist, Unique_Node_List* new_worklist,
+                                     PhaseNumber phase_num) :
+  PhaseRemoveUseless(gvn, worklist, Remove_Useless_And_Renumber_Live) {
+
+  assert(RenumberLiveNodes, "RenumberLiveNodes must be set to true for node renumbering to take place");
+  assert(C->live_nodes() == _useful.size(), "the number of live nodes must match the number of useful nodes");
+  assert(gvn->nodes_size() == 0, "GVN must not contain any nodes at this point");
+
+  uint old_unique_count = C->unique();
+  uint live_node_count = C->live_nodes();
+  uint worklist_size = worklist->size();
+
+  // Storage for the updated type information.
+  Type_Array new_type_array(C->comp_arena());
+
+  // Iterate over the set of live nodes.
+  uint current_idx = 0; // The current new node ID. Incremented after every assignment.
+  for (uint i = 0; i < _useful.size(); i++) {
+    Node* n = _useful.at(i);
+    const Type* type = gvn->type_or_null(n);
+    new_type_array.map(current_idx, type);
+
+    bool in_worklist = false;
+    if (worklist->member(n)) {
+      in_worklist = true;
+    }
+
+    n->set_idx(current_idx); // Update node ID.
+
+    if (in_worklist) {
+      new_worklist->push(n);
+    }
+
+    current_idx++;
+  }
+
+  assert(worklist_size == new_worklist->size(), "the new worklist must have the same size as the original worklist");
+  assert(live_node_count == current_idx, "all live nodes must be processed");
+
+  // Replace the compiler's type information with the updated type information.
+  gvn->replace_types(new_type_array);
+
+  // Update the unique node count of the compilation to the number of currently live nodes.
+  C->set_unique(live_node_count);
+
+  // Set the dead node count to 0 and reset dead node list.
+  C->reset_dead_node_list();
+}
+
 
 //=============================================================================
 //------------------------------PhaseTransform---------------------------------
--- a/src/share/vm/opto/phaseX.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/opto/phaseX.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -148,11 +148,21 @@
   Unique_Node_List _useful;   // Nodes reachable from root
                               // list is allocated from current resource area
 public:
-  PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist );
+  PhaseRemoveUseless(PhaseGVN *gvn, Unique_Node_List *worklist, PhaseNumber phase_num = Remove_Useless);
 
   Unique_Node_List *get_useful() { return &_useful; }
 };
 
+//------------------------------PhaseRenumber----------------------------------
+// Phase that first performs a PhaseRemoveUseless, then it renumbers compiler
+// structures accordingly.
+class PhaseRenumberLive : public PhaseRemoveUseless {
+public:
+  PhaseRenumberLive(PhaseGVN* gvn,
+                    Unique_Node_List* worklist, Unique_Node_List* new_worklist,
+                    PhaseNumber phase_num = Remove_Useless_And_Renumber_Live);
+};
+
 
 //------------------------------PhaseTransform---------------------------------
 // Phases that analyze, then transform.  Constructing the Phase object does any
@@ -162,7 +172,7 @@
 class PhaseTransform : public Phase {
 protected:
   Arena*     _arena;
-  Node_Array _nodes;           // Map old node indices to new nodes.
+  Node_List  _nodes;           // Map old node indices to new nodes.
   Type_Array _types;           // Map old node indices to Types.
 
   // ConNode caches:
@@ -187,7 +197,13 @@
 
   Arena*      arena()   { return _arena; }
   Type_Array& types()   { return _types; }
+  void replace_types(Type_Array new_types) {
+    _types = new_types;
+  }
   // _nodes is used in varying ways by subclasses, which define local accessors
+  uint nodes_size() {
+    return _nodes.size();
+  }
 
 public:
   // Get a previously recorded type for the node n.
--- a/src/share/vm/prims/jni.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/prims/jni.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1796,34 +1796,34 @@
 
 // the runtime type of subword integral basic types is integer
 DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN
-                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLBOOLEANMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLBOOLEANMETHODV_RETURN(_ret_ref))
 DEFINE_CALLMETHODV(jbyte,    Byte,    T_BYTE
-                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLBYTEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLBYTEMETHODV_RETURN(_ret_ref))
 DEFINE_CALLMETHODV(jchar,    Char,    T_CHAR
-                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLCHARMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLCHARMETHODV_RETURN(_ret_ref))
 DEFINE_CALLMETHODV(jshort,   Short,   T_SHORT
-                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLSHORTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLSHORTMETHODV_RETURN(_ret_ref))
 
 DEFINE_CALLMETHODV(jobject,  Object,  T_OBJECT
-                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLOBJECTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLOBJECTMETHODV_RETURN(_ret_ref))
 DEFINE_CALLMETHODV(jint,     Int,     T_INT,
-                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
+                  HOTSPOT_JNI_CALLINTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLINTMETHODV_RETURN(_ret_ref))
 DEFINE_CALLMETHODV(jlong,    Long,    T_LONG
-                  , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLLONGMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLLONGMETHODV_RETURN(_ret_ref))
 // Float and double probes don't return value because dtrace doesn't currently support it
 DEFINE_CALLMETHODV(jfloat,   Float,   T_FLOAT
-                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
+                  , HOTSPOT_JNI_CALLFLOATMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLFLOATMETHODV_RETURN())
 DEFINE_CALLMETHODV(jdouble,  Double,  T_DOUBLE
-                  , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
+                  , HOTSPOT_JNI_CALLDOUBLEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLDOUBLEMETHODV_RETURN())
 
 #define DEFINE_CALLMETHODA(ResultType, Result, Tag \
                           , EntryProbe, ReturnProbe)    \
@@ -1848,34 +1848,34 @@
 
 // the runtime type of subword integral basic types is integer
 DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN
-                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLBOOLEANMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLBOOLEANMETHODA_RETURN(_ret_ref))
 DEFINE_CALLMETHODA(jbyte,    Byte,    T_BYTE
-                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLBYTEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLBYTEMETHODA_RETURN(_ret_ref))
 DEFINE_CALLMETHODA(jchar,    Char,    T_CHAR
-                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLCHARMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLCHARMETHODA_RETURN(_ret_ref))
 DEFINE_CALLMETHODA(jshort,   Short,   T_SHORT
-                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLSHORTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLSHORTMETHODA_RETURN(_ret_ref))
 
 DEFINE_CALLMETHODA(jobject,  Object,  T_OBJECT
-                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLOBJECTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLOBJECTMETHODA_RETURN(_ret_ref))
 DEFINE_CALLMETHODA(jint,     Int,     T_INT,
-                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
+                  HOTSPOT_JNI_CALLINTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLINTMETHODA_RETURN(_ret_ref))
 DEFINE_CALLMETHODA(jlong,    Long,    T_LONG
-                  , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
+                  , HOTSPOT_JNI_CALLLONGMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLLONGMETHODA_RETURN(_ret_ref))
 // Float and double probes don't return value because dtrace doesn't currently support it
 DEFINE_CALLMETHODA(jfloat,   Float,   T_FLOAT
-                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
+                  , HOTSPOT_JNI_CALLFLOATMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLFLOATMETHODA_RETURN())
 DEFINE_CALLMETHODA(jdouble,  Double,  T_DOUBLE
-                  , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
-                  HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
+                  , HOTSPOT_JNI_CALLDOUBLEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
+                  HOTSPOT_JNI_CALLDOUBLEMETHODA_RETURN())
 
 DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
@@ -3137,7 +3137,7 @@
 JNI_END
 
 DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z
-                      , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
+                      , HOTSPOT_JNI_SETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
                       HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
 DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b
                       , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
--- a/src/share/vm/prims/whitebox.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/prims/whitebox.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -45,6 +45,7 @@
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
 #include "gc_implementation/g1/concurrentMark.hpp"
+#include "gc_implementation/g1/concurrentMarkThread.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
 #endif // INCLUDE_ALL_GCS
@@ -323,8 +324,16 @@
 
 WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
   G1CollectedHeap* g1 = G1CollectedHeap::heap();
-  ConcurrentMark* cm = g1->concurrent_mark();
-  return cm->concurrent_marking_in_progress();
+  return g1->concurrent_mark()->cmThread()->during_cycle();
+WB_END
+
+WB_ENTRY(jboolean, WB_G1StartMarkCycle(JNIEnv* env, jobject o))
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  if (!g1h->concurrent_mark()->cmThread()->during_cycle()) {
+    g1h->collect(GCCause::_wb_conc_mark);
+    return true;
+  }
+  return false;
 WB_END
 
 WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
@@ -1031,6 +1040,7 @@
   {CC"g1NumMaxRegions",    CC"()J",                   (void*)&WB_G1NumMaxRegions  },
   {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
   {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
+  {CC"g1StartConcMarkCycle",       CC"()Z",           (void*)&WB_G1StartMarkCycle  },
   {CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;",
                                                       (void*)&WB_G1AuxiliaryMemoryUsage  },
 #endif // INCLUDE_ALL_GCS
--- a/src/share/vm/runtime/arguments.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -3414,7 +3414,7 @@
   }
 
   if (!PrintSharedArchiveAndExit) {
-    ClassLoader::trace_class_path("[classpath: ", _java_class_path->value());
+    ClassLoader::trace_class_path(tty, "[classpath: ", _java_class_path->value());
   }
 }
 
--- a/src/share/vm/runtime/safepoint.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/runtime/safepoint.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -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
@@ -739,80 +739,12 @@
 // ------------------------------------------------------------------------------------------------------
 // Exception handlers
 
-#ifndef PRODUCT
-
-#ifdef SPARC
-
-#ifdef _LP64
-#define PTR_PAD ""
-#else
-#define PTR_PAD "        "
-#endif
-
-static void print_ptrs(intptr_t oldptr, intptr_t newptr, bool wasoop) {
-  bool is_oop = newptr ? (cast_to_oop(newptr))->is_oop() : false;
-  tty->print_cr(PTR_FORMAT PTR_PAD " %s %c " PTR_FORMAT PTR_PAD " %s %s",
-                oldptr, wasoop?"oop":"   ", oldptr == newptr ? ' ' : '!',
-                newptr, is_oop?"oop":"   ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":"     "));
-}
-
-static void print_longs(jlong oldptr, jlong newptr, bool wasoop) {
-  bool is_oop = newptr ? (cast_to_oop(newptr))->is_oop() : false;
-  tty->print_cr(PTR64_FORMAT " %s %c " PTR64_FORMAT " %s %s",
-                oldptr, wasoop?"oop":"   ", oldptr == newptr ? ' ' : '!',
-                newptr, is_oop?"oop":"   ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":"     "));
-}
-
-static void print_me(intptr_t *new_sp, intptr_t *old_sp, bool *was_oops) {
-#ifdef _LP64
-  tty->print_cr("--------+------address-----+------before-----------+-------after----------+");
-  const int incr = 1;           // Increment to skip a long, in units of intptr_t
-#else
-  tty->print_cr("--------+--address-+------before-----------+-------after----------+");
-  const int incr = 2;           // Increment to skip a long, in units of intptr_t
-#endif
-  tty->print_cr("---SP---|");
-  for( int i=0; i<16; i++ ) {
-    tty->print("blob %c%d |"PTR_FORMAT" ","LO"[i>>3],i&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
-  tty->print_cr("--------|");
-  for( int i1=0; i1<frame::memory_parameter_word_sp_offset-16; i1++ ) {
-    tty->print("argv pad|"PTR_FORMAT" ",new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
-  tty->print("     pad|"PTR_FORMAT" ",new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++);
-  tty->print_cr("--------|");
-  tty->print(" G1     |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
-  tty->print(" G3     |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
-  tty->print(" G4     |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
-  tty->print(" G5     |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
-  tty->print_cr(" FSR    |"PTR_FORMAT" "PTR64_FORMAT"       "PTR64_FORMAT,new_sp,*(jlong*)old_sp,*(jlong*)new_sp);
-  old_sp += incr; new_sp += incr; was_oops += incr;
-  // Skip the floats
-  tty->print_cr("--Float-|"PTR_FORMAT,new_sp);
-  tty->print_cr("---FP---|");
-  old_sp += incr*32;  new_sp += incr*32;  was_oops += incr*32;
-  for( int i2=0; i2<16; i2++ ) {
-    tty->print("call %c%d |"PTR_FORMAT" ","LI"[i2>>3],i2&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
-  tty->cr();
-}
-#endif  // SPARC
-#endif  // PRODUCT
-
 
 void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) {
   assert(thread->is_Java_thread(), "polling reference encountered by VM thread");
   assert(thread->thread_state() == _thread_in_Java, "should come from Java code");
   assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
 
-  // Uncomment this to get some serious before/after printing of the
-  // Sparc safepoint-blob frame structure.
-  /*
-  intptr_t* sp = thread->last_Java_sp();
-  intptr_t stack_copy[150];
-  for( int i=0; i<150; i++ ) stack_copy[i] = sp[i];
-  bool was_oops[150];
-  for( int i=0; i<150; i++ )
-    was_oops[i] = stack_copy[i] ? ((oop)stack_copy[i])->is_oop() : false;
-  */
-
   if (ShowSafepointMsgs) {
     tty->print("handle_polling_page_exception: ");
   }
@@ -824,7 +756,6 @@
   ThreadSafepointState* state = thread->safepoint_state();
 
   state->handle_polling_page_exception();
-  // print_me(sp,stack_copy,was_oops);
 }
 
 
--- a/src/share/vm/runtime/synchronizer.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/runtime/synchronizer.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -121,7 +121,7 @@
     }                                                                      \
   }
 
-#define HOTSPOT_MONITOR_PROBE_waited HOTSPOT_MONITOR_PROBE_WAITED
+#define HOTSPOT_MONITOR_PROBE_waited HOTSPOT_MONITOR_WAITED
 
 #define DTRACE_MONITOR_PROBE(probe, monitor, obj, thread)                  \
   {                                                                        \
--- a/src/share/vm/runtime/thread.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/runtime/thread.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -141,8 +141,8 @@
 
 #else /* USDT2 */
 
-#define HOTSPOT_THREAD_PROBE_start HOTSPOT_THREAD_PROBE_START
-#define HOTSPOT_THREAD_PROBE_stop HOTSPOT_THREAD_PROBE_STOP
+#define HOTSPOT_THREAD_PROBE_start HOTSPOT_THREAD_START
+#define HOTSPOT_THREAD_PROBE_stop HOTSPOT_THREAD_STOP
 
 #define DTRACE_THREAD_PROBE(probe, javathread)                             \
   {                                                                        \
--- a/src/share/vm/runtime/threadLocalStorage.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/runtime/threadLocalStorage.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, 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
@@ -38,6 +38,11 @@
 # include "os_bsd.inline.hpp"
 #endif
 
+// Solaris no longer has this kind of ThreadLocalStorage implementation.
+// This will be removed from all platforms in the near future.
+
+#ifndef SOLARIS
+
 // static member initialization
 int ThreadLocalStorage::_thread_index = -1;
 
@@ -65,3 +70,5 @@
 bool ThreadLocalStorage::is_initialized() {
     return (thread_index() != -1);
 }
+
+#endif // SOLARIS
--- a/src/share/vm/runtime/threadLocalStorage.hpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/runtime/threadLocalStorage.hpp	Tue Jan 05 08:40:50 2016 -0800
@@ -38,10 +38,14 @@
 extern "C" uintptr_t _raw_thread_id();
 
 class ThreadLocalStorage : AllStatic {
+
+ // Exported API
  public:
   static void    set_thread(Thread* thread);
   static Thread* get_thread_slow();
   static void    invalidate_all() { pd_invalidate_all(); }
+  static void    init();
+  static bool    is_initialized();
 
   // Machine dependent stuff
 #ifdef TARGET_OS_ARCH_linux_x86
@@ -78,17 +82,12 @@
 # include "threadLS_bsd_zero.hpp"
 #endif
 
-
+#ifndef SOLARIS
  public:
   // Accessor
   static inline int  thread_index()              { return _thread_index; }
   static inline void set_thread_index(int index) { _thread_index = index; }
 
-  // Initialization
-  // Called explicitly from VMThread::activate_system instead of init_globals.
-  static void init();
-  static bool is_initialized();
-
  private:
   static int     _thread_index;
 
@@ -97,6 +96,9 @@
   // Processor dependent parts of set_thread and initialization
   static void pd_set_thread(Thread* thread);
   static void pd_init();
+
+#endif // SOLARIS
+
   // Invalidate any thread cacheing or optimization schemes.
   static void pd_invalidate_all();
 
--- a/src/share/vm/utilities/vmError.cpp	Tue Dec 22 12:28:01 2015 -0800
+++ b/src/share/vm/utilities/vmError.cpp	Tue Jan 05 08:40:50 2016 -0800
@@ -229,7 +229,7 @@
 
   if (signame) {
     jio_snprintf(buf, buflen,
-                 "%s (0x%x) at pc=" PTR_FORMAT ", pid=%d, tid=" UINTX_FORMAT,
+                 "%s (0x%x) at pc=" PTR_FORMAT ", pid=%d, tid=" INTPTR_FORMAT,
                  signame, _id, _pc,
                  os::current_process_id(), os::current_thread_id());
   } else if (_filename != NULL && _lineno > 0) {
@@ -237,7 +237,7 @@
     char separator = os::file_separator()[0];
     const char *p = strrchr(_filename, separator);
     int n = jio_snprintf(buf, buflen,
-                         "Internal Error at %s:%d, pid=%d, tid=" UINTX_FORMAT,
+                         "Internal Error at %s:%d, pid=%d, tid=" INTPTR_FORMAT,
                          p ? p + 1 : _filename, _lineno,
                          os::current_process_id(), os::current_thread_id());
     if (n >= 0 && n < buflen && _message) {
@@ -251,7 +251,7 @@
     }
   } else {
     jio_snprintf(buf, buflen,
-                 "Internal Error (0x%x), pid=%d, tid=" UINTX_FORMAT,
+                 "Internal Error (0x%x), pid=%d, tid=" INTPTR_FORMAT,
                  _id, os::current_process_id(), os::current_thread_id());
   }
 
@@ -438,7 +438,7 @@
 
      // process id, thread id
      st->print(", pid=%d", os::current_process_id());
-     st->print(", tid=" UINTX_FORMAT, os::current_thread_id());
+     st->print(", tid=" INTPTR_FORMAT, os::current_thread_id());
      st->cr();
 
   STEP(40, "(printing error message)")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/loopopts/UseCountedLoopSafepoints.java	Tue Jan 05 08:40:50 2016 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6869327
+ * @summary Test that C2 flag UseCountedLoopSafepoints ensures a safepoint is kept in a CountedLoop
+ * @library /testlibrary
+ * @run main UseCountedLoopSafepoints
+ */
+
+import java.util.concurrent.atomic.AtomicLong;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class UseCountedLoopSafepoints {
+    private static final AtomicLong _num = new AtomicLong(0);
+
+    // Uses the fact that an EnableBiasedLocking vmop will be started
+    // after 500ms, while we are still in the loop. If there is a
+    // safepoint in the counted loop, then we will reach safepoint
+    // very quickly. Otherwise SafepointTimeout will be hit.
+    public static void main (String args[]) throws Exception {
+        if (args.length == 1) {
+            final int loops = Integer.parseInt(args[0]);
+            for (int i = 0; i < loops; i++) {
+                _num.addAndGet(1);
+            }
+        } else {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                    "-XX:+IgnoreUnrecognizedVMOptions",
+                    "-XX:-TieredCompilation",
+                    "-XX:+UseBiasedLocking",
+                    "-XX:BiasedLockingStartupDelay=500",
+                    "-XX:+SafepointTimeout",
+                    "-XX:SafepointTimeoutDelay=2000",
+                    "-XX:+UseCountedLoopSafepoints",
+                    "UseCountedLoopSafepoints",
+                    "2000000000"
+                    );
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+            output.shouldNotContain("Timeout detected");
+            output.shouldHaveExitValue(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/whitebox/TestConcMarkCycleWB.java	Tue Jan 05 08:40:50 2016 -0800
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test TestConMarkCycleWB
+ * @bug 8065579
+ * @requires vm.gc=="null" | vm.gc=="G1"
+ * @library /testlibrary /testlibrary/whitebox
+ * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.WhiteBox TestConcMarkCycleWB
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC TestConcMarkCycleWB
+ * @summary Verifies that ConcurrentMarking-related WB works properly
+ */
+import static com.oracle.java.testlibrary.Asserts.assertFalse;
+import static com.oracle.java.testlibrary.Asserts.assertTrue;
+import sun.hotspot.WhiteBox;
+
+public class TestConcMarkCycleWB {
+
+    public static void main(String[] args) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        wb.youngGC();
+        assertTrue(wb.g1StartConcMarkCycle());
+        while (wb.g1InConcurrentMark()) {
+            Thread.sleep(5);
+        }
+
+        wb.fullGC();
+        assertTrue(wb.g1StartConcMarkCycle());
+        while (wb.g1InConcurrentMark()) {
+            Thread.sleep(5);
+        }
+        assertTrue(wb.g1StartConcMarkCycle());
+    }
+}
--- a/test/runtime/NMT/JcmdWithNMTDisabled.java	Tue Dec 22 12:28:01 2015 -0800
+++ b/test/runtime/NMT/JcmdWithNMTDisabled.java	Tue Jan 05 08:40:50 2016 -0800
@@ -26,10 +26,7 @@
  * @key nmt jcmd
  * @summary Verify that jcmd correctly reports that NMT is not enabled
  * @library /testlibrary
- * First run without enabling NMT
- * @run main/othervm JcmdWithNMTDisabled
- * Then run with explicitly disabling NMT, should not be any difference
- * @run main/othervm -XX:NativeMemoryTracking=off JcmdWithNMTDisabled
+ * @run main JcmdWithNMTDisabled 1
  */
 
 import com.oracle.java.testlibrary.*;
@@ -39,6 +36,27 @@
   static String pid;
 
   public static void main(String args[]) throws Exception {
+
+    // This test explicitly needs to be run with the exact command lines below, not passing on
+    // arguments from the parent VM is a conscious choice to avoid NMT being turned on.
+    if (args.length > 0) {
+      ProcessBuilder pb;
+      OutputAnalyzer output;
+      String testjdkPath = System.getProperty("test.jdk");
+
+      // First run without enabling NMT
+      pb = ProcessTools.createJavaProcessBuilder("-Dtest.jdk=" + testjdkPath, "JcmdWithNMTDisabled");
+      output = new OutputAnalyzer(pb.start());
+      output.shouldHaveExitValue(0);
+
+      // Then run with explicitly disabling NMT, should not be any difference
+      pb = ProcessTools.createJavaProcessBuilder("-Dtest.jdk=" + testjdkPath, "-XX:NativeMemoryTracking=off", "JcmdWithNMTDisabled");
+      output = new OutputAnalyzer(pb.start());
+      output.shouldHaveExitValue(0);
+
+      return;
+    }
+
     // Grab my own PID
     pid = Integer.toString(ProcessTools.getProcessId());
 
--- a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Tue Dec 22 12:28:01 2015 -0800
+++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Tue Jan 05 08:40:50 2016 -0800
@@ -74,11 +74,12 @@
    * @param expectedString String that buffer should contain
    * @throws RuntimeException If the string was not found
    */
-  public void shouldContain(String expectedString) {
+  public OutputAnalyzer shouldContain(String expectedString) {
     if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
         reportDiagnosticSummary();
         throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n");
     }
+    return this;
   }
 
   /**
@@ -87,11 +88,12 @@
    * @param expectedString String that buffer should contain
    * @throws RuntimeException If the string was not found
    */
-  public void stdoutShouldContain(String expectedString) {
+  public OutputAnalyzer stdoutShouldContain(String expectedString) {
     if (!stdout.contains(expectedString)) {
         reportDiagnosticSummary();
         throw new RuntimeException("'" + expectedString + "' missing from stdout \n");
     }
+    return this;
   }
 
   /**
@@ -100,11 +102,12 @@
    * @param expectedString String that buffer should contain
    * @throws RuntimeException If the string was not found
    */
-  public void stderrShouldContain(String expectedString) {
+  public OutputAnalyzer stderrShouldContain(String expectedString) {
     if (!stderr.contains(expectedString)) {
         reportDiagnosticSummary();
         throw new RuntimeException("'" + expectedString + "' missing from stderr \n");
     }
+    return this;
   }
 
   /**
@@ -113,7 +116,7 @@
    * @param expectedString String that the buffer should not contain
    * @throws RuntimeException If the string was found
    */
-  public void shouldNotContain(String notExpectedString) {
+  public OutputAnalyzer shouldNotContain(String notExpectedString) {
     if (stdout.contains(notExpectedString)) {
         reportDiagnosticSummary();
         throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
@@ -122,6 +125,7 @@
         reportDiagnosticSummary();
         throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
     }
+    return this;
   }
 
   /**
@@ -130,11 +134,12 @@
    * @param expectedString String that the buffer should not contain
    * @throws RuntimeException If the string was found
    */
-  public void stdoutShouldNotContain(String notExpectedString) {
+  public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
     if (stdout.contains(notExpectedString)) {
         reportDiagnosticSummary();
         throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
     }
+    return this;
   }
 
   /**
@@ -143,11 +148,12 @@
    * @param expectedString String that the buffer should not contain
    * @throws RuntimeException If the string was found
    */
-  public void stderrShouldNotContain(String notExpectedString) {
+  public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
     if (stderr.contains(notExpectedString)) {
         reportDiagnosticSummary();
         throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
     }
+    return this;
   }
 
   /**
@@ -157,7 +163,7 @@
    * @param pattern
    * @throws RuntimeException If the pattern was not found
    */
-  public void shouldMatch(String pattern) {
+  public OutputAnalyzer shouldMatch(String pattern) {
       Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (!stdoutMatcher.find() && !stderrMatcher.find()) {
@@ -165,6 +171,7 @@
           throw new RuntimeException("'" + pattern
                 + "' missing from stdout/stderr \n");
       }
+      return this;
   }
 
   /**
@@ -174,13 +181,14 @@
    * @param pattern
    * @throws RuntimeException If the pattern was not found
    */
-  public void stdoutShouldMatch(String pattern) {
+  public OutputAnalyzer stdoutShouldMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (!matcher.find()) {
           reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
                 + "' missing from stdout \n");
       }
+      return this;
   }
 
   /**
@@ -190,13 +198,14 @@
    * @param pattern
    * @throws RuntimeException If the pattern was not found
    */
-  public void stderrShouldMatch(String pattern) {
+  public OutputAnalyzer stderrShouldMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (!matcher.find()) {
           reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
                 + "' missing from stderr \n");
       }
+      return this;
   }
 
   /**
@@ -206,7 +215,7 @@
    * @param pattern
    * @throws RuntimeException If the pattern was found
    */
-  public void shouldNotMatch(String pattern) {
+  public OutputAnalyzer shouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (matcher.find()) {
           reportDiagnosticSummary();
@@ -219,6 +228,7 @@
           throw new RuntimeException("'" + pattern
                   + "' found in stderr: '" + matcher.group() + "' \n");
       }
+      return this;
   }
 
   /**
@@ -228,13 +238,14 @@
    * @param pattern
    * @throws RuntimeException If the pattern was found
    */
-  public void stdoutShouldNotMatch(String pattern) {
+  public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (matcher.find()) {
           reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
                   + "' found in stdout \n");
       }
+      return this;
   }
 
   /**
@@ -244,13 +255,14 @@
    * @param pattern
    * @throws RuntimeException If the pattern was found
    */
-  public void stderrShouldNotMatch(String pattern) {
+  public OutputAnalyzer stderrShouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (matcher.find()) {
           reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
                   + "' found in stderr \n");
       }
+      return this;
   }
 
   /**
@@ -290,12 +302,13 @@
    * @param expectedExitValue Expected exit value from process
    * @throws RuntimeException If the exit value from the process did not match the expected value
    */
-  public void shouldHaveExitValue(int expectedExitValue) {
+  public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
       if (getExitValue() != expectedExitValue) {
           reportDiagnosticSummary();
           throw new RuntimeException("Expected to get exit value of ["
                   + expectedExitValue + "]\n");
       }
+      return this;
   }
 
 
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Tue Dec 22 12:28:01 2015 -0800
+++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Tue Jan 05 08:40:50 2016 -0800
@@ -174,12 +174,16 @@
   public native long incMetaspaceCapacityUntilGC(long increment);
   public native long metaspaceCapacityUntilGC();
 
-  // force Young GC
+  // Force Young GC
   public native void youngGC();
 
-  // force Full GC
+  // Force Full GC
   public native void fullGC();
 
+  // Method tries to start concurrent mark cycle.
+  // It returns false if CM Thread is always in concurrent cycle.
+  public native boolean g1StartConcMarkCycle();
+
   // Tests on ReservedSpace/VirtualSpace classes
   public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations);
   public native void runMemoryUnitTests();